mirror of
				https://github.com/Redocly/redoc.git
				synced 2025-10-31 07:47:29 +03:00 
			
		
		
		
	fix: property with nested allOf (#2083)
This commit is contained in:
		
							parent
							
								
									1a1bc26503
								
							
						
					
					
						commit
						7cc0500f3c
					
				|  | @ -843,6 +843,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView | ||||||
|             ], |             ], | ||||||
|             "schema": Object { |             "schema": Object { | ||||||
|               "allOf": undefined, |               "allOf": undefined, | ||||||
|  |               "description": undefined, | ||||||
|               "discriminator": Object { |               "discriminator": Object { | ||||||
|                 "propertyName": "type", |                 "propertyName": "type", | ||||||
|               }, |               }, | ||||||
|  | @ -858,11 +859,13 @@ exports[`Components SchemaView discriminator should correctly render SchemaView | ||||||
|                   ], |                   ], | ||||||
|                 }, |                 }, | ||||||
|               }, |               }, | ||||||
|  |               "readOnly": undefined, | ||||||
|               "required": Array [ |               "required": Array [ | ||||||
|                 "type", |                 "type", | ||||||
|               ], |               ], | ||||||
|               "title": "Dog", |               "title": "Dog", | ||||||
|               "type": "object", |               "type": "object", | ||||||
|  |               "writeOnly": undefined, | ||||||
|               "x-circular-ref": undefined, |               "x-circular-ref": undefined, | ||||||
|               "x-parentRefs": Array [ |               "x-parentRefs": Array [ | ||||||
|                 "#/components/schemas/Pet", |                 "#/components/schemas/Pet", | ||||||
|  | @ -1699,6 +1702,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView | ||||||
|             ], |             ], | ||||||
|             "schema": Object { |             "schema": Object { | ||||||
|               "allOf": undefined, |               "allOf": undefined, | ||||||
|  |               "description": undefined, | ||||||
|               "discriminator": Object { |               "discriminator": Object { | ||||||
|                 "propertyName": "type", |                 "propertyName": "type", | ||||||
|               }, |               }, | ||||||
|  | @ -1717,11 +1721,13 @@ exports[`Components SchemaView discriminator should correctly render SchemaView | ||||||
|                   ], |                   ], | ||||||
|                 }, |                 }, | ||||||
|               }, |               }, | ||||||
|  |               "readOnly": undefined, | ||||||
|               "required": Array [ |               "required": Array [ | ||||||
|                 "type", |                 "type", | ||||||
|               ], |               ], | ||||||
|               "title": "Cat", |               "title": "Cat", | ||||||
|               "type": "object", |               "type": "object", | ||||||
|  |               "writeOnly": undefined, | ||||||
|               "x-circular-ref": undefined, |               "x-circular-ref": undefined, | ||||||
|               "x-parentRefs": Array [ |               "x-parentRefs": Array [ | ||||||
|                 "#/components/schemas/Pet", |                 "#/components/schemas/Pet", | ||||||
|  | @ -2811,6 +2817,7 @@ exports[`Components SchemaView discriminator should correctly render SchemaView | ||||||
|       ], |       ], | ||||||
|       "schema": Object { |       "schema": Object { | ||||||
|         "allOf": undefined, |         "allOf": undefined, | ||||||
|  |         "description": undefined, | ||||||
|         "discriminator": Object { |         "discriminator": Object { | ||||||
|           "propertyName": "type", |           "propertyName": "type", | ||||||
|         }, |         }, | ||||||
|  | @ -2826,11 +2833,13 @@ exports[`Components SchemaView discriminator should correctly render SchemaView | ||||||
|             ], |             ], | ||||||
|           }, |           }, | ||||||
|         }, |         }, | ||||||
|  |         "readOnly": undefined, | ||||||
|         "required": Array [ |         "required": Array [ | ||||||
|           "type", |           "type", | ||||||
|         ], |         ], | ||||||
|         "title": "Dog", |         "title": "Dog", | ||||||
|         "type": "object", |         "type": "object", | ||||||
|  |         "writeOnly": undefined, | ||||||
|         "x-circular-ref": undefined, |         "x-circular-ref": undefined, | ||||||
|         "x-parentRefs": Array [ |         "x-parentRefs": Array [ | ||||||
|           "#/components/schemas/Pet", |           "#/components/schemas/Pet", | ||||||
|  |  | ||||||
|  | @ -217,6 +217,9 @@ export class OpenAPIParser { | ||||||
|         items, |         items, | ||||||
|         required, |         required, | ||||||
|         title, |         title, | ||||||
|  |         description, | ||||||
|  |         readOnly, | ||||||
|  |         writeOnly, | ||||||
|         oneOf, |         oneOf, | ||||||
|         anyOf, |         anyOf, | ||||||
|         'x-circular-ref': isCircular, |         'x-circular-ref': isCircular, | ||||||
|  | @ -305,6 +308,9 @@ export class OpenAPIParser { | ||||||
|       receiver = { |       receiver = { | ||||||
|         ...receiver, |         ...receiver, | ||||||
|         title: receiver.title || title, |         title: receiver.title || title, | ||||||
|  |         description: receiver.description || description, | ||||||
|  |         readOnly: receiver.readOnly !== undefined ? receiver.readOnly : readOnly, | ||||||
|  |         writeOnly: receiver.writeOnly !== undefined ? receiver.writeOnly : writeOnly, | ||||||
|         'x-circular-ref': receiver['x-circular-ref'] || isCircular, |         'x-circular-ref': receiver['x-circular-ref'] || isCircular, | ||||||
|         ...otherConstraints, |         ...otherConstraints, | ||||||
|       }; |       }; | ||||||
|  |  | ||||||
|  | @ -1,3 +1,5 @@ | ||||||
|  | import { parseYaml } from '@redocly/openapi-core'; | ||||||
|  | import { outdent } from 'outdent'; | ||||||
| import { RequestBodyModel } from '../../models/RequestBody'; | import { RequestBodyModel } from '../../models/RequestBody'; | ||||||
| import { OpenAPIParser } from '../../OpenAPIParser'; | import { OpenAPIParser } from '../../OpenAPIParser'; | ||||||
| import { RedocNormalizedOptions } from '../../RedocNormalizedOptions'; | import { RedocNormalizedOptions } from '../../RedocNormalizedOptions'; | ||||||
|  | @ -23,5 +25,55 @@ describe('Models', () => { | ||||||
|       expect(consoleError).not.toHaveBeenCalled(); |       expect(consoleError).not.toHaveBeenCalled(); | ||||||
|       expect(req).toEqual({ description: '', required: false }); |       expect(req).toEqual({ description: '', required: false }); | ||||||
|     }); |     }); | ||||||
|  | 
 | ||||||
|  |     test('should have correct field data when it includes allOf', () => { | ||||||
|  |       const spec = parseYaml(outdent` | ||||||
|  |           openapi: 3.0.0 | ||||||
|  |           paths: | ||||||
|  |             /user: | ||||||
|  |               post: | ||||||
|  |                 tags: | ||||||
|  |                   - user | ||||||
|  |                 summary: Create user | ||||||
|  |                 description: This can only be done by the logged in user. | ||||||
|  |                 operationId: createUser | ||||||
|  |                 requestBody: | ||||||
|  |                   content: | ||||||
|  |                     application/json: | ||||||
|  |                       schema: | ||||||
|  |                         $ref: '#/components/schemas/User' | ||||||
|  |                   description: Created user object | ||||||
|  |                   required: true | ||||||
|  |           components: | ||||||
|  |             schemas: | ||||||
|  |               User: | ||||||
|  |                 allOf: | ||||||
|  |                   - type: object | ||||||
|  |                     properties: | ||||||
|  |                       name: | ||||||
|  |                         type: string | ||||||
|  |                         description: correct description name | ||||||
|  |                         readOnly: false | ||||||
|  |                         writeOnly: false | ||||||
|  |                         allOf: | ||||||
|  |                           - $ref: '#/components/schemas/NameField' | ||||||
|  |               NameField: | ||||||
|  |                 description: name description | ||||||
|  |                 readOnly: true | ||||||
|  |                 writeOnly: true | ||||||
|  |           `) as any;
 | ||||||
|  | 
 | ||||||
|  |       parser = new OpenAPIParser(spec, undefined, opts); | ||||||
|  |       const req = new RequestBodyModel({ | ||||||
|  |         parser, | ||||||
|  |         infoOrRef: spec.paths['/user'].post.requestBody, | ||||||
|  |         options: opts, | ||||||
|  |         isEvent: false, | ||||||
|  |       }); | ||||||
|  |       const nameField = req.content?.mediaTypes[0].schema?.fields?.[0]; | ||||||
|  |       expect(nameField?.schema.readOnly).toBe(false); | ||||||
|  |       expect(nameField?.schema.writeOnly).toBe(false); | ||||||
|  |       expect(nameField?.description).toMatchInlineSnapshot(`"correct description name"`); | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -1,7 +1,10 @@ | ||||||
| /* eslint-disable @typescript-eslint/no-var-requires */ | /* eslint-disable @typescript-eslint/no-var-requires */ | ||||||
|  | import { parseYaml } from '@redocly/openapi-core'; | ||||||
|  | import { outdent } from 'outdent'; | ||||||
| import { SchemaModel } from '../../models/Schema'; | import { SchemaModel } from '../../models/Schema'; | ||||||
| import { OpenAPIParser } from '../../OpenAPIParser'; | import { OpenAPIParser } from '../../OpenAPIParser'; | ||||||
| import { RedocNormalizedOptions } from '../../RedocNormalizedOptions'; | import { RedocNormalizedOptions } from '../../RedocNormalizedOptions'; | ||||||
|  | import { printSchema } from './helpers'; | ||||||
| 
 | 
 | ||||||
| const opts = new RedocNormalizedOptions({}); | const opts = new RedocNormalizedOptions({}); | ||||||
| 
 | 
 | ||||||
|  | @ -240,5 +243,45 @@ describe('Models', () => { | ||||||
|         }, |         }, | ||||||
|       ); |       ); | ||||||
|     }); |     }); | ||||||
|  | 
 | ||||||
|  |     test('should get correct fields data if it includes allOf', () => { | ||||||
|  |       const spec = parseYaml(outdent` | ||||||
|  |       openapi: 3.0.0 | ||||||
|  |       components: | ||||||
|  |         schemas: | ||||||
|  |           User: | ||||||
|  |             allOf: | ||||||
|  |               - type: object | ||||||
|  |                 properties: | ||||||
|  |                   name: | ||||||
|  |                     type: string | ||||||
|  |                     description: correct description name | ||||||
|  |                     readOnly: false | ||||||
|  |                     writeOnly: false | ||||||
|  |                   allOf: | ||||||
|  |                     - '#/components/schemas/NameField' | ||||||
|  |           NameField: | ||||||
|  |             type: object | ||||||
|  |             description: name description | ||||||
|  |             readOnly: true | ||||||
|  |             writeOnly: false | ||||||
|  | 
 | ||||||
|  |       `) as any;
 | ||||||
|  | 
 | ||||||
|  |       parser = new OpenAPIParser(spec, undefined, opts); | ||||||
|  |       const schema = new SchemaModel( | ||||||
|  |         parser, | ||||||
|  |         spec.components.schemas.User, | ||||||
|  |         '#/components/schemas/User', | ||||||
|  |         opts, | ||||||
|  |       ); | ||||||
|  |       const fieldSchema = schema.fields?.[0].schema; | ||||||
|  |       expect(fieldSchema?.readOnly).toBe(false); | ||||||
|  |       expect(fieldSchema?.writeOnly).toBe(false); | ||||||
|  |       expect(printSchema(schema)).toMatchInlineSnapshot(` | ||||||
|  |         "name: <string> (correct description name) | ||||||
|  |         allOf: <any>" | ||||||
|  |       `);
 | ||||||
|  |     }); | ||||||
|   }); |   }); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | @ -4,18 +4,24 @@ exports[`Models Schema schemaDefinition should resolve field with conditional op | ||||||
| Object { | Object { | ||||||
|   "allOf": undefined, |   "allOf": undefined, | ||||||
|   "default": undefined, |   "default": undefined, | ||||||
|  |   "description": undefined, | ||||||
|   "items": Object { |   "items": Object { | ||||||
|     "allOf": undefined, |     "allOf": undefined, | ||||||
|  |     "description": undefined, | ||||||
|     "format": "url", |     "format": "url", | ||||||
|  |     "readOnly": undefined, | ||||||
|     "title": undefined, |     "title": undefined, | ||||||
|     "type": "string", |     "type": "string", | ||||||
|  |     "writeOnly": undefined, | ||||||
|     "x-circular-ref": undefined, |     "x-circular-ref": undefined, | ||||||
|     "x-parentRefs": Array [], |     "x-parentRefs": Array [], | ||||||
|   }, |   }, | ||||||
|   "maxItems": 20, |   "maxItems": 20, | ||||||
|   "minItems": 1, |   "minItems": 1, | ||||||
|  |   "readOnly": undefined, | ||||||
|   "title": "isString", |   "title": "isString", | ||||||
|   "type": "string", |   "type": "string", | ||||||
|  |   "writeOnly": undefined, | ||||||
|   "x-circular-ref": undefined, |   "x-circular-ref": undefined, | ||||||
|   "x-displayName": "isString", |   "x-displayName": "isString", | ||||||
|   "x-parentRefs": Array [], |   "x-parentRefs": Array [], | ||||||
|  | @ -26,23 +32,29 @@ exports[`Models Schema schemaDefinition should resolve field with conditional op | ||||||
| Object { | Object { | ||||||
|   "allOf": undefined, |   "allOf": undefined, | ||||||
|   "default": undefined, |   "default": undefined, | ||||||
|  |   "description": undefined, | ||||||
|   "items": Object { |   "items": Object { | ||||||
|     "allOf": undefined, |     "allOf": undefined, | ||||||
|  |     "description": undefined, | ||||||
|     "format": "url", |     "format": "url", | ||||||
|  |     "readOnly": undefined, | ||||||
|     "title": undefined, |     "title": undefined, | ||||||
|     "type": "string", |     "type": "string", | ||||||
|  |     "writeOnly": undefined, | ||||||
|     "x-circular-ref": undefined, |     "x-circular-ref": undefined, | ||||||
|     "x-parentRefs": Array [], |     "x-parentRefs": Array [], | ||||||
|   }, |   }, | ||||||
|   "maxItems": 10, |   "maxItems": 10, | ||||||
|   "minItems": 1, |   "minItems": 1, | ||||||
|   "pattern": "\\\\d+", |   "pattern": "\\\\d+", | ||||||
|  |   "readOnly": undefined, | ||||||
|   "title": "notString", |   "title": "notString", | ||||||
|   "type": Array [ |   "type": Array [ | ||||||
|     "string", |     "string", | ||||||
|     "integer", |     "integer", | ||||||
|     "null", |     "null", | ||||||
|   ], |   ], | ||||||
|  |   "writeOnly": undefined, | ||||||
|   "x-circular-ref": undefined, |   "x-circular-ref": undefined, | ||||||
|   "x-displayName": "notString", |   "x-displayName": "notString", | ||||||
|   "x-parentRefs": Array [], |   "x-parentRefs": Array [], | ||||||
|  | @ -52,6 +64,7 @@ Object { | ||||||
| exports[`Models Schema schemaDefinition should resolve schema with conditional operators 1`] = ` | exports[`Models Schema schemaDefinition should resolve schema with conditional operators 1`] = ` | ||||||
| Object { | Object { | ||||||
|   "allOf": undefined, |   "allOf": undefined, | ||||||
|  |   "description": undefined, | ||||||
|   "maxItems": 2, |   "maxItems": 2, | ||||||
|   "properties": Object { |   "properties": Object { | ||||||
|     "test": Object { |     "test": Object { | ||||||
|  | @ -62,20 +75,25 @@ Object { | ||||||
|       ], |       ], | ||||||
|       "items": Object { |       "items": Object { | ||||||
|         "allOf": undefined, |         "allOf": undefined, | ||||||
|  |         "description": undefined, | ||||||
|         "format": "url", |         "format": "url", | ||||||
|  |         "readOnly": undefined, | ||||||
|         "title": undefined, |         "title": undefined, | ||||||
|         "type": "string", |         "type": "string", | ||||||
|  |         "writeOnly": undefined, | ||||||
|         "x-circular-ref": undefined, |         "x-circular-ref": undefined, | ||||||
|         "x-parentRefs": Array [], |         "x-parentRefs": Array [], | ||||||
|       }, |       }, | ||||||
|       "maxItems": 20, |       "maxItems": 20, | ||||||
|       "minItems": 1, |       "minItems": 1, | ||||||
|  |       "readOnly": undefined, | ||||||
|       "title": undefined, |       "title": undefined, | ||||||
|       "type": Array [ |       "type": Array [ | ||||||
|         "string", |         "string", | ||||||
|         "integer", |         "integer", | ||||||
|         "null", |         "null", | ||||||
|       ], |       ], | ||||||
|  |       "writeOnly": undefined, | ||||||
|       "x-circular-ref": undefined, |       "x-circular-ref": undefined, | ||||||
|       "x-parentRefs": Array [], |       "x-parentRefs": Array [], | ||||||
|       "x-refsStack": Array [ |       "x-refsStack": Array [ | ||||||
|  | @ -83,8 +101,10 @@ Object { | ||||||
|       ], |       ], | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   "readOnly": undefined, | ||||||
|   "title": "=== 10", |   "title": "=== 10", | ||||||
|   "type": "object", |   "type": "object", | ||||||
|  |   "writeOnly": undefined, | ||||||
|   "x-circular-ref": undefined, |   "x-circular-ref": undefined, | ||||||
|   "x-parentRefs": Array [], |   "x-parentRefs": Array [], | ||||||
| } | } | ||||||
|  | @ -93,6 +113,7 @@ Object { | ||||||
| exports[`Models Schema schemaDefinition should resolve schema with conditional operators 2`] = ` | exports[`Models Schema schemaDefinition should resolve schema with conditional operators 2`] = ` | ||||||
| Object { | Object { | ||||||
|   "allOf": undefined, |   "allOf": undefined, | ||||||
|  |   "description": undefined, | ||||||
|   "maxItems": 20, |   "maxItems": 20, | ||||||
|   "properties": Object { |   "properties": Object { | ||||||
|     "test": Object { |     "test": Object { | ||||||
|  | @ -113,8 +134,10 @@ Object { | ||||||
|       ], |       ], | ||||||
|     }, |     }, | ||||||
|   }, |   }, | ||||||
|  |   "readOnly": undefined, | ||||||
|   "title": "case 2", |   "title": "case 2", | ||||||
|   "type": "object", |   "type": "object", | ||||||
|  |   "writeOnly": undefined, | ||||||
|   "x-circular-ref": undefined, |   "x-circular-ref": undefined, | ||||||
|   "x-parentRefs": Array [], |   "x-parentRefs": Array [], | ||||||
| } | } | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user