瀏覽代碼

Merge pull request #13 from ErnestStaug/master

form-data support
Shalvah 5 年之前
父節點
當前提交
a4bf9927a9

+ 2 - 1
composer.json

@@ -67,7 +67,8 @@
     },
     "config": {
         "preferred-install": "dist",
-        "sort-packages": true
+        "sort-packages": true,
+        "process-timeout": 600
     },
     "replace": {
         "mpociot/laravel-apidoc-generator": "*"

+ 46 - 8
src/Writing/PostmanCollectionWriter.php

@@ -69,28 +69,66 @@ class PostmanCollectionWriter
         return json_encode($collection, JSON_PRETTY_PRINT);
     }
 
-    protected function generateEndpointItem($route)
+    protected function generateEndpointItem($route): array
     {
-        $mode = 'raw';
-
         $method = $route['methods'][0];
 
         return [
-            'name' => $route['metadata']['title'] != '' ? $route['metadata']['title'] : $route['uri'],
+            'name' => $route['metadata']['title'] !== '' ? $route['metadata']['title'] : $route['uri'],
             'request' => [
                 'url' => $this->makeUrlData($route),
                 'method' => $method,
                 'header' => $this->resolveHeadersForRoute($route),
-                'body' => [
-                    'mode' => $mode,
-                    $mode => json_encode($route['cleanBodyParameters'], JSON_PRETTY_PRINT),
-                ],
+                'body' => $this->getBodyData($route),
                 'description' => $route['metadata']['description'] ?? null,
                 'response' => [],
             ],
         ];
     }
 
+    protected function getBodyData(array $route): array
+    {
+
+        $body = [];
+        $contentType = $route['headers']['Content-Type'] ?? null;
+        switch ($contentType) {
+            case 'multipart/form-data':
+                $mode = 'formdata';
+                break;
+            case 'application/json':
+            default:
+                $mode = 'raw';
+        }
+        $body['mode'] = $mode;
+
+        switch ($mode) {
+            case 'formdata':
+                foreach ($route['cleanBodyParameters'] as $key => $value) {
+                    $params = [
+                        'key' => $key,
+                        'value' => $value,
+                        'type' => 'text'
+                    ];
+                    $body[$mode][] = $params;
+                }
+                foreach ($route['fileParameters'] as $key => $value) {
+                    $params = [
+                        'key' => $key,
+                        'src' => [],
+                        'type' => 'file'
+                    ];
+                    $body[$mode][] = $params;
+                }
+                break;
+            case 'raw':
+            default:
+                $body[$mode] = json_encode($route['cleanBodyParameters'], JSON_PRETTY_PRINT);
+                $body['options'][$mode]['language'] = 'json';
+        }
+        return $body;
+    }
+
+
     protected function resolveHeadersForRoute($route)
     {
         $headers = collect($route['headers']);

+ 11 - 0
tests/Fixtures/TestController.php

@@ -89,6 +89,17 @@ class TestController extends Controller
         return '';
     }
 
+    /**
+     * Endpoint with body form data parameters.
+     *
+     * @bodyParam name string required Name of image. Example: cat.jpg
+     * @bodyParam image file required The image.
+     */
+    public function withFormDataParams()
+    {
+        return '';
+    }
+
     /**
      * Endpoint with body parameters as array.
      *

+ 54 - 9
tests/Fixtures/collection.json

@@ -41,7 +41,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "This will be the long description.\nIt can also be multiple lines long.",
                         "response": []
@@ -77,7 +82,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -113,7 +123,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "{\n    \"user_id\": 9,\n    \"room_id\": \"consequatur\",\n    \"forever\": false,\n    \"another_one\": 11613.31890586,\n    \"yet_another_param\": {\n        \"name\": \"consequatur\"\n    },\n    \"even_more_param\": [\n        11613.31890586\n    ],\n    \"book\": {\n        \"name\": \"consequatur\",\n        \"author_id\": 17,\n        \"pages_count\": 17\n    },\n    \"ids\": [\n        17\n    ],\n    \"users\": [\n        {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\"\n        }\n    ]\n}"
+                            "raw": "{\n    \"user_id\": 9,\n    \"room_id\": \"consequatur\",\n    \"forever\": false,\n    \"another_one\": 11613.31890586,\n    \"yet_another_param\": {\n        \"name\": \"consequatur\"\n    },\n    \"even_more_param\": [\n        11613.31890586\n    ],\n    \"book\": {\n        \"name\": \"consequatur\",\n        \"author_id\": 17,\n        \"pages_count\": 17\n    },\n    \"ids\": [\n        17\n    ],\n    \"users\": [\n        {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\"\n        }\n    ]\n}",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -180,7 +195,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -216,7 +236,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -252,7 +277,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -288,7 +318,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -330,7 +365,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []
@@ -387,7 +427,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []

+ 12 - 2
tests/Fixtures/collection_custom_url.json

@@ -33,7 +33,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "This will be the long description.\nIt can also be multiple lines long.",
                         "response": []
@@ -61,7 +66,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []

+ 6 - 1
tests/Fixtures/collection_with_body_parameters.json

@@ -33,7 +33,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "{\n    \"user_id\": 9,\n    \"room_id\": \"consequatur\",\n    \"forever\": false,\n    \"another_one\": 11613.31890586,\n    \"yet_another_param\": {\n        \"name\": \"consequatur\"\n    },\n    \"even_more_param\": [\n        11613.31890586\n    ],\n    \"book\": {\n        \"name\": \"consequatur\",\n        \"author_id\": 17,\n        \"pages_count\": 17\n    },\n    \"ids\": [\n        17\n    ],\n    \"users\": [\n        {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\"\n        }\n    ]\n}"
+                            "raw": "{\n    \"user_id\": 9,\n    \"room_id\": \"consequatur\",\n    \"forever\": false,\n    \"another_one\": 11613.31890586,\n    \"yet_another_param\": {\n        \"name\": \"consequatur\"\n    },\n    \"even_more_param\": [\n        11613.31890586\n    ],\n    \"book\": {\n        \"name\": \"consequatur\",\n        \"author_id\": 17,\n        \"pages_count\": 17\n    },\n    \"ids\": [\n        17\n    ],\n    \"users\": [\n        {\n            \"first_name\": \"John\",\n            \"last_name\": \"Doe\"\n        }\n    ]\n}",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []

+ 6 - 1
tests/Fixtures/collection_with_custom_headers.json

@@ -37,7 +37,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []

+ 56 - 0
tests/Fixtures/collection_with_form_data_parameters.json

@@ -0,0 +1,56 @@
+{
+    "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": "Endpoint with body form data parameters.",
+                    "request": {
+                        "url": {
+                            "protocol": "http",
+                            "host": "localhost",
+                            "path": "api\/withFormDataParams",
+                            "query": []
+                        },
+                        "method": "GET",
+                        "header": [
+                            {
+                                "key": "Content-Type",
+                                "value": "multipart\/form-data"
+                            },
+                            {
+                                "key": "Accept",
+                                "value": "application\/json"
+                            }
+                        ],
+                        "body": {
+                            "mode": "formdata",
+                            "formdata": [
+                                {
+                                    "key": "name",
+                                    "value": "cat.jpg",
+                                    "type": "text"
+                                },
+                                {
+                                    "key": "image",
+                                    "src": [],
+                                    "type": "file"
+                                }
+                            ]
+                        },
+                        "description": "",
+                        "response": []
+                    }
+                }
+            ]
+        }
+    ]
+}

+ 6 - 1
tests/Fixtures/collection_with_query_parameters.json

@@ -64,7 +64,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []

+ 12 - 2
tests/Fixtures/collection_with_secure_url.json

@@ -33,7 +33,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "This will be the long description.\nIt can also be multiple lines long.",
                         "response": []
@@ -61,7 +66,12 @@
                         ],
                         "body": {
                             "mode": "raw",
-                            "raw": "[]"
+                            "raw": "[]",
+                            "options": {
+                                "raw": {
+                                    "language": "json"
+                                }
+                            }
                         },
                         "description": "",
                         "response": []

+ 16 - 0
tests/GenerateDocumentationTest.php

@@ -347,6 +347,22 @@ class GenerateDocumentationTest extends TestCase
         $this->assertEquals($fixtureCollection, $generatedCollection);
     }
 
+    /** @test */
+    public function generated_postman_collection_can_add_form_data_parameters()
+    {
+        RouteFacade::get('/api/withFormDataParams', TestController::class . '@withFormDataParams');
+        // We want to have the same values for params each time
+        config(['scribe.faker_seed' => 1234]);
+        config(['scribe.routes.0.match.prefixes' => ['api/*']]);
+        $this->artisan('scribe: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_form_data_parameters.json'), true);
+        $this->assertEquals($fixtureCollection, $generatedCollection);
+    }
+
     /** @test */
     public function can_append_custom_http_headers()
     {