summaryrefslogtreecommitdiff
path: root/spec/frontend/__helpers__
diff options
context:
space:
mode:
Diffstat (limited to 'spec/frontend/__helpers__')
-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
-rw-r--r--spec/frontend/__helpers__/mock_apollo_helper.js2
-rw-r--r--spec/frontend/__helpers__/mock_dom_observer.js4
-rw-r--r--spec/frontend/__helpers__/vuex_action_helper.js1
-rw-r--r--spec/frontend/__helpers__/yaml_transformer.js11
7 files changed, 115 insertions, 3 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.',
+ );
+ });
+ });
+});
diff --git a/spec/frontend/__helpers__/mock_apollo_helper.js b/spec/frontend/__helpers__/mock_apollo_helper.js
index c07a6d8ef85..bae9f33be87 100644
--- a/spec/frontend/__helpers__/mock_apollo_helper.js
+++ b/spec/frontend/__helpers__/mock_apollo_helper.js
@@ -1,7 +1,7 @@
import { InMemoryCache } from '@apollo/client/core';
import { createMockClient as createMockApolloClient } from 'mock-apollo-client';
import VueApollo from 'vue-apollo';
-import possibleTypes from '~/graphql_shared/possibleTypes.json';
+import possibleTypes from '~/graphql_shared/possible_types.json';
import { typePolicies } from '~/lib/graphql';
export function createMockClient(handlers = [], resolvers = {}, cacheOptions = {}) {
diff --git a/spec/frontend/__helpers__/mock_dom_observer.js b/spec/frontend/__helpers__/mock_dom_observer.js
index dd26b594ad9..bc2646be4c2 100644
--- a/spec/frontend/__helpers__/mock_dom_observer.js
+++ b/spec/frontend/__helpers__/mock_dom_observer.js
@@ -22,14 +22,14 @@ class MockObserver {
takeRecords() {}
- // eslint-disable-next-line babel/camelcase
+ // eslint-disable-next-line camelcase
$_triggerObserve(node, { entry = {}, options = {} } = {}) {
if (this.$_hasObserver(node, options)) {
this.$_cb([{ target: node, ...entry }]);
}
}
- // eslint-disable-next-line babel/camelcase
+ // eslint-disable-next-line camelcase
$_hasObserver(node, options = {}) {
return this.$_observers.some(
([obvNode, obvOptions]) => node === obvNode && isMatch(options, obvOptions),
diff --git a/spec/frontend/__helpers__/vuex_action_helper.js b/spec/frontend/__helpers__/vuex_action_helper.js
index 68203b544ef..95a811d0385 100644
--- a/spec/frontend/__helpers__/vuex_action_helper.js
+++ b/spec/frontend/__helpers__/vuex_action_helper.js
@@ -49,6 +49,7 @@ const noop = () => {};
* expectedActions: [],
* })
*/
+
export default (
actionArg,
payloadArg,
diff --git a/spec/frontend/__helpers__/yaml_transformer.js b/spec/frontend/__helpers__/yaml_transformer.js
new file mode 100644
index 00000000000..a23f9b1f715
--- /dev/null
+++ b/spec/frontend/__helpers__/yaml_transformer.js
@@ -0,0 +1,11 @@
+/* eslint-disable import/no-commonjs */
+const JsYaml = require('js-yaml');
+
+// This will transform YAML files to JSON strings
+module.exports = {
+ process: (sourceContent) => {
+ const jsonContent = JsYaml.load(sourceContent);
+ const json = JSON.stringify(jsonContent);
+ return `module.exports = ${json}`;
+ },
+};