From 6cd7ca182fec0b909fc8c606828e0bb11314d0cd Mon Sep 17 00:00:00 2001 From: Thomas Farr Date: Fri, 10 May 2024 23:26:32 +1200 Subject: [PATCH] Adds initial test for InlineObjectSchemaValidator (#289) Signed-off-by: Thomas Farr --- tools/linter/InlineObjectSchemaValidator.ts | 8 +- tools/linter/utils/index.ts | 4 + .../InlineObjectSchemaValidator.test.ts | 32 ++++++++ .../namespaces/ops.yaml | 73 +++++++++++++++++++ .../schemas/schemas.yaml | 18 +++++ 5 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 tools/test/linter/InlineObjectSchemaValidator.test.ts create mode 100644 tools/test/linter/fixtures/inline_object_schema_validator/namespaces/ops.yaml create mode 100644 tools/test/linter/fixtures/inline_object_schema_validator/schemas/schemas.yaml diff --git a/tools/linter/InlineObjectSchemaValidator.ts b/tools/linter/InlineObjectSchemaValidator.ts index 7acf5eb48..f54b641f3 100644 --- a/tools/linter/InlineObjectSchemaValidator.ts +++ b/tools/linter/InlineObjectSchemaValidator.ts @@ -34,10 +34,12 @@ export default class InlineObjectSchemaValidator { return } - const this_key = ctx.key - const parent_key = ctx.parent().key + const ancestry = ctx.keys.reverse() - if (parent_key === 'properties' || this_key === 'additionalProperties' || this_key === 'items') { + if (ancestry[1] === 'properties' || + ancestry[0] === 'additionalProperties' || + ancestry[0] === 'items' || + (ancestry[0] === 'schema' && ancestry[2] === 'parameters' && ancestry[3] !== 'components')) { errors.push(ctx.error('object schemas should be defined out-of-line via a $ref')) } } diff --git a/tools/linter/utils/index.ts b/tools/linter/utils/index.ts index d20fbf5d4..5e6bea1c3 100644 --- a/tools/linter/utils/index.ts +++ b/tools/linter/utils/index.ts @@ -53,6 +53,10 @@ export class SpecificationContext { get key (): string { return this._location[this._location.length - 1] } + + get keys (): string[] { + return [...this._location] + } } export type MaybeRef = O | OpenAPIV3.ReferenceObject diff --git a/tools/test/linter/InlineObjectSchemaValidator.test.ts b/tools/test/linter/InlineObjectSchemaValidator.test.ts new file mode 100644 index 000000000..ddc5a47de --- /dev/null +++ b/tools/test/linter/InlineObjectSchemaValidator.test.ts @@ -0,0 +1,32 @@ +import SchemasFolder from '../../linter/components/SchemasFolder' +import NamespacesFolder from '../../linter/components/NamespacesFolder' +import InlineObjectSchemaValidator from '../../linter/InlineObjectSchemaValidator' + +test('validate()', () => { + const root_folder = './test/linter/fixtures/inline_object_schema_validator' + const namespaces_folder = new NamespacesFolder(`${root_folder}/namespaces`) + const schemas_folder = new SchemasFolder(`${root_folder}/schemas`) + const validator = new InlineObjectSchemaValidator(namespaces_folder, schemas_folder) + expect(validator.validate()).toEqual([ + { + file: 'namespaces/ops.yaml', + location: '#/paths/~1the~1path/post/parameters/3/schema', + message: 'object schemas should be defined out-of-line via a $ref' + }, + { + file: 'namespaces/ops.yaml', + location: '#/paths/~1the~1path/post/requestBody/content/application~1json/schema/items', + message: 'object schemas should be defined out-of-line via a $ref' + }, + { + file: 'namespaces/ops.yaml', + location: '#/paths/~1the~1path/post/responses/200/content/application~1json/schema/properties/inline_object_as_a_property_is_not_ok', + message: 'object schemas should be defined out-of-line via a $ref' + }, + { + file: 'schemas/schemas.yaml', + location: '#/components/schemas/additionalProperties_with_object_value_schema_can_not_be_inline/additionalProperties', + message: 'object schemas should be defined out-of-line via a $ref' + } + ]) +}) diff --git a/tools/test/linter/fixtures/inline_object_schema_validator/namespaces/ops.yaml b/tools/test/linter/fixtures/inline_object_schema_validator/namespaces/ops.yaml new file mode 100644 index 000000000..0a58a5719 --- /dev/null +++ b/tools/test/linter/fixtures/inline_object_schema_validator/namespaces/ops.yaml @@ -0,0 +1,73 @@ +paths: + /the/path: + post: + parameters: + - $ref: '#/components/parameters/query.ref_string_is_ok' + - $ref: '#/components/parameters/query.ref_object_is_ok' + - name: inline_string_is_ok + in: query + schema: + type: string + - name: inline_object_is_not_ok + in: query + schema: + type: object + properties: + the_prop: + type: boolean + requestBody: + content: + application/json: + schema: + type: array + items: + title: inline_object_as_array_items_is_not_ok + type: object + properties: + item_prop: + type: number + responses: + '200': + content: + application/json: + schema: + type: object + properties: + inline_object_as_a_property_is_not_ok: + type: object + properties: + nested_prop: + type: string +components: + parameters: + query.ref_string_is_ok: + name: ref_string_is_ok + in: query + schema: + type: string + query.ref_object_is_ok: + name: ref_object_is_ok + in: query + schema: + type: object + properties: + setting: + type: integer + requestBodies: + obj: + content: + application/json: + schema: + type: object + properties: + prop: + type: number + responses: + obj@200: + content: + application/json: + schema: + type: object + properties: + prop: + type: number \ No newline at end of file diff --git a/tools/test/linter/fixtures/inline_object_schema_validator/schemas/schemas.yaml b/tools/test/linter/fixtures/inline_object_schema_validator/schemas/schemas.yaml new file mode 100644 index 000000000..a4566682a --- /dev/null +++ b/tools/test/linter/fixtures/inline_object_schema_validator/schemas/schemas.yaml @@ -0,0 +1,18 @@ +components: + schemas: + object_is_ok: + type: object + properties: + prop: + type: string + object_with_only_additionalProperties_can_be_inline: + type: object + additionalProperties: + type: string + additionalProperties_with_object_value_schema_can_not_be_inline: + type: object + additionalProperties: + type: object + properties: + inline_object_with_no_properties_is_ok: + type: object \ No newline at end of file