From 88c4e35da2c4b9d8ef02edf65d8b26c262399862 Mon Sep 17 00:00:00 2001 From: Frode Aannevik Date: Sat, 16 Jun 2018 01:34:19 +0200 Subject: [PATCH] fix allOf with readOnly/writeOnly resets the readOnly/writeOnly to default (undefined) before merging it with next subschema ref: https://github.com/Rebilly/ReDoc/issues/532 rel: https://github.com/Rebilly/ReDoc/issues/422 --- src/services/OpenAPIParser.ts | 4 + src/services/__tests__/OpenAPIParser.test.ts | 109 +++++++++++++++++++ 2 files changed, 113 insertions(+) create mode 100644 src/services/__tests__/OpenAPIParser.test.ts diff --git a/src/services/OpenAPIParser.ts b/src/services/OpenAPIParser.ts index 8982bf3d..9b60471f 100644 --- a/src/services/OpenAPIParser.ts +++ b/src/services/OpenAPIParser.ts @@ -225,6 +225,10 @@ export class OpenAPIParser { receiver.properties[prop] = subSchema.properties[prop]; } else { // merge inner properties + // let readOnly/writeOnly be overridden if property is redefined + // i.e. fallback on default value of readOnly/writeOnly when merging + delete receiver.properties[prop].readOnly; + delete receiver.properties[prop].writeOnly; receiver.properties[prop] = this.mergeAllOf( { allOf: [receiver.properties[prop], subSchema.properties[prop]] }, $ref + '/properties/' + prop, diff --git a/src/services/__tests__/OpenAPIParser.test.ts b/src/services/__tests__/OpenAPIParser.test.ts new file mode 100644 index 00000000..1fd7a146 --- /dev/null +++ b/src/services/__tests__/OpenAPIParser.test.ts @@ -0,0 +1,109 @@ +import { convertObj } from 'swagger2openapi'; +import { OpenAPIParser, RedocNormalizedOptions } from '../'; + +const options = new RedocNormalizedOptions({}); +describe('OpenAPIParser mergeAllOf', async () => { + const parser = new OpenAPIParser( + { openapi: '3.0', info: { title: 'test', version: '0' }, paths: {} }, + undefined, + options, + ); + + it('merge readOnly from allOf', () => { + expect(parser.mergeAllOf({ + allOf: [ + { + properties: { + id: { type: 'string', readOnly: true }, + name: { type: 'string' }, + }, + }, + { properties: { name: { type: 'string', readOnly: true } } }, + ], + }, '', false).properties).toEqual({ + id: { + type: 'string', + readOnly: true, + }, + name: { + type: 'string', + allOf: undefined, + parentRefs: [], + readOnly: true, + }, + }); + }); + + it('merge writeOnly from allOf', () => { + expect(parser.mergeAllOf({ + allOf: [ + { + properties: { + id: { type: 'string', readOnly: true }, + name: { type: 'string' }, + }, + }, + { properties: { name: { type: 'string', writeOnly: true } } }, + ], + }, '', false).properties).toEqual({ + id: { + type: 'string', + readOnly: true, + }, + name: { + type: 'string', + allOf: undefined, + parentRefs: [], + writeOnly: true, + }, + }); + }); + + it('reset readOnly before merge', () => { + expect(parser.mergeAllOf({ + allOf: [ + { + properties: { + id: { type: 'string', readOnly: true }, + name: { type: 'string' }, + }, + }, + { properties: { id: { type: 'string', readOnly: true } } }, + { properties: { id: { type: 'string' } } }, + ], + }, '', false).properties).toEqual({ + id: { + allOf: undefined, + parentRefs: [], + type: 'string', + }, + name: { + type: 'string', + }, + }); + }); + + it('reset writeOnly before merge', () => { + expect(parser.mergeAllOf({ + allOf: [ + { + properties: { + id: { type: 'string', readOnly: true }, + name: { type: 'string' }, + }, + }, + { properties: { id: { type: 'string', writeOnly: true } } }, + { properties: { id: { type: 'string' } } }, + ], + }, '', false).properties).toEqual({ + id: { + allOf: undefined, + parentRefs: [], + type: 'string', + }, + name: { + type: 'string', + }, + }); + }); +});