diff --git a/test/definitions/3.0.0/models/info/info/index.mjs b/test/definitions/3.0.0/models/info/info/index.mjs index efa23f61..3be3bc0e 100644 --- a/test/definitions/3.0.0/models/info/info/index.mjs +++ b/test/definitions/3.0.0/models/info/info/index.mjs @@ -4,7 +4,14 @@ import path from 'path'; const jsonSchema = require('@definitions/3.0.0/info.json'); -describe('Info', () => { +describe('Info', async () => { + await import('./properties/description.mjs'); + await import('./properties/termsOfService.mjs'); + await import('./properties/contact.mjs'); + await import('./properties/license.mjs'); + await import('./properties/tags.mjs'); + await import('./properties/externalDocs.mjs'); + it(TestHelper.exampleIsValidTestName, () => TestHelper.objectIsValid( jsonSchema, path.resolve(__dirname, './example.json'), diff --git a/test/definitions/3.0.0/models/info/info/properties/contact.mjs b/test/definitions/3.0.0/models/info/info/properties/contact.mjs new file mode 100644 index 00000000..8d1f6d5f --- /dev/null +++ b/test/definitions/3.0.0/models/info/info/properties/contact.mjs @@ -0,0 +1,81 @@ +import {describe, it} from 'vitest'; +import TestHelper from '@test/test-helper'; +import path from 'path'; + +const jsonSchema = require('@definitions/3.0.0/info.json'); + +describe('Info: contact', () => { + it(`${TestHelper.propertyIsNotValidWhenIsTestName} null`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": null + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} empty`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": {} + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} string`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": "short description" + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} object`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": { + "name": "AsyncAPI", + "url": "https://www.asyncapi.com", + "email": "java@asyncapi.com" + } + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} array`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": [ + null, [], "", {}, false, 123 + ] + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} number`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": 123 + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} boolean`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "contact": false + }, + ['must be object'] + )); +}); diff --git a/test/definitions/3.0.0/models/info/info/properties/description.mjs b/test/definitions/3.0.0/models/info/info/properties/description.mjs new file mode 100644 index 00000000..315df5bc --- /dev/null +++ b/test/definitions/3.0.0/models/info/info/properties/description.mjs @@ -0,0 +1,80 @@ +import {describe, it} from 'vitest'; +import TestHelper from '@test/test-helper'; +import path from 'path'; + +const jsonSchema = require('@definitions/3.0.0/info.json'); + +describe('Info: description', () => { + it(`${TestHelper.propertyIsNotValidWhenIsTestName} null`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": null + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} empty`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": "" + }, + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} string`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": "short description" + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} object`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": { + "longVariant": "", + "shortVariant": "" + } + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} array`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": [ + null, [], "", {}, false, 123 + ] + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} number`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": 123 + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} boolean`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "description": false + }, + ['must be string'] + )); +}); diff --git a/test/definitions/3.0.0/models/info/info/properties/externalDocs.mjs b/test/definitions/3.0.0/models/info/info/properties/externalDocs.mjs new file mode 100644 index 00000000..ade365d7 --- /dev/null +++ b/test/definitions/3.0.0/models/info/info/properties/externalDocs.mjs @@ -0,0 +1,105 @@ +import {describe, it} from 'vitest'; +import TestHelper from '@test/test-helper'; +import path from 'path'; + +const jsonSchema = require('@definitions/3.0.0/info.json'); + +describe('Info: externalDocs', () => { + it(`${TestHelper.propertyIsNotValidWhenIsTestName} null`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": null + }, + [ + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf' + ] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} empty`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": {} + }, + [ + 'must have required property \'$ref\'', + 'must have required property \'url\'', + 'must match exactly one schema in oneOf' + ] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} string`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": "short description" + }, + [ + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf' + ] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} object`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": { + "description" : "Find more info here", + "url" : "https://example.com" + } + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} array`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": [ + null, [], "", {}, false, 123 + ] + }, + [ + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf' + ] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} number`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": 123 + }, + [ + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf' + ] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} boolean`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "externalDocs": false + }, + [ + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf' + ] + )); +}); diff --git a/test/definitions/3.0.0/models/info/info/properties/license.mjs b/test/definitions/3.0.0/models/info/info/properties/license.mjs new file mode 100644 index 00000000..392db039 --- /dev/null +++ b/test/definitions/3.0.0/models/info/info/properties/license.mjs @@ -0,0 +1,81 @@ +import {describe, it} from 'vitest'; +import TestHelper from '@test/test-helper'; +import path from 'path'; + +const jsonSchema = require('@definitions/3.0.0/info.json'); + +describe('Info: license', () => { + it(`${TestHelper.propertyIsNotValidWhenIsTestName} null`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": null + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} empty`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": {} + }, + ['must have required property \'name\''] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} string`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": "short description" + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} object`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": { + "name": "Apache License 2.0", + "url": "http://www.apache.org/licenses/" + } + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} array`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": [ + null, [], "", {}, false, 123 + ] + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} number`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": 123 + }, + ['must be object'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} boolean`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "license": false + }, + ['must be object'] + )); +}); diff --git a/test/definitions/3.0.0/models/info/info/properties/tags.mjs b/test/definitions/3.0.0/models/info/info/properties/tags.mjs new file mode 100644 index 00000000..7dc1f770 --- /dev/null +++ b/test/definitions/3.0.0/models/info/info/properties/tags.mjs @@ -0,0 +1,142 @@ +import {describe, it} from 'vitest'; +import TestHelper from '@test/test-helper'; +import path from 'path'; + +const jsonSchema = require('@definitions/3.0.0/info.json'); + +describe('Info: tags', () => { + it(`${TestHelper.propertyIsNotValidWhenIsTestName} null`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": null + }, + ['must be array'] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} empty`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": [] + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} string`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": "short description" + }, + ['must be array'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} object`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": {} + }, + ['must be array'] + )); + + it(`${TestHelper.propertyIsValidWhenIsTestName} array of tags`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": [ + { + "$ref": "#/components/tags" + }, + { + "name": "user", + "description": "User-related messages", + } + ] + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} array of duplicated tags`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": [ + { + "$ref": "#/components/tags" + }, + { + "$ref": "#/components/tags" + }, + { + "name": "user", + "description": "User-related messages", + } + ] + }, + ['must NOT have duplicate items (items ## 0 and 1 are identical)'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} not array of tags`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": [ + null, [], "", {}, false, 123 + ] + }, + // 6 properties to check + [ + // null + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf', + // [] + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf', + // "" + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf', + // {} + 'must have required property \'$ref\'', + 'must have required property \'name\'', + 'must match exactly one schema in oneOf', + // false + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf', + // 123 + 'must be object', + 'must be object', + 'must match exactly one schema in oneOf', + ] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} number`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": 123 + }, + ['must be array'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} boolean`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "tags": false + }, + ['must be array'] + )); +}); diff --git a/test/definitions/3.0.0/models/info/info/properties/termsOfService.mjs b/test/definitions/3.0.0/models/info/info/properties/termsOfService.mjs new file mode 100644 index 00000000..b44a666b --- /dev/null +++ b/test/definitions/3.0.0/models/info/info/properties/termsOfService.mjs @@ -0,0 +1,91 @@ +import {describe, it} from 'vitest'; +import TestHelper from '@test/test-helper'; +import path from 'path'; + +const jsonSchema = require('@definitions/3.0.0/info.json'); + +describe('Info: termsOfService', () => { + it(`${TestHelper.propertyIsValidWhenIsTestName} URI`, () => TestHelper.objectIsValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": "https://stage.lo/terms-of-service" + }, + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} null`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": null + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} empty`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": "" + }, + ['must match format "uri"'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} string`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": "terms of service" + }, + ['must match format "uri"'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} object`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": { + "longVariant": "", + "shortVariant": "" + } + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} array`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": [ + null, [], "", {}, false, 123 + ] + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} number`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": 123 + }, + ['must be string'] + )); + + it(`${TestHelper.propertyIsNotValidWhenIsTestName} boolean`, () => TestHelper.objectIsNotValid( + jsonSchema, + { + "title": "AsyncApi sample", + "version": "2.0", + "termsOfService": false + }, + ['must be string'] + )); +}); diff --git a/test/test-helper.mjs b/test/test-helper.mjs index ac549ba1..999bb90f 100644 --- a/test/test-helper.mjs +++ b/test/test-helper.mjs @@ -40,6 +40,14 @@ export default class TestHelper { return 'is not valid when is wrongly extended'; } + static get propertyIsValidWhenIsTestName() { + return 'property is valid when is'; + } + + static get propertyIsNotValidWhenIsTestName() { + return 'property is not valid when is'; + } + static validator(jsonSchema) { const ajv = new Ajv({ jsonPointers: true, @@ -54,17 +62,36 @@ export default class TestHelper { return schemesV3_0_0(ajv).compile(jsonSchema); } - static objectIsValid(jsonSchemaPath, objectFilePath) { + /** + * Expects that given json is valid against given Json Schema. + * + * @param jsonSchemaPath is a path to required Json Schema + * @param json is a path to Json file or is as raw Json + */ + static objectIsValid(jsonSchemaPath, json) { const validator = this.validator(jsonSchemaPath); - const model = JSON.parse(fs.readFileSync(objectFilePath, 'utf-8')); + const model = (typeof json === 'string') + ? JSON.parse(fs.readFileSync(json, 'utf-8')) + : json + ; const validationResult = validator(model); assert(validationResult === true, `Object MUST be valid`); } - static objectIsNotValid(jsonSchemaPath, objectFilePath, expectedValidationErrorMessages) { + /** + * Expects that given json is not valid against given Json Schema. + * + * @param jsonSchemaPath is a path to required Json Schema + * @param json is a path to Json file or is as raw Json + * @param expectedValidationErrorMessages list of expected error messages + */ + static objectIsNotValid(jsonSchemaPath, json, expectedValidationErrorMessages) { const validator = this.validator(jsonSchemaPath); - const model = JSON.parse(fs.readFileSync(objectFilePath, 'utf-8')); + const model = (typeof json === 'string') + ? JSON.parse(fs.readFileSync(json, 'utf-8')) + : json + ; const validationResult = validator(model); assert(validationResult === false, `Object MUST NOT be valid`);