From 16d82d595e8ab07fc1431233dc44ea650f5805a3 Mon Sep 17 00:00:00 2001 From: Vladimir Gorej Date: Fri, 6 Jan 2023 14:31:22 +0100 Subject: [PATCH] test(resolver): add tests for OpenAPI 3.1.0 allowMetaPatches option Closes #2760 --- .../openapi-3-1-swagger-client/visitor.js | 40 +-- .../dereferenced.json | 32 ++ .../$anchor-external-meta-patches/ex.json | 15 + .../$anchor-external-meta-patches/root.json | 21 ++ .../dereferenced.json | 43 +++ .../$anchor-internal-meta-patches/root.json | 32 ++ .../dereferenced.json | 30 ++ .../nested/ex.json | 8 + .../$id-uri-direct-meta-patches/root.json | 22 ++ .../dereferenced.json | 30 ++ .../nested/ex.json | 8 + .../$id-uri-enclosing-meta-patches/root.json | 22 ++ .../dereferenced.json | 30 ++ .../nested/ex.json | 8 + .../nested/nested/ex.json | 8 + .../$id-uri-external-meta-patches/root.json | 21 ++ .../dereferenced.json | 35 ++ .../$ref-url-$anchor-meta-patches/root.json | 31 ++ .../$ref-url-meta-patches/dereferenced.json | 39 +++ .../$ref-url-meta-patches/root.json | 30 ++ .../dereferenced.json | 33 ++ .../$ref-url-pointer-meta-patches/root.json | 30 ++ .../dereferenced.json | 36 ++ .../root.json | 32 ++ .../dereferenced.json | 24 ++ .../$ref-url-resolvable-meta-patches/ex.json | 8 + .../root.json | 21 ++ .../$ref-urn-meta-patches/dereferenced.json | 39 +++ .../$ref-urn-meta-patches/root.json | 30 ++ .../dereferenced.json | 33 ++ .../$ref-urn-pointer-meta-patches/root.json | 30 ++ .../schema-object/index.js | 324 ++++++++++++++++-- .../openapi-3-1/__snapshots__/index.js.snap | 309 +++++++++++++++++ test/resolver/strategies/openapi-3-1/index.js | 18 + 34 files changed, 1425 insertions(+), 47 deletions(-) create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/ex.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/nested/ex.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/nested/ex.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/ex.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/nested/ex.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/ex.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/root.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/dereferenced.json create mode 100644 test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/root.json diff --git a/src/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitor.js b/src/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitor.js index 7cb4e2697e..83ab42d617 100644 --- a/src/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitor.js +++ b/src/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/visitor.js @@ -134,11 +134,8 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c const objectFragment = fragment; // apply meta patch only when not already applied if (typeof objectFragment.get('$$ref') === 'undefined') { - const absoluteJSONPointerURL = url.resolve( - reference.uri, - referenceElement.$ref?.toValue() - ); - objectFragment.set('$$ref', absoluteJSONPointerURL); + const absoluteURI = url.resolve(reference.uri, referenceElement.$ref?.toValue()); + objectFragment.set('$$ref', absoluteURI); } } @@ -226,11 +223,8 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c if (this.allowMetaPatches) { // apply meta patch only when not already applied if (typeof mergedResult.get('$$ref') === 'undefined') { - const absoluteJSONPointerURL = url.resolve( - reference.uri, - pathItemElement.$ref?.toValue() - ); - mergedResult.set('$$ref', absoluteJSONPointerURL); + const absoluteURI = url.resolve(reference.uri, pathItemElement.$ref?.toValue()); + mergedResult.set('$$ref', absoluteURI); } } @@ -255,13 +249,14 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c } // compute baseURI using rules around $id and $ref keywords - const retrieveURI = this.reference.uri; - const $refBaseURI = resolveSchema$refField(retrieveURI, referencingElement); + let { reference } = this; + let { uri: retrievalURI } = reference; + const $refBaseURI = resolveSchema$refField(retrievalURI, referencingElement); const $refBaseURIStrippedHash = url.stripHash($refBaseURI); const file = File({ uri: $refBaseURIStrippedHash }); const isUnknownURI = !this.options.resolve.resolvers.some((r) => r.canRead(file)); const isURL = !isUnknownURI; - const isExternal = isURL && this.reference.uri !== $refBaseURIStrippedHash; + const isExternal = isURL && retrievalURI !== $refBaseURIStrippedHash; // ignore resolving external Schema Objects if (!this.options.resolve.external && isExternal) { @@ -272,13 +267,11 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c this.indirections.push(referencingElement); // determining reference, proper evaluation and selection mechanism - let reference; let referencedElement; try { if (isUnknownURI || isURL) { // we're dealing with canonical URI or URL with possible fragment - reference = this.reference; const selector = $refBaseURI; referencedElement = uriEvaluate( selector, @@ -288,6 +281,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c } else { // we're assuming here that we're dealing with JSON Pointer here reference = await this.toReference(url.unsanitize($refBaseURI)); + retrievalURI = reference.uri; const selector = uriToPointer($refBaseURI); referencedElement = maybeRefractToSchemaElement( // @ts-ignore @@ -303,6 +297,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c if (isAnchor(uriToAnchor($refBaseURI))) { // we're dealing with JSON Schema $anchor here reference = await this.toReference(url.unsanitize($refBaseURI)); + retrievalURI = reference.uri; const selector = uriToAnchor($refBaseURI); referencedElement = $anchorEvaluate( selector, @@ -312,6 +307,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c } else { // we're assuming here that we're dealing with JSON Pointer here reference = await this.toReference(url.unsanitize($refBaseURI)); + retrievalURI = reference.uri; const selector = uriToPointer($refBaseURI); referencedElement = maybeRefractToSchemaElement( // @ts-ignore @@ -363,7 +359,7 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c $ref: referencingElement.$ref?.toValue(), }); // annotate referenced element with info about origin - jsonSchemaBooleanElement.setMetaProperty('ref-origin', reference.uri); + jsonSchemaBooleanElement.setMetaProperty('ref-origin', retrievalURI); return jsonSchemaBooleanElement; } @@ -373,10 +369,10 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c ancestorsLineage.includes(memberElement) ); if (hasCycle && !this.useCircularStructures) { - if (url.isHttpUrl(reference.uri) || url.isFileSystemPath(reference.uri)) { + if (url.isHttpUrl(retrievalURI) || url.isFileSystemPath(retrievalURI)) { // make the referencing URL or file system path absolute - const absoluteURI = url.resolve(reference.uri, referencingElement.$ref?.toValue()); - referencingElement.set('$ref', absoluteURI); + const baseURI = url.resolve(retrievalURI, $refBaseURI); + referencingElement.set('$ref', baseURI); } // skip processing this schema but traverse all it's child schemas @@ -402,14 +398,14 @@ const OpenApi3_1SwaggerClientDereferenceVisitor = OpenApi3_1DereferenceVisitor.c $ref: referencingElement.$ref?.toValue(), }); // annotate fragment with info about origin - mergedSchemaElement.setMetaProperty('ref-origin', reference.uri); + mergedSchemaElement.setMetaProperty('ref-origin', retrievalURI); // allowMetaPatches option processing if (this.allowMetaPatches) { // apply meta patch only when not already applied if (typeof mergedSchemaElement.get('$$ref') === 'undefined') { - const absoluteURI = url.resolve(reference.uri, referencingElement.$ref?.toValue()); - mergedSchemaElement.set('$$ref', absoluteURI); + const baseURI = url.resolve(retrievalURI, $refBaseURI); + mergedSchemaElement.set('$$ref', baseURI); } } diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/dereferenced.json new file mode 100644 index 0000000000..37f10c4d90 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/dereferenced.json @@ -0,0 +1,32 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "/home/smartbear/ex.json#user-profile", + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/ex.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/ex.json new file mode 100644 index 0000000000..b32830bdc4 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/ex.json @@ -0,0 +1,15 @@ +{ + "$defs": { + "UserProfile": { + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/root.json new file mode 100644 index 0000000000..5f55276688 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-external-meta-patches/root.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "./ex.json#user-profile" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/dereferenced.json new file mode 100644 index 0000000000..b518687936 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/dereferenced.json @@ -0,0 +1,43 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "/home/smartbear/root.json#user-profile", + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + }, + "UserProfile": { + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/root.json new file mode 100644 index 0000000000..f9a30fb1ca --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$anchor-internal-meta-patches/root.json @@ -0,0 +1,32 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "#user-profile" + } + } + }, + "UserProfile": { + "$anchor": "user-profile", + "properties": { + "firstName": { + "type": "string" + }, + "lastName": { + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/dereferenced.json new file mode 100644 index 0000000000..cc0b42c3bd --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/dereferenced.json @@ -0,0 +1,30 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "/home/smartbear/nested/ex.json", + "$id": "./nested/", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/nested/ex.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/nested/ex.json new file mode 100644 index 0000000000..b7f7f6299c --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/nested/ex.json @@ -0,0 +1,8 @@ +{ + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/root.json new file mode 100644 index 0000000000..2c9fd869f7 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-direct-meta-patches/root.json @@ -0,0 +1,22 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$id": "./nested/", + "$ref": "./ex.json" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/dereferenced.json new file mode 100644 index 0000000000..dc30ebd20c --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/dereferenced.json @@ -0,0 +1,30 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "$id": "./nested/", + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "/home/smartbear/nested/ex.json", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/nested/ex.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/nested/ex.json new file mode 100644 index 0000000000..b7f7f6299c --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/nested/ex.json @@ -0,0 +1,8 @@ +{ + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/root.json new file mode 100644 index 0000000000..4c3fa339ca --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-enclosing-meta-patches/root.json @@ -0,0 +1,22 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "$id": "./nested/", + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "./ex.json" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/dereferenced.json new file mode 100644 index 0000000000..74004b7e38 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/dereferenced.json @@ -0,0 +1,30 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "/home/smartbear/nested/nested/ex.json", + "$id": "./nested/", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/ex.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/ex.json new file mode 100644 index 0000000000..d5a6ae02c1 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/ex.json @@ -0,0 +1,8 @@ +{ + "$defs": { + "UserProfile": { + "$id": "./nested/", + "$ref": "./ex.json" + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/nested/ex.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/nested/ex.json new file mode 100644 index 0000000000..b7f7f6299c --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/nested/nested/ex.json @@ -0,0 +1,8 @@ +{ + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/root.json new file mode 100644 index 0000000000..ede427d60e --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$id-uri-external-meta-patches/root.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "./nested/ex.json#/$defs/UserProfile" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/dereferenced.json new file mode 100644 index 0000000000..992f27b053 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/dereferenced.json @@ -0,0 +1,35 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "https://swagger.io/schemas/user-profile#avatar", + "$anchor": "avatar", + "type": "string" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "$anchor": "avatar", + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/root.json new file mode 100644 index 0000000000..ab1df7012d --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-$anchor-meta-patches/root.json @@ -0,0 +1,31 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "https://swagger.io/schemas/user-profile#avatar" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "$anchor": "avatar", + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/dereferenced.json new file mode 100644 index 0000000000..922f26d1e7 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/dereferenced.json @@ -0,0 +1,39 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "https://swagger.io/schemas/user-profile", + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/root.json new file mode 100644 index 0000000000..1b6485de39 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-meta-patches/root.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "https://swagger.io/schemas/user-profile" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/dereferenced.json new file mode 100644 index 0000000000..ec0f7a0249 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/dereferenced.json @@ -0,0 +1,33 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "https://swagger.io/schemas/user-profile#/properties/avatar", + "type": "string" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/root.json new file mode 100644 index 0000000000..89e31d3af1 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-pointer-meta-patches/root.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "https://swagger.io/schemas/user-profile#/properties/avatar" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/dereferenced.json new file mode 100644 index 0000000000..ab314e576d --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/dereferenced.json @@ -0,0 +1,36 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "$id": "https://swagger.io/schemas/user", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profileAvatar": { + "$$ref": "https://swagger.io/schemas/user-profile/avatar", + "$id": "/schemas/user-profile/avatar", + "type": "string" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "$id": "/schemas/user-profile/avatar", + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/root.json new file mode 100644 index 0000000000..80a5976a86 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-relative-reference-meta-patches/root.json @@ -0,0 +1,32 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "$id": "https://swagger.io/schemas/user", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profileAvatar": { + "$ref": "/schemas/user-profile/avatar" + } + } + }, + "UserProfile": { + "$id": "https://swagger.io/schemas/user-profile", + "type": "object", + "properties": { + "avatar": { + "$id": "/schemas/user-profile/avatar", + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/dereferenced.json new file mode 100644 index 0000000000..436e8470d0 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/dereferenced.json @@ -0,0 +1,24 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "/home/smartbear/ex.json#/properties/avatar", + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/ex.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/ex.json new file mode 100644 index 0000000000..b7f7f6299c --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/ex.json @@ -0,0 +1,8 @@ +{ + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/root.json new file mode 100644 index 0000000000..7e6dec92a2 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-url-resolvable-meta-patches/root.json @@ -0,0 +1,21 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "./ex.json#/properties/avatar" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/dereferenced.json new file mode 100644 index 0000000000..fbe573f547 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/dereferenced.json @@ -0,0 +1,39 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + }, + "UserProfile": { + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/root.json new file mode 100644 index 0000000000..2c3a9eabd4 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-meta-patches/root.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f" + } + } + }, + "UserProfile": { + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/dereferenced.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/dereferenced.json new file mode 100644 index 0000000000..e7c6fd279f --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/dereferenced.json @@ -0,0 +1,33 @@ +[ + { + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$$ref": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#/properties/avatar", + "type": "string" + } + } + }, + "UserProfile": { + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } + } +] diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/root.json b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/root.json new file mode 100644 index 0000000000..c53665d5a4 --- /dev/null +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/__fixtures__/$ref-urn-pointer-meta-patches/root.json @@ -0,0 +1,30 @@ +{ + "openapi": "3.1.0", + "components": { + "schemas": { + "User": { + "type": "object", + "properties": { + "login": { + "type": "string" + }, + "password": { + "type": "string" + }, + "profile": { + "$ref": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f#/properties/avatar" + } + } + }, + "UserProfile": { + "$id": "urn:uuid:ee564b8a-7a87-4125-8c96-e9f123d6766f", + "type": "object", + "properties": { + "avatar": { + "type": "string" + } + } + } + } + } +} diff --git a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js index 055186a580..6f1fa954e2 100644 --- a/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js +++ b/test/helpers/apidom/reference/dereference/strategies/openapi-3-1-swagger-client/schema-object/index.js @@ -122,7 +122,7 @@ describe('dereference', () => { parse: { mediaType: mediaTypes.latest('json') }, }); refSet.refs[0].uri = '/home/smartbear/root.json'; - const actual = await dereference('/home/smartbear/root.json', { + const actual = await dereference(refSet.refs[0].uri, { parse: { mediaType: mediaTypes.latest('json') }, dereference: { refSet, @@ -495,9 +495,8 @@ describe('dereference', () => { }); describe('given Schema Objects with $id keyword defined directly in referencing Schema Object', () => { - const fixturePath = path.join(rootFixturePath, '$id-uri-direct'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$id-uri-direct'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -506,12 +505,35 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$id-uri-direct-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + refSet.refs[1].uri = '/home/smartbear/nested/ex.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $id keyword defined in enclosing Schema Object', () => { - const fixturePath = path.join(rootFixturePath, '$id-uri-enclosing'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$id-uri-enclosing'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -520,12 +542,35 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$id-uri-enclosing-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + refSet.refs[1].uri = '/home/smartbear/nested/ex.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $id keyword pointing to external files', () => { - const fixturePath = path.join(rootFixturePath, '$id-uri-external'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$id-uri-external'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -534,6 +579,31 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$id-uri-external-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + refSet.refs[1].uri = '/home/smartbear/nested/ex.json'; + refSet.refs[2].uri = '/home/smartbear/nested/nested/ex.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with unresolvable $id values', () => { @@ -560,9 +630,8 @@ describe('dereference', () => { }); describe('given Schema Objects with $ref keyword containing URL', () => { - const fixturePath = path.join(rootFixturePath, '$ref-url'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -571,12 +640,34 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing relative references', () => { - const fixturePath = path.join(rootFixturePath, '$ref-url-relative-reference'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-relative-reference'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -585,12 +676,37 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join( + rootFixturePath, + '$ref-url-relative-reference-meta-patches' + ); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing URL and JSON Pointer fragment', () => { - const fixturePath = path.join(rootFixturePath, '$ref-url-pointer'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-pointer'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -599,12 +715,34 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-pointer-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing URL and $anchor', () => { - const fixturePath = path.join(rootFixturePath, '$ref-url-$anchor'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-$anchor'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -613,12 +751,34 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-$anchor-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing resolvable URL', () => { - const fixturePath = path.join(rootFixturePath, '$ref-url-resolvable'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-resolvable'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -627,6 +787,30 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-url-resolvable-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + refSet.refs[1].uri = '/home/smartbear/ex.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing unresolvable URL', () => { @@ -649,9 +833,8 @@ describe('dereference', () => { }); describe('given Schema Objects with $ref keyword containing Uniform Resource Name', () => { - const fixturePath = path.join(rootFixturePath, '$ref-urn'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-urn'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -660,12 +843,34 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-urn-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing Uniform Resource Name and JSON Pointer fragment', () => { - const fixturePath = path.join(rootFixturePath, '$ref-urn-pointer'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-urn-pointer'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -674,6 +879,29 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$ref-urn-pointer-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + refSet, + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $ref keyword containing Uniform Resource Name and $anchor', () => { @@ -710,9 +938,8 @@ describe('dereference', () => { }); describe('given Schema Objects with $anchor keyword pointing to internal schema', () => { - const fixturePath = path.join(rootFixturePath, '$anchor-internal'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$anchor-internal'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -721,12 +948,34 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$anchor-internal-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs[0].uri = '/home/smartbear/root.json'; + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + refSet, + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with $anchor keyword pointing to external schema', () => { - const fixturePath = path.join(rootFixturePath, '$anchor-external'); - test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$anchor-external'); const rootFilePath = path.join(fixturePath, 'root.json'); const actual = await dereference(rootFilePath, { parse: { mediaType: mediaTypes.latest('json') }, @@ -735,6 +984,31 @@ describe('dereference', () => { expect(toValue(actual)).toEqual(expected); }); + + describe('and allowMetaPatches=true', () => { + test('should dereference', async () => { + const fixturePath = path.join(rootFixturePath, '$anchor-external-meta-patches'); + const rootFilePath = path.join(fixturePath, 'root.json'); + const refSet = await resolve(rootFilePath, { + parse: { mediaType: mediaTypes.latest('json') }, + }); + refSet.refs.forEach((ref) => { + ref.uri = `/home/smartbear/${path.basename(ref.uri)}`; + }); + const actual = await dereference(refSet.refs[0].uri, { + parse: { mediaType: mediaTypes.latest('json') }, + dereference: { + strategies: [ + OpenApi3_1SwaggerClientDereferenceStrategy({ allowMetaPatches: true }), + ], + refSet, + }, + }); + const expected = globalThis.loadJsonFile(path.join(fixturePath, 'dereferenced.json')); + + expect(toValue(actual)).toEqual(expected); + }); + }); }); describe('given Schema Objects with various document boundaries', () => { diff --git a/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap b/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap index 1df0b36310..6f91e60cbb 100644 --- a/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap +++ b/test/resolver/strategies/openapi-3-1/__snapshots__/index.js.snap @@ -1,5 +1,314 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP +exports[`resolve OpenAPI 3.1.0 strategy given OpenAPI 3.1.0 definition and allowMetaPatches=true should resolve 1`] = ` +{ + "errors": [], + "spec": { + "$$normalized": true, + "components": { + "schemas": { + "Error": { + "properties": { + "code": { + "format": "int32", + "type": "integer", + }, + "message": { + "type": "string", + }, + }, + "required": [ + "code", + "message", + ], + "type": "object", + }, + "Pet": { + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + "Pets": { + "items": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Pet", + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + "maxItems": 100, + "type": "array", + }, + }, + }, + "info": { + "license": { + "name": "MIT", + }, + "title": "Swagger Petstore", + "version": "1.0.0", + }, + "openapi": "3.1.0", + "paths": { + "/pets": { + "get": { + "operationId": "listPets", + "parameters": [ + { + "description": "How many items to return at one time (max 100)", + "in": "query", + "name": "limit", + "required": false, + "schema": { + "format": "int32", + "maximum": 100, + "type": "integer", + }, + }, + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Pets", + "items": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Pet", + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + "maxItems": 100, + "type": "array", + }, + }, + }, + "description": "A paged array of pets", + "headers": { + "x-next": { + "description": "A link to the next page of responses", + "schema": { + "type": "string", + }, + }, + }, + }, + "default": { + "content": { + "application/json": { + "schema": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Error", + "properties": { + "code": { + "format": "int32", + "type": "integer", + }, + "message": { + "type": "string", + }, + }, + "required": [ + "code", + "message", + ], + "type": "object", + }, + }, + }, + "description": "unexpected error", + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + "summary": "List all pets", + "tags": [ + "pets", + ], + }, + "post": { + "operationId": "createPets", + "responses": { + "201": { + "description": "Null response", + }, + "default": { + "content": { + "application/json": { + "schema": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Error", + "properties": { + "code": { + "format": "int32", + "type": "integer", + }, + "message": { + "type": "string", + }, + }, + "required": [ + "code", + "message", + ], + "type": "object", + }, + }, + }, + "description": "unexpected error", + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + "summary": "Create a pet", + "tags": [ + "pets", + ], + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + }, + "/pets/{petId}": { + "get": { + "operationId": "showPetById", + "parameters": [ + { + "description": "The id of the pet to retrieve", + "in": "path", + "name": "petId", + "required": true, + "schema": { + "type": "string", + }, + }, + ], + "responses": { + "200": { + "content": { + "application/json": { + "schema": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Pet", + "properties": { + "id": { + "format": "int64", + "type": "integer", + }, + "name": { + "type": "string", + }, + "tag": { + "type": "string", + }, + }, + "required": [ + "id", + "name", + ], + "type": "object", + }, + }, + }, + "description": "Expected response to a valid request", + }, + "default": { + "content": { + "application/json": { + "schema": { + "$$ref": "https://example.com/petstore.json#/components/schemas/Error", + "properties": { + "code": { + "format": "int32", + "type": "integer", + }, + "message": { + "type": "string", + }, + }, + "required": [ + "code", + "message", + ], + "type": "object", + }, + }, + }, + "description": "unexpected error", + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + "summary": "Info for a specific pet", + "tags": [ + "pets", + ], + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + }, + }, + "servers": [ + { + "url": "http://petstore.swagger.io/v1", + }, + ], + }, +} +`; + exports[`resolve OpenAPI 3.1.0 strategy given OpenAPI 3.1.0 definition should resolve 1`] = ` { "errors": [], diff --git a/test/resolver/strategies/openapi-3-1/index.js b/test/resolver/strategies/openapi-3-1/index.js index e007e8f47b..342b891527 100644 --- a/test/resolver/strategies/openapi-3-1/index.js +++ b/test/resolver/strategies/openapi-3-1/index.js @@ -24,6 +24,24 @@ describe('resolve', () => { fetchMock.restore(); }); + + describe('and allowMetaPatches=true', () => { + test('should resolve', async () => { + const url = 'https://example.com/petstore.json'; + const response = new Response( + globalThis.loadFile(path.join(fixturePath, 'petstore.json')) + ); + fetchMock.get(url, response, { repeat: 1 }); + const resolvedSpec = await Swagger.resolve({ + url: 'https://example.com/petstore.json', + allowMetaPatches: true, + }); + + expect(resolvedSpec).toMatchSnapshot(); + + fetchMock.restore(); + }); + }); }); }); });