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

Make @responseFile accept relative paths too

shalvah 4 éve
szülő
commit
6f2155e2e1

+ 1 - 1
docs/contributing.md

@@ -61,7 +61,7 @@ Installing dependencies comes in two forms.
 
 Tests are located in the tests/ folder. Currently, feature tests go in the `GenerateDocumentationTest` class in the base folder, unit tests go in their respective classes in the `Unit` folder, and tests for included strategies go in the `Strategies` folder. 
 
-Note that some of the unit and strategy tests extend PHPUnit\Framework\TestCase while others extend Orchestra\Testbench\TestCase. The first case is for tests that don't need any special Laravel functionality. The second case is for tests that depend on some Laravel functionality or helpers (like `storage_path` in `UseResponseFileTagTest` and `ResponseCallsTest` that depends on Laravel routing.)
+Note that some of the unit and strategy tests extend PHPUnit\Framework\TestCase while others extend Orchestra\Testbench\TestCase. The first case is for tests that don't need any special Laravel functionality. The second case is for tests that depend on some Laravel functionality or helpers (like `ResponseCallsTest` that depends on Laravel routing.)
 
 ```eval_rst
 .. Note::  Avoid tests that make assertions on the generated HTML or Markdown output. It's a very unreliable testing approach. Instead assert on structured, consistent data like the parsed route output and Postman collection. 

+ 6 - 2
docs/documenting/documenting-endpoint-responses.md

@@ -67,7 +67,7 @@ To indicate a binary response, use `<<binary>>` as the value of the response, fo
 ## `@responseFile`
 `@responseFile` works similarly to `@response`, but instead of inlining the response, you pass a file containing your JSON response. This can be helpful if your response body is large. 
 
-To use `@responseFile`, place the response as a JSON string in a file within your Laravel storage directory and specify the relative path to it. For instance, we can put this response in a file named `users.get.json` in `storage/responses/`:
+To use `@responseFile`, place the response as a JSON string in a file somewhere in your project directory and specify the relative path to it. For instance, we can put this response in a file named `users.get.json` in `storage/responses/`:
 
 ```
 {"id":4,"name":"Jessica Jones"}
@@ -77,7 +77,7 @@ Then in the controller:
 
 ```php
 /**
- * @responseFile responses/users.get.json
+ * @responseFile storage/responses/users.get.json
  */
 public function getUser(int $id)
 {
@@ -85,6 +85,10 @@ public function getUser(int $id)
 }
 ```
 
+```eval_rst
+.. Tip:: If the file is in your Laravel storage directory, you can omit the :code:`storage/` part from the file name.
+```
+
 You can also have multiple `@responseFile` tags on a single method, distinguished by status code and/or scenarios.
 
 ```php

+ 18 - 7
src/Extracting/Strategies/Responses/UseResponseFileTag.php

@@ -23,7 +23,7 @@ class UseResponseFileTag extends Strategy
      * @param array $alreadyExtractedData
      *
      * @return array|null
-     *@throws \Exception If the response file does not exist
+     * @throws \Exception If the response file does not exist
      *
      */
     public function __invoke(Route $route, \ReflectionClass $controller, \ReflectionFunctionAbstract $method, array $routeRules, array $alreadyExtractedData = [])
@@ -60,14 +60,24 @@ class UseResponseFileTag extends Strategy
             [$_, $status, $mainContent] = $result;
             $json = $result[3] ?? null;
 
-            ['attributes' => $attributes, 'content' => $relativeFilePath] = a::parseIntoContentAndAttributes($mainContent, ['status', 'scenario']);
+            ['attributes' => $attributes, 'content' => $filePath] = a::parseIntoContentAndAttributes($mainContent, ['status', 'scenario']);
 
             $status = $attributes['status'] ?: ($status ?: 200);
             $description = $attributes['scenario'] ? "$status, {$attributes['scenario']}" : "$status";
 
-            $filePath = storage_path($relativeFilePath);
-            if (! file_exists($filePath)) {
-                c::warn("@responseFile {$relativeFilePath} does not exist");
+            if (!file_exists($filePath)) {
+                // Try Laravel storage folder
+                if (!file_exists(storage_path($filePath))) {
+                    c::warn("@responseFile {$filePath} does not exist");
+
+                    return [
+                        'content' => null,
+                        'status' => (int)$status,
+                        'description' => $description,
+                    ];
+                }
+
+                $filePath = storage_path($filePath);
             }
             $content = file_get_contents($filePath, true);
             if ($json) {
@@ -75,10 +85,11 @@ class UseResponseFileTag extends Strategy
                 $content = json_encode(array_merge(json_decode($content, true), json_decode($json, true)));
             }
 
+
             return [
                 'content' => $content,
-                'status' => (int) $status,
-                'description' => $description
+                'status' => (int)$status,
+                'description' => $description,
             ];
         }, $responseFileTags);
 

+ 6 - 27
tests/Strategies/Responses/UseResponseFileTagTest.php

@@ -3,27 +3,15 @@
 namespace Knuckles\Scribe\Tests\Strategies\Responses;
 
 use Knuckles\Scribe\Extracting\Strategies\Responses\UseResponseFileTag;
-use Knuckles\Scribe\ScribeServiceProvider;
 use Knuckles\Scribe\Tools\DocumentationConfig;
 use Mpociot\Reflection\DocBlock\Tag;
 use DMS\PHPUnitExtensions\ArraySubset\ArraySubsetAsserts;
-use Orchestra\Testbench\TestCase;
+use PHPUnit\Framework\TestCase;
 
 class UseResponseFileTagTest extends TestCase
 {
     use ArraySubsetAsserts;
 
-    protected function getPackageProviders($app)
-    {
-        $providers = [
-            ScribeServiceProvider::class,
-        ];
-        if (class_exists(\Dingo\Api\Provider\LaravelServiceProvider::class)) {
-            $providers[] = \Dingo\Api\Provider\LaravelServiceProvider::class;
-        }
-        return $providers;
-    }
-
     /**
      * @test
      * @dataProvider responseFileTags
@@ -33,9 +21,6 @@ class UseResponseFileTagTest extends TestCase
         $filePath =  __DIR__ . '/../../Fixtures/response_test.json';
         $filePath2 =  __DIR__ . '/../../Fixtures/response_error_test.json';
 
-        copy($filePath, storage_path('response_test.json'));
-        copy($filePath2, storage_path('response_error_test.json'));
-
         $strategy = new UseResponseFileTag(new DocumentationConfig([]));
         $results = $strategy->getFileResponses($tags);
 
@@ -52,20 +37,14 @@ class UseResponseFileTagTest extends TestCase
             ],
         ], $results);
 
-        unlink(storage_path('response_test.json'));
-        unlink(storage_path('response_error_test.json'));
     }
 
     /** @test */
     public function can_add_or_replace_key_value_pair_in_response_file()
     {
-
-        $filePath = __DIR__ . '/../../Fixtures/response_test.json';
-        copy($filePath, storage_path('response_test.json'));
-
         $strategy = new UseResponseFileTag(new DocumentationConfig([]));
         $tags = [
-            new Tag('responseFile', 'response_test.json {"message" : "Serendipity", "gender": "male"}'),
+            new Tag('responseFile', 'tests/Fixtures/response_test.json {"message" : "Serendipity", "gender": "male"}'),
         ];
         $results = $strategy->getFileResponses($tags);
 
@@ -82,8 +61,8 @@ class UseResponseFileTagTest extends TestCase
         return [
             "with status as initial position" => [
                 [
-                    new Tag('responseFile', 'response_test.json'),
-                    new Tag('responseFile', '401 response_error_test.json'),
+                    new Tag('responseFile', 'tests/Fixtures/response_test.json'),
+                    new Tag('responseFile', '401 tests/Fixtures/response_error_test.json'),
                 ],
                 [
                     [
@@ -99,8 +78,8 @@ class UseResponseFileTagTest extends TestCase
 
             "with attributes" => [
                 [
-                    new Tag('responseFile', 'scenario="success" response_test.json'),
-                    new Tag('responseFile', 'status=401 scenario=\'auth problem\' response_error_test.json'),
+                    new Tag('responseFile', 'scenario="success" tests/Fixtures/response_test.json'),
+                    new Tag('responseFile', 'status=401 scenario=\'auth problem\' tests/Fixtures/response_error_test.json'),
                 ],
                 [
                     [