UNPKG

@redocly/openapi-core

Version:

See https://github.com/Redocly/redocly-cli

967 lines (925 loc) 27.9 kB
import { outdent } from 'outdent'; import { parseYamlToDocument, replaceSourceWithRef } from '../../../../__tests__/utils'; import { lintDocumentForTest } from './utils/lint-document-for-test'; describe('Oas3 component-name-unique', () => { describe('schema', () => { it('should report on multiple schemas with same name', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 components: schemas: SomeSchema: type: object Test: type: object properties: there: $ref: '/test.yaml#/components/schemas/SomeSchema' `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` openapi: 3.0.0 components: schemas: SomeSchema: type: object `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/schemas/SomeSchema", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'schemas/SomeSchema' is not unique. It is also defined at: - /test.yaml#/components/schemas/SomeSchema", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/schemas/SomeSchema", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'schemas/SomeSchema' is not unique. It is also defined at: - /foobar.yaml#/components/schemas/SomeSchema", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should report on multiple schemas with same name - filename', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 components: schemas: SomeSchema: type: object Test: type: object properties: there: $ref: '/SomeSchema.yaml' `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/SomeSchema.yaml', body: outdent` type: object properties: test: type: number `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/schemas/SomeSchema", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'schemas/SomeSchema' is not unique. It is also defined at: - /SomeSchema.yaml", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/", "reportOnKey": false, "source": "/SomeSchema.yaml", }, ], "message": "Component 'schemas/SomeSchema' is not unique. It is also defined at: - /foobar.yaml#/components/schemas/SomeSchema", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should not report on multiple schemas with different names', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 components: schemas: SomeSchema: type: object Test: type: object properties: there: $ref: '/test.yaml#/components/schemas/OtherSchema' `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` openapi: 3.0.0 components: schemas: OtherSchema: type: object `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); }); }); describe('parameter', () => { it('should report if multiple parameters have same component name', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: get: parameters: - $ref: '#/components/parameters/ParameterOne' - $ref: '/test.yaml#/components/parameters/ParameterOne' components: parameters: ParameterOne: name: parameterOne in: query schema: type: integer `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` openapi: 3.0.0 components: parameters: ParameterOne: name: oneParameter in: query schema: type: integer `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/parameters/ParameterOne", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'parameters/ParameterOne' is not unique. It is also defined at: - /test.yaml#/components/parameters/ParameterOne", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/parameters/ParameterOne", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'parameters/ParameterOne' is not unique. It is also defined at: - /foobar.yaml#/components/parameters/ParameterOne", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should report on multiple parameters with same component name - filename', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: get: parameters: - $ref: '#/components/parameters/ParameterOne' - $ref: '/ParameterOne.yaml' components: parameters: ParameterOne: name: parameterOne in: query schema: type: integer `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/ParameterOne.yaml', body: outdent` name: oneParameter in: query schema: type: integer `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/parameters/ParameterOne", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'parameters/ParameterOne' is not unique. It is also defined at: - /ParameterOne.yaml", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/", "reportOnKey": false, "source": "/ParameterOne.yaml", }, ], "message": "Component 'parameters/ParameterOne' is not unique. It is also defined at: - /foobar.yaml#/components/parameters/ParameterOne", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should not report on multiple parameters with different component names', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: get: parameters: - $ref: '#/components/parameters/ParameterOne' - $ref: '/test.yaml#/components/parameters/OneParameter' components: parameters: ParameterOne: name: parameterOne in: query schema: type: integer `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` openapi: 3.0.0 components: parameters: OneParameter: name: oneParameter in: query schema: type: integer `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); }); }); describe('response', () => { it('should report if multiple responses have same component name', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: get: responses: '200': $ref: '#/components/responses/SuccessResponse' /test2: get: responses: '200': $ref: '/test.yaml#/components/responses/SuccessResponse' components: responses: SuccessResponse: description: Successful response content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` openapi: 3.0.0 components: responses: SuccessResponse: description: Successful response content: application/json: schema: type: string `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/responses/SuccessResponse", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'responses/SuccessResponse' is not unique. It is also defined at: - /test.yaml#/components/responses/SuccessResponse", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/responses/SuccessResponse", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'responses/SuccessResponse' is not unique. It is also defined at: - /foobar.yaml#/components/responses/SuccessResponse", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should report on multiple responses with same component name - filename', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: get: responses: '200': $ref: '#/components/responses/SuccessResponse' /test2: get: responses: '200': $ref: '/SuccessResponse.yaml' components: responses: SuccessResponse: description: Successful response content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/SuccessResponse.yaml', body: outdent` description: Successful response content: application/json: schema: type: string `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/responses/SuccessResponse", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'responses/SuccessResponse' is not unique. It is also defined at: - /SuccessResponse.yaml", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/", "reportOnKey": false, "source": "/SuccessResponse.yaml", }, ], "message": "Component 'responses/SuccessResponse' is not unique. It is also defined at: - /foobar.yaml#/components/responses/SuccessResponse", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should not report on multiple responses with different component names', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: get: responses: '200': $ref: '#/components/responses/TestSuccessResponse' /test2: get: responses: '200': $ref: '/test.yaml#/components/responses/Test2SuccessResponse' components: responses: TestSuccessResponse: description: Successful response content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` openapi: 3.0.0 components: responses: Test2SuccessResponse: description: Successful response content: application/json: schema: type: string `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); }); }); describe('request-body', () => { it('should report if multiple request bodies have same component name', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: post: requestBody: $ref: '#/components/requestBodies/MyRequestBody' /test2: post: requestBody: $ref: '/test.yaml#/components/requestBodies/MyRequestBody' components: requestBodies: MyRequestBody: required: true content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` components: requestBodies: MyRequestBody: required: true content: application/json: schema: type: string `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /test.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /foobar.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should report on multiple responses with same component name - filename', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: post: requestBody: $ref: '#/components/requestBodies/MyRequestBody' /test2: post: requestBody: $ref: '/MyRequestBody.yaml' components: requestBodies: MyRequestBody: required: true content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/MyRequestBody.yaml', body: outdent` components: requestBodies: MyRequestBody: required: true content: application/json: schema: type: string `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /MyRequestBody.yaml", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/", "reportOnKey": false, "source": "/MyRequestBody.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /foobar.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should not report on multiple responses with different component names', async () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: post: requestBody: $ref: '#/components/requestBodies/TestRequestBody' /test2: post: requestBody: $ref: '/test.yaml#/components/requestBodies/Test2RequestBody' components: requestBodies: TestRequestBody: required: true content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` components: requestBodies: Test2RequestBody: required: true content: application/json: schema: type: string `, }, ]; const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(`[]`); }); }); describe('different severities', () => { const document = parseYamlToDocument( outdent` openapi: 3.0.0 paths: /test: post: requestBody: $ref: '#/components/requestBodies/MyRequestBody' /test2: post: requestBody: $ref: '/test.yaml#/components/requestBodies/MyRequestBody' components: schemas: SomeSchema: type: object Test: type: object properties: there: $ref: '/test.yaml#/components/schemas/SomeSchema' requestBodies: MyRequestBody: required: true content: application/json: schema: type: string `, '/foobar.yaml' ); const additionalDocuments = [ { absoluteRef: '/test.yaml', body: outdent` components: schemas: SomeSchema: type: object requestBodies: MyRequestBody: required: true content: application/json: schema: type: string `, }, ]; it('should report both schema and request body', async () => { const results = await lintDocumentForTest( { 'component-name-unique': 'error' }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /test.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /foobar.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/schemas/SomeSchema", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'schemas/SomeSchema' is not unique. It is also defined at: - /test.yaml#/components/schemas/SomeSchema", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/schemas/SomeSchema", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'schemas/SomeSchema' is not unique. It is also defined at: - /foobar.yaml#/components/schemas/SomeSchema", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); it('should not report if severity is off for specific component type', async () => { const results = await lintDocumentForTest( { 'component-name-unique': { severity: 'error', schemas: 'off' } }, document, additionalDocuments ); expect(replaceSourceWithRef(results)).toMatchInlineSnapshot(` [ { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/foobar.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /test.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, { "location": [ { "pointer": "#/components/requestBodies/MyRequestBody", "reportOnKey": false, "source": "/test.yaml", }, ], "message": "Component 'requestBodies/MyRequestBody' is not unique. It is also defined at: - /foobar.yaml#/components/requestBodies/MyRequestBody", "ruleId": "component-name-unique", "severity": "error", "suggest": [], }, ] `); }); }); });