From d3bd5c33bd6967830539825a63eaabe0ef5884e8 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Thu, 7 Dec 2023 14:51:43 +0100 Subject: [PATCH] Correctly add schemas references by nested schemas Signed-off-by: Joas Schilling --- generate-spec | 14 +- src/Helpers.php | 3 + tests/appinfo/routes.php | 1 + tests/lib/Controller/SettingsController.php | 15 ++ tests/openapi.json | 174 ++++++++++++++++++++ 5 files changed, 201 insertions(+), 6 deletions(-) diff --git a/generate-spec b/generate-spec index 8d47ece..f69a472 100755 --- a/generate-spec +++ b/generate-spec @@ -761,12 +761,14 @@ foreach ($scopePaths as $scope => $paths) { } // Queue potential sub-refs for exporting as well - if (isset($schemas[$schemaName]['allOf'])) { - foreach ($schemas[$schemaName]['allOf'] as $subType) { - $newRefs = Helpers::collectUsedRefs($subType); - foreach ($newRefs as $newRef) { - if (!isset($scopedSchemas[substr($newRef, strlen('#/components/schemas/'))])) { - $usedSchemas[] = $newRef; + foreach (['allOf', 'oneOf', 'anyOf', 'properties'] as $group) { + if (isset($schemas[$schemaName][$group])) { + foreach ($schemas[$schemaName][$group] as $subType) { + $newRefs = Helpers::collectUsedRefs($subType); + foreach ($newRefs as $newRef) { + if (!isset($scopedSchemas[substr($newRef, strlen('#/components/schemas/'))])) { + $usedSchemas[] = $newRef; + } } } } diff --git a/src/Helpers.php b/src/Helpers.php index 7d7e7ba..8fe3799 100644 --- a/src/Helpers.php +++ b/src/Helpers.php @@ -262,6 +262,9 @@ static function collectUsedRefs(array $data): array { } } } + if (isset($data['items'])) { + $refs[] = self::collectUsedRefs($data['items']); + } return array_merge(...$refs); } } diff --git a/tests/appinfo/routes.php b/tests/appinfo/routes.php index 13dd501..5b32560 100644 --- a/tests/appinfo/routes.php +++ b/tests/appinfo/routes.php @@ -32,6 +32,7 @@ ['name' => 'Settings#adminScope', 'url' => '/api/{apiVersion}/admin', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']], ['name' => 'Settings#doubleScope', 'url' => '/api/{apiVersion}/double', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']], ['name' => 'Settings#throwing', 'url' => '/api/{apiVersion}/throwing', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']], + ['name' => 'Settings#nestedSchemas', 'url' => '/api/{apiVersion}/nested-schemas', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']], ['name' => 'Settings2#defaultAdminScopeOverwritten', 'url' => '/api/{apiVersion}/default-admin-overwritten', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']], ['name' => 'Settings2#defaultAdminScope', 'url' => '/api/{apiVersion}/default-admin', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']], diff --git a/tests/lib/Controller/SettingsController.php b/tests/lib/Controller/SettingsController.php index d7f7084..c1c19a9 100644 --- a/tests/lib/Controller/SettingsController.php +++ b/tests/lib/Controller/SettingsController.php @@ -35,6 +35,7 @@ /** * @psalm-import-type NotificationsPushDevice from ResponseDefinitions + * @psalm-import-type NotificationsNotification from ResponseDefinitions */ #[OpenAPI(scope: OpenAPI::SCOPE_FEDERATION)] class SettingsController extends OCSController { @@ -134,4 +135,18 @@ public function doubleScope(): DataResponse { public function throwing(): DataResponse { throw new OCSNotFoundException(); } + + /** + * @NoAdminRequired + * + * Route is ignored because of scope on the controller + * + * @return DataResponse, array{}> + * + * 200: OK + */ + #[OpenAPI] + public function nestedSchemas(): DataResponse { + return new DataResponse(); + } } diff --git a/tests/openapi.json b/tests/openapi.json index 4eb5bb0..efc029b 100644 --- a/tests/openapi.json +++ b/tests/openapi.json @@ -43,6 +43,104 @@ "type": "string" } } + }, + "Notification": { + "type": "object", + "required": [ + "notification_id", + "app", + "user", + "datetime", + "object_type", + "object_id", + "subject", + "message", + "link", + "actions" + ], + "properties": { + "notification_id": { + "type": "integer", + "format": "int64" + }, + "app": { + "type": "string" + }, + "user": { + "type": "string" + }, + "datetime": { + "type": "string" + }, + "object_type": { + "type": "string" + }, + "object_id": { + "type": "string" + }, + "subject": { + "type": "string" + }, + "message": { + "type": "string" + }, + "link": { + "type": "string" + }, + "actions": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationAction" + } + }, + "subjectRich": { + "type": "string" + }, + "subjectRichParameters": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "messageRich": { + "type": "string" + }, + "messageRichParameters": { + "type": "object", + "additionalProperties": { + "type": "object" + } + }, + "icon": { + "type": "string" + }, + "shouldNotify": { + "type": "boolean" + } + } + }, + "NotificationAction": { + "type": "object", + "required": [ + "label", + "link", + "type", + "primary" + ], + "properties": { + "label": { + "type": "string" + }, + "link": { + "type": "string" + }, + "type": { + "type": "string" + }, + "primary": { + "type": "boolean" + } + } } } }, @@ -189,6 +287,82 @@ } } }, + "/ocs/v2.php/apps/notifications/api/{apiVersion}/nested-schemas": { + "post": { + "operationId": "settings-nested-schemas", + "summary": "Route is ignored because of scope on the controller", + "tags": [ + "settings" + ], + "security": [ + { + "bearer_auth": [] + }, + { + "basic_auth": [] + } + ], + "parameters": [ + { + "name": "apiVersion", + "in": "path", + "required": true, + "schema": { + "type": "string", + "enum": [ + "v2" + ], + "default": "v2" + } + }, + { + "name": "OCS-APIRequest", + "in": "header", + "description": "Required to be true for the API request to pass", + "required": true, + "schema": { + "type": "boolean", + "default": true + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "type": "object", + "required": [ + "ocs" + ], + "properties": { + "ocs": { + "type": "object", + "required": [ + "meta", + "data" + ], + "properties": { + "meta": { + "$ref": "#/components/schemas/OCSMeta" + }, + "data": { + "type": "array", + "items": { + "$ref": "#/components/schemas/Notification" + } + } + } + } + } + } + } + } + } + } + } + }, "/ocs/v2.php/apps/notifications/api/{apiVersion}/default-admin-overwritten": { "post": { "operationId": "settings2-default-admin-scope-overwritten",