Forráskód Böngészése

Made ResponseCalls strategy only execute if no successful responses exist.

shalvah 5 éve
szülő
commit
d23710171d

+ 2 - 0
docs/documenting.md

@@ -318,3 +318,5 @@ If you don't specify an example response using any of the above means, this pack
 - You can set Laravel config variables. This is useful so you can prevent external services like notifications from being triggered. By default the `app.env` is set to 'documentation'. You can add more variables in the `config` key.
 
 - By default, the package will generate dummy values for your documented body and query parameters and send in the request. If you specified example values using `@bodyParam` or `@queryParam`, those will be used instead. You can configure additional parameters or overwrite the existing ones for the request in the `queryParams`, and `bodyParams` sections.
+
+- The `ResponseCalls` strategy will only attempt to fetch a response if there are no responses with a status code of 2xx already.

+ 2 - 1
docs/plugins.md

@@ -165,4 +165,5 @@ Each strategy class must implement the __invoke method with the parameters as de
         ]
     }
 ```
-Responses are _additive_. This means all the responses returned from each stage are added together.
+
+Responses are _additive_. This means all the responses returned from each stage are added to the `responses` array. But note that the `ResponseCalls` strategy will only attempt to fetch a response if there are no responses with a status code of 2xx already.

+ 6 - 3
src/Strategies/Responses/ResponseCalls.php

@@ -313,15 +313,18 @@ class ResponseCalls extends Strategy
      *
      * @return bool
      */
-    private function shouldMakeApiCall(Route $route, array $rulesToApply, array $context): bool
+    protected function shouldMakeApiCall(Route $route, array $rulesToApply, array $context): bool
     {
         $allowedMethods = $rulesToApply['methods'] ?? [];
         if (empty($allowedMethods)) {
             return false;
         }
 
-        if (! empty($context['responses'])) {
-            // Don't attempt a response call if there are already responses
+        // Don't attempt a response call if there are already successful responses
+        $successResponses = collect($context['responses'])->filter(function ($response) {
+            return ((string) $response['status'])[0] == '2';
+        })->count();
+        if ($successResponses) {
             return false;
         }
 

+ 6 - 3
src/Tools/Generator.php

@@ -117,7 +117,9 @@ class Generator
     {
         $responses = $this->iterateThroughStrategies('responses', $context, [$route, $controller, $method, $rulesToApply]);
         if (count($responses)) {
-            return $responses;
+            return array_filter($responses, function ($response) {
+                return $response['content'] != null;
+            });
         }
 
         return null;
@@ -152,8 +154,9 @@ class Generator
         $context[$stage] = $context[$stage] ?? [];
         foreach ($strategies as $strategyClass) {
             $strategy = new $strategyClass($stage, $this->config);
-            $arguments[] = $context;
-            $results = $strategy(...$arguments);
+            $strategyArgs = $arguments;
+            $strategyArgs[] = $context;
+            $results = $strategy(...$strategyArgs);
             if (! is_null($results)) {
                 foreach ($results as $index => $item) {
                     if ($stage == "responses") {

+ 2 - 0
tests/Fixtures/TestController.php

@@ -4,6 +4,7 @@ namespace Mpociot\ApiDoc\Tests\Fixtures;
 
 use Illuminate\Http\Request;
 use Illuminate\Routing\Controller;
+use Mpociot\ApiDoc\Tests\Unit\GeneratorTestCase;
 
 /**
  * @group Group A
@@ -258,6 +259,7 @@ class TestController extends Controller
      */
     public function withResponseTag()
     {
+        GeneratorTestCase::$globalValue = rand();
         return '';
     }
 

+ 9 - 26
tests/Fixtures/index.md

@@ -61,11 +61,6 @@ fetch(url, {
 ```
 
 
-> Example response:
-
-```json
-null
-```
 
 ### HTTP Request
 `GET api/withDescription`
@@ -191,11 +186,6 @@ fetch(url, {
 ```
 
 
-> Example response:
-
-```json
-null
-```
 
 ### HTTP Request
 `GET api/withBodyParameters`
@@ -264,11 +254,6 @@ fetch(url, {
 ```
 
 
-> Example response:
-
-```json
-null
-```
 
 ### HTTP Request
 `GET api/withQueryParameters`
@@ -320,11 +305,6 @@ fetch(url, {
 ```
 
 
-> Example response:
-
-```json
-null
-```
 
 ### HTTP Request
 `GET api/withAuthTag`
@@ -370,11 +350,9 @@ fetch(url, {
 
 ```json
 {
-    "data": {
-        "id": 0,
-        "name": "Tested Again",
-        "email": "a@b.com"
-    }
+    "id": 4,
+    "name": "Tested Again",
+    "email": "a@b.com"
 }
 ```
 
@@ -487,7 +465,12 @@ fetch(url, {
 {
     "data": [
         {
-            "id": 0,
+            "id": 4,
+            "name": "Tested Again",
+            "email": "a@b.com"
+        },
+        {
+            "id": 4,
             "name": "Tested Again",
             "email": "a@b.com"
         }

+ 1 - 1
tests/GenerateDocumentationTest.php

@@ -37,7 +37,7 @@ class GenerateDocumentationTest extends TestCase
 
     public function tearDown(): void
     {
-        //      Utils::deleteDirectoryAndContents('/public/docs');
+             Utils::deleteDirectoryAndContents('/public/docs');
     }
 
     /**

+ 48 - 1
tests/Unit/GeneratorTestCase.php

@@ -39,9 +39,10 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ],
         'default_group' => 'general',
-
     ];
 
+    public static $globalValue = null;
+
     protected function getPackageProviders($app)
     {
         return [
@@ -672,6 +673,52 @@ abstract class GeneratorTestCase extends TestCase
         ], json_decode($response['content'], true));
     }
 
+    /** @test */
+    public function does_not_make_response_call_if_success_response_already_gotten()
+    {
+        $route = $this->createRoute('POST', '/withResponseTag', 'withResponseTag', true);
+
+        $rules = [
+            'headers' => [
+                'Content-Type' => 'application/json',
+                'Accept' => 'application/json',
+            ],
+            'response_calls' => [
+                'methods' => ['*'],
+            ],
+        ];
+        $config = [
+            'strategies' => [
+                'responses' => [
+                    \Mpociot\ApiDoc\Strategies\Responses\UseResponseTag::class,
+                    \Mpociot\ApiDoc\Strategies\Responses\ResponseCalls::class,
+                ],
+            ],
+        ];
+        $generator = new Generator(new DocumentationConfig($config));
+        $parsed = $generator->processRoute($route, $rules);
+
+        $this->assertCount(1, $parsed['responses']);
+        $response = Arr::first($parsed['responses']);
+
+        $this->assertTrue(is_array($parsed));
+        $this->assertArrayHasKey('showresponse', $parsed);
+        $this->assertTrue($parsed['showresponse']);
+        $this->assertTrue(is_array($response));
+        $this->assertEquals(200, $response['status']);
+        $this->assertArraySubset([
+            'id' => 4,
+            'name' => 'banana',
+            'color' => 'red',
+            'weight' => '1 kg',
+            'delicious' => true,
+            'responseTag' => true,
+        ], json_decode($response['content'], true));
+
+        // This may probably not be the best way to test this, but 🤷‍♀️
+        $this->assertNull(static::$globalValue);
+    }
+
     /** @test */
     public function can_override_config_during_response_call()
     {