diff --git a/src/specmap/lib/refs.js b/src/specmap/lib/refs.js index 1bc109956..a40c2a6ee 100644 --- a/src/specmap/lib/refs.js +++ b/src/specmap/lib/refs.js @@ -16,6 +16,26 @@ const JSONRefError = createError('JSONRefError', function (message, extra, oriEr const docCache = {} const specmapRefs = new WeakMap() +const skipResolutionTestFns = [ + path => ( + // OpenAPI 3.0 Response Media Type Example + // ["paths", *, *, "responses", *, "content", *, "example"] + path[0] === 'paths' + && path[3] === 'responses' + && path[5] === 'content' + && path[7] === 'example' + ), + path => ( + // OpenAPI 3.0 Request Body Media Type Example + // ["paths", *, *, "responses", *, "content", *, "example"] + path[0] === 'paths' + && path[3] === 'requestBody' + && path[4] === 'content' + && path[6] === 'example' + ) +] + +const shouldSkipResolution = path => skipResolutionTestFns.some(fn => fn(path)) // ========================= // Core @@ -45,7 +65,8 @@ const plugin = { plugin: (ref, key, fullPath, specmap) => { const specmapInstance = specmap.getInstance() const parent = fullPath.slice(0, -1) - if (isFreelyNamed(parent)) { + + if (isFreelyNamed(parent) || shouldSkipResolution(parent)) { return } diff --git a/test/bugs/ui-4924.js b/test/bugs/ui-4924.js new file mode 100644 index 000000000..9d13356cf --- /dev/null +++ b/test/bugs/ui-4924.js @@ -0,0 +1,110 @@ +// https://github.com/swagger-api/swagger-ui/issues/4466 +// https://github.com/swagger-api/swagger-ui/issues/4467 + +import resolveSubtree from '../../src/subtree-resolver' + +const spec = { + openapi: '3.0.0', + paths: { + '/order': { + post: { + requestBody: { + content: { + 'application/json': { + example: { + user: { + $ref: '#/components/examples/User/value' + }, + quantity: 1 + } + } + } + }, + responses: { + 200: { + description: 'OK', + content: { + 'application/json': { + example: { + user: { + $ref: '#/components/examples/User/value' + }, + quantity: 1 + } + } + } + } + } + } + } + }, + components: { + examples: { + User: { + value: { + id: 1, + name: 'Sasha' + } + } + } + } +} + + +test( + 'should not resolve $ref pointers within OpenAPI RequestBody/Response media type examples', + async () => { + const res = await resolveSubtree(spec, []) + + expect(res).toEqual({ + errors: [], + spec: { + $$normalized: true, + openapi: '3.0.0', + paths: { + '/order': { + post: { + requestBody: { + content: { + 'application/json': { + example: { + user: { + $ref: '#/components/examples/User/value' + }, + quantity: 1 + } + } + } + }, + responses: { + 200: { + description: 'OK', + content: { + 'application/json': { + example: { + user: { + $ref: '#/components/examples/User/value' + }, + quantity: 1 + } + } + } + } + } + } + } + }, + components: { + examples: { + User: { + value: { + id: 1, + name: 'Sasha' + } + } + } + } + } + }) + } +)