Browse Source

Merge remote-tracking branch 'origin/master' into plugin-arch

# Conflicts:
#	src/Tools/Generator.php
#	src/Tools/Traits/ParamHelpers.php
shalvah 5 years ago
parent
commit
4572ffef35

+ 13 - 0
CHANGELOG.md

@@ -12,6 +12,19 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
 ### Fixed
 
 ### Removed
+c-generator/pull/575)
+
+## [3.16.2] - Wednesday, 4 September 2019
+### Fixed
+- Support for Laravel 6 (https://github.com/mpociot/laravel-apidoc-generator/commit/f7dd8d19b75755763e8e20ab4025075eba5cd51a)
+
+## [3.16.1] - Wednesday, 4 September 2019
+### Added
+- Use HTTPS in Postman collection if base_url is HTTPS (https://github.com/mpociot/laravel-apidoc-generator/pull/575)
+
+## [3.16.0] - Wednesday, 4 September 2019
+### Added
+- Support for Laravel 6 (https://github.com/mpociot/laravel-apidoc-generator/pull/572)
 
 ## [3.15.0] - Saturday, 31 August 2019
 ### Added

+ 4 - 4
composer.json

@@ -17,10 +17,10 @@
     "require": {
         "php": ">=7.0.0",
         "fzaninotto/faker": "~1.8",
-        "illuminate/routing": "5.5.* || 5.6.* || 5.7.* || 5.8.*",
-        "illuminate/support": "5.5.* || 5.6.* || 5.7.* || 5.8.*",
-        "illuminate/console": "5.5.* || 5.6.* || 5.7.* || 5.8.*",
-        "mpociot/documentarian": "^0.2.0",
+        "illuminate/routing": "^5.5|^6.0",
+        "illuminate/support": "^5.5|^6.0",
+        "illuminate/console": "^5.5|^6.0",
+        "mpociot/documentarian": "^0.3.0",
         "mpociot/reflection-docblock": "^1.0.1",
         "ramsey/uuid": "^3.8",
         "league/flysystem": "^1.0"

+ 1 - 0
phpstan.neon

@@ -5,6 +5,7 @@ parameters:
     ignoreErrors:
         - '#Call to an undefined static method Illuminate\\Support\\Facades\\Route::getRoutes().#'
         - '#Call to an undefined static method Illuminate\\Support\\Facades\\URL::forceRootUrl()#'
+        - '#Call to an undefined static method Illuminate\\Support\\Facades\\URL::forceScheme()#'
         - '#Call to an undefined method Illuminate\\Routing\\Route::versions().#'
         - '#(.*)NunoMaduro\\Collision(.*)#'
         - '#Instantiated class Whoops\\Exception\\Inspector not found\.#'

+ 1 - 1
resources/views/documentarian.blade.php

@@ -8,7 +8,7 @@
 @foreach($parsedRoutes as $groupName => $routes)
 #{!! $groupName !!}
 {{-- We pick the first non-empty description we see. --}}
-{!! array_first($routes, function ($route) { return $route['groupDescription'] !== ''; })['groupDescription'] ?? '' !!}
+{!! \Illuminate\Support\Arr::first($routes, function ($route) { return $route['groupDescription'] !== ''; })['groupDescription'] ?? '' !!}
 @foreach($routes as $parsedRoute)
 @if($writeCompareFile === true)
 {!! $parsedRoute['output'] !!}

+ 4 - 0
src/Postman/CollectionWriter.php

@@ -3,6 +3,7 @@
 namespace Mpociot\ApiDoc\Postman;
 
 use Ramsey\Uuid\Uuid;
+use Illuminate\Support\Str;
 use Illuminate\Support\Collection;
 use Illuminate\Support\Facades\URL;
 
@@ -33,6 +34,9 @@ class CollectionWriter
     {
         try {
             URL::forceRootUrl($this->baseUrl);
+            if (Str::startsWith($this->baseUrl, 'https://')) {
+                URL::forceScheme('https');
+            }
         } catch (\Error $e) {
             echo "Warning: Couldn't force base url as your version of Lumen doesn't have the forceRootUrl method.\n";
             echo "You should probably double check URLs in your generated Postman collection.\n";

+ 4 - 3
src/Strategies/Responses/UseTransformerTags.php

@@ -4,6 +4,7 @@ namespace Mpociot\ApiDoc\Strategies\Responses;
 
 use ReflectionClass;
 use ReflectionMethod;
+use Illuminate\Support\Arr;
 use League\Fractal\Manager;
 use Illuminate\Routing\Route;
 use Mpociot\ApiDoc\Tools\Flags;
@@ -91,7 +92,7 @@ class UseTransformerTags extends Strategy
      */
     private function getClassToBeTransformed(array $tags, ReflectionMethod $transformerMethod)
     {
-        $modelTag = array_first(array_filter($tags, function ($tag) {
+        $modelTag = Arr::first(array_filter($tags, function ($tag) {
             return ($tag instanceof Tag) && strtolower($tag->getName()) == 'transformermodel';
         }));
 
@@ -99,7 +100,7 @@ class UseTransformerTags extends Strategy
         if ($modelTag) {
             $type = $modelTag->getContent();
         } else {
-            $parameter = array_first($transformerMethod->getParameters());
+            $parameter = Arr::first($transformerMethod->getParameters());
             if ($parameter->hasType() && ! $parameter->getType()->isBuiltin() && class_exists((string) $parameter->getType())) {
                 // ladies and gentlemen, we have a type!
                 $type = (string) $parameter->getType();
@@ -157,6 +158,6 @@ class UseTransformerTags extends Strategy
             })
         );
 
-        return array_first($transFormerTags);
+        return Arr::first($transFormerTags);
     }
 }

+ 1 - 0
src/Tools/Generator.php

@@ -4,6 +4,7 @@ namespace Mpociot\ApiDoc\Tools;
 
 use ReflectionClass;
 use ReflectionMethod;
+use Illuminate\Support\Str;
 use Illuminate\Routing\Route;
 use Mpociot\ApiDoc\Tools\Traits\ParamHelpers;
 use Symfony\Component\HttpFoundation\Response;

+ 7 - 6
src/Tools/RouteMatcher.php

@@ -2,6 +2,7 @@
 
 namespace Mpociot\ApiDoc\Tools;
 
+use Illuminate\Support\Str;
 use Illuminate\Routing\Route;
 use Dingo\Api\Routing\RouteCollection;
 use Illuminate\Support\Facades\Route as RouteFacade;
@@ -71,10 +72,10 @@ class RouteMatcher
             ? ! empty(array_intersect($route->versions(), $routeRule['match']['versions'] ?? []))
             : true;
 
-        return str_is($mustIncludes, $route->getName())
-            || str_is($mustIncludes, $route->uri())
-            || (str_is($routeRule['match']['domains'] ?? [], $route->getDomain())
-            && str_is($routeRule['match']['prefixes'] ?? [], $route->uri())
+        return Str::is($mustIncludes, $route->getName())
+            || Str::is($mustIncludes, $route->uri())
+            || (Str::is($routeRule['match']['domains'] ?? [], $route->getDomain())
+            && Str::is($routeRule['match']['prefixes'] ?? [], $route->uri())
             && $matchesVersion);
     }
 
@@ -82,7 +83,7 @@ class RouteMatcher
     {
         $excludes = $routeRule['exclude'] ?? [];
 
-        return str_is($excludes, $route->getName())
-            || str_is($excludes, $route->uri());
+        return Str::is($excludes, $route->getName())
+            || Str::is($excludes, $route->uri());
     }
 }

+ 4 - 2
src/Tools/Traits/ParamHelpers.php

@@ -3,6 +3,8 @@
 namespace Mpociot\ApiDoc\Tools\Traits;
 
 use Faker\Factory;
+use Illuminate\Support\Arr;
+use Illuminate\Support\Str;
 use Mpociot\Reflection\DocBlock\Tag;
 
 trait ParamHelpers
@@ -39,10 +41,10 @@ trait ParamHelpers
      */
     protected function cleanValueFrom($name, $value, array &$values = [])
     {
-        if (str_contains($name, '[')) {
+        if (Str::contains($name, '[')) {
             $name = str_replace(['][', '[', ']', '..'], ['.', '.', '', '.*.'], $name);
         }
-        array_set($values, str_replace('.*', '.0', $name), $value);
+        Arr::set($values, str_replace('.*', '.0', $name), $value);
     }
 
     /**

+ 55 - 0
tests/Fixtures/collection_with_secure_url.json

@@ -0,0 +1,55 @@
+{
+    "variables": [],
+    "info": {
+        "name": "Laravel API",
+        "_postman_id": "",
+        "description": "",
+        "schema": "https:\/\/schema.getpostman.com\/json\/collection\/v2.0.0\/collection.json"
+    },
+    "item": [
+        {
+            "name": "Group A",
+            "description": "",
+            "item": [
+                {
+                    "name": "Example title.",
+                    "request": {
+                        "url": "https:\/\/yourapp.app\/api\/test",
+                        "method": "GET",
+                        "header": [
+                            {
+                                "key": "Accept",
+                                "value": "application/json"
+                            }
+                        ],
+                        "body": {
+                            "mode": "formdata",
+                            "formdata": []
+                        },
+                        "description": "This will be the long description.\nIt can also be multiple lines long.",
+                        "response": []
+                    }
+                },
+                {
+                    "name": "https:\/\/yourapp.app\/api\/responseTag",
+                    "request": {
+                        "url": "https:\/\/yourapp.app\/api\/responseTag",
+                        "method": "POST",
+                        "header": [
+                            {
+                                "key": "Accept",
+                                "value": "application/json"
+                            }
+                        ],
+                        "body": {
+                            "mode": "formdata",
+                            "formdata": []
+                        },
+                        "description": "",
+                        "response": []
+                    }
+                }
+            ]
+        }
+    ]
+}

+ 17 - 0
tests/GenerateDocumentationTest.php

@@ -279,6 +279,23 @@ class GenerateDocumentationTest extends TestCase
         $this->assertEquals($generatedCollection, $fixtureCollection);
     }
 
+    /** @test */
+    public function generated_postman_collection_can_have_secure_url()
+    {
+        Config::set('apidoc.base_url', 'https://yourapp.app');
+        RouteFacade::get('/api/test', TestController::class.'@withEndpointDescription');
+        RouteFacade::post('/api/responseTag', TestController::class.'@withResponseTag');
+
+        config(['apidoc.routes.0.match.prefixes' => ['api/*']]);
+        $this->artisan('apidoc:generate');
+
+        $generatedCollection = json_decode(file_get_contents(__DIR__.'/../public/docs/collection.json'), true);
+        // The Postman ID varies from call to call; erase it to make the test data reproducible.
+        $generatedCollection['info']['_postman_id'] = '';
+        $fixtureCollection = json_decode(file_get_contents(__DIR__.'/Fixtures/collection_with_secure_url.json'), true);
+        $this->assertEquals($generatedCollection, $fixtureCollection);
+    }
+
     /** @test */
     public function generated_postman_collection_can_append_custom_http_headers()
     {

+ 17 - 16
tests/Unit/GeneratorTestCase.php

@@ -2,6 +2,7 @@
 
 namespace Mpociot\ApiDoc\Tests\Unit;
 
+use Illuminate\Support\Arr;
 use Orchestra\Testbench\TestCase;
 use Mpociot\ApiDoc\Tools\Generator;
 use Mpociot\ApiDoc\Tools\DocumentationConfig;
@@ -338,7 +339,7 @@ abstract class GeneratorTestCase extends TestCase
     {
         $route = $this->createRoute('POST', '/responseTag', 'withResponseTag');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -359,7 +360,7 @@ abstract class GeneratorTestCase extends TestCase
     {
         $route = $this->createRoute('POST', '/responseTag', 'withResponseTagAndStatusCode');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -408,7 +409,7 @@ abstract class GeneratorTestCase extends TestCase
         config(['apidoc.fractal.serializer' => $serializer]);
         $route = $this->createRoute('GET', '/transformerTag', 'transformerTag');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -426,7 +427,7 @@ abstract class GeneratorTestCase extends TestCase
     {
         $route = $this->createRoute('GET', '/transformerTagWithModel', 'transformerTagWithModel');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -444,7 +445,7 @@ abstract class GeneratorTestCase extends TestCase
     {
         $route = $this->createRoute('GET', '/transformerCollectionTag', 'transformerCollectionTag');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -463,7 +464,7 @@ abstract class GeneratorTestCase extends TestCase
     {
         $route = $this->createRoute('GET', '/transformerCollectionTagWithModel', 'transformerCollectionTagWithModel');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -492,7 +493,7 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route, $rules);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -519,7 +520,7 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route, $rules);
-        $response = json_decode(array_first($parsed['response'])['content'], true);
+        $response = json_decode(Arr::first($parsed['response'])['content'], true);
         $originalValue = $response['app.env'];
 
         $now = time();
@@ -532,7 +533,7 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route, $rules);
-        $response = json_decode(array_first($parsed['response'])['content'], true);
+        $response = json_decode(Arr::first($parsed['response'])['content'], true);
         $newValue = $response['app.env'];
         $this->assertEquals($now, $newValue);
         $this->assertNotEquals($originalValue, $newValue);
@@ -553,7 +554,7 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route, $rules);
-        $response = json_decode(array_first($parsed['response'])['content'], true);
+        $response = json_decode(Arr::first($parsed['response'])['content'], true);
         $param = $response['param'];
         $this->assertEquals($rand, $param);
     }
@@ -573,7 +574,7 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route, $rules);
-        $response = json_decode(array_first($parsed['response'])['content'], true);
+        $response = json_decode(Arr::first($parsed['response'])['content'], true);
         $param = $response['param'];
         $this->assertEquals($rand, $param);
     }
@@ -596,12 +597,12 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route1, $rules);
-        $response = json_decode(array_first($parsed['response'])['content'], true);
+        $response = json_decode(Arr::first($parsed['response'])['content'], true);
         $param = $response['param'];
         $this->assertEquals($rand1, $param);
 
         $parsed = $this->generator->processRoute($route2, $rules);
-        $response = json_decode(array_first($parsed['response'])['content'], true);
+        $response = json_decode(Arr::first($parsed['response'])['content'], true);
         $param = $response['param'];
         $this->assertEquals($rand2, $param);
     }
@@ -616,7 +617,7 @@ abstract class GeneratorTestCase extends TestCase
 
         $route = $this->createRoute('GET', '/responseFileTag', 'responseFileTag');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -641,7 +642,7 @@ abstract class GeneratorTestCase extends TestCase
 
         $route = $this->createRoute('GET', '/responseFileTagAndCustomJson', 'responseFileTagAndCustomJson');
         $parsed = $this->generator->processRoute($route);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);
@@ -740,7 +741,7 @@ abstract class GeneratorTestCase extends TestCase
             ],
         ];
         $parsed = $this->generator->processRoute($route, $rules);
-        $response = array_first($parsed['response']);
+        $response = Arr::first($parsed['response']);
 
         $this->assertTrue(is_array($parsed));
         $this->assertArrayHasKey('showresponse', $parsed);

+ 8 - 7
tests/Unit/RouteMatcherTest.php

@@ -2,6 +2,7 @@
 
 namespace Mpociot\ApiDoc\Tests\Unit;
 
+use Illuminate\Support\Str;
 use Dingo\Api\Routing\Router;
 use Orchestra\Testbench\TestCase;
 use Mpociot\ApiDoc\Tools\RouteMatcher;
@@ -108,7 +109,7 @@ class RouteMatcherTest extends TestCase
         $routes = $this->matcher->getRoutesToBeDocumented($routeRules);
         $this->assertCount(4, $routes);
         foreach ($routes as $route) {
-            $this->assertTrue(str_is('prefix2/*', $route['route']->uri()));
+            $this->assertTrue(Str::is('prefix2/*', $route['route']->uri()));
         }
     }
 
@@ -130,14 +131,14 @@ class RouteMatcherTest extends TestCase
         $routes = $this->matcher->getDingoRoutesToBeDocumented($routeRules);
         $this->assertCount(4, $routes);
         foreach ($routes as $route) {
-            $this->assertTrue(str_is('prefix1/*', $route['route']->uri()));
+            $this->assertTrue(Str::is('prefix1/*', $route['route']->uri()));
         }
 
         $routeRules[0]['match']['prefixes'] = ['prefix2/*'];
         $routes = $this->matcher->getDingoRoutesToBeDocumented($routeRules);
         $this->assertCount(4, $routes);
         foreach ($routes as $route) {
-            $this->assertTrue(str_is('prefix2/*', $route['route']->uri()));
+            $this->assertTrue(Str::is('prefix2/*', $route['route']->uri()));
         }
     }
 
@@ -337,14 +338,14 @@ class RouteMatcherTest extends TestCase
 
         $routes = collect($routes);
         $firstRuleGroup = $routes->filter(function ($route) {
-            return str_is('prefix1/*', $route['route']->uri())
-                && str_is('domain1.*', $route['route']->getDomain());
+            return Str::is('prefix1/*', $route['route']->uri())
+                && Str::is('domain1.*', $route['route']->getDomain());
         });
         $this->assertCount(2, $firstRuleGroup);
 
         $secondRuleGroup = $routes->filter(function ($route) {
-            return str_is('prefix2/*', $route['route']->uri())
-                && str_is('domain2.*', $route['route']->getDomain());
+            return Str::is('prefix2/*', $route['route']->uri())
+                && Str::is('domain2.*', $route['route']->getDomain());
         });
         $this->assertCount(2, $secondRuleGroup);
     }