Skip to content

Commit 94962d4

Browse files
committed
Handle all possible cases of other Schemas when importing used schemas
Signed-off-by: Joas Schilling <coding@schilljs.com>
1 parent 8a351f6 commit 94962d4

6 files changed

Lines changed: 143 additions & 5 deletions

File tree

generate-spec

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -770,7 +770,7 @@ foreach ($scopePaths as $scope => $paths) {
770770
}
771771

772772
// Queue potential sub-refs for exporting as well
773-
foreach (['allOf', 'oneOf', 'anyOf', 'properties'] as $group) {
773+
foreach (['allOf', 'oneOf', 'anyOf', 'properties', 'additionalProperties'] as $group) {
774774
if (isset($schemas[$schemaName][$group])) {
775775
foreach ($schemas[$schemaName][$group] as $subType) {
776776
$newRefs = Helpers::collectUsedRefs($subType);
@@ -783,6 +783,15 @@ foreach ($scopePaths as $scope => $paths) {
783783
}
784784
}
785785

786+
if (isset($schemas[$schemaName]['items'])) {
787+
$newRefs = Helpers::collectUsedRefs($schemas[$schemaName]['items']);
788+
foreach ($newRefs as $newRef) {
789+
if (!isset($scopedSchemas[substr($newRef, strlen('#/components/schemas/'))])) {
790+
$usedSchemas[] = $newRef;
791+
}
792+
}
793+
}
794+
786795
$scopedSchemas[$schemaName] = $schemas[$schemaName];
787796
}
788797

src/Helpers.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -253,10 +253,12 @@ static function collectUsedRefs(array $data): array {
253253
if (isset($data['$ref'])) {
254254
$refs[] = [$data['$ref']];
255255
}
256-
if (isset($data['properties'])) {
257-
foreach ($data['properties'] as $property) {
258-
if (is_array($property)) {
259-
$refs[] = self::collectUsedRefs($property);
256+
foreach (['allOf', 'oneOf', 'anyOf', 'properties', 'additionalProperties'] as $group) {
257+
if (isset($data[$group]) && is_array($data[$group])) {
258+
foreach ($data[$group] as $property) {
259+
if (is_array($property)) {
260+
$refs[] = self::collectUsedRefs($property);
261+
}
260262
}
261263
}
262264
}

tests/appinfo/routes.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
['name' => 'Settings#adminScope', 'url' => '/api/{apiVersion}/admin', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
3333
['name' => 'Settings#doubleScope', 'url' => '/api/{apiVersion}/double', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
3434
['name' => 'Settings#nestedSchemas', 'url' => '/api/{apiVersion}/nested-schemas', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
35+
['name' => 'Settings#listSchemas', 'url' => '/api/{apiVersion}/list-schemas', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
3536

3637
['name' => 'Settings2#defaultAdminScopeOverwritten', 'url' => '/api/{apiVersion}/default-admin-overwritten', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],
3738
['name' => 'Settings2#defaultAdminScope', 'url' => '/api/{apiVersion}/default-admin', 'verb' => 'POST', 'requirements' => ['apiVersion' => '(v2)']],

tests/lib/Controller/SettingsController.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
/**
3636
* @psalm-import-type NotificationsPushDevice from ResponseDefinitions
3737
* @psalm-import-type NotificationsNotification from ResponseDefinitions
38+
* @psalm-import-type NotificationsCollection from ResponseDefinitions
3839
*/
3940
#[OpenAPI(scope: OpenAPI::SCOPE_FEDERATION)]
4041
class SettingsController extends OCSController {
@@ -133,4 +134,18 @@ public function doubleScope(): DataResponse {
133134
public function nestedSchemas(): DataResponse {
134135
return new DataResponse();
135136
}
137+
138+
/**
139+
* @NoAdminRequired
140+
*
141+
* Route is ignored because of scope on the controller
142+
*
143+
* @return DataResponse<Http::STATUS_OK, NotificationsCollection, array{}>
144+
*
145+
* 200: OK
146+
*/
147+
#[OpenAPI]
148+
public function listSchemas(): DataResponse {
149+
return new DataResponse();
150+
}
136151
}

tests/lib/ResponseDefinitions.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,15 @@
2727
namespace OCA\Notifications;
2828

2929
/**
30+
* @psalm-type NotificationsItem = array{
31+
* label: string,
32+
* link: string,
33+
* type: string,
34+
* primary: bool,
35+
* }
36+
*
37+
* @psalm-type NotificationsCollection = list<NotificationsItem>
38+
*
3039
* @psalm-type NotificationsNotificationAction = array{
3140
* label: string,
3241
* link: string,

tests/openapi.json

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@
119119
}
120120
}
121121
},
122+
"Collection": {
123+
"type": "array",
124+
"items": {
125+
"$ref": "#/components/schemas/Item"
126+
}
127+
},
122128
"NotificationAction": {
123129
"type": "object",
124130
"required": [
@@ -141,6 +147,29 @@
141147
"type": "boolean"
142148
}
143149
}
150+
},
151+
"Item": {
152+
"type": "object",
153+
"required": [
154+
"label",
155+
"link",
156+
"type",
157+
"primary"
158+
],
159+
"properties": {
160+
"label": {
161+
"type": "string"
162+
},
163+
"link": {
164+
"type": "string"
165+
},
166+
"type": {
167+
"type": "string"
168+
},
169+
"primary": {
170+
"type": "boolean"
171+
}
172+
}
144173
}
145174
}
146175
},
@@ -363,6 +392,79 @@
363392
}
364393
}
365394
},
395+
"/ocs/v2.php/apps/notifications/api/{apiVersion}/list-schemas": {
396+
"post": {
397+
"operationId": "settings-list-schemas",
398+
"summary": "Route is ignored because of scope on the controller",
399+
"tags": [
400+
"settings"
401+
],
402+
"security": [
403+
{
404+
"bearer_auth": []
405+
},
406+
{
407+
"basic_auth": []
408+
}
409+
],
410+
"parameters": [
411+
{
412+
"name": "apiVersion",
413+
"in": "path",
414+
"required": true,
415+
"schema": {
416+
"type": "string",
417+
"enum": [
418+
"v2"
419+
],
420+
"default": "v2"
421+
}
422+
},
423+
{
424+
"name": "OCS-APIRequest",
425+
"in": "header",
426+
"description": "Required to be true for the API request to pass",
427+
"required": true,
428+
"schema": {
429+
"type": "boolean",
430+
"default": true
431+
}
432+
}
433+
],
434+
"responses": {
435+
"200": {
436+
"description": "OK",
437+
"content": {
438+
"application/json": {
439+
"schema": {
440+
"type": "object",
441+
"required": [
442+
"ocs"
443+
],
444+
"properties": {
445+
"ocs": {
446+
"type": "object",
447+
"required": [
448+
"meta",
449+
"data"
450+
],
451+
"properties": {
452+
"meta": {
453+
"$ref": "#/components/schemas/OCSMeta"
454+
},
455+
"data": {
456+
"$ref": "#/components/schemas/Collection"
457+
}
458+
}
459+
}
460+
}
461+
}
462+
}
463+
}
464+
}
465+
}
466+
}
467+
},
366468
"/ocs/v2.php/apps/notifications/api/{apiVersion}/default-admin-overwritten": {
367469
"post": {
368470
"operationId": "settings2-default-admin-scope-overwritten",

0 commit comments

Comments
 (0)