Browse Source

Add tests + fix bug for user defined endpoints and --no-extraction

shalvah 3 years ago
parent
commit
b7f8539b1b

+ 3 - 1
composer.dingo.json

@@ -44,7 +44,9 @@
         "laravel/lumen-framework": "^6.0|^7.0|^8.0",
         "orchestra/testbench": "^4.0|^5.0|^6.0",
         "phpstan/phpstan": "^0.12.19",
-        "phpunit/phpunit": "^9.0"
+        "phpunit/phpunit": "^9.0",
+        "symfony/css-selector": "^5.3",
+        "symfony/dom-crawler": "^5.3"
     },
     "suggest": {
         "league/fractal": "Required for transformers support"

+ 3 - 1
composer.json

@@ -44,7 +44,9 @@
     "nikic/fast-route": "^1.3",
     "orchestra/testbench": "^4.0|^5.0|^6.0",
     "phpstan/phpstan": "^0.12.19",
-    "phpunit/phpunit": "^9.0"
+    "phpunit/phpunit": "^9.0",
+    "symfony/css-selector": "^5.3",
+    "symfony/dom-crawler": "^5.3"
   },
   "suggest": {
     "league/fractal": "Required for transformers support"

+ 1 - 1
resources/example_custom_endpoint.yaml

@@ -8,7 +8,7 @@
 #  metadata:
 #    groupName: The group the endpoint belongs to. Can be a new group or an existing group.
 #    groupDescription: A description for the group. You don't need to set this for every endpoint; once is enough.
-#    title: 'Do something.'
+#    title: Do something
 #    description: 'This endpoint allows you to do something.'
 #    authenticated: false
 #  headers:

+ 2 - 3
resources/views/themes/default/groups.blade.php

@@ -1,8 +1,7 @@
 @foreach($groupedEndpoints as $group)
     <h1 id="{!! Str::slug($group['name']) !!}">{!! $group['name'] !!}</h1>
-    <p>
-        {!! Parsedown::instance()->text($group['description']) !!}
-    </p>
+
+    {!! Parsedown::instance()->text($group['description']) !!}
 
     @foreach($group['endpoints'] as $endpoint)
         @include("scribe::themes.default.endpoint")

+ 1 - 1
src/Commands/GenerateDocumentation.php

@@ -292,7 +292,7 @@ class GenerateDocumentation extends Command
                 return $group['name'] === ($endpoint['metadata']['groupName'] ?? $this->docConfig->get('default_group', ''));
             });
 
-            if ($existingGroupKey) {
+            if ($existingGroupKey !== null) {
                 $groupedEndpoints[$existingGroupKey]['endpoints'][] = OutputEndpointData::fromExtractedEndpointArray($endpoint);
             } else {
                 $groupedEndpoints[] = [

+ 45 - 0
tests/Fixtures/.scribe/endpoints/0.yaml

@@ -0,0 +1,45 @@
+name: General
+description: 'Swalla la la'
+endpoints:
+  -
+    httpMethods:
+      - GET
+    uri: api/healthcheck
+    metadata:
+      title: Healthcheck
+      description: |-
+        Check that the service is up. If everything is okay, you'll get a 200 OK response.
+
+        Otherwise, the request will fail with a 400 error, and a response listing the failed services.
+      authenticated: false
+    headers:
+      Content-Type: application/json
+      Accept: application/json
+    urlParameters: []
+    queryParameters: []
+    bodyParameters: []
+    responses:
+      -
+        status: 200
+        content: '{"status":"up","services":{"database":"up","redis":"up"}}'
+        headers:
+          cache-control: 'no-cache, private'
+          content-type: application/json
+          x-ratelimit-limit: '60'
+          x-ratelimit-remaining: '56'
+          access-control-allow-origin: '*'
+        description: null
+      -
+        status: 400
+        content: '{"status": "down", "services": {"database": "up", "redis": "down"}}'
+        headers: []
+        description: '400, Service is unhealthy'
+    responseFields:
+      status:
+        name: status
+        description: 'The status of this API (`up` or `down`).'
+        type: string
+      services:
+        name: services
+        description: 'Map of each downstream service and their status (`up` or `down`).'
+        type: object

+ 3 - 0
tests/Fixtures/.scribe/intro.md

@@ -0,0 +1,3 @@
+# Introduction
+
+Heyaa introduction!👋

+ 40 - 0
tests/Fixtures/custom.0.yaml

@@ -0,0 +1,40 @@
+- httpMethods:
+    - POST
+  uri: userDefined/yeah
+  metadata:
+    groupName: 1. Group 1
+    title: 'User defined'
+    description: 'This endpoint allows you to do something.'
+    authenticated: false
+  headers:
+    Content-Type: application/json
+    Accept: application/json
+  urlParameters: {}
+  queryParameters:
+    speed:
+      name: speed
+      description: How fast the thing should be done. Can be `slow` or `fast`.
+      required: false
+      example: fast
+      type: string
+  bodyParameters:
+    something:
+      name: something
+      description: The things we should do.
+      required: true
+      example:
+        - string 1
+        - string 2
+      type: 'string[]'
+  responses:
+    - status: 200
+      description: 'When the thing was done smoothly.'
+      content:
+         {
+           "hey": "ho ho ho"
+         }
+  responseFields:
+    hey:
+      name: hey
+      description: Who knows?
+      type: string

+ 50 - 16
tests/GenerateDocumentationTest.php

@@ -11,6 +11,7 @@ use Knuckles\Scribe\Tests\Fixtures\TestPartialResourceController;
 use Knuckles\Scribe\Tests\Fixtures\TestResourceController;
 use Knuckles\Scribe\Tests\Fixtures\TestUser;
 use Knuckles\Scribe\Tools\Utils;
+use Symfony\Component\DomCrawler\Crawler;
 use Symfony\Component\Yaml\Yaml;
 
 class GenerateDocumentationTest extends BaseLaravelTest
@@ -40,22 +41,6 @@ class GenerateDocumentationTest extends BaseLaravelTest
         Utils::deleteDirectoryAndContents('.scribe');
     }
 
-    /**
-     * @param \Illuminate\Foundation\Application $app
-     *
-     * @return array
-     */
-    protected function getPackageProviders($app)
-    {
-        $providers = [
-            ScribeServiceProvider::class,
-        ];
-        if (class_exists(\Dingo\Api\Provider\LaravelServiceProvider::class)) {
-            $providers[] = \Dingo\Api\Provider\LaravelServiceProvider::class;
-        }
-        return $providers;
-    }
-
     /** @test */
     public function can_process_traditional_laravel_route_syntax()
     {
@@ -372,4 +357,53 @@ class GenerateDocumentationTest extends BaseLaravelTest
         $this->assertEquals([], $group['endpoints'][0]['urlParameters']);
         $this->assertStringNotContainsString('Some other useful stuff.', file_get_contents($authFilePath));
     }
+
+    /** @test */
+    public function will_not_extract_if_noExtraction_flag_is_set()
+    {
+        config(['scribe.routes.0.exclude' => ['*']]);
+
+        Utils::copyDirectory(__DIR__.'/Fixtures/.scribe', '.scribe');
+        $output = $this->artisan('scribe:generate', ['--no-extraction' => true]);
+        $this->assertStringNotContainsString("Processing route", $output);
+
+        $html = file_get_contents('public/docs/index.html');
+
+        $crawler = new Crawler($html);
+        [$intro, $auth] = $crawler->filter('h1 + p')->getIterator();
+        $this->assertEquals('Heyaa introduction!👋', trim($intro->firstChild->textContent));
+        $this->assertEquals('This is just a test.', trim($auth->firstChild->textContent));
+        $endpoints = $crawler->filter('h1')->getNode(2);
+        $this->assertEquals('General', trim($endpoints->textContent));
+        $expectedEndpoint = $crawler->filter('h2');
+        $this->assertCount(1, $expectedEndpoint);
+        $this->assertEquals("Healthcheck", $expectedEndpoint->text());
+    }
+
+    /** @test */
+    public function merges_user_defined_endpoints()
+    {
+        RouteFacade::get('/api/action1', [TestGroupController::class, 'action1']);
+        RouteFacade::get('/api/action2', [TestGroupController::class, 'action2']);
+        config(['scribe.routes.0.prefixes' => ['api/*']]);
+
+        if (!is_dir('.scribe/endpoints')) mkdir('.scribe/endpoints', 0777, true);
+        copy(__DIR__ . '/Fixtures/custom.0.yaml', '.scribe/endpoints/custom.0.yaml');
+
+        $this->artisan('scribe:generate');
+        $html = file_get_contents('public/docs/index.html');
+
+        $crawler = new Crawler($html);
+        $headings = $crawler->filter('h1')->getIterator();
+        // There should only be four headings — intro, auth and two groups
+        $this->assertCount(4, $headings);
+        [$_, $_, $group1, $group2] = $headings;
+        $this->assertEquals('1. Group 1', trim($group1->textContent));
+        $this->assertEquals('2. Group 2', trim($group2->textContent));
+        $expectedEndpoints = $crawler->filter('h2');
+        $this->assertCount(3, $expectedEndpoints->getIterator());
+        $this->assertEquals("Some endpoint.", $expectedEndpoints->getNode(0)->textContent);
+        $this->assertEquals("User defined", $expectedEndpoints->getNode(1)->textContent);
+        $this->assertEquals("GET api/action2", $expectedEndpoints->getNode(2)->textContent);
+    }
 }