summaryrefslogtreecommitdiff
path: root/spec/frontend/__helpers__/matchers
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/__helpers__/matchers')
-rw-r--r--spec/frontend/__helpers__/matchers/index.js1
-rw-r--r--spec/frontend/__helpers__/matchers/to_validate_json_schema.js34
-rw-r--r--spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js65
3 files changed, 100 insertions, 0 deletions
diff --git a/spec/frontend/__helpers__/matchers/index.js b/spec/frontend/__helpers__/matchers/index.js
index 76571bafb06..9b83ced10e1 100644
--- a/spec/frontend/__helpers__/matchers/index.js
+++ b/spec/frontend/__helpers__/matchers/index.js
@@ -1,3 +1,4 @@
export * from './to_have_sprite_icon';
export * from './to_have_tracking_attributes';
export * from './to_match_interpolated_text';
+export * from './to_validate_json_schema';
diff --git a/spec/frontend/__helpers__/matchers/to_validate_json_schema.js b/spec/frontend/__helpers__/matchers/to_validate_json_schema.js
new file mode 100644
index 00000000000..ff391f08c55
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_validate_json_schema.js
@@ -0,0 +1,34 @@
+// NOTE: Make sure to initialize ajv when using this helper
+
+const getAjvErrorMessage = ({ errors }) => {
+ return (errors || []).map((error) => {
+ return `Error with item ${error.instancePath}: ${error.message}`;
+ });
+};
+
+export function toValidateJsonSchema(testData, validator) {
+ if (!(validator instanceof Function && validator.schema)) {
+ return {
+ validator,
+ message: () =>
+ 'Validator must be a validating function with property "schema", created with `ajv.compile`. See https://ajv.js.org/api.html#ajv-compile-schema-object-data-any-boolean-promise-any.',
+ pass: false,
+ };
+ }
+
+ const isValid = validator(testData);
+
+ return {
+ actual: testData,
+ message: () => {
+ if (isValid) {
+ // We can match, but still fail because we're in a `expect...not.` context
+ return 'Expected the given data not to pass the schema validation, but found that it was considered valid.';
+ }
+
+ const errorMessages = getAjvErrorMessage(validator).join('\n');
+ return `Expected the given data to pass the schema validation, but found that it was considered invalid. Errors:\n${errorMessages}`;
+ },
+ pass: isValid,
+ };
+}
diff --git a/spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js b/spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js
new file mode 100644
index 00000000000..fd42c710c65
--- /dev/null
+++ b/spec/frontend/__helpers__/matchers/to_validate_json_schema_spec.js
@@ -0,0 +1,65 @@
+import Ajv from 'ajv';
+import AjvFormats from 'ajv-formats';
+
+const JSON_SCHEMA = {
+ type: 'object',
+ properties: {
+ fruit: {
+ type: 'string',
+ minLength: 3,
+ },
+ },
+};
+
+const ajv = new Ajv({
+ strictTypes: false,
+ strictTuples: false,
+ allowMatchingProperties: true,
+});
+
+AjvFormats(ajv);
+const schema = ajv.compile(JSON_SCHEMA);
+
+describe('custom matcher toValidateJsonSchema', () => {
+ it('throws error if validator is not compiled correctly', () => {
+ expect(() => {
+ expect({}).toValidateJsonSchema({});
+ }).toThrow(
+ 'Validator must be a validating function with property "schema", created with `ajv.compile`. See https://ajv.js.org/api.html#ajv-compile-schema-object-data-any-boolean-promise-any.',
+ );
+ });
+
+ describe('positive assertions', () => {
+ it.each`
+ description | input
+ ${'valid input'} | ${{ fruit: 'apple' }}
+ `('schema validation passes for $description', ({ input }) => {
+ expect(input).toValidateJsonSchema(schema);
+ });
+
+ it('throws if not matching', () => {
+ expect(() => expect(null).toValidateJsonSchema(schema)).toThrowError(
+ `Expected the given data to pass the schema validation, but found that it was considered invalid. Errors:
+Error with item : must be object`,
+ );
+ });
+ });
+
+ describe('negative assertions', () => {
+ it.each`
+ description | input
+ ${'no input'} | ${null}
+ ${'input with invalid type'} | ${'banana'}
+ ${'input with invalid length'} | ${{ fruit: 'aa' }}
+ ${'input with invalid type'} | ${{ fruit: 12345 }}
+ `('schema validation fails for $description', ({ input }) => {
+ expect(input).not.toValidateJsonSchema(schema);
+ });
+
+ it('throws if matching', () => {
+ expect(() => expect({ fruit: 'apple' }).not.toValidateJsonSchema(schema)).toThrowError(
+ 'Expected the given data not to pass the schema validation, but found that it was considered valid.',
+ );
+ });
+ });
+});