diff --git a/packages/validate/__tests__/integration/api/index.js b/packages/validate/__tests__/integration/api/index.js deleted file mode 100644 index e6ea9aad..00000000 --- a/packages/validate/__tests__/integration/api/index.js +++ /dev/null @@ -1,277 +0,0 @@ -import validate from '../../../src'; -import { GROUP_ATTRIBUTE, DOTNET_CLASSNAMES } from '../../../src/lib/constants'; -import defaults from '../../../src/lib/defaults'; - -describe('Validate > Integration > API > addGroup', () => { - - it('should add a validation group', async () => { - // expect.assertions(6); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - - expect(validator.getState().groups).toEqual({}); - input.setAttribute('required', 'required'); - validator.addGroup([input]); - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - - }); - - it('should return leave state unchanged if it cannot add the validation group', async () => { - document.body.innerHTML = `
- - -
`; - const input = document.querySelector('#group1-1'); - const [ validator ] = validate('form'); - console.warn = jest.fn(); - - expect(validator.getState().groups).toEqual({}); - validator.addGroup([input]); - expect(validator.getState().groups).toEqual({}); - expect(console.warn).toHaveBeenCalled(); - }); - - -}); - -describe('Validate > Integration > API > removeGroup', () => { - - it('should remove a validation group', async () => { - // expect.assertions(6); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - input.removeAttribute('required'); - validator.removeGroup('group1'); - expect(validator.getState().groups).toEqual({}); - - }); - -}); - -describe('Validate > Integration > API > validateGroup', () => { - - it('should validate an individual validation group when called', async () => { - // expect.assertions(6); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - await validator.validateGroup('group1'); - - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - - input.value = "test"; - await validator.validateGroup('group1'); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`)).toBeNull(); - }); - -}); - -describe('Validate > Integration > API > addMethod', () => { - - it('should add a validation method to a group', async () => { - // expect.assertions(6); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - const method = () => false; - const message = 'Custom error'; - validator.addMethod('group1', method, message); - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }, { type: 'custom', method, message }], - fields: [input], - valid: false - } - }); - }); - - it('should not add a validation method if parameters are missing', async () => { - // expect.assertions(6); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - console.warn = jest.fn(); - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - const method = () => false; - const message = 'Custom error'; - - validator.addMethod(undefined, method, message); - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - expect(console.warn).toHaveBeenCalled(); - - }); - - it('should not add a validation method if fields cannot be found', async () => { - // expect.assertions(6); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - - expect(validator.getState().groups).toEqual({ - groupX: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - const method = () => false; - const message = 'Custom error'; - - validator.addMethod('neither-name-or-group-name', method, message); - expect(validator.getState().groups).toEqual({ - groupX: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - - }); - - it('Should add a validation method when provided an array of fields and a new group name', () => { - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const validator = validate('form')[0]; - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - const method = () => false; - const message = 'Custom error'; - validator.addMethod('CustomGroup', method, message, [ input ]); - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - }, - CustomGroup: { - serverErrorNode: false, - validators: [{ type: 'custom', method, message }], - fields: [input], - valid: false - } - }); - }); - -}); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/errors/index.js b/packages/validate/__tests__/integration/errors/index.js deleted file mode 100644 index 4f1adc53..00000000 --- a/packages/validate/__tests__/integration/errors/index.js +++ /dev/null @@ -1,93 +0,0 @@ -import validate from '../../../src'; -import { DOTNET_CLASSNAMES } from '../../../src/lib/constants'; -import defaults from '../../../src/lib/defaults'; - -describe('Validate > Integration > errors', () => { - - it('Should render client-side error container as the last element in a label', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - await validator.validate(); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - }); - - it('Should render a text node error to a server-side error container', async () => { - expect.assertions(3); - document.body.innerHTML = `
- - - -
`; - const [ validator ] = validate('form'); - await validator.validate(); - const errorContainer = document.getElementById('ssec'); - //render error message - expect(errorContainer.firstChild).toBeDefined(); - expect(errorContainer.classList.contains(DOTNET_CLASSNAMES.ERROR)).toEqual(true); - expect(errorContainer.firstChild.textContent).toEqual(defaults.messages.required()); - }); - - it('Should clear a server-rendered error node before rendering a text node error to a server-side error container', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - - The server dislikes this value -
`; - const [ validator ] = validate('form'); - expect(validator.getState().errors.group1).toEqual('The server dislikes this value'); - await validator.validate(); - const errorContainer = document.getElementById('ssec'); - //render error message - expect(errorContainer.firstChild).toBeDefined(); - expect(errorContainer.classList.contains(DOTNET_CLASSNAMES.ERROR)).toEqual(true); - expect(errorContainer.firstChild.textContent).toEqual(defaults.messages.required()); - }); - - it('Should render the invalid input value in the error message if the {{value}} token is used in the supplied error message', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - - -
`; - const [ validator ] = validate('form'); - await validator.validate(); - const errorContainer = document.getElementById('ssec'); - //render error message - expect(errorContainer.textContent).toEqual('test is not a valid email address'); - }); - -}); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/real-time/index.js b/packages/validate/__tests__/integration/real-time/index.js deleted file mode 100644 index f0c72891..00000000 --- a/packages/validate/__tests__/integration/real-time/index.js +++ /dev/null @@ -1,138 +0,0 @@ -import validate from '../../../src'; -import defaults from '../../../src/lib/defaults'; -import { DOTNET_CLASSNAMES } from '../../../src/lib/constants'; - - -describe('Validate > Integration > Real-time', () => { - - it('should start real-time validation after first form submission', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - - const form = document.querySelector('form'); - const [ validator ] = validate(form); - await validator.validate(); - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - expect(validator.getState().realTimeValidation).toEqual(true); - }); - - it('should remove error message and not replace if field is valid', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - - const form = document.querySelector('form'); - const input = document.querySelector('input'); - const [ validator ] = validate(form); - await validator.validate(); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`)).toBeDefined(); - input.value = 'Super'; - const event = new Event('input', { bubbles: false }); - input.dispatchEvent(event); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`)).toBeNull(); - }); - - - it('should update error message based on real-time validation', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - - const form = document.querySelector('form'); - const input = document.querySelector('input'); - const [ validator ] = validate(form); - await validator.validate(); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - input.value = 'Super'; - const event = new Event('input', { bubbles: false }); - input.dispatchEvent(event); - - //have to game Jest to ensure that the error is rendered in time for the assertion - const nextMsg = await new Promise((resolve, reject) => setTimeout(() => { - resolve(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent); - }, 16)); - - expect(nextMsg).toEqual(defaults.messages.email()); - }); - - it('should trigger real-time validation with appropriate event for the input type', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - - const form = document.querySelector('form'); - const input = document.querySelector('input'); - const [ validator ] = validate(form); - await validator.validate(); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - input.checked = 'checked'; - const event = new Event('change', { bubbles: false }); - input.dispatchEvent(event); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`)).toBeNull(); - }); - - it('should run realtime validation after a new group is added post first validation', async () => { - expect.assertions(3); - document.body.innerHTML = `
- - -
`; - - const form = document.querySelector('form'); - const [ validator ] = validate(form); - await validator.validate(); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - - const newLabel = document.createElement('label'); - newLabel.textContent = 'Group2'; - newLabel.setAttribute('for', 'group2'); - form.appendChild(newLabel); - - const newInput = document.createElement('input'); - newInput.setAttribute('type', 'text'); - newInput.setAttribute('id', 'group2'); - newInput.setAttribute('name', 'group2'); - newInput.required = true; - form.appendChild(newInput); - - validator.addGroup([newInput]); - await validator.validate(); - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - - newInput.value = 'Sample'; - const event = new Event('input', { bubbles: false }); - newInput.dispatchEvent(event); - expect([].slice.call(document.querySelectorAll(`.${DOTNET_CLASSNAMES.ERROR}`)).length).toEqual(1); - }); - -}); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/reset/index.js b/packages/validate/__tests__/integration/reset/index.js deleted file mode 100644 index b148e257..00000000 --- a/packages/validate/__tests__/integration/reset/index.js +++ /dev/null @@ -1,60 +0,0 @@ -import validate from '../../../src'; - -describe('Validate > Integration > Reset', () => { - - it('should clear errors messages from state and DOM, remove error classNames and attributes, remove errors from state', async () => { - document.body.innerHTML = `
-
- - -
-
- - -
-
`; - // const mockState = { - // groups: { - // group1: { - // fields: Array.from(document.getElementsByName('group1')), - // errorMessages: ['This field is required'], - // valid: false - // }, - // group2: { - // fields: Array.from(document.getElementsByName('group2')), - // errorMessages: ['This field is required'], - // valid: false - // } - // }, - // errors: { - // group1: document.getElementById('test-error-node-1'), - // group2: document.getElementById('test-error-node-2') - // } - // }; - const [ validator ] = validate('.form'); - //Validate and set errors in state and DOM - await validator.validate(); - expect(validator.getState().groups.group1.valid).toEqual(false); - expect(validator.getState().groups.group2.valid).toEqual(false); - expect(validator.getState().errors.group1).toEqual(document.querySelector('#group1').previousElementSibling); - expect(validator.getState().errors.group2).toEqual(document.querySelector('#group2').previousElementSibling); - expect(validator.getState().groups.group1.fields[0].parentNode.classList.contains('is--invalid')).toEqual(true); - expect(validator.getState().groups.group2.fields[0].parentNode.classList.contains('is--invalid')).toEqual(true); - expect(validator.getState().groups.group1.fields[0].getAttribute('aria-invalid')).toEqual('true'); - expect(validator.getState().groups.group2.fields[0].getAttribute('aria-invalid')).toEqual('true'); - - //reset to remove errors from state and DOM - validator.getState().form.dispatchEvent(new Event('reset')); - expect(validator.getState().groups.group1.valid).toEqual(true); - expect(validator.getState().groups.group2.valid).toEqual(true); - expect(validator.getState().groups.group1.errorMessages).toEqual([]); - expect(validator.getState().groups.group2.errorMessages).toEqual([]); - expect(validator.getState().errors.group1).toBeUndefined(); - expect(validator.getState().errors.group2).toBeUndefined(); - expect(validator.getState().groups.group1.fields[0].parentNode.classList.contains('is--invalid')).toEqual(false); - expect(validator.getState().groups.group2.fields[0].parentNode.classList.contains('is--invalid')).toEqual(false); - expect(validator.getState().groups.group1.fields[0].getAttribute('aria-invalid')).toEqual(null); - expect(validator.getState().groups.group2.fields[0].getAttribute('aria-invalid')).toEqual(null); - }); - -}); diff --git a/packages/validate/__tests__/integration/submit/index.js b/packages/validate/__tests__/integration/submit/index.js deleted file mode 100644 index dd39eded..00000000 --- a/packages/validate/__tests__/integration/submit/index.js +++ /dev/null @@ -1,53 +0,0 @@ -import validate from '../../../src'; - -describe('Validate > Integration > Submit', () => { - - it('should call the submit function if validation passes', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - - // const form = document.querySelector('form'); - // const button = document.querySelector('button'); - const submit = jest.fn(); - const [ validator ] = validate(document.querySelector('form'), { submit }); - await validator.validate({ target: true, preventDefault(){} }); - // button.click(); - expect(validator.getState().settings.submit).toEqual(submit); - expect(submit).toBeCalled(); - - }); - -}); - -describe('Validate > Integration > preSubmitHook', () => { - - it('should call the submit function if validation passes', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - - // const form = document.querySelector('form'); - // const button = document.querySelector('button'); - const preSubmitHook = jest.fn(); - const [ validator ] = validate(document.querySelector('form'), { preSubmitHook }); - - await validator.validate({ target: true, preventDefault(){} }); - expect(validator.getState().settings.preSubmitHook).toEqual(preSubmitHook); - expect(preSubmitHook).toBeCalled(); - - }); - -}); \ No newline at end of file diff --git a/packages/validate/__tests__/jest/api/api.js b/packages/validate/__tests__/jest/api/api.js new file mode 100644 index 00000000..c3e46957 --- /dev/null +++ b/packages/validate/__tests__/jest/api/api.js @@ -0,0 +1,251 @@ +import validate from "../../../src"; +import { GROUP_ATTRIBUTE, DOTNET_CLASSNAMES } from "../../../src/lib/constants"; +import defaults from "../../../src/lib/defaults"; + +describe("Validate > Integration > API > addGroup", () => { + it("should add a validation group", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + + expect(validator.getState().groups).toEqual({}); + input.setAttribute("required", "required"); + validator.addGroup([input]); + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + }); + + it("should return leave state unchanged if it cannot add the validation group", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const [validator] = validate("form"); + console.warn = jest.fn(); + + expect(validator.getState().groups).toEqual({}); + validator.addGroup([input]); + expect(validator.getState().groups).toEqual({}); + expect(console.warn).toHaveBeenCalled(); + }); +}); + +describe("Validate > Integration > API > removeGroup", () => { + it("should remove a validation group", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + input.removeAttribute("required"); + validator.removeGroup("group1"); + expect(validator.getState().groups).toEqual({}); + }); +}); + +describe("Validate > Integration > API > validateGroup", () => { + it("should validate an individual validation group when called", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + await validator.validateGroup("group1"); + + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); + + input.value = "test"; + await validator.validateGroup("group1"); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`)).toBeNull(); + }); +}); + +describe("Validate > Integration > API > addMethod", () => { + it("should add a validation method to a group", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + const method = () => false; + const message = "Custom error"; + validator.addMethod("group1", method, message); + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }, { type: "custom", method, message }], + fields: [input], + valid: false, + }, + }); + }); + + it("should not add a validation method if parameters are missing", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + console.warn = jest.fn(); + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + const method = () => false; + const message = "Custom error"; + + validator.addMethod(undefined, method, message); + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + expect(console.warn).toHaveBeenCalled(); + }); + + it("should not add a validation method if fields cannot be found", async () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + + expect(validator.getState().groups).toEqual({ + groupX: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + const method = () => false; + const message = "Custom error"; + + validator.addMethod("neither-name-or-group-name", method, message); + expect(validator.getState().groups).toEqual({ + groupX: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + }); + + it("Should add a validation method when provided an array of fields and a new group name", () => { + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector("#group1-1"); + const validator = validate("form")[0]; + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + }); + const method = () => false; + const message = "Custom error"; + validator.addMethod("CustomGroup", method, message, [input]); + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: "required" }], + fields: [input], + valid: false, + }, + CustomGroup: { + serverErrorNode: false, + validators: [{ type: "custom", method, message }], + fields: [input], + valid: false, + }, + }); + }); +}); diff --git a/packages/validate/__tests__/integration/api/validate/bypass-disabled.js b/packages/validate/__tests__/jest/api/validate/bypass-disabled.js similarity index 95% rename from packages/validate/__tests__/integration/api/validate/bypass-disabled.js rename to packages/validate/__tests__/jest/api/validate/bypass-disabled.js index cb15bc7a..8cf457d8 100644 --- a/packages/validate/__tests__/integration/api/validate/bypass-disabled.js +++ b/packages/validate/__tests__/jest/api/validate/bypass-disabled.js @@ -1,32 +1,30 @@ -import validate from '../../../../src'; - -describe('Validate > Integration > api > validate > bypass disabled fields', () => { - - it('should return true for disabled groups regardless of validation criteria and value', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - - - - - -
`; - const [ validator ] = validate('form'); - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); -}); +import validate from '../../../../src'; + +describe('Validate > Integration > api > validate > bypass disabled fields', () => { + + it('should return true for disabled groups regardless of validation criteria and value', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + + + +
`; + const [ validator ] = validate('form'); + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); +}); diff --git a/packages/validate/__tests__/integration/api/validate/dateISO.js b/packages/validate/__tests__/jest/api/validate/dateISO.js similarity index 82% rename from packages/validate/__tests__/integration/api/validate/dateISO.js rename to packages/validate/__tests__/jest/api/validate/dateISO.js index 82bfd613..11f5379b 100644 --- a/packages/validate/__tests__/integration/api/validate/dateISO.js +++ b/packages/validate/__tests__/jest/api/validate/dateISO.js @@ -1,55 +1,43 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > dateISO', () => { - //return boolean validityState - //start realtimevalidation - //render errors - //focus on first invalid field - - //return boolean validityState - //submit form - - it('should validate a form based on the data-val dateISO validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1-1'); - const label = document.getElementById('group1-1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('DateISO error message'); - }); - - it('should validate a form based on the data-val dateISO validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > dateISO', () => { + it('should validate a form based on the data-val dateISO validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1-1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('DateISO error message'); + }); + + it('should validate a form based on the data-val dateISO validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/digits.js b/packages/validate/__tests__/jest/api/validate/digits.js similarity index 82% rename from packages/validate/__tests__/integration/api/validate/digits.js rename to packages/validate/__tests__/jest/api/validate/digits.js index 1aea4065..2f78dabf 100644 --- a/packages/validate/__tests__/integration/api/validate/digits.js +++ b/packages/validate/__tests__/jest/api/validate/digits.js @@ -1,55 +1,43 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > digits', () => { - //return boolean validityState - //start realtimevalidation - //render errors - //focus on first invalid field - - //return boolean validityState - //submit form - - it('should validate a form based on the data-val digits validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Digits error message'); - }); - - it('should validate a form based on the data-val digits validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > digits', () => { + it('should validate a form based on the data-val digits validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Digits error message'); + }); + + it('should validate a form based on the data-val digits validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/email.js b/packages/validate/__tests__/jest/api/validate/email.js similarity index 84% rename from packages/validate/__tests__/integration/api/validate/email.js rename to packages/validate/__tests__/jest/api/validate/email.js index b5ca1947..4536e7a4 100644 --- a/packages/validate/__tests__/integration/api/validate/email.js +++ b/packages/validate/__tests__/jest/api/validate/email.js @@ -1,98 +1,79 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > email', () => { - //return boolean validityState - //start realtimevalidation - //render errors - //focus on first invalid field - - //return boolean validityState - //submit form - - it('should validate a form based on the HTML5 email validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.email()); - }); - - it('should validate a form based on the HTML5 email validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val email validator returning false, starting realTimeValidation, ', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - - -
`; - const input = document.getElementById('group2'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - //validityState - expect(validityState).toEqual(false); - //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - //focus on firstinvalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Email error message'); - - }); - - it('should validate a form based on the data-val email validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(true); - }); -}); +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > email', () => { + it('should validate a form based on the HTML5 email validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.email()); + }); + + it('should validate a form based on the HTML5 email validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val email validator returning false, starting realTimeValidation, ', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + + +
`; + const input = document.getElementById('group2'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Email error message'); + + }); + + it('should validate a form based on the data-val email validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); +}); diff --git a/packages/validate/__tests__/integration/api/validate/equalto.js b/packages/validate/__tests__/jest/api/validate/equalto.js similarity index 90% rename from packages/validate/__tests__/integration/api/validate/equalto.js rename to packages/validate/__tests__/jest/api/validate/equalto.js index ce8a1095..a75136fa 100644 --- a/packages/validate/__tests__/integration/api/validate/equalto.js +++ b/packages/validate/__tests__/jest/api/validate/equalto.js @@ -1,60 +1,55 @@ -import library from '../../../../src'; -import { validate, assembleValidationGroup } from '../../../../src/lib/validator'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > equalto', () => { - - it('should validate a form based on the data-val equalto validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.querySelector('#DoubleConfirmEmail'); - // const label = document.getElementById('DoubleConfirmEmail-label'); - const validator = library('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Equalto error message'); - }); - - it('should validate a form based on the data-val equalto validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = ` - - - `; - const input = document.querySelector('#DoubleConfirmEmail'); - const group = assembleValidationGroup({}, input).DoubleConfirmEmail; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - +import library from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import { validate, assembleValidationGroup } from '../../../../src/lib/validator'; + +describe('Validate > Integration > api > validate > equalto', () => { + + it('should validate a form based on the data-val equalto validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector('#DoubleConfirmEmail'); + const validator = library('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Equalto error message'); + }); + + it('should validate a form based on the data-val equalto validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = ` + + + `; + const input = document.querySelector('#DoubleConfirmEmail'); + const group = assembleValidationGroup({}, input).DoubleConfirmEmail; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/length.js b/packages/validate/__tests__/jest/api/validate/length.js similarity index 90% rename from packages/validate/__tests__/integration/api/validate/length.js rename to packages/validate/__tests__/jest/api/validate/length.js index 667b1616..cb958a70 100644 --- a/packages/validate/__tests__/integration/api/validate/length.js +++ b/packages/validate/__tests__/jest/api/validate/length.js @@ -1,52 +1,48 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > length', () => { - - it('should validate a form based on the data-val length validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is outwith the min and max length range', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Length error message'); - }); - - it('should validate a form based on the data-val length validator returning true if within the min and max length range', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > length', () => { + + it('should validate a form based on the data-val length validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is outwith the min and max length range', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Length error message'); + }); + + it('should validate a form based on the data-val length validator returning true if within the min and max length range', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/max.js b/packages/validate/__tests__/jest/api/validate/max.js similarity index 89% rename from packages/validate/__tests__/integration/api/validate/max.js rename to packages/validate/__tests__/jest/api/validate/max.js index 3421a89f..11a9d57e 100644 --- a/packages/validate/__tests__/integration/api/validate/max.js +++ b/packages/validate/__tests__/jest/api/validate/max.js @@ -1,91 +1,83 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > max', () => { - - it('should validate a form based on the HTML5 max validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.max({ max: 2 })); - }); - - it('should validate a form based on the data-val equalto validator returning true if valid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Max error message'); - }); - - it('should validate a form based on the data-val max validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val max validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > max', () => { + + it('should validate a form based on the HTML5 max validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.max({ max: 2 })); + }); + + it('should validate a form based on the data-val equalto validator returning true if valid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Max error message'); + }); + + it('should validate a form based on the data-val max validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val max validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/maxlength.js b/packages/validate/__tests__/jest/api/validate/maxlength.js similarity index 89% rename from packages/validate/__tests__/integration/api/validate/maxlength.js rename to packages/validate/__tests__/jest/api/validate/maxlength.js index 424de9ae..13f9584d 100644 --- a/packages/validate/__tests__/integration/api/validate/maxlength.js +++ b/packages/validate/__tests__/jest/api/validate/maxlength.js @@ -1,91 +1,83 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > maxlength', () => { - - it('should validate a form based on the HTML5 maxlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.maxlength({ max: 5 })); - }); - - it('should validate a form based on the data-val maxlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Maxlength error message'); - }); - - it('should validate a form based on the HTML5 maxlength validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val maxlength validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > maxlength', () => { + + it('should validate a form based on the HTML5 maxlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.maxlength({ max: 5 })); + }); + + it('should validate a form based on the data-val maxlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Maxlength error message'); + }); + + it('should validate a form based on the HTML5 maxlength validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val maxlength validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/min.js b/packages/validate/__tests__/jest/api/validate/min.js similarity index 91% rename from packages/validate/__tests__/integration/api/validate/min.js rename to packages/validate/__tests__/jest/api/validate/min.js index 4235a760..0a8049f5 100644 --- a/packages/validate/__tests__/integration/api/validate/min.js +++ b/packages/validate/__tests__/jest/api/validate/min.js @@ -1,89 +1,83 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > min', () => { - - it('should validate a form based on the HTML5 min validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.min({ min: 2 })); - }); - - it('should validate a form based on the data-val min validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Min error message'); - }); - - it('should validate a form based on the HTML5 min validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val min validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > min', () => { + + it('should validate a form based on the HTML5 min validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.min({ min: 2 })); + }); + + it('should validate a form based on the data-val min validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Min error message'); + }); + + it('should validate a form based on the HTML5 min validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val min validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/minlength.js b/packages/validate/__tests__/jest/api/validate/minlength.js similarity index 89% rename from packages/validate/__tests__/integration/api/validate/minlength.js rename to packages/validate/__tests__/jest/api/validate/minlength.js index 76caf568..92980b38 100644 --- a/packages/validate/__tests__/integration/api/validate/minlength.js +++ b/packages/validate/__tests__/jest/api/validate/minlength.js @@ -1,91 +1,83 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > minlength', () => { - - it('should validate a form based on the HTML5 minlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.minlength({ min: 3 })); - }); - - it('should validate a form based on the data-val minlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Minlength error message'); - }); - - it('should validate a form based on the HTML5 minlength validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val minlength validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > minlength', () => { + + it('should validate a form based on the HTML5 minlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.minlength({ min: 3 })); + }); + + it('should validate a form based on the data-val minlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Minlength error message'); + }); + + it('should validate a form based on the HTML5 minlength validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val minlength validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/number.js b/packages/validate/__tests__/jest/api/validate/number.js similarity index 89% rename from packages/validate/__tests__/integration/api/validate/number.js rename to packages/validate/__tests__/jest/api/validate/number.js index e215ff89..40607102 100644 --- a/packages/validate/__tests__/integration/api/validate/number.js +++ b/packages/validate/__tests__/jest/api/validate/number.js @@ -1,64 +1,59 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > number', () => { - - it('should validate a form based on the HTML5 number validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val number validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Number error message'); - }); - - it('should validate a form based on the data-val number validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > number', () => { + + it('should validate a form based on the HTML5 number validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val number validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Number error message'); + }); + + it('should validate a form based on the data-val number validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/range.js b/packages/validate/__tests__/jest/api/validate/range.js similarity index 88% rename from packages/validate/__tests__/integration/api/validate/range.js rename to packages/validate/__tests__/jest/api/validate/range.js index cd76477a..b1aa321c 100644 --- a/packages/validate/__tests__/integration/api/validate/range.js +++ b/packages/validate/__tests__/jest/api/validate/range.js @@ -1,143 +1,128 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > equalto', () => { - - it('should validate a form based on the data-val range validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the value is out of range', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.querySelector('#group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Range error message'); - }); - - it('should validate a form based on the data-val range validator returning true if value > min with no max', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val range validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the value <= min with no max', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.querySelector('#group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Range error message'); - }); - - it('should validate a form based on the data-val range validator returning true if value <= max with no min', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val range validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the value > max with no min', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.querySelector('#group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Range error message'); - }); - - it('should validate a form based on the data-val range validator returning true if value is in range', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > equalto', () => { + + it('should validate a form based on the data-val range validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the value is out of range', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector('#group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Range error message'); + }); + + it('should validate a form based on the data-val range validator returning true if value > min with no max', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val range validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the value <= min with no max', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector('#group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Range error message'); + }); + + it('should validate a form based on the data-val range validator returning true if value <= max with no min', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val range validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the value > max with no min', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.querySelector('#group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Range error message'); + }); + + it('should validate a form based on the data-val range validator returning true if value is in range', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/regex-pattern.js b/packages/validate/__tests__/jest/api/validate/regex-pattern.js similarity index 89% rename from packages/validate/__tests__/integration/api/validate/regex-pattern.js rename to packages/validate/__tests__/jest/api/validate/regex-pattern.js index d47b9316..27c4507a 100644 --- a/packages/validate/__tests__/integration/api/validate/regex-pattern.js +++ b/packages/validate/__tests__/jest/api/validate/regex-pattern.js @@ -1,90 +1,82 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > regex/pattern', () => { - it('should validate a form based on the HTML5 pattern validator returning false, staring realTimeValidation, focusing on first invalid field, and rendering an error message if the value does not match', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.pattern()); - }); - - it('should validate a form based on the data-val regex validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Regex error message'); - }); - - it('should validate a form based on the HTML5 pattern validator returning true if the pattern is matched', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the HTML5 pattern validator returning true if the pattern is matched', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > regex/pattern', () => { + it('should validate a form based on the HTML5 pattern validator returning false, staring realTimeValidation, focusing on first invalid field, and rendering an error message if the value does not match', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.pattern()); + }); + + it('should validate a form based on the data-val regex validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Regex error message'); + }); + + it('should validate a form based on the HTML5 pattern validator returning true if the pattern is matched', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the HTML5 pattern validator returning true if the pattern is matched', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/remote.js b/packages/validate/__tests__/jest/api/validate/remote.js similarity index 92% rename from packages/validate/__tests__/integration/api/validate/remote.js rename to packages/validate/__tests__/jest/api/validate/remote.js index 5afe33e6..ba7cede4 100644 --- a/packages/validate/__tests__/integration/api/validate/remote.js +++ b/packages/validate/__tests__/jest/api/validate/remote.js @@ -1,142 +1,133 @@ -import mock from 'xhr-mock'; -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > remote', () => { - - beforeEach(() => mock.setup()); - - afterEach(() => mock.teardown()); - - it('should validate a form based on the HTML5 remote validator returning false, staring realTimeValidation, focusing on first invalid field, and rendering an error message if the remote validation returns an error', async () => { - expect.assertions(4); - - mock.post('/api/validate', { - status: 201, - body: 'Remote error message' - }); - document.body.innerHTML = `
- - - -
`; - const input = document.getElementById('group1'); - const validator = validate('form')[0]; - - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Remote error message'); - }); - - it('should validate a form based on the HTML5 remote validator returning false, staring realTimeValidation, focusing on first invalid field, and rendering the error message if noe is returned from the remote validation API', async () => { - expect.assertions(4); - - mock.post('/api/validate', { - status: 201, - body: 'Error message from API' - }); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const validator = validate('form')[0]; - - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // focus on first invalid node - expect(document.activeElement).toEqual(input); - // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Error message from API'); - }); - - it('should validate a form based on the HTML5 remote validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the remote validation returns an error via a GET request', async () => { - expect.assertions(4); - - mock.get('/api/validate?group1=Failure&group2=Value%202', { - status: 201, - body: 'false' - }); - document.body.innerHTML = `
- - - -
`; - const input = document.getElementById('group1'); - const validator = validate('form')[0]; - - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // focus on first invalid node - expect(document.activeElement).toEqual(input); - // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Remote error message'); - }); - - it('should validate a form based on the data-val remote validator returning true if it passes remote validate', async () => { - expect.assertions(1); - - mock.post('/api/validate', { - status: 201, - body: 'true' - }); - document.body.innerHTML = `
- -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import mock from 'xhr-mock'; +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > remote', () => { + + beforeEach(() => mock.setup()); + + afterEach(() => mock.teardown()); + + it('should validate a form based on the HTML5 remote validator returning false, staring realTimeValidation, focusing on first invalid field, and rendering an error message if the remote validation returns an error', async () => { + expect.assertions(4); + + mock.post('/api/validate', { + status: 201, + body: 'Remote error message' + }); + document.body.innerHTML = `
+ + + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Remote error message'); + }); + + it('should validate a form based on the HTML5 remote validator returning false, staring realTimeValidation, focusing on first invalid field, and rendering the error message if noe is returned from the remote validation API', async () => { + expect.assertions(4); + + mock.post('/api/validate', { + status: 201, + body: 'Error message from API' + }); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Error message from API'); + }); + + it('should validate a form based on the HTML5 remote validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if the remote validation returns an error via a GET request', async () => { + expect.assertions(4); + + mock.get('/api/validate?group1=Failure&group2=Value%202', { + status: 201, + body: 'false' + }); + document.body.innerHTML = `
+ + + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Remote error message'); + }); + + it('should validate a form based on the data-val remote validator returning true if it passes remote validate', async () => { + expect.assertions(1); + + mock.post('/api/validate', { + status: 201, + body: 'true' + }); + document.body.innerHTML = `
+ +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/required.js b/packages/validate/__tests__/jest/api/validate/required.js similarity index 84% rename from packages/validate/__tests__/integration/api/validate/required.js rename to packages/validate/__tests__/jest/api/validate/required.js index 24511f6a..25754dfb 100644 --- a/packages/validate/__tests__/integration/api/validate/required.js +++ b/packages/validate/__tests__/jest/api/validate/required.js @@ -1,100 +1,82 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > required', () => { - //return boolean validityState - //start realtimevalidation - //render errors - //focus on first invalid field - - //return boolean validityState - //submit form - - it('should validate a form based on the HTML5 required validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1-1'); - const label = document.getElementById('group1-1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); - }); - - it('should validate a form based on the HTML5 required validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val required validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - - -
`; - const input = document.getElementById('group2'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - //validityState - expect(validityState).toEqual(false); - //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - //focus on firstinvalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Required error message'); - - }); - - it('should validate a form based on the data-val required validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(true); - }); -}); +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > required', () => { + + it('should validate a form based on the HTML5 required validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1-1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.required()); + }); + + it('should validate a form based on the HTML5 required validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val required validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + + +
`; + const input = document.getElementById('group2'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Required error message'); + + }); + + it('should validate a form based on the data-val required validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); +}); diff --git a/packages/validate/__tests__/integration/api/validate/stringlength.js b/packages/validate/__tests__/jest/api/validate/stringlength.js similarity index 90% rename from packages/validate/__tests__/integration/api/validate/stringlength.js rename to packages/validate/__tests__/jest/api/validate/stringlength.js index b2c9b5bd..23ab653c 100644 --- a/packages/validate/__tests__/integration/api/validate/stringlength.js +++ b/packages/validate/__tests__/jest/api/validate/stringlength.js @@ -1,50 +1,46 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; - -describe('Validate > Integration > api > validate > stringlength', () => { - - it('should validate a form based on the data-val stringlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is outwith the min and max length range', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - // realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // // focus on first invalid node - expect(document.activeElement).toEqual(input); - // // render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Stringlength error message'); - }); - - it('should validate a form based on the data-val stringlength validator returning true if within the min and max length range', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; + +describe('Validate > Integration > api > validate > stringlength', () => { + + it('should validate a form based on the data-val stringlength validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is outwith the min and max length range', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Stringlength error message'); + }); + + it('should validate a form based on the data-val stringlength validator returning true if within the min and max length range', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/api/validate/url.js b/packages/validate/__tests__/jest/api/validate/url.js similarity index 88% rename from packages/validate/__tests__/integration/api/validate/url.js rename to packages/validate/__tests__/jest/api/validate/url.js index d0578417..f86efb81 100644 --- a/packages/validate/__tests__/integration/api/validate/url.js +++ b/packages/validate/__tests__/jest/api/validate/url.js @@ -1,98 +1,85 @@ -import validate from '../../../../src'; -import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; -import defaults from '../../../../src/lib/defaults'; - -describe('Validate > Integration > api > validate > url', () => { - //html5 spec regex approximation: - ///^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? - - it('should validate a form based on the HTML5 url validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - -
`; - const input = document.getElementById('group1'); - const label = document.getElementById('group1-label'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(false); - // //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - // //focus on first invalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.url()); - }); - - it('should validate a form based on the HTML5 url validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - // //validityState - expect(validityState).toEqual(true); - }); - - it('should validate a form based on the data-val email validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { - expect.assertions(4); - document.body.innerHTML = `
- - - -
`; - const input = document.getElementById('group2'); - const validator = validate('form')[0]; - const validityState = await validator.validate(); - //validityState - expect(validityState).toEqual(false); - //realtimeValidation start - expect(validator.getState().realTimeValidation).toEqual(true); - //focus on firstinvalid node - expect(document.activeElement).toEqual(input); - //render error message - expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Url error message'); - - }); - - - it('should validate a form based on the data-val url validator returning true if valid', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - - -
`; - const validator = validate('form')[0]; - const validityState = await validator.validate(); - //validityState - expect(validityState).toEqual(true); - - }); - - +import validate from '../../../../src'; +import { DOTNET_CLASSNAMES } from '../../../../src/lib/constants'; +import defaults from '../../../../src/lib/defaults'; + +describe('Validate > Integration > api > validate > url', () => { + //html5 spec regex approximation: + ///^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? + + it('should validate a form based on the HTML5 url validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + +
`; + const input = document.getElementById('group1'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual(defaults.messages.url()); + }); + + it('should validate a form based on the HTML5 url validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should validate a form based on the data-val email validator returning false, starting realTimeValidation, focusing on first invalid field, and rendering an error message if a field is invalid', async () => { + expect.assertions(4); + document.body.innerHTML = `
+ + + +
`; + const input = document.getElementById('group2'); + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(validator.getState().realTimeValidation).toEqual(true); + expect(document.activeElement).toEqual(input); + expect(document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`).textContent).toEqual('Url error message'); + }); + + it('should validate a form based on the data-val url validator returning true if valid', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + + +
`; + const validator = validate('form')[0]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + + }); + + }); \ No newline at end of file diff --git a/packages/validate/__tests__/jest/errors.js b/packages/validate/__tests__/jest/errors.js new file mode 100644 index 00000000..ca4b94fe --- /dev/null +++ b/packages/validate/__tests__/jest/errors.js @@ -0,0 +1,126 @@ +import { + h, + clearError, + clearErrors, +} from '../../src/lib/dom'; +import { DOTNET_CLASSNAMES } from '../../src/lib/constants'; + +describe('Validate > Unit > DOM > clearError', () => { + + it('should delete the errorNode for the group from state', async () => { + document.body.innerHTML = `
+
+ + + This field is required +
+
`; + const mockState = { + groups: { + group1: { + serverErrorNode: false, + fields: Array.from(document.getElementsByName('group1')) + } + }, + errors: { + group1: document.getElementById('test-error-node') + } + }; + clearError('group1')(mockState); + expect(mockState.errors.group1).toBeUndefined(); + }); + + + it('should remove a server-side rendered text node for the group from state', async () => { + document.body.innerHTML = `
+
+ + + +
+
`; + const errorNode = document.createTextNode('This field is required'); + const serverErrorNode = document.getElementById('test-server-error-node'); + serverErrorNode.appendChild(errorNode); + const mockState = { + groups: { + group1: { + serverErrorNode, + fields: Array.from(document.getElementsByName('group1')) + } + }, + errors: { + group1: errorNode + } + }; + + clearError('group1')(mockState); + expect(mockState.errors.group1).toBeUndefined(); + }); +}); + +describe('Validate > Unit > DOM > clearErrors', () => { + + it('Should remove all errors from state for valid groups', async () => { + document.body.innerHTML = `
+
+ + + This field is required +
+
+ + + This field is required +
+
`; + const mockState = { + groups: { + group1: { + serverErrorNode: false, + fields: Array.from(document.getElementsByName('group1')) + }, + group2: { + serverErrorNode: false, + fields: Array.from(document.getElementsByName('group2')) + } + }, + errors: { + group1: document.getElementById('test-error-node-1'), + group2: document.getElementById('test-error-node-2') + } + }; + clearErrors(mockState); + expect(mockState.errors.group1).toBeUndefined(); + expect(mockState.errors.group2).toBeUndefined(); + }); + + it('should not change state if there are no errors', async () => { + document.body.innerHTML = `
+
+ + +
+
+ + +
+
`; + const mockState = { + groups: { + group1: { + serverErrorNode: false, + fields: Array.from(document.getElementsByName('group1')) + }, + group2: { + serverErrorNode: false, + fields: Array.from(document.getElementsByName('group2')) + } + }, + errors: {} + }; + const copy = Object.assign({}, mockState); + clearErrors(mockState); + expect(copy).toEqual(mockState); + }); +}); \ No newline at end of file diff --git a/packages/validate/__tests__/unit/initialisation.js b/packages/validate/__tests__/jest/initialisation.js similarity index 99% rename from packages/validate/__tests__/unit/initialisation.js rename to packages/validate/__tests__/jest/initialisation.js index 998243ab..b7eb4b6e 100644 --- a/packages/validate/__tests__/unit/initialisation.js +++ b/packages/validate/__tests__/jest/initialisation.js @@ -4,7 +4,6 @@ import { getSelection } from '../../src/lib/validator/utils'; let validators; const setUpDOM = () => { - // Set up our document body document.body.innerHTML = `
diff --git a/packages/validate/__tests__/unit/validator/methods.js b/packages/validate/__tests__/jest/methods.js similarity index 96% rename from packages/validate/__tests__/unit/validator/methods.js rename to packages/validate/__tests__/jest/methods.js index ed51976f..1c084d28 100644 --- a/packages/validate/__tests__/unit/validator/methods.js +++ b/packages/validate/__tests__/jest/methods.js @@ -1,828 +1,780 @@ -import mock from 'xhr-mock'; -import Methods from '../../../src/lib/validator/methods'; - -//required -describe('Validate > Unit > Validator > methods > required', () => { - - it('should return false for group containing a single empty field', () => { - document.body.innerHTML = `
`; - const group = { fields: [document.querySelector('#field')] }; - expect(Methods.required(group)).toEqual(false); - }); - - it('should return false for group with no value', () => { - document.body.innerHTML = `
- - -
`; - const group = { fields: [document.querySelector('#field-1'), document.querySelector('#field-1')] }; - expect(Methods.required(group)).toEqual(false); - }); - - it('should return true for a group with a single required field wuith a value', () => { - document.body.innerHTML = `
`; - const group = { fields: [document.querySelector('#field')] }; - expect(Methods.required(group)).toEqual(true); - }); - - it('should return true for group with value', () => { - document.body.innerHTML = `
- - -
`; - const group = { fields: [document.querySelector('#field-1'), document.querySelector('#field-1')] }; - expect(Methods.required(group)).toEqual(true); - }); - -}); - - -//email -describe('Validate > Unit > Validator > methods > email', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.email(group)).toEqual(true); - }); - - it('should return false for group containing a non-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.email(group)).toEqual(false); - }); - - it('should return true for group containing an on-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.email(group)).toEqual(true); - }); - -}); - - -//url -describe('Validate > Unit > Validator > methods > url', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.url(group)).toEqual(true); - }); - - it('should return false for group containing a non-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.url(group)).toEqual(false); - }); - - it('should return true for group containing an on-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.url(group)).toEqual(true); - }); - -}); - -//dateISO -describe('Validate > Unit > Validator > methods > dateISO', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.dateISO(group)).toEqual(true); - }); - - it('should return false for group containing a non-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.dateISO(group)).toEqual(false); - }); - - it('should return true for group containing an on-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.dateISO(group)).toEqual(true); - }); - -}); - -//number -describe('Validate > Unit > Validator > methods > number', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.number(group)).toEqual(true); - }); - - it('should return false for group containing a non-spec value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.number(group)).toEqual(false); - }); - - it('should return true for group containing an on-spec value', () => { - document.body.innerHTML = `
- - - -
`; - const group1 = { - validators: [], - fields: [document.querySelector('#field1')] - }; - expect(Methods.number(group1)).toEqual(true); - const group2 = { - validators: [], - fields: [document.querySelector('#field2')] - }; - expect(Methods.number(group2)).toEqual(true); - const group3 = { - validators: [], - fields: [document.querySelector('#field3')] - }; - expect(Methods.number(group3)).toEqual(true); - }); - -}); - - -//digits -describe('Validate > Unit > Validator > methods > digits', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.digits(group)).toEqual(true); - }); - - it('should return false for group containing a non-spec value', () => { - document.body.innerHTML = `
- - - -
`; - const group1 = { - validators: [], - fields: [document.querySelector('#field1')] - }; - expect(Methods.digits(group1)).toEqual(false); - - const group2 = { - validators: [], - fields: [document.querySelector('#field2')] - }; - expect(Methods.digits(group2)).toEqual(false); - - const group3 = { - validators: [], - fields: [document.querySelector('#field3')] - }; - expect(Methods.digits(group3)).toEqual(false); - }); - - it('should return true for group containing an on-spec value', () => { - document.body.innerHTML = `
- -
`; - const group1 = { - validators: [], - fields: [document.querySelector('#field1')] - }; - expect(Methods.digits(group1)).toEqual(true); - }); - -}); - - -//minlength -describe('Validate > Unit > Validator > methods > minlength', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'minlength', - params: { min: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.minlength(group)).toEqual(true); - }); - - it('should return false for group with a value < min', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'minlength', - params: { min: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.minlength(group)).toEqual(false); - }); - - it('should return true for group with a value => min', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'minlength', - params: { min: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.minlength(group)).toEqual(true); - }); - -}); - -//maxlength -describe('Validate > Unit > Validator > methods > maxlength', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'maxlength', - params: { max: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.maxlength(group)).toEqual(true); - }); - - it('should return false for group with a value > max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'maxlength', - params: { max: 5 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.maxlength(group)).toEqual(false); - }); - - it('should return true for group with a value <= max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'maxlength', - params: { max: 5 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.maxlength(group)).toEqual(true); - }); - -}); - -//equalto -describe('Validate > Unit > Validator > methods > equalto', () => { - - it('should return true for groups with no value', () => { - document.body.innerHTML = `
- - -
`; - const group = { - validators: [ - { - type: 'equalto', - params: { other: [[document.querySelector('#field2')]] } - } - ], - fields: [document.querySelector('#field1')] - }; - expect(Methods.equalto(group)).toEqual(true); - }); - - it('should return false for groups with unequal values', () => { - document.body.innerHTML = `
- - -
`; - const group = { - validators: [ - { - type: 'equalto', - params: { other: [[document.querySelector('#field2')]] } - } - ], - fields: [document.querySelector('#field1')] - }; - expect(Methods.equalto(group)).toEqual(false); - }); - - it('should return true for groups with unequal values', () => { - document.body.innerHTML = `
- - -
`; - const group = { - validators: [ - { - type: 'equalto', - params: { other: [[document.querySelector('#field2')]] } - } - ], - fields: [document.querySelector('#field1')] - }; - expect(Methods.equalto(group)).toEqual(true); - }); - -}); - - -//pattern -describe('Validate > Unit > Validator > methods > pattern', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'pattern', - params: { regex: /^(pass)$/ } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.pattern(group)).toEqual(true); - }); - - it('should return false for group with a non-matching value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'pattern', - params: { regex: /^(pass)$/ } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.pattern(group)).toEqual(false); - }); - - it('should return false for group with a matching value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'pattern', - params: { regex: /^(pass)$/ } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.pattern(group)).toEqual(true); - }); - -}); - - -//regex -describe('Validate > Unit > Validator > methods > regex', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'regex', - params: { pattern: /^(pass)$/ } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.regex(group)).toEqual(true); - }); - - it('should return false for group with a non-matching value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'regex', - params: { pattern: /^(pass)$/ } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.regex(group)).toEqual(false); - }); - - it('should return false for group with a matching value', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'regex', - params: { pattern: /^(pass)$/ } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.regex(group)).toEqual(true); - }); - -}); - -//min -describe('Validate > Unit > Validator > methods > min', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'min', - params: { min: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.min(group)).toEqual(true); - }); - - it('should return false for group with a value < min', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'min', - params: { min: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.min(group)).toEqual(false); - }); - - it('should return true for group with a value => min', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'min', - params: { min: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.min(group)).toEqual(true); - }); - -}); - -//max -describe('Validate > Unit > Validator > methods > max', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'max', - params: { max: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.max(group)).toEqual(true); - }); - - it('should return false for group with a value > max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'max', - params: { max: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.max(group)).toEqual(false); - }); - - it('should return true for group with a value <= max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'max', - params: { max: 5 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.max(group)).toEqual(true); - }); - -}); - - -//stringlength -describe('Validate > Unit > Validator > methods > stringlength', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'stringlength', - params: { max: 3 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.stringlength(group)).toEqual(true); - }); - - it('should return false for group with a value > max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'stringlength', - params: { max: 5 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.stringlength(group)).toEqual(false); - }); - - it('should return true for group with a value <= max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'stringlength', - params: { max: 5 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.stringlength(group)).toEqual(true); - }); - -}); - - -//length -describe('Validate > Unit > Validator > methods > length', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'length', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.length(group)).toEqual(true); - }); - - it('should return false for group with a value > max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'length', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.length(group)).toEqual(false); - }); - - it('should return false for group with a value < min', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'length', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.length(group)).toEqual(false); - }); - - it('should return true for group with a value >= min and <= max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'length', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.length(group)).toEqual(true); - }); - -}); - - -//range -describe('Validate > Unit > Validator > methods > range', () => { - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'range', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.range(group)).toEqual(true); - }); - - it('should return false for group with a value > max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'range', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.range(group)).toEqual(false); - }); - - it('should return false for group with a value < min', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'range', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.range(group)).toEqual(false); - }); - - it('should return true for group with a value >= min and <= max', () => { - document.body.innerHTML = `
`; - const group = { - validators: [ - { - type: 'range', - params: { min: 5, max: 8 } - } - ], - fields: [document.querySelector('#field')] - }; - expect(Methods.range(group)).toEqual(true); - }); - -}); - - -//remote -describe('Validate > Unit > Validator > methods > remote', () => { - - beforeEach(() => mock.setup()); - - afterEach(() => mock.teardown()); - - it('should return false for when the remote validation returns \'false\'', async () => { - - mock.post('/api/validate', { - status: 201, - body: 'false' - }); - - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - const params = { - url: '/api/validate' - }; - const res = await Methods.remote(group, params); - expect(res).toEqual('false'); - }); - - it('should return false for when the remote validation returns "false"', async () => { - - mock.post('/api/validate', { - status: 201, - body: 'true' - }); - - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - const params = { - url: '/api/validate' - }; - const res = await Methods.remote(group, params); - expect(res).toEqual('true'); - }); - - -}); - -//custom -describe('Validate > Unit > Validator > methods > custom', () => { - const customValidator = (value, fields) => value === 'Contrived validator'; - - it('should return true for group with no value that is not required', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.custom(customValidator, group)).toEqual(true); - }); - - it('should return false when the custom validation function return false', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.custom(customValidator, group)).toEqual(false); - }); - - - it('should return true when the custom validation function return true', () => { - document.body.innerHTML = `
`; - const group = { - validators: [], - fields: [document.querySelector('#field')] - }; - expect(Methods.custom(customValidator, group)).toEqual(true); - }); - +import mock from 'xhr-mock'; +import Methods from '../../src/lib/validator/methods'; + +describe('Validate > Unit > Validator > methods > required', () => { + + it('should return false for group containing a single empty field', () => { + document.body.innerHTML = `
`; + const group = { fields: [document.querySelector('#field')] }; + expect(Methods.required(group)).toEqual(false); + }); + + it('should return false for group with no value', () => { + document.body.innerHTML = `
+ + +
`; + const group = { fields: [document.querySelector('#field-1'), document.querySelector('#field-1')] }; + expect(Methods.required(group)).toEqual(false); + }); + + it('should return true for a group with a single required field wuith a value', () => { + document.body.innerHTML = `
`; + const group = { fields: [document.querySelector('#field')] }; + expect(Methods.required(group)).toEqual(true); + }); + + it('should return true for group with value', () => { + document.body.innerHTML = `
+ + +
`; + const group = { fields: [document.querySelector('#field-1'), document.querySelector('#field-1')] }; + expect(Methods.required(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > email', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.email(group)).toEqual(true); + }); + + it('should return false for group containing a non-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.email(group)).toEqual(false); + }); + + it('should return true for group containing an on-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.email(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > url', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.url(group)).toEqual(true); + }); + + it('should return false for group containing a non-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.url(group)).toEqual(false); + }); + + it('should return true for group containing an on-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.url(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > dateISO', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.dateISO(group)).toEqual(true); + }); + + it('should return false for group containing a non-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.dateISO(group)).toEqual(false); + }); + + it('should return true for group containing an on-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.dateISO(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > number', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.number(group)).toEqual(true); + }); + + it('should return false for group containing a non-spec value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.number(group)).toEqual(false); + }); + + it('should return true for group containing an on-spec value', () => { + document.body.innerHTML = `
+ + + +
`; + const group1 = { + validators: [], + fields: [document.querySelector('#field1')] + }; + expect(Methods.number(group1)).toEqual(true); + const group2 = { + validators: [], + fields: [document.querySelector('#field2')] + }; + expect(Methods.number(group2)).toEqual(true); + const group3 = { + validators: [], + fields: [document.querySelector('#field3')] + }; + expect(Methods.number(group3)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > digits', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.digits(group)).toEqual(true); + }); + + it('should return false for group containing a non-spec value', () => { + document.body.innerHTML = `
+ + + +
`; + const group1 = { + validators: [], + fields: [document.querySelector('#field1')] + }; + expect(Methods.digits(group1)).toEqual(false); + + const group2 = { + validators: [], + fields: [document.querySelector('#field2')] + }; + expect(Methods.digits(group2)).toEqual(false); + + const group3 = { + validators: [], + fields: [document.querySelector('#field3')] + }; + expect(Methods.digits(group3)).toEqual(false); + }); + + it('should return true for group containing an on-spec value', () => { + document.body.innerHTML = `
+ +
`; + const group1 = { + validators: [], + fields: [document.querySelector('#field1')] + }; + expect(Methods.digits(group1)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > minlength', () => { + + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'minlength', + params: { min: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.minlength(group)).toEqual(true); + }); + + it('should return false for group with a value < min', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'minlength', + params: { min: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.minlength(group)).toEqual(false); + }); + + it('should return true for group with a value => min', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'minlength', + params: { min: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.minlength(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > maxlength', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'maxlength', + params: { max: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.maxlength(group)).toEqual(true); + }); + + it('should return false for group with a value > max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'maxlength', + params: { max: 5 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.maxlength(group)).toEqual(false); + }); + + it('should return true for group with a value <= max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'maxlength', + params: { max: 5 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.maxlength(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > equalto', () => { + it('should return true for groups with no value', () => { + document.body.innerHTML = `
+ + +
`; + const group = { + validators: [ + { + type: 'equalto', + params: { other: [[document.querySelector('#field2')]] } + } + ], + fields: [document.querySelector('#field1')] + }; + expect(Methods.equalto(group)).toEqual(true); + }); + + it('should return false for groups with unequal values', () => { + document.body.innerHTML = `
+ + +
`; + const group = { + validators: [ + { + type: 'equalto', + params: { other: [[document.querySelector('#field2')]] } + } + ], + fields: [document.querySelector('#field1')] + }; + expect(Methods.equalto(group)).toEqual(false); + }); + + it('should return true for groups with unequal values', () => { + document.body.innerHTML = `
+ + +
`; + const group = { + validators: [ + { + type: 'equalto', + params: { other: [[document.querySelector('#field2')]] } + } + ], + fields: [document.querySelector('#field1')] + }; + expect(Methods.equalto(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > pattern', () => { + + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'pattern', + params: { regex: /^(pass)$/ } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.pattern(group)).toEqual(true); + }); + + it('should return false for group with a non-matching value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'pattern', + params: { regex: /^(pass)$/ } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.pattern(group)).toEqual(false); + }); + + it('should return false for group with a matching value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'pattern', + params: { regex: /^(pass)$/ } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.pattern(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > regex', () => { + + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'regex', + params: { pattern: /^(pass)$/ } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.regex(group)).toEqual(true); + }); + + it('should return false for group with a non-matching value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'regex', + params: { pattern: /^(pass)$/ } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.regex(group)).toEqual(false); + }); + + it('should return false for group with a matching value', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'regex', + params: { pattern: /^(pass)$/ } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.regex(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > min', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'min', + params: { min: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.min(group)).toEqual(true); + }); + + it('should return false for group with a value < min', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'min', + params: { min: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.min(group)).toEqual(false); + }); + + it('should return true for group with a value => min', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'min', + params: { min: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.min(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > max', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'max', + params: { max: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.max(group)).toEqual(true); + }); + + it('should return false for group with a value > max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'max', + params: { max: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.max(group)).toEqual(false); + }); + + it('should return true for group with a value <= max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'max', + params: { max: 5 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.max(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > stringlength', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'stringlength', + params: { max: 3 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.stringlength(group)).toEqual(true); + }); + + it('should return false for group with a value > max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'stringlength', + params: { max: 5 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.stringlength(group)).toEqual(false); + }); + + it('should return true for group with a value <= max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'stringlength', + params: { max: 5 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.stringlength(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > length', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'length', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.length(group)).toEqual(true); + }); + + it('should return false for group with a value > max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'length', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.length(group)).toEqual(false); + }); + + it('should return false for group with a value < min', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'length', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.length(group)).toEqual(false); + }); + + it('should return true for group with a value >= min and <= max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'length', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.length(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > range', () => { + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'range', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.range(group)).toEqual(true); + }); + + it('should return false for group with a value > max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'range', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.range(group)).toEqual(false); + }); + + it('should return false for group with a value < min', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'range', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.range(group)).toEqual(false); + }); + + it('should return true for group with a value >= min and <= max', () => { + document.body.innerHTML = `
`; + const group = { + validators: [ + { + type: 'range', + params: { min: 5, max: 8 } + } + ], + fields: [document.querySelector('#field')] + }; + expect(Methods.range(group)).toEqual(true); + }); + +}); + +describe('Validate > Unit > Validator > methods > remote', () => { + beforeEach(() => mock.setup()); + afterEach(() => mock.teardown()); + + it('should return false for when the remote validation returns \'false\'', async () => { + mock.post('/api/validate', { + status: 201, + body: 'false' + }); + + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + const params = { + url: '/api/validate' + }; + const res = await Methods.remote(group, params); + expect(res).toEqual('false'); + }); + + it('should return false for when the remote validation returns "false"', async () => { + mock.post('/api/validate', { + status: 201, + body: 'true' + }); + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + const params = { + url: '/api/validate' + }; + const res = await Methods.remote(group, params); + expect(res).toEqual('true'); + }); +}); + +describe('Validate > Unit > Validator > methods > custom', () => { + const customValidator = (value, fields) => value === 'Contrived validator'; + + it('should return true for group with no value that is not required', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.custom(customValidator, group)).toEqual(true); + }); + + it('should return false when the custom validation function return false', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.custom(customValidator, group)).toEqual(false); + }); + + + it('should return true when the custom validation function return true', () => { + document.body.innerHTML = `
`; + const group = { + validators: [], + fields: [document.querySelector('#field')] + }; + expect(Methods.custom(customValidator, group)).toEqual(true); + }); }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/normalise-validators/dateISO.js b/packages/validate/__tests__/jest/normalise-validators/dateISO.js similarity index 97% rename from packages/validate/__tests__/integration/normalise-validators/dateISO.js rename to packages/validate/__tests__/jest/normalise-validators/dateISO.js index ab5e25c7..17e98589 100644 --- a/packages/validate/__tests__/integration/normalise-validators/dateISO.js +++ b/packages/validate/__tests__/jest/normalise-validators/dateISO.js @@ -1,21 +1,21 @@ -import { normaliseValidators } from '../../../src/lib/validator'; - -describe('Validate > Integration > normalise-vaidators > dateISO', () => { - - it('should return the correct validation model for data-val email', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - expect(normaliseValidators(input)).toEqual([ - { - type: 'dateISO', - message: 'DateISO error message' - } - ]); - }); +import { normaliseValidators } from '../../../src/lib/validator'; + +describe('Validate > Integration > normalise-vaidators > dateISO', () => { + + it('should return the correct validation model for data-val email', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + expect(normaliseValidators(input)).toEqual([ + { + type: 'dateISO', + message: 'DateISO error message' + } + ]); + }); }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/normalise-validators/digits.js b/packages/validate/__tests__/jest/normalise-validators/digits.js similarity index 97% rename from packages/validate/__tests__/integration/normalise-validators/digits.js rename to packages/validate/__tests__/jest/normalise-validators/digits.js index 88f2878b..70d5618b 100644 --- a/packages/validate/__tests__/integration/normalise-validators/digits.js +++ b/packages/validate/__tests__/jest/normalise-validators/digits.js @@ -1,21 +1,21 @@ -import { normaliseValidators } from '../../../src/lib/validator'; - -describe('Validate > Integration > normalise-vaidators > dateISO', () => { - - it('should return the correct validation model for data-val email', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - expect(normaliseValidators(input)).toEqual([ - { - type: 'digits', - message: 'Digits error message' - } - ]); - }); +import { normaliseValidators } from '../../../src/lib/validator'; + +describe('Validate > Integration > normalise-vaidators > dateISO', () => { + + it('should return the correct validation model for data-val email', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + expect(normaliseValidators(input)).toEqual([ + { + type: 'digits', + message: 'Digits error message' + } + ]); + }); }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/normalise-validators/email.js b/packages/validate/__tests__/jest/normalise-validators/email.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/email.js rename to packages/validate/__tests__/jest/normalise-validators/email.js diff --git a/packages/validate/__tests__/integration/normalise-validators/equalto.js b/packages/validate/__tests__/jest/normalise-validators/equalto.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/equalto.js rename to packages/validate/__tests__/jest/normalise-validators/equalto.js diff --git a/packages/validate/__tests__/integration/normalise-validators/length.js b/packages/validate/__tests__/jest/normalise-validators/length.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/length.js rename to packages/validate/__tests__/jest/normalise-validators/length.js diff --git a/packages/validate/__tests__/integration/normalise-validators/max.js b/packages/validate/__tests__/jest/normalise-validators/max.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/max.js rename to packages/validate/__tests__/jest/normalise-validators/max.js diff --git a/packages/validate/__tests__/integration/normalise-validators/maxlength.js b/packages/validate/__tests__/jest/normalise-validators/maxlength.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/maxlength.js rename to packages/validate/__tests__/jest/normalise-validators/maxlength.js diff --git a/packages/validate/__tests__/integration/normalise-validators/min.js b/packages/validate/__tests__/jest/normalise-validators/min.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/min.js rename to packages/validate/__tests__/jest/normalise-validators/min.js diff --git a/packages/validate/__tests__/integration/normalise-validators/minlength.js b/packages/validate/__tests__/jest/normalise-validators/minlength.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/minlength.js rename to packages/validate/__tests__/jest/normalise-validators/minlength.js diff --git a/packages/validate/__tests__/integration/normalise-validators/number.js b/packages/validate/__tests__/jest/normalise-validators/number.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/number.js rename to packages/validate/__tests__/jest/normalise-validators/number.js diff --git a/packages/validate/__tests__/integration/normalise-validators/range.js b/packages/validate/__tests__/jest/normalise-validators/range.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/range.js rename to packages/validate/__tests__/jest/normalise-validators/range.js diff --git a/packages/validate/__tests__/integration/normalise-validators/regex-pattern.js b/packages/validate/__tests__/jest/normalise-validators/regex-pattern.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/regex-pattern.js rename to packages/validate/__tests__/jest/normalise-validators/regex-pattern.js diff --git a/packages/validate/__tests__/integration/normalise-validators/remote.js b/packages/validate/__tests__/jest/normalise-validators/remote.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/remote.js rename to packages/validate/__tests__/jest/normalise-validators/remote.js diff --git a/packages/validate/__tests__/integration/normalise-validators/required.js b/packages/validate/__tests__/jest/normalise-validators/required.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/required.js rename to packages/validate/__tests__/jest/normalise-validators/required.js diff --git a/packages/validate/__tests__/integration/normalise-validators/stringlength.js b/packages/validate/__tests__/jest/normalise-validators/stringlength.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/stringlength.js rename to packages/validate/__tests__/jest/normalise-validators/stringlength.js diff --git a/packages/validate/__tests__/integration/normalise-validators/url.js b/packages/validate/__tests__/jest/normalise-validators/url.js similarity index 100% rename from packages/validate/__tests__/integration/normalise-validators/url.js rename to packages/validate/__tests__/jest/normalise-validators/url.js diff --git a/packages/validate/__tests__/integration/plugins/date.js b/packages/validate/__tests__/jest/plugins/date.js similarity index 97% rename from packages/validate/__tests__/integration/plugins/date.js rename to packages/validate/__tests__/jest/plugins/date.js index 254fa9c0..0f8aff9a 100644 --- a/packages/validate/__tests__/integration/plugins/date.js +++ b/packages/validate/__tests__/jest/plugins/date.js @@ -1,561 +1,561 @@ -import validate from '../../../src'; -import { isValidDate, isFutureDate, isPastDate } from '../../../src/lib/plugins/methods/date'; - -describe('Validate > Integration > Plugins > Valid Date', () => { - - it('should add a validation method to a group', async () => { - expect.assertions(2); - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const dayErrorNode = document.querySelector('#date-Day-error-message'); - const monthInput = document.querySelector('#dateMonth'); - const monthErrorNode = document.querySelector('#date-Month-error-message'); - const yearInput = document.querySelector('#dateYear'); - const yearErrorNode = document.querySelector('#date-Year-error-message'); - const [ validator ] = validate('form'); - - expect(validator.getState().groups).toEqual({ - dateDay: { - serverErrorNode: dayErrorNode, - validators: [{ type: 'required', message: 'Enter a day' }], - fields: [dayInput], - valid: false - }, - dateMonth: { - serverErrorNode: monthErrorNode, - validators: [{ type: 'required', message: 'Enter a month' }], - fields: [monthInput], - valid: false - }, - dateYear: { - serverErrorNode: yearErrorNode, - validators: [{ type: 'required', message: 'Enter a year' }], - fields: [yearInput], - valid: false - } - }); - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a valid date'; - validator.addMethod('date', isValidDate, message, dateFields); - - expect(validator.getState().groups).toEqual({ - dateDay: { - serverErrorNode: dayErrorNode, - validators: [{ type: 'required', message: 'Enter a day' }], - fields: [dayInput], - valid: false - }, - dateMonth: { - serverErrorNode: monthErrorNode, - validators: [{ type: 'required', message: 'Enter a month' }], - fields: [monthInput], - valid: false - }, - dateYear: { - serverErrorNode: yearErrorNode, - validators: [{ type: 'required', message: 'Enter a year' }], - fields: [yearInput], - valid: false - }, - date: { - serverErrorNode: dateErrorNode, - validators: [{ type: 'custom', method: isValidDate, message }], - fields: dateFields, - valid: false - } - }); - }); - - it('should return false for a missing day, month, or year', async () => { - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a valid date'; - validator.addMethod('date', isValidDate, message, dateFields); - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - expect(dateErrorNode.textContent).toEqual(message); - }); - - it('should return false for an impossible date', async () => { - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a valid date'; - validator.addMethod('date', isValidDate, message, dateFields); - - const invalidDates = [ - ['-1', '1', '2000'], - ['32', '1', '2000'], - ['31', '2', '2000'], - ['29', '2', '2021'], - ['01', '13', '2021'] - ]; - - await Promise.all(invalidDates.map(async testcase => { - dayInput.value = testcase[0]; - monthInput.value = testcase[1]; - yearInput.value = testcase[2]; - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - expect(dateErrorNode.textContent).toEqual(message); - })); - }); - - it('should return true for a valid date', async () => { - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a valid date'; - validator.addMethod('date', isValidDate, message, dateFields); - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - -}); - -describe('Validate > Integration > Plugins > Date in future', () => { - - it('should add a validation method to a group', async () => { - expect.assertions(2); - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const dayErrorNode = document.querySelector('#date-Day-error-message'); - const monthInput = document.querySelector('#dateMonth'); - const monthErrorNode = document.querySelector('#date-Month-error-message'); - const yearInput = document.querySelector('#dateYear'); - const yearErrorNode = document.querySelector('#date-Year-error-message'); - const [ validator ] = validate('form'); - - expect(validator.getState().groups).toEqual({ - dateDay: { - serverErrorNode: dayErrorNode, - validators: [{ type: 'required', message: 'Enter a day' }], - fields: [dayInput], - valid: false - }, - dateMonth: { - serverErrorNode: monthErrorNode, - validators: [{ type: 'required', message: 'Enter a month' }], - fields: [monthInput], - valid: false - }, - dateYear: { - serverErrorNode: yearErrorNode, - validators: [{ type: 'required', message: 'Enter a year' }], - fields: [yearInput], - valid: false - } - }); - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the future'; - validator.addMethod('date', isFutureDate, message, dateFields); - - expect(validator.getState().groups).toEqual({ - dateDay: { - serverErrorNode: dayErrorNode, - validators: [{ type: 'required', message: 'Enter a day' }], - fields: [dayInput], - valid: false - }, - dateMonth: { - serverErrorNode: monthErrorNode, - validators: [{ type: 'required', message: 'Enter a month' }], - fields: [monthInput], - valid: false - }, - dateYear: { - serverErrorNode: yearErrorNode, - validators: [{ type: 'required', message: 'Enter a year' }], - fields: [yearInput], - valid: false - }, - date: { - serverErrorNode: dateErrorNode, - validators: [{ type: 'custom', method: isFutureDate, message }], - fields: dateFields, - valid: false - } - }); - }); - - it('should return false for a date in the past', async () => { - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the future'; - validator.addMethod('date', isFutureDate, message, dateFields); - - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - expect(dateErrorNode.textContent).toEqual(message); - }); - - it('should return true for a date in the future', async () => { - const currentDateYear = new Date().getFullYear(); - - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the future'; - validator.addMethod('date', isFutureDate, message, dateFields); - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should return false for todays date', async () => { - const currentDateYear = new Date().getFullYear(); - const currentDateMonth = new Date().getMonth() + 1; - const currentDateDay = new Date().getDate(); - - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the future'; - validator.addMethod('date', isFutureDate, message, dateFields); - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - }); - -}); - -describe('Validate > Integration > Plugins > Date in Past', () => { - - it('should add a validation method to a group', async () => { - expect.assertions(2); - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const dayErrorNode = document.querySelector('#date-Day-error-message'); - const monthInput = document.querySelector('#dateMonth'); - const monthErrorNode = document.querySelector('#date-Month-error-message'); - const yearInput = document.querySelector('#dateYear'); - const yearErrorNode = document.querySelector('#date-Year-error-message'); - const [ validator ] = validate('form'); - - expect(validator.getState().groups).toEqual({ - dateDay: { - serverErrorNode: dayErrorNode, - validators: [{ type: 'required', message: 'Enter a day' }], - fields: [dayInput], - valid: false - }, - dateMonth: { - serverErrorNode: monthErrorNode, - validators: [{ type: 'required', message: 'Enter a month' }], - fields: [monthInput], - valid: false - }, - dateYear: { - serverErrorNode: yearErrorNode, - validators: [{ type: 'required', message: 'Enter a year' }], - fields: [yearInput], - valid: false - } - }); - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the past'; - validator.addMethod('date', isPastDate, message, dateFields); - - expect(validator.getState().groups).toEqual({ - dateDay: { - serverErrorNode: dayErrorNode, - validators: [{ type: 'required', message: 'Enter a day' }], - fields: [dayInput], - valid: false - }, - dateMonth: { - serverErrorNode: monthErrorNode, - validators: [{ type: 'required', message: 'Enter a month' }], - fields: [monthInput], - valid: false - }, - dateYear: { - serverErrorNode: yearErrorNode, - validators: [{ type: 'required', message: 'Enter a year' }], - fields: [yearInput], - valid: false - }, - date: { - serverErrorNode: dateErrorNode, - validators: [{ type: 'custom', method: isPastDate, message }], - fields: dateFields, - valid: false - } - }); - }); - - it('should return false for a date in the future', async () => { - const currentDateYear = new Date().getFullYear(); - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dateErrorNode = document.querySelector('#date-error-message'); - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the past'; - validator.addMethod('date', isPastDate, message, dateFields); - - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - expect(dateErrorNode.textContent).toEqual(message); - }); - - it('should return true for a date in the past', async () => { - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the past'; - validator.addMethod('date', isPastDate, message, dateFields); - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should return true for todays date', async () => { - const currentDateYear = new Date().getFullYear(); - const currentDateMonth = new Date().getMonth() + 1; - const currentDateDay = new Date().getDate(); - - document.body.innerHTML = `
-
- - Date - - - - - -
- - - -
-
-
`; - - const dayInput = document.querySelector('#dateDay'); - const monthInput = document.querySelector('#dateMonth'); - const yearInput = document.querySelector('#dateYear'); - const [ validator ] = validate('form'); - - const dateFields = [ dayInput, monthInput, yearInput ]; - const message = 'Enter a date in the past'; - validator.addMethod('date', isPastDate, message, dateFields); - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - +import validate from '../../../src'; +import { isValidDate, isFutureDate, isPastDate } from '../../../src/lib/plugins/methods/date'; + +describe('Validate > Integration > Plugins > Valid Date', () => { + + it('should add a validation method to a group', async () => { + expect.assertions(2); + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const dayErrorNode = document.querySelector('#date-Day-error-message'); + const monthInput = document.querySelector('#dateMonth'); + const monthErrorNode = document.querySelector('#date-Month-error-message'); + const yearInput = document.querySelector('#dateYear'); + const yearErrorNode = document.querySelector('#date-Year-error-message'); + const [ validator ] = validate('form'); + + expect(validator.getState().groups).toEqual({ + dateDay: { + serverErrorNode: dayErrorNode, + validators: [{ type: 'required', message: 'Enter a day' }], + fields: [dayInput], + valid: false + }, + dateMonth: { + serverErrorNode: monthErrorNode, + validators: [{ type: 'required', message: 'Enter a month' }], + fields: [monthInput], + valid: false + }, + dateYear: { + serverErrorNode: yearErrorNode, + validators: [{ type: 'required', message: 'Enter a year' }], + fields: [yearInput], + valid: false + } + }); + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a valid date'; + validator.addMethod('date', isValidDate, message, dateFields); + + expect(validator.getState().groups).toEqual({ + dateDay: { + serverErrorNode: dayErrorNode, + validators: [{ type: 'required', message: 'Enter a day' }], + fields: [dayInput], + valid: false + }, + dateMonth: { + serverErrorNode: monthErrorNode, + validators: [{ type: 'required', message: 'Enter a month' }], + fields: [monthInput], + valid: false + }, + dateYear: { + serverErrorNode: yearErrorNode, + validators: [{ type: 'required', message: 'Enter a year' }], + fields: [yearInput], + valid: false + }, + date: { + serverErrorNode: dateErrorNode, + validators: [{ type: 'custom', method: isValidDate, message }], + fields: dateFields, + valid: false + } + }); + }); + + it('should return false for a missing day, month, or year', async () => { + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a valid date'; + validator.addMethod('date', isValidDate, message, dateFields); + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(dateErrorNode.textContent).toEqual(message); + }); + + it('should return false for an impossible date', async () => { + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a valid date'; + validator.addMethod('date', isValidDate, message, dateFields); + + const invalidDates = [ + ['-1', '1', '2000'], + ['32', '1', '2000'], + ['31', '2', '2000'], + ['29', '2', '2021'], + ['01', '13', '2021'] + ]; + + await Promise.all(invalidDates.map(async testcase => { + dayInput.value = testcase[0]; + monthInput.value = testcase[1]; + yearInput.value = testcase[2]; + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(dateErrorNode.textContent).toEqual(message); + })); + }); + + it('should return true for a valid date', async () => { + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a valid date'; + validator.addMethod('date', isValidDate, message, dateFields); + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + +}); + +describe('Validate > Integration > Plugins > Date in future', () => { + + it('should add a validation method to a group', async () => { + expect.assertions(2); + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const dayErrorNode = document.querySelector('#date-Day-error-message'); + const monthInput = document.querySelector('#dateMonth'); + const monthErrorNode = document.querySelector('#date-Month-error-message'); + const yearInput = document.querySelector('#dateYear'); + const yearErrorNode = document.querySelector('#date-Year-error-message'); + const [ validator ] = validate('form'); + + expect(validator.getState().groups).toEqual({ + dateDay: { + serverErrorNode: dayErrorNode, + validators: [{ type: 'required', message: 'Enter a day' }], + fields: [dayInput], + valid: false + }, + dateMonth: { + serverErrorNode: monthErrorNode, + validators: [{ type: 'required', message: 'Enter a month' }], + fields: [monthInput], + valid: false + }, + dateYear: { + serverErrorNode: yearErrorNode, + validators: [{ type: 'required', message: 'Enter a year' }], + fields: [yearInput], + valid: false + } + }); + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the future'; + validator.addMethod('date', isFutureDate, message, dateFields); + + expect(validator.getState().groups).toEqual({ + dateDay: { + serverErrorNode: dayErrorNode, + validators: [{ type: 'required', message: 'Enter a day' }], + fields: [dayInput], + valid: false + }, + dateMonth: { + serverErrorNode: monthErrorNode, + validators: [{ type: 'required', message: 'Enter a month' }], + fields: [monthInput], + valid: false + }, + dateYear: { + serverErrorNode: yearErrorNode, + validators: [{ type: 'required', message: 'Enter a year' }], + fields: [yearInput], + valid: false + }, + date: { + serverErrorNode: dateErrorNode, + validators: [{ type: 'custom', method: isFutureDate, message }], + fields: dateFields, + valid: false + } + }); + }); + + it('should return false for a date in the past', async () => { + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the future'; + validator.addMethod('date', isFutureDate, message, dateFields); + + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(dateErrorNode.textContent).toEqual(message); + }); + + it('should return true for a date in the future', async () => { + const currentDateYear = new Date().getFullYear(); + + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the future'; + validator.addMethod('date', isFutureDate, message, dateFields); + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should return false for todays date', async () => { + const currentDateYear = new Date().getFullYear(); + const currentDateMonth = new Date().getMonth() + 1; + const currentDateDay = new Date().getDate(); + + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the future'; + validator.addMethod('date', isFutureDate, message, dateFields); + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + }); + +}); + +describe('Validate > Integration > Plugins > Date in Past', () => { + + it('should add a validation method to a group', async () => { + expect.assertions(2); + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const dayErrorNode = document.querySelector('#date-Day-error-message'); + const monthInput = document.querySelector('#dateMonth'); + const monthErrorNode = document.querySelector('#date-Month-error-message'); + const yearInput = document.querySelector('#dateYear'); + const yearErrorNode = document.querySelector('#date-Year-error-message'); + const [ validator ] = validate('form'); + + expect(validator.getState().groups).toEqual({ + dateDay: { + serverErrorNode: dayErrorNode, + validators: [{ type: 'required', message: 'Enter a day' }], + fields: [dayInput], + valid: false + }, + dateMonth: { + serverErrorNode: monthErrorNode, + validators: [{ type: 'required', message: 'Enter a month' }], + fields: [monthInput], + valid: false + }, + dateYear: { + serverErrorNode: yearErrorNode, + validators: [{ type: 'required', message: 'Enter a year' }], + fields: [yearInput], + valid: false + } + }); + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the past'; + validator.addMethod('date', isPastDate, message, dateFields); + + expect(validator.getState().groups).toEqual({ + dateDay: { + serverErrorNode: dayErrorNode, + validators: [{ type: 'required', message: 'Enter a day' }], + fields: [dayInput], + valid: false + }, + dateMonth: { + serverErrorNode: monthErrorNode, + validators: [{ type: 'required', message: 'Enter a month' }], + fields: [monthInput], + valid: false + }, + dateYear: { + serverErrorNode: yearErrorNode, + validators: [{ type: 'required', message: 'Enter a year' }], + fields: [yearInput], + valid: false + }, + date: { + serverErrorNode: dateErrorNode, + validators: [{ type: 'custom', method: isPastDate, message }], + fields: dateFields, + valid: false + } + }); + }); + + it('should return false for a date in the future', async () => { + const currentDateYear = new Date().getFullYear(); + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dateErrorNode = document.querySelector('#date-error-message'); + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the past'; + validator.addMethod('date', isPastDate, message, dateFields); + + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + expect(dateErrorNode.textContent).toEqual(message); + }); + + it('should return true for a date in the past', async () => { + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the past'; + validator.addMethod('date', isPastDate, message, dateFields); + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should return true for todays date', async () => { + const currentDateYear = new Date().getFullYear(); + const currentDateMonth = new Date().getMonth() + 1; + const currentDateDay = new Date().getDate(); + + document.body.innerHTML = `
+
+ + Date + + + + + +
+ + + +
+
+
`; + + const dayInput = document.querySelector('#dateDay'); + const monthInput = document.querySelector('#dateMonth'); + const yearInput = document.querySelector('#dateYear'); + const [ validator ] = validate('form'); + + const dateFields = [ dayInput, monthInput, yearInput ]; + const message = 'Enter a date in the past'; + validator.addMethod('date', isPastDate, message, dateFields); + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/plugins/luhn.js b/packages/validate/__tests__/jest/plugins/luhn.js similarity index 88% rename from packages/validate/__tests__/integration/plugins/luhn.js rename to packages/validate/__tests__/jest/plugins/luhn.js index 8665ab92..a0ac58fd 100644 --- a/packages/validate/__tests__/integration/plugins/luhn.js +++ b/packages/validate/__tests__/jest/plugins/luhn.js @@ -1,123 +1,114 @@ -import validate from '../../../src'; -import luhn from '../../../src/lib/plugins/methods/luhn'; - -describe('Validate > Integration > Plugins > Luhn', () => { - - it('should add a validation method to a group', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - -
`; - // const form = document.querySelector('.form'); - const input = document.querySelector('#group1-1'); - const [ validator ] = validate('form'); - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }], - fields: [input], - valid: false - } - }); - const message = 'Custom error'; - validator.addMethod('group1', luhn, message); - - expect(validator.getState().groups).toEqual({ - group1: { - serverErrorNode: false, - validators: [{ type: 'required' }, { type: 'custom', method: luhn, message }], - fields: [input], - valid: false - } - }); - }); - - it('should not validate a clean optional field', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const [ validator ] = validate('form'); - const message = 'Custom error'; - validator.addMethod('group1', luhn, message); - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - }); - - it('should return false for a malformed credit card number', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - -
`; - const [ validator ] = validate('form'); - const message = 'Custom error'; - validator.addMethod('group1', luhn, message); - const validityState = await validator.validate(); - expect(validityState).toEqual(false); - }); - - it('should return true for valid credit card numbers', async () => { - const formats = { - 'American Express': 378282246310005, - 'American Express 2': 371449635398431, - 'American Express Corporate': 378734493671000, - 'Australian BankCard': 5610591081018250, - 'Diners Club': 30569309025904, - Discover: 6011111111111117, - 'Discover 2': 6011000990139424, - JCB: 3530111333300000, - 'JCB 2': 3566002020360505, - MasterCard: 5555555555554444, - 'MasterCard 2': 5105105105105100, - Visa: 4111111111111111, - 'Visa 2': 4012888888881881 - }; - expect.assertions(Object.values(formats).length); - document.body.innerHTML = `
- - -
`; - const [ validator ] = validate('form'); - const field = document.querySelector('#group1-1'); - const message = 'Custom error'; - validator.addMethod('group1', luhn, message); - - for (let format in formats) { - field.value = formats[format]; - const validityState = await validator.validate(); - expect(validityState).toEqual(true); - } - - // Alternative implementation of the test... - // const validityStates = await Promise.all(Object.values(formats).map(format => async () => { - // field.value = formats[format]; - // return await validator.validate(); - // })); - - // const aggregage = validityStates.reduce((acc, curr) => !curr ? false : acc, true); - // expect(aggregage).toEqual(true); - }); - +import validate from '../../../src'; +import luhn from '../../../src/lib/plugins/methods/luhn'; + +describe('Validate > Integration > Plugins > Luhn', () => { + + it('should add a validation method to a group', async () => { + expect.assertions(2); + document.body.innerHTML = `
+ + +
`; + // const form = document.querySelector('.form'); + const input = document.querySelector('#group1-1'); + const [ validator ] = validate('form'); + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: 'required' }], + fields: [input], + valid: false + } + }); + const message = 'Custom error'; + validator.addMethod('group1', luhn, message); + + expect(validator.getState().groups).toEqual({ + group1: { + serverErrorNode: false, + validators: [{ type: 'required' }, { type: 'custom', method: luhn, message }], + fields: [input], + valid: false + } + }); + }); + + it('should not validate a clean optional field', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const [ validator ] = validate('form'); + const message = 'Custom error'; + validator.addMethod('group1', luhn, message); + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + }); + + it('should return false for a malformed credit card number', async () => { + expect.assertions(1); + document.body.innerHTML = `
+ + +
`; + const [ validator ] = validate('form'); + const message = 'Custom error'; + validator.addMethod('group1', luhn, message); + const validityState = await validator.validate(); + expect(validityState).toEqual(false); + }); + + it('should return true for valid credit card numbers', async () => { + const formats = { + 'American Express': 378282246310005, + 'American Express 2': 371449635398431, + 'American Express Corporate': 378734493671000, + 'Australian BankCard': 5610591081018250, + 'Diners Club': 30569309025904, + Discover: 6011111111111117, + 'Discover 2': 6011000990139424, + JCB: 3530111333300000, + 'JCB 2': 3566002020360505, + MasterCard: 5555555555554444, + 'MasterCard 2': 5105105105105100, + Visa: 4111111111111111, + 'Visa 2': 4012888888881881 + }; + expect.assertions(Object.values(formats).length); + document.body.innerHTML = `
+ + +
`; + const [ validator ] = validate('form'); + const field = document.querySelector('#group1-1'); + const message = 'Custom error'; + validator.addMethod('group1', luhn, message); + + for (let format in formats) { + field.value = formats[format]; + const validityState = await validator.validate(); + expect(validityState).toEqual(true); + } + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/unit/reducers.js b/packages/validate/__tests__/jest/reducers.js similarity index 98% rename from packages/validate/__tests__/unit/reducers.js rename to packages/validate/__tests__/jest/reducers.js index 44bbefee..22020a0e 100644 --- a/packages/validate/__tests__/unit/reducers.js +++ b/packages/validate/__tests__/jest/reducers.js @@ -1,7 +1,6 @@ import { ACTIONS, GROUP_ATTRIBUTE } from '../../src/lib/constants'; import Reducers from '../../src/lib/reducers'; -//set initial state describe('Validate > Unit > Reducers > Set initial state', () => { it('should compose a new object based on default empty state object and initial payload', async () => { expect.assertions(1); @@ -23,7 +22,6 @@ describe('Validate > Unit > Reducers > Set initial state', () => { }); }); -//clear errors describe('Validate > Unit > Reducers > Clear errors', () => { it('should compose a new object with each group Object containing an empty array of errorMessages and a true validity property', async () => { expect.assertions(1); @@ -69,7 +67,6 @@ describe('Validate > Unit > Reducers > Clear errors', () => { }); }); -//clear error describe('Validate > Unit > Reducers > Clear error', () => { it('should compose a new object with a group Object containing an empty array of errorMessages and a true validity property for a given group name', async () => { expect.assertions(1); @@ -115,7 +112,6 @@ describe('Validate > Unit > Reducers > Clear error', () => { }); }); -//add validation errors describe('Validate > Unit > Reducers > Add validation errors', () => { it('should compose a new object with group Objects containing an array of errorMessages and a false validity property', async () => { expect.assertions(1); @@ -168,8 +164,6 @@ describe('Validate > Unit > Reducers > Add validation errors', () => { }); }); - -//add validation error describe('Validate > Unit > Reducers > Add validation error', () => { it('should compose a new Object updating one of the group Objects with an array of errorMessages and a false validity property', async () => { expect.assertions(1); @@ -212,7 +206,6 @@ describe('Validate > Unit > Reducers > Add validation error', () => { }); }); -//add validation method describe('Validate > Unit > Reducers > Add validation method', () => { it('should add a validator of type custom to an existing field group', async () => { expect.assertions(1); @@ -341,11 +334,9 @@ describe('Validate > Unit > Reducers > Add validation method', () => { }); }); -//Add group describe('Validate > Unit > Reducers > Add group', () => { it('should add a new validation group', async () => { expect.assertions(1); - // const validatorFn = (value, fields, param) => false; const state = { groups: { group1: { @@ -392,11 +383,9 @@ describe('Validate > Unit > Reducers > Add group', () => { }); }); -//Remove group describe('Validate > Unit > Reducers > Remove group', () => { it('should remove a validation group', async () => { expect.assertions(1); - // const validatorFn = (value, fields, param) => false; const state = { groups: { group1: { diff --git a/packages/validate/__tests__/jest/reset.js b/packages/validate/__tests__/jest/reset.js new file mode 100644 index 00000000..383faf10 --- /dev/null +++ b/packages/validate/__tests__/jest/reset.js @@ -0,0 +1,30 @@ +import validate from '../../src'; + +describe('Validate > Reset', () => { + + it('should clear errors messages from state and DOM, remove error classNames and attributes, remove errors from state', async () => { + document.body.innerHTML = `
+
+ + +
+
+ + +
+
`; + + const [ validator ] = validate('.form'); + await validator.validate(); + expect(validator.getState().groups.group1.valid).toEqual(false); + expect(validator.getState().groups.group2.valid).toEqual(false); + + validator.getState().form.dispatchEvent(new Event('reset')); + expect(validator.getState().groups.group1.valid).toEqual(true); + expect(validator.getState().groups.group2.valid).toEqual(true); + expect(validator.getState().groups.group1.errorMessages).toEqual([]); + expect(validator.getState().groups.group2.errorMessages).toEqual([]); + expect(validator.getState().errors.group1).toBeUndefined(); + expect(validator.getState().errors.group2).toBeUndefined(); + }); +}); diff --git a/packages/validate/__tests__/unit/store.js b/packages/validate/__tests__/jest/store.js similarity index 98% rename from packages/validate/__tests__/unit/store.js rename to packages/validate/__tests__/jest/store.js index f54b4d43..b625aa61 100644 --- a/packages/validate/__tests__/unit/store.js +++ b/packages/validate/__tests__/jest/store.js @@ -5,7 +5,7 @@ let Store; beforeAll(() => { Store = createStore(); }); -//createStore + describe('Validate > Unit > Store > createStore', () => { it('should create a store object with update and get functions', async () => { expect.assertions(5); @@ -17,7 +17,6 @@ describe('Validate > Unit > Store > createStore', () => { }); }); -//getState describe('Validate > Unit > Store > getState', () => { it('should return the state object', async () => { expect.assertions(1); @@ -25,7 +24,6 @@ describe('Validate > Unit > Store > getState', () => { }); }); -//update describe('Validate > Unit > Store > update', () => { it('should update state using reducers and nextState payload', async () => { expect.assertions(1); diff --git a/packages/validate/__tests__/jest/submit.js b/packages/validate/__tests__/jest/submit.js new file mode 100644 index 00000000..eee7b4a0 --- /dev/null +++ b/packages/validate/__tests__/jest/submit.js @@ -0,0 +1,21 @@ +import validate from '../../src'; + +describe('Validate > Integration > Submit', () => { + it('should call the submit function if validation passes', async () => { + expect.assertions(2); + document.body.innerHTML = `
+ + +
`; + + const submit = jest.fn(); + const [ validator ] = validate(document.querySelector('form'), { submit }); + await validator.validate({ target: true, preventDefault(){} }); + expect(validator.getState().settings.submit).toEqual(submit); + expect(submit).toBeCalled(); + }); +}); \ No newline at end of file diff --git a/packages/validate/__tests__/unit/validator/utils.js b/packages/validate/__tests__/jest/utils.js similarity index 98% rename from packages/validate/__tests__/unit/validator/utils.js rename to packages/validate/__tests__/jest/utils.js index a0374663..eab3ad08 100644 --- a/packages/validate/__tests__/unit/validator/utils.js +++ b/packages/validate/__tests__/jest/utils.js @@ -13,7 +13,7 @@ import { escapeAttributeValue, extractValueFromGroup, findErrors -} from '../../../src/lib/validator/utils'; +} from '../../src/lib/validator/utils'; describe('Validate > Unit > Utils > isCheckable', () => { it('should return true if the field is of type radio', async () => { @@ -24,6 +24,7 @@ describe('Validate > Unit > Utils > isCheckable', () => { const field = document.getElementById('radio'); expect(isCheckable(field)).toEqual(true); }); + it('should return true if the field is of type checkbox', async () => { expect.assertions(1); document.body.innerHTML = `
@@ -32,6 +33,7 @@ describe('Validate > Unit > Utils > isCheckable', () => { const field = document.getElementById('checkbox'); expect(isCheckable(field)).toEqual(true); }); + it('should return false if the field is not of type radio or checkbox', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -51,6 +53,7 @@ describe('Validate > Unit > Utils > isFile', () => { const field = document.getElementById('file'); expect(isFile(field)).toEqual(true); }); + it('should return false if the field is not of type file', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -72,6 +75,7 @@ describe('Validate > Unit > Utils > isSelect', () => { const field = document.getElementById('select'); expect(isSelect(field)).toEqual(true); }); + it('should return false if the field is not a select', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -91,6 +95,7 @@ describe('Validate > Unit > Utils > isSubmitButton', () => { const node = document.getElementById('btn'); expect(isSubmitButton(node)).toEqual(true); }); + it('should return true if the node is a button', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -99,6 +104,7 @@ describe('Validate > Unit > Utils > isSubmitButton', () => { const node = document.getElementById('btn'); expect(isSubmitButton(node)).toEqual(true); }); + it('should return false if the node is not a button and not of type submit', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -118,6 +124,7 @@ describe('Validate > Unit > Utils > hasNameValue', () => { const node = document.getElementById('field'); expect(hasNameValue(node)).toEqual(true); }); + it('should return false if the node has no name attribute', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -126,6 +133,7 @@ describe('Validate > Unit > Utils > hasNameValue', () => { const node = document.getElementById('field'); expect(hasNameValue(node)).toEqual(false); }); + it('should return false if the node has no value attribute', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -144,6 +152,7 @@ describe('Validate > Unit > Utils > isRequired', () => { }; expect(isRequired(group)).toEqual(true); }); + it('should return false if the group does not contain a required validator', async () => { expect.assertions(1); const group = { @@ -161,6 +170,7 @@ describe('Validate > Unit > Utils > isHidden', () => { expect(isHidden(field)).toEqual(true); }); + it('should return false if the field is not of type hidden', async () => { expect.assertions(1); document.body.innerHTML = ``; @@ -180,6 +190,7 @@ describe('Validate > Unit > Utils > hasValue', () => { expect(hasValue(field)).toEqual(true); }); + it('should return false if the field has an empty value', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -189,6 +200,7 @@ describe('Validate > Unit > Utils > hasValue', () => { expect(hasValue(field)).toEqual(false); }); + it('should return false if the field has no value attribute', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -200,7 +212,6 @@ describe('Validate > Unit > Utils > hasValue', () => { }); }); -//groupValueReducer describe('Validate > Unit > Utils > groupValueReducer', () => { it('should return the String value given an input with a value', async () => { expect.assertions(1); @@ -210,6 +221,7 @@ describe('Validate > Unit > Utils > groupValueReducer', () => { const field = document.querySelector('#field'); expect(groupValueReducer('', field)).toEqual('Test value'); }); + it('should trim String value given an input with a value whitespace', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -218,6 +230,7 @@ describe('Validate > Unit > Utils > groupValueReducer', () => { const field = document.querySelector('#field'); expect(groupValueReducer('', field)).toEqual('Test value'); }); + it('should return an empty String given an input without a value and an initial empty string', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -226,6 +239,7 @@ describe('Validate > Unit > Utils > groupValueReducer', () => { const field = document.querySelector('#field'); expect(groupValueReducer('', field)).toEqual(''); }); + it('should return an Array containing a String value given a checkable input with a value', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -234,6 +248,7 @@ describe('Validate > Unit > Utils > groupValueReducer', () => { const field = document.querySelector('#field'); expect(groupValueReducer('', field)).toEqual(['Test value']); }); + it('should return an Array containing a String value given a checkable input with a value and an initial Array', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -242,6 +257,7 @@ describe('Validate > Unit > Utils > groupValueReducer', () => { const field = document.querySelector('#field'); expect(groupValueReducer([], field)).toEqual(['Test value']); }); + it('should return an empty String given a checkable input that is not checked and an initial empty string', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -252,7 +268,6 @@ describe('Validate > Unit > Utils > groupValueReducer', () => { }); }); -// resolveGetParams describe('Validate > Unit > Utils > resolveGetParams', () => { it('should return a url param String name/value pair given an array containing a single array of a single input', async () => { expect.assertions(1); @@ -262,6 +277,7 @@ describe('Validate > Unit > Utils > resolveGetParams', () => { const fields = [document.querySelector('#field')]; expect(resolveGetParams([fields])).toEqual('field=Test'); }); + it('should return a url param String name/value pair given an array containing multiple arrays of single inputs', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -272,6 +288,7 @@ describe('Validate > Unit > Utils > resolveGetParams', () => { const field2 = [document.querySelector('#field2')]; expect(resolveGetParams([field1, field2])).toEqual('field1=One&field2=Two'); }); + it('should return a uri-encoded url param String name/value pair given an array containing multiple arrays of single inputs', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -284,7 +301,6 @@ describe('Validate > Unit > Utils > resolveGetParams', () => { }); }); -// domNodesFromCommaList describe('Validate > Unit > Utils > domNodesFromCommaList', () => { it('should return an array of arrays of nodes matching each name in a comma separated String', async () => { expect.assertions(1); @@ -296,6 +312,7 @@ describe('Validate > Unit > Utils > domNodesFromCommaList', () => { const field2s = document.querySelector('#field2'); expect(domNodesFromCommaList('field1,field2')).toEqual([[field1s], [field2s]]); }); + it('should return an array of empty arrays for a comma separated String that does not select any node name attributes', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -306,17 +323,12 @@ describe('Validate > Unit > Utils > domNodesFromCommaList', () => { }); }); -// escapeAttributeValue describe('Validate > Unit > Utils > escapeAttributeValue', () => { it('should escape special characters matching /([!"#$%&\'()*+,./:;<=>?@[\\]^`{|}~] in a String', async () => { expect(escapeAttributeValue('')).toEqual('\\alert\\(\\"Boo\\"\\)\\<\\/script\\>'); }); }); -//getStatePrefix -//appendStatePrefix - -//extractValueFromGroup // -> see groupValueReducer describe('Validate > Unit > Utils > extractValueFromGroup', () => { it('should return the String value given a group with a field array containing an input with a value', async () => { expect.assertions(1); @@ -326,6 +338,7 @@ describe('Validate > Unit > Utils > extractValueFromGroup', () => { const group = { fields: [document.querySelector('#field')] }; expect(extractValueFromGroup(group)).toEqual('Test value'); }); + it('should return the String value given a field array containing an input with a value', async () => { expect.assertions(1); document.body.innerHTML = ` @@ -336,10 +349,7 @@ describe('Validate > Unit > Utils > extractValueFromGroup', () => { }); }); -//fetch - describe('Validate > Unit > Utils > findErrors', () => { - it('Should find serverErrorNodes and convert string error messages to DOM nodes', async () => { document.body.innerHTML = ` @@ -356,5 +366,4 @@ describe('Validate > Unit > Utils > findErrors', () => { const errors = findErrors(groups); expect(errors.group1).toEqual(serverErrorNode.textContent); }); - }); \ No newline at end of file diff --git a/packages/validate/__tests__/unit/validator/index.js b/packages/validate/__tests__/jest/validator.js similarity index 95% rename from packages/validate/__tests__/unit/validator/index.js rename to packages/validate/__tests__/jest/validator.js index 12371ba8..87c42275 100644 --- a/packages/validate/__tests__/unit/validator/index.js +++ b/packages/validate/__tests__/jest/validator.js @@ -4,13 +4,11 @@ import { extractDataValValidators, extractAttrValidators, extractErrorMessage, - // reduceErrorMessages, removeUnvalidatableGroups, getInitialState -} from '../../../src/lib/validator'; -import defaults from '../../../src/lib/defaults'; +} from '../../src/lib/validator'; +import defaults from '../../src/lib/defaults'; -//resolveParam describe('Validate > Unit > Validator > resolveParam', () => { it('should return a param Object indexed by second part of param name and String value', async () => { expect.assertions(1); @@ -28,6 +26,7 @@ describe('Validate > Unit > Validator > resolveParam', () => { const resolved = resolveParam(param, input); expect(resolved).toEqual({ min: '2' }); }); + it('should return a param Object indexed by second part of param name, and an array of arrays of DOMNodes', async () => { expect.assertions(1); document.body.innerHTML = ` Unit > Validator > resolveParam', () => { }); }); - -//extractParams describe('Validate > Unit > Validator > extractParams', () => { it('should return false when supplied an unknown .NET MVC adaptors/validation method', async () => { expect.assertions(1); expect(extractParams(null, 'unknown-adaptor')).toEqual(false); }); + it('should return an Object containing all parameters for matched adaptor/validation method on an input', async () => { expect.assertions(1); document.body.innerHTML = ` Unit > Validator > extractParams', () => { }); }); -//extractDataValValidators describe('Validate > Unit > Validator > extractDataValValidators', () => { it('should return an empty array if a given node does not contain data-attributes defining known validators', async () => { expect.assertions(1); @@ -111,7 +108,6 @@ describe('Validate > Unit > Validator > extractDataValValidators', () => { }); }); -//extractAttrValidators describe('Validate > Unit > Validator > extractAttrValidators', () => { it('should return an empty array if a given node does not contain HTML5 constraint validation attributes', async () => { expect.assertions(1); @@ -154,14 +150,6 @@ describe('Validate > Unit > Validator > extractAttrValidators', () => { }); }); -//normaliseValidators --> see integration tests - - -//validate --> see integration validate tests - -//assembleValidationGroup -> see integration assembleValidationGroup tests - -//extractErrorMessage describe('Validate > Unit > Validator > extractErrorMessage', () => { it('should return an error message given a validator containing a message', async () => { expect.assertions(1); @@ -196,13 +184,6 @@ describe('Validate > Unit > Validator > extractErrorMessage', () => { }); - -// To do -// can do better here, factory > validate function in need of refactor -// -//extractErrorMessage - - describe('Validate > Unit > Validator > removeUnvalidatableGroups', () => { it('should remove groups that do not contain validators from the array of vaidationGroups', async () => { expect.assertions(1); @@ -240,7 +221,6 @@ describe('Validate > Unit > Validator > removeUnvalidatableGroups', () => { valid: false } }); - }); it('should remove groups with all hidden fields from the array of validationGroups', async () => { @@ -264,13 +244,10 @@ describe('Validate > Unit > Validator > removeUnvalidatableGroups', () => { valid: false } }; - expect(removeUnvalidatableGroups(groups)).toEqual({}); }); - }); -//getInitialState describe('Validate > Unit > Validator > getInitialState', () => { it('should return a state object containing only groups that are validatable', async () => { expect.assertions(1); @@ -284,7 +261,6 @@ describe('Validate > Unit > Validator > getInitialState', () => { name="group2" type="text">`; const input1 = document.querySelector('#group1'); - // const input2 = document.querySelector('#group2'); const form = document.querySelector('form'); expect(getInitialState(form, {})).toEqual({ @@ -302,6 +278,7 @@ describe('Validate > Unit > Validator > getInitialState', () => { } }); }); + it('should return a state object containing any settings passed to init', async () => { expect.assertions(1); document.body.innerHTML = `
Integration > validator > digits', () => { - - it('should return the validityState false for data-val digits validator with non-spec date', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val digits validator with an no-spec date', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > digits', () => { + + it('should return the validityState false for data-val digits validator with non-spec date', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val digits validator with an no-spec date', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/email.js b/packages/validate/__tests__/jest/validator/email.js similarity index 97% rename from packages/validate/__tests__/integration/validator/email.js rename to packages/validate/__tests__/jest/validator/email.js index 173deed4..54bcf2ae 100644 --- a/packages/validate/__tests__/integration/validator/email.js +++ b/packages/validate/__tests__/jest/validator/email.js @@ -1,113 +1,113 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > email', () => { - //html5 spec regex approximation: - ///^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ - it('should return the validityState false for HTML5 email validator with non-spec email address', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for HTML5 email validator with an on-spec email address', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty HTML5 email validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val email validator with non-spec email address', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val email validator with an on-spec email address', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty data-val email validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for emails names containing accents and diacritic marks', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for emails containing accents and diacritic marks in the domain name', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > email', () => { + //html5 spec regex approximation: + ///^[a-zA-Z0-9.!#$%&'*+\/=?^_`{|}~-]+@[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$/ + it('should return the validityState false for HTML5 email validator with non-spec email address', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for HTML5 email validator with an on-spec email address', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty HTML5 email validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val email validator with non-spec email address', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val email validator with an on-spec email address', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty data-val email validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for emails names containing accents and diacritic marks', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for emails containing accents and diacritic marks in the domain name', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/equalto.js b/packages/validate/__tests__/jest/validator/equalto.js similarity index 97% rename from packages/validate/__tests__/integration/validator/equalto.js rename to packages/validate/__tests__/jest/validator/equalto.js index d9ea5cec..f3138cb2 100644 --- a/packages/validate/__tests__/integration/validator/equalto.js +++ b/packages/validate/__tests__/jest/validator/equalto.js @@ -1,141 +1,141 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > equalto', () => { - - it('should return the validityState false for data-val equalto validator with a value not matching another single field', async () => { - expect.assertions(1); - document.body.innerHTML = ` - `; - const input = document.querySelector('#VERIFY-EMAIL'); - const group = assembleValidationGroup({}, input)['VERIFY-EMAIL']; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val equalto validator with a value matching another single field', async () => { - expect.assertions(1); - document.body.innerHTML = ` - `; - const input = document.querySelector('#VERIFY-EMAIL'); - const group = assembleValidationGroup({}, input)['VERIFY-EMAIL']; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val equalto validator with a value not matching the other field(s)', async () => { - expect.assertions(1); - document.body.innerHTML = ` - - `; - const input = document.querySelector('#DoubleConfirmEmail'); - const group = assembleValidationGroup({}, input).DoubleConfirmEmail; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for data-val equalto validator with a value not matching the other field(s) with an empty value', async () => { - expect.assertions(1); - document.body.innerHTML = ` - - `; - const input = document.querySelector('#DoubleConfirmEmail'); - const group = assembleValidationGroup({}, input).DoubleConfirmEmail; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val equalto validator with a value matching the other field(s)', async () => { - expect.assertions(1); - document.body.innerHTML = ` - - `; - const input = document.querySelector('#DoubleConfirmEmail'); - const group = assembleValidationGroup({}, input).DoubleConfirmEmail; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for an unrequired data-val equalto validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ` - - `; - const input = document.querySelector('#DoubleConfirmEmail'); - const group = assembleValidationGroup({}, input).DoubleConfirmEmail; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > equalto', () => { + + it('should return the validityState false for data-val equalto validator with a value not matching another single field', async () => { + expect.assertions(1); + document.body.innerHTML = ` + `; + const input = document.querySelector('#VERIFY-EMAIL'); + const group = assembleValidationGroup({}, input)['VERIFY-EMAIL']; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val equalto validator with a value matching another single field', async () => { + expect.assertions(1); + document.body.innerHTML = ` + `; + const input = document.querySelector('#VERIFY-EMAIL'); + const group = assembleValidationGroup({}, input)['VERIFY-EMAIL']; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val equalto validator with a value not matching the other field(s)', async () => { + expect.assertions(1); + document.body.innerHTML = ` + + `; + const input = document.querySelector('#DoubleConfirmEmail'); + const group = assembleValidationGroup({}, input).DoubleConfirmEmail; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for data-val equalto validator with a value not matching the other field(s) with an empty value', async () => { + expect.assertions(1); + document.body.innerHTML = ` + + `; + const input = document.querySelector('#DoubleConfirmEmail'); + const group = assembleValidationGroup({}, input).DoubleConfirmEmail; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val equalto validator with a value matching the other field(s)', async () => { + expect.assertions(1); + document.body.innerHTML = ` + + `; + const input = document.querySelector('#DoubleConfirmEmail'); + const group = assembleValidationGroup({}, input).DoubleConfirmEmail; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for an unrequired data-val equalto validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ` + + `; + const input = document.querySelector('#DoubleConfirmEmail'); + const group = assembleValidationGroup({}, input).DoubleConfirmEmail; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/index.js b/packages/validate/__tests__/jest/validator/index.js similarity index 100% rename from packages/validate/__tests__/integration/validator/index.js rename to packages/validate/__tests__/jest/validator/index.js diff --git a/packages/validate/__tests__/integration/validator/isHidden.js b/packages/validate/__tests__/jest/validator/isHidden.js similarity index 100% rename from packages/validate/__tests__/integration/validator/isHidden.js rename to packages/validate/__tests__/jest/validator/isHidden.js diff --git a/packages/validate/__tests__/integration/validator/length.js b/packages/validate/__tests__/jest/validator/length.js similarity index 97% rename from packages/validate/__tests__/integration/validator/length.js rename to packages/validate/__tests__/jest/validator/length.js index 05ef617d..a85bebe5 100644 --- a/packages/validate/__tests__/integration/validator/length.js +++ b/packages/validate/__tests__/jest/validator/length.js @@ -1,53 +1,53 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > length', () => { - - it('should return the validityState false for data-val length validator with value greater than max length', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val length validator with value within the min and max length range', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired data-val length validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > length', () => { + + it('should return the validityState false for data-val length validator with value greater than max length', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val length validator with value within the min and max length range', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired data-val length validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/max.js b/packages/validate/__tests__/jest/validator/max.js similarity index 97% rename from packages/validate/__tests__/integration/validator/max.js rename to packages/validate/__tests__/jest/validator/max.js index a350c23a..0e693bc7 100644 --- a/packages/validate/__tests__/integration/validator/max.js +++ b/packages/validate/__tests__/jest/validator/max.js @@ -1,118 +1,118 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > max', () => { - - it('should return the validityState false for HTML5 max validator with value greater than max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for data-val max validator with value greater than max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for HTML5 max validator with value less than or equal to max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for data-val max validator with value less or equal to max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for HTML5 max validator with a non-numeric value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for data-val max validator with a non-numeric value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for unrequired HTML5 max validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired data-val max validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > max', () => { + + it('should return the validityState false for HTML5 max validator with value greater than max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for data-val max validator with value greater than max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for HTML5 max validator with value less than or equal to max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for data-val max validator with value less or equal to max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for HTML5 max validator with a non-numeric value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for data-val max validator with a non-numeric value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for unrequired HTML5 max validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired data-val max validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/maxlength.js b/packages/validate/__tests__/jest/validator/maxlength.js similarity index 97% rename from packages/validate/__tests__/integration/validator/maxlength.js rename to packages/validate/__tests__/jest/validator/maxlength.js index aa4270e7..cf6919da 100644 --- a/packages/validate/__tests__/integration/validator/maxlength.js +++ b/packages/validate/__tests__/jest/validator/maxlength.js @@ -1,89 +1,89 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > maxlength', () => { - - it('should return the validityState false for data-val maxlength validator with value length greater than maxlength', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val maxlength validator with value length less than the max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired data-val maxlength validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for HTML5 maxlength validator with value length greater than max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for HTML5 maxlength validator with value length less than max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired HTML5 maxlength validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > maxlength', () => { + + it('should return the validityState false for data-val maxlength validator with value length greater than maxlength', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val maxlength validator with value length less than the max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired data-val maxlength validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for HTML5 maxlength validator with value length greater than max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for HTML5 maxlength validator with value length less than max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired HTML5 maxlength validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/min.js b/packages/validate/__tests__/jest/validator/min.js similarity index 97% rename from packages/validate/__tests__/integration/validator/min.js rename to packages/validate/__tests__/jest/validator/min.js index 068a5d51..ff240091 100644 --- a/packages/validate/__tests__/integration/validator/min.js +++ b/packages/validate/__tests__/jest/validator/min.js @@ -1,105 +1,105 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > min', () => { - - it('should return the validityState false for HTML5 min validator with value less than min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for data-val min validator with value less than min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - - it('should return the validityState true for HTML5 min validator with value greater than min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val min validator with value greater than min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val min validator with a non-numeric value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for unrequired HTML5 min validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired data-val min validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > min', () => { + + it('should return the validityState false for HTML5 min validator with value less than min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for data-val min validator with value less than min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + + it('should return the validityState true for HTML5 min validator with value greater than min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val min validator with value greater than min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val min validator with a non-numeric value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for unrequired HTML5 min validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired data-val min validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/minlength.js b/packages/validate/__tests__/jest/validator/minlength.js similarity index 97% rename from packages/validate/__tests__/integration/validator/minlength.js rename to packages/validate/__tests__/jest/validator/minlength.js index f46570e5..d2c98d5a 100644 --- a/packages/validate/__tests__/integration/validator/minlength.js +++ b/packages/validate/__tests__/jest/validator/minlength.js @@ -1,89 +1,89 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > minlength', () => { - - it('should return the validityState false for data-val minlength validator with value length less than minlength', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val minlength validator with value length greater than the min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired data-val minlength validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for HTML5 minlength validator with value length less than min length', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for HTML5 minlength validator with value length greater than min length', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for unrequired HTML5 minlength validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > minlength', () => { + + it('should return the validityState false for data-val minlength validator with value length less than minlength', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val minlength validator with value length greater than the min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired data-val minlength validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for HTML5 minlength validator with value length less than min length', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for HTML5 minlength validator with value length greater than min length', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for unrequired HTML5 minlength validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/number.js b/packages/validate/__tests__/jest/validator/number.js similarity index 97% rename from packages/validate/__tests__/integration/validator/number.js rename to packages/validate/__tests__/jest/validator/number.js index ad6913bf..a1a459cd 100644 --- a/packages/validate/__tests__/integration/validator/number.js +++ b/packages/validate/__tests__/jest/validator/number.js @@ -1,88 +1,88 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > number', () => { - - it('should return the validityState true for HTML5 number validator with a number', async () => { - expect.assertions(2); - document.body.innerHTML = ` - `; - const input1 = document.querySelector('#group1'); - const group1 = assembleValidationGroup({}, input1).group1; - const input2 = document.querySelector('#group2'); - const group2 = assembleValidationGroup({}, input2).group2; - expect(await validate(group1, group1.validators[0])).toEqual(true); - expect(await validate(group2, group2.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty HTML5 number validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val number validator with non-number', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val number validator with a number', async () => { - expect.assertions(2); - document.body.innerHTML = ``; - const input1 = document.querySelector('#group1'); - const group1 = assembleValidationGroup({}, input1).group1; - const input2 = document.querySelector('#group2'); - const group2 = assembleValidationGroup({}, input2).group2; - expect(await validate(group1, group1.validators[0])).toEqual(true); - expect(await validate(group2, group2.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty data-val number validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > number', () => { + + it('should return the validityState true for HTML5 number validator with a number', async () => { + expect.assertions(2); + document.body.innerHTML = ` + `; + const input1 = document.querySelector('#group1'); + const group1 = assembleValidationGroup({}, input1).group1; + const input2 = document.querySelector('#group2'); + const group2 = assembleValidationGroup({}, input2).group2; + expect(await validate(group1, group1.validators[0])).toEqual(true); + expect(await validate(group2, group2.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty HTML5 number validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val number validator with non-number', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val number validator with a number', async () => { + expect.assertions(2); + document.body.innerHTML = ``; + const input1 = document.querySelector('#group1'); + const group1 = assembleValidationGroup({}, input1).group1; + const input2 = document.querySelector('#group2'); + const group2 = assembleValidationGroup({}, input2).group2; + expect(await validate(group1, group1.validators[0])).toEqual(true); + expect(await validate(group2, group2.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty data-val number validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/range.js b/packages/validate/__tests__/jest/validator/range.js similarity index 97% rename from packages/validate/__tests__/integration/validator/range.js rename to packages/validate/__tests__/jest/validator/range.js index 62aeeffb..0a97a565 100644 --- a/packages/validate/__tests__/integration/validator/range.js +++ b/packages/validate/__tests__/jest/validator/range.js @@ -1,113 +1,113 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > range', () => { - - it('should return the validityState false for data-val range validator with value outside the specified range', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val range validator with value inside the specified range', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for an unrequired data-val range validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for data-val range validator with value > min with no max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val range validator with value <= min with no max', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val range validator with value <= max with no min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val range validator with value > max with no min', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > range', () => { + + it('should return the validityState false for data-val range validator with value outside the specified range', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val range validator with value inside the specified range', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for an unrequired data-val range validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for data-val range validator with value > min with no max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val range validator with value <= min with no max', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val range validator with value <= max with no min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val range validator with value > max with no min', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/regex-pattern.js b/packages/validate/__tests__/jest/validator/regex-pattern.js similarity index 97% rename from packages/validate/__tests__/integration/validator/regex-pattern.js rename to packages/validate/__tests__/jest/validator/regex-pattern.js index 8bed4169..b4910ea5 100644 --- a/packages/validate/__tests__/integration/validator/regex-pattern.js +++ b/packages/validate/__tests__/jest/validator/regex-pattern.js @@ -1,88 +1,88 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > regex/pattern', () => { - it('should return the validityState false for HTML5 pattern validator with non-matching value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for HTML5 pattern validator with matching value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty HTML5 pattern validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val regex validator with non-matching value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val regex validator with a matching value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty data-val pattern validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > regex/pattern', () => { + it('should return the validityState false for HTML5 pattern validator with non-matching value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for HTML5 pattern validator with matching value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty HTML5 pattern validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val regex validator with non-matching value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val regex validator with a matching value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty data-val pattern validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/remote.js b/packages/validate/__tests__/jest/validator/remote.js similarity index 97% rename from packages/validate/__tests__/integration/validator/remote.js rename to packages/validate/__tests__/jest/validator/remote.js index 7faece60..010222f9 100644 --- a/packages/validate/__tests__/integration/validator/remote.js +++ b/packages/validate/__tests__/jest/validator/remote.js @@ -1,66 +1,66 @@ -import mock from 'xhr-mock'; -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > remote', () => { - - beforeEach(() => mock.setup()); - - afterEach(() => mock.teardown()); - - it('should return the validityState false for data-val remote validator with a failed remote validation', async () => { - expect.assertions(1); - - mock.post('/api/validate', { - status: 201, - body: 'false' - }); - document.body.innerHTML = ` - `; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - const res = await validate(group, group.validators[0]); - expect(res).toEqual('false'); - }); - - it('should return the validityState true for data-val remote validator with a passed remote validation', async () => { - expect.assertions(1); - - mock.post('/api/validate', { - status: 201, - body: 'true' - }); - document.body.innerHTML = ` - `; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - const res = await validate(group, group.validators[0]); - expect(res).toEqual('true'); - }); - +import mock from 'xhr-mock'; +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > remote', () => { + + beforeEach(() => mock.setup()); + + afterEach(() => mock.teardown()); + + it('should return the validityState false for data-val remote validator with a failed remote validation', async () => { + expect.assertions(1); + + mock.post('/api/validate', { + status: 201, + body: 'false' + }); + document.body.innerHTML = ` + `; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + const res = await validate(group, group.validators[0]); + expect(res).toEqual('false'); + }); + + it('should return the validityState true for data-val remote validator with a passed remote validation', async () => { + expect.assertions(1); + + mock.post('/api/validate', { + status: 201, + body: 'true' + }); + document.body.innerHTML = ` + `; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + const res = await validate(group, group.validators[0]); + expect(res).toEqual('true'); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/required.js b/packages/validate/__tests__/jest/validator/required.js similarity index 97% rename from packages/validate/__tests__/integration/validator/required.js rename to packages/validate/__tests__/jest/validator/required.js index 9b127389..a8317375 100644 --- a/packages/validate/__tests__/integration/validator/required.js +++ b/packages/validate/__tests__/jest/validator/required.js @@ -1,106 +1,106 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > assembleValidationGroup > required', () => { - it('should return the validation group for HTML5 required validator', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1-1'); - const group = [input].reduce(assembleValidationGroup, {}); - expect(group).toEqual({ - group1: { - valid: false, - validators: [{ type: 'required' }], - fields: [input], - serverErrorNode: false - } - }); - }); -}); - -describe('Validate > Integration > validator > required', () => { - it('should return the validityState false for HTML5 required validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for HTML5 required validator with no value other than whitespace', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for HTML5 required validator with a value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for data-val required validator with no value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for data-val required validator with no value but whitespace', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for data-val required validator with a value', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > assembleValidationGroup > required', () => { + it('should return the validation group for HTML5 required validator', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1-1'); + const group = [input].reduce(assembleValidationGroup, {}); + expect(group).toEqual({ + group1: { + valid: false, + validators: [{ type: 'required' }], + fields: [input], + serverErrorNode: false + } + }); + }); +}); + +describe('Validate > Integration > validator > required', () => { + it('should return the validityState false for HTML5 required validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for HTML5 required validator with no value other than whitespace', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for HTML5 required validator with a value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for data-val required validator with no value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for data-val required validator with no value but whitespace', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for data-val required validator with a value', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/stringlength.js b/packages/validate/__tests__/jest/validator/stringlength.js similarity index 97% rename from packages/validate/__tests__/integration/validator/stringlength.js rename to packages/validate/__tests__/jest/validator/stringlength.js index b262852d..0d30cdc4 100644 --- a/packages/validate/__tests__/integration/validator/stringlength.js +++ b/packages/validate/__tests__/jest/validator/stringlength.js @@ -1,50 +1,50 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > stringlength', () => { - - it('should return the validityState false for data-val stringlength validator with value greater than max length', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for non-required empty data-val stringlength validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for data-val stringlength validator with value less than max length', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > stringlength', () => { + + it('should return the validityState false for data-val stringlength validator with value greater than max length', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for non-required empty data-val stringlength validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for data-val stringlength validator with value less than max length', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + }); \ No newline at end of file diff --git a/packages/validate/__tests__/integration/validator/url.js b/packages/validate/__tests__/jest/validator/url.js similarity index 97% rename from packages/validate/__tests__/integration/validator/url.js rename to packages/validate/__tests__/jest/validator/url.js index 3f643dff..79418891 100644 --- a/packages/validate/__tests__/integration/validator/url.js +++ b/packages/validate/__tests__/jest/validator/url.js @@ -1,71 +1,71 @@ -import { validate, assembleValidationGroup } from '../../../src/lib/validator'; - -describe('Validate > Integration > validator > url', () => { - //html5 spec regex approximation: - ///^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? - it('should return the validityState false for HTML5 url validator with non-spec url', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState false for data-val url validator with non-spec url', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(false); - }); - - it('should return the validityState true for non-required empty HTML5 url validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState true for non-required empty data-val url validator field', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - it('should return the validityState false for HTML5 url validator with an on-spec url', async () => { - expect.assertions(1); - document.body.innerHTML = ``; - const input = document.querySelector('#group1'); - const group = assembleValidationGroup({}, input).group1; - expect(await validate(group, group.validators[0])).toEqual(true); - }); - - +import { validate, assembleValidationGroup } from '../../../src/lib/validator'; + +describe('Validate > Integration > validator > url', () => { + //html5 spec regex approximation: + ///^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))? + it('should return the validityState false for HTML5 url validator with non-spec url', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState false for data-val url validator with non-spec url', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(false); + }); + + it('should return the validityState true for non-required empty HTML5 url validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState true for non-required empty data-val url validator field', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + it('should return the validityState false for HTML5 url validator with an on-spec url', async () => { + expect.assertions(1); + document.body.innerHTML = ``; + const input = document.querySelector('#group1'); + const group = assembleValidationGroup({}, input).group1; + expect(await validate(group, group.validators[0])).toEqual(true); + }); + + }); \ No newline at end of file diff --git a/packages/validate/__tests__/playwright/accessibility.spec.js b/packages/validate/__tests__/playwright/accessibility.spec.js new file mode 100644 index 00000000..9da718c7 --- /dev/null +++ b/packages/validate/__tests__/playwright/accessibility.spec.js @@ -0,0 +1,66 @@ +const { test, expect } = require('@playwright/test'); +import AxeBuilder from '@axe-core/playwright'; + +test.beforeEach(async ({ page }) => { + await page.goto('/'); +}); + +test.describe('Validate > Accessibility > Axe', { tag: '@reduced'}, () => { + test('Should not have any automatically detectable accessibility issues', async ({ page }) => { + let accessibilityScanResults = await new AxeBuilder({ page }).analyze(); + expect(accessibilityScanResults.violations).toEqual([]); + + await page.click('#submitTest'); + accessibilityScanResults = await new AxeBuilder({ page }).analyze(); + expect(accessibilityScanResults.violations).toEqual([]); + + await page.goto('/mini-no-server-errors.html'); + accessibilityScanResults = await new AxeBuilder({ page }).analyze(); + expect(accessibilityScanResults.violations).toEqual([]); + + await page.click('#submitTest'); + accessibilityScanResults = await new AxeBuilder({ page }).analyze(); + expect(accessibilityScanResults.violations).toEqual([]); + }); +}); + +test.describe('Validate > Accessibility > focus', { tag: '@all'}, () => { + test('Should focus on the first invalid field in a form post-validation', async ({ page }) => { + await page.goto('/mini.html'); + await page.click('#submitTest'); + const fNameInput = page.locator('#fname'); + await expect(fNameInput).toBeFocused(); + }); +}); + +test.describe('Validate > Accessibility > Aria', { tag: '@all'}, () => { + test('Should add an aria required attribute to improve accessibility', async ({ page }) => { + await page.goto('/mini.html'); + const fNameInput = page.locator('#fname'); + const lNameInput = page.locator('#lname'); + await expect(lNameInput).toHaveAttribute('aria-required', 'true'); + await expect(fNameInput).toHaveAttribute('aria-required', 'true'); + }); + + test('Should NOT add an aria required attribute to radio buttons', async ({ page }) => { + await page.goto('/'); + const radioInput = await page.locator('[name="radio"]').all(); + for (const radio of radioInput) { + await expect(radio).not.toHaveAttribute('aria-required', 'true'); + } + }); + + test('Should NOT add an aria required attribute to multiple checkboxes', async ({ page }) => { + await page.goto('/'); + const checkboxInput = await page.locator('[name="opts"]').all(); + for (const checkbox of checkboxInput) { + await expect(checkbox).not.toHaveAttribute('aria-required', 'true'); + } + }); + + test('Should add an aria required attribute to single checkboxes', async ({ page }) => { + await page.goto('/'); + const termsConditions = page.locator('[name="tcs"]'); + await expect(termsConditions).toHaveAttribute('aria-required', 'true'); + }); +}); \ No newline at end of file diff --git a/packages/validate/__tests__/playwright/errors.spec.js b/packages/validate/__tests__/playwright/errors.spec.js new file mode 100644 index 00000000..19bbf7fa --- /dev/null +++ b/packages/validate/__tests__/playwright/errors.spec.js @@ -0,0 +1,175 @@ +const { test, expect } = require('@playwright/test'); +import { DOTNET_CLASSNAMES } from '../../src/lib/constants'; + +test.beforeEach(async ({ page }) => { + await page.goto('/'); +}); + + +test.describe('Validate > Errors > Render errors', { tag: '@all'}, () => { + + test('Should add a client side error message container if no server container exists', async ({ page }) => { + await page.goto('/mini-no-server-errors.html'); + await expect(page.locator("#fname-error-message")).toHaveCount(0); + await expect(page.locator("#lname-error-message")).toHaveCount(0); + + await page.fill("#fname", "John"); + await page.click("#submitTest"); + + await expect(page.locator("#fname-error-message")).toHaveCount(0); + await expect(page.locator("#lname-error-message")).toHaveCount(1); + + const message = await page.evaluate(() => document.querySelector("#lname").getAttribute("data-val-required")); + await expect(page.locator("#lname-error-message")).toHaveText(message); + await expect(page.locator("#lname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#lname")).toHaveAttribute("aria-describedby", "lname-error-message"); + await expect(page.locator("//*[@id='lname']//parent::div")).toHaveClass(/is--invalid/); + + }); + + test('Should add a client side error message container as the next sibling of the associated label', async ({ page }) => { + await page.goto('/mini-no-server-errors.html'); + await page.click("#submitTest"); + const errorContainer = page.locator("[for='fname'] + *"); + expect(errorContainer).not.toBeNull(); + await expect(errorContainer).toHaveClass(new RegExp(`^${DOTNET_CLASSNAMES.ERROR}$`)); + await expect(errorContainer).toHaveAttribute("id", "fname-error-message"); + }); + + test('Should add an error message text node to a serverErrorNode, and attributes to reflect invalidity', async ({ page }) => { + + await page.goto('/mini.html'); + await expect(page.locator("[data-valmsg-for='fname']")).toHaveCount(1); + await expect(page.locator("[data-valmsg-for='lname']")).toHaveCount(1); + + const message1 = await page.evaluate(() => document.querySelector("#fname").getAttribute("data-val-required")); + const message2 = await page.evaluate(() => document.querySelector("#lname").getAttribute("data-val-required")); + + await page.click("#submitTest"); + + await expect(page.locator("[data-valmsg-for='fname']")).toHaveText(message1); + await expect(page.locator("[data-valmsg-for='lname']")).toHaveText(message2); + + await expect(page.locator("#fname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#fname")).toHaveAttribute("aria-describedby", "fname-error-message"); + await expect(page.locator("//*[@id='fname']//parent::div")).toHaveClass(/is--invalid/); + + await expect(page.locator("#lname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#lname")).toHaveAttribute("aria-describedby", "lname-error-message"); + await expect(page.locator("//*[@id='lname']//parent::div")).toHaveClass(/is--invalid/); + }); + + test('Should replace text inside an error node completely, if text already exists', async ({ page }) => { + await page.goto('/mini.html'); + + const lnameErrorNode = page.locator("[data-valmsg-for='lname']"); + await expect(lnameErrorNode).toHaveCount(1); + await expect(lnameErrorNode).toHaveText("Existing server error"); + + const message1 = await page.evaluate(() => document.querySelector("#lname").getAttribute("data-val-required")); + await page.click("#submitTest"); + await expect(lnameErrorNode).toHaveText(message1); + }); +}); + +test.describe('Validate > Errors > Clear errors', { tag: '@all'}, () => { + + test('Should empty a server-side rendered errorNode container, remove invalid classNames and aria', async ({ page }) => { + + await page.goto('/mini.html'); + await page.click("#submitTest"); + + const fnameErrorNode = page.locator("[data-valmsg-for='fname']"); + const lnameErrorNode = page.locator("[data-valmsg-for='lname']"); + + const message1 = await page.evaluate(() => document.querySelector("#fname").getAttribute("data-val-required")); + const message2 = await page.evaluate(() => document.querySelector("#lname").getAttribute("data-val-required")); + + await expect(fnameErrorNode).toHaveCount(1); + await expect(lnameErrorNode).toHaveCount(1); + + await expect(fnameErrorNode).toHaveText(message1); + await expect(lnameErrorNode).toHaveText(message2); + await expect(page.locator("#fname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#fname")).toHaveAttribute("aria-describedby", "fname-error-message"); + await expect(page.locator("//*[@id='fname']//parent::div")).toHaveClass(/is--invalid/); + await expect(page.locator("#lname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#lname")).toHaveAttribute("aria-describedby", "lname-error-message"); + await expect(page.locator("//*[@id='lname']//parent::div")).toHaveClass(/is--invalid/); + + await page.fill("#fname", "John"); + await page.fill("#lname", "Smith"); + + await expect(fnameErrorNode).toBeEmpty(); + await expect(lnameErrorNode).toBeEmpty(); + await expect(page.locator("#fname")).not.toHaveAttribute("aria-invalid"); + await expect(page.locator("#fname")).not.toHaveAttribute("aria-describedby"); + await expect(page.locator("//*[@id='fname']//parent::div")).not.toHaveClass(/is--invalid/); + await expect(page.locator("#lname")).not.toHaveAttribute("aria-invalid"); + await expect(page.locator("#lname")).not.toHaveAttribute("aria-describedby"); + await expect(page.locator("//*[@id='lname']//parent::div")).not.toHaveClass(/is--invalid/); + }); + + test('Should remove a client-side error node when valid', async ({ page }) => { + + await page.goto('/mini-no-server-errors.html'); + + await expect(page.locator("#fname-error-message")).toHaveCount(0); + await expect(page.locator("#lname-error-message")).toHaveCount(0); + + await page.click("#submitTest"); + + await expect(page.locator("#fname-error-message")).toHaveCount(1); + await expect(page.locator("#lname-error-message")).toHaveCount(1); + + await page.fill("#fname", "John"); + await page.fill("#lname", "Smith"); + + await expect(page.locator("#fname-error-message")).toHaveCount(0); + await expect(page.locator("#lname-error-message")).toHaveCount(0); + }); + + test('Should remove the aria-describedby attribute relating to the error, but preserve other aria-describedby values', async ({ page }) => { + await page.goto('/mini-no-server-errors.html'); + await page.evaluate(() => { + const fname = document.getElementById('fname'); + const lname = document.getElementById('lname'); + const title = document.createElement('h2'); + title.id = "form-title"; + title.innerText = "Title"; + fname.setAttribute('aria-describedby', 'form-title'); + lname.setAttribute('aria-describedby', 'form-title'); + fname.parentNode.insertBefore(title, fname); + }); + + await page.click("#submitTest"); + + await expect(page.locator("#fname")).toHaveAttribute("aria-describedby", "form-title fname-error-message"); + await expect(page.locator("#lname")).toHaveAttribute("aria-describedby", "form-title lname-error-message"); + + await page.fill("#fname", "John"); + await page.fill("#lname", "Smith"); + + await expect(page.locator("#fname")).toHaveAttribute("aria-describedby", "form-title"); + await expect(page.locator("#lname")).toHaveAttribute("aria-describedby", "form-title"); + + }); + +}); + +test.describe('Validate > Errors > Error message tokens', { tag: '@all'}, () => { + + test('Should return an error message string containing the input value if the {{value}} token is found in the error message', async ({ page }) => { + await page.fill("#email", "test"); + await page.click("#submitTest"); + await expect(page.locator("#email-error-message")).toHaveText("test is not a valid email address"); + }); + + test('Should return an error message with a comma delimited string of values if more than one field is in a group', async ({ page }) => { + await page.fill("#group1", "test"); + await page.fill("#group2", "test2"); + await page.click("#submitTest"); + await expect(page.locator("#group1-error-message")).toHaveText("test, test2 are not valid inputs"); + }); + +}); diff --git a/packages/validate/__tests__/playwright/post-validation.spec.js b/packages/validate/__tests__/playwright/post-validation.spec.js new file mode 100644 index 00000000..5e7cafda --- /dev/null +++ b/packages/validate/__tests__/playwright/post-validation.spec.js @@ -0,0 +1,111 @@ +const { test, expect } = require("@playwright/test"); + +test.beforeEach(async ({ page }) => { + await page.goto("/"); +}); + +test.describe("Validate > Post-validation", { tag: "@all" }, () => { + test("Should add correct user input to the form data if the form is valid", async ({ page }) => { + let capturedParams = null; + let routeResolve; + const routePromise = new Promise((resolve) => { + routeResolve = resolve; + }); + await page.route("**/test", async (route, request) => { + const postData = request.postData(); + const params = new URLSearchParams(postData); + capturedParams = params; + await route.fulfill({ status: 200, body: "OK" }); + routeResolve(); + }); + + await page.goto("/mini.html"); + await page.fill("#fname", "John"); + await page.fill("#lname", "Doe"); + await page.click("#submitTest"); + + await routePromise; + + expect(capturedParams).not.toBeNull(); + expect(capturedParams.get("fname")).toBe("John"); + expect(capturedParams.get("lname")).toBe("Doe"); + }); + + test("Should mutate the action attribute of the form if the submit button clicked has a formaction", async ({ page }) => { + let capturedParams = null; + let routeResolve; + const routePromise = new Promise((resolve) => { + routeResolve = resolve; + }); + await page.route("**/alternative", async (route, request) => { + const postData = request.postData(); + const params = new URLSearchParams(postData); + capturedParams = params; + await route.fulfill({ status: 200, body: "OK" }); + routeResolve(); + }); + + await page.goto("/mini.html"); + await page.locator("#submitTest").evaluate((button) => { + button.setAttribute("formaction", "/alternative"); + }); + await page.fill("#fname", "John"); + await page.fill("#lname", "Doe"); + await page.click("#submitTest"); + + await routePromise; + + expect(capturedParams).not.toBeNull(); + expect(capturedParams.get("fname")).toBe("John"); + expect(capturedParams.get("lname")).toBe("Doe"); + }); + + test("Should call the presubmit hook pre-submit", async ({ page }) => { + let capturedParams = null; + let routeResolve; + const routePromise = new Promise((resolve) => { + routeResolve = resolve; + }); + await page.route("**/test", async (route, request) => { + const postData = request.postData(); + const params = new URLSearchParams(postData); + capturedParams = params; + await route.fulfill({ status: 200, body: "OK" }); + routeResolve(); + }); + + await page.goto("/mini.html"); + await page.fill("#fname", "John"); + await page.fill("#lname", "Doe"); + await page.click("#submitTest"); + + await routePromise; + + expect(capturedParams).not.toBeNull(); + expect(capturedParams.get("hiddenCheck")).toBe("true"); + }); + + test("Should add hidden field duplicate of a button field, for conferring submit button values", async ({ page }) => { + let capturedParams = null; + let routeResolve; + const routePromise = new Promise((resolve) => { + routeResolve = resolve; + }); + await page.route("**/test", async (route, request) => { + const postData = request.postData(); + const params = new URLSearchParams(postData); + capturedParams = params; + await route.fulfill({ status: 200, body: "OK" }); + routeResolve(); + }); + + await page.goto("/mini.html"); + await page.fill("#fname", "John"); + await page.fill("#lname", "Doe"); + await page.click("#submitTest"); + + await routePromise; + expect(capturedParams).not.toBeNull(); + expect(capturedParams.get("submitTest")).toBe("checking"); + }); +}); diff --git a/packages/validate/__tests__/playwright/real-time.spec.js b/packages/validate/__tests__/playwright/real-time.spec.js new file mode 100644 index 00000000..7a056cda --- /dev/null +++ b/packages/validate/__tests__/playwright/real-time.spec.js @@ -0,0 +1,99 @@ +const { test, expect } = require('@playwright/test'); + +test.describe('Validate > Realtime validation', { tag: '@all'}, () => { + test('Should start real-time validation after first form submission', async ({ page }) => { + await page.goto("/"); + const emailInput = page.locator('#email'); + const emailErrorContainer = page.locator('[data-valmsg-for="email"]'); + await expect(emailErrorContainer).toBeEmpty(); + await expect(emailInput).not.toHaveAttribute('aria-invalid'); + await expect(emailInput).not.toHaveAttribute('aria-describedby'); + await expect(page.locator("//*[@id='email']//parent::div")).not.toHaveClass(/is--invalid/); + + await page.fill('#email', 'invalid-email'); + await expect(emailErrorContainer).toBeEmpty(); + await expect(emailInput).not.toHaveAttribute('aria-invalid'); + await expect(emailInput).not.toHaveAttribute('aria-describedby'); + await expect(page.locator("//*[@id='email']//parent::div")).not.toHaveClass(/is--invalid/); + + await page.click('#submitTest'); + await expect(emailErrorContainer).toHaveText('invalid-email is not a valid email address'); + await expect(emailInput).toHaveAttribute('aria-invalid'); + await expect(emailInput).toHaveAttribute('aria-describedby'); + await expect(page.locator("//*[@id='email']//parent::div")).toHaveClass(/is--invalid/); + + await page.fill('#email', 'test@test.com'); + await expect(emailErrorContainer).toBeEmpty(); + await expect(emailInput).not.toHaveAttribute('aria-invalid'); + await expect(emailInput).not.toHaveAttribute('aria-describedby'); + await expect(page.locator("//*[@id='email']//parent::div")).not.toHaveClass(/is--invalid/); + }); + + test('Should update error message on real-time input', async ({ page }) => { + await page.goto("/"); + const emailInput = page.locator('#email'); + const emailErrorContainer = page.locator('[data-valmsg-for="email"]'); + await expect(emailErrorContainer).toBeEmpty(); + await emailInput.fill('invalid-email'); + await page.click('#submitTest'); + await expect(emailErrorContainer).toHaveText('invalid-email is not a valid email address'); + await emailInput.clear(); + await expect(emailErrorContainer).toHaveText('Email must not be empty'); + await emailInput.fill('test@test.com'); + await expect(emailErrorContainer).toBeEmpty(); + }) + + test('Should update realtime on non-text input types', async ({ page }) => { + await page.goto("/"); + const selectBoxErrorContainer = page.locator('#selectexample-error-message'); + const checkboxErrorContainer = page.locator('#opts-error-message'); + const radioErrorContainer = page.locator('#radio-error-message'); + + const selectBox = page.locator('#selectexample'); + const checkbox1 = page.locator('#opt1'); + const radio1 = page.locator('#radio-1'); + + await page.click('#submitTest'); + + await expect(selectBoxErrorContainer).toHaveText('You must select an option'); + await expect(checkboxErrorContainer).toHaveText('Select at least one option'); + await expect(radioErrorContainer).toHaveText('Select an option'); + + await selectBox.selectOption('option1'); + await expect(selectBoxErrorContainer).toBeEmpty(); + + await checkbox1.check(); + await expect(checkboxErrorContainer).toBeEmpty(); + + await radio1.check(); + await expect(radioErrorContainer).toBeEmpty(); + + }); + + test('Should apply realtime validation to groups added later', async ({ page }) => { + + await page.goto("/"); + await page.evaluate(() => { + const newLabel = document.createElement('label'); + newLabel.textContent = 'New Input'; + newLabel.setAttribute('for', 'newinput'); + document.querySelector('form').appendChild(newLabel); + const newInput = document.createElement('input'); + newInput.setAttribute('type', 'text'); + newInput.setAttribute('id', 'newinput'); + newInput.setAttribute('name', 'newinput'); + newInput.setAttribute('data-val', 'true'); + newInput.setAttribute('data-val-required', 'New input is required'); + document.querySelector('form').appendChild(newInput); + window.validator.addGroup([newInput]); + }); + + await page.click('#submitTest'); + const newInputErrorContainer = page.locator('#newinput-error-message'); + const newInput = page.locator('#newinput'); + await expect(newInputErrorContainer).toHaveText('New input is required'); + await expect(newInput).toHaveAttribute('aria-invalid'); + await expect(newInput).toHaveAttribute('aria-describedby'); + await expect(page.locator("//*[@id='newinput']//parent::form")).toHaveClass(/is--invalid/); + }); +}); diff --git a/packages/validate/__tests__/playwright/reset.spec.js b/packages/validate/__tests__/playwright/reset.spec.js new file mode 100644 index 00000000..5e16341a --- /dev/null +++ b/packages/validate/__tests__/playwright/reset.spec.js @@ -0,0 +1,37 @@ +const { test, expect } = require('@playwright/test'); + +test.describe('Validate > Reset', { tag: '@all'}, () => { + test('Should reset the form errors when a reset event is dispached', async ({ page }) => { + await page.goto('/mini.html'); + + const fnameErrorNode = page.locator("[data-valmsg-for='fname']"); + const lnameErrorNode = page.locator("[data-valmsg-for='lname']"); + + const message1 = await page.evaluate(() => document.querySelector("#fname").getAttribute("data-val-required")); + const message2 = await page.evaluate(() => document.querySelector("#lname").getAttribute("data-val-required")); + + await expect(fnameErrorNode).toBeEmpty(); + await expect(lnameErrorNode).toHaveText('Existing server error'); + + await page.click('#submitTest'); + await expect(fnameErrorNode).toHaveText(message1); + await expect(lnameErrorNode).toHaveText(message2); + await expect(page.locator("#fname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#fname")).toHaveAttribute("aria-describedby", "fname-error-message"); + await expect(page.locator("//*[@id='fname']//parent::div")).toHaveClass(/is--invalid/); + await expect(page.locator("#lname")).toHaveAttribute("aria-invalid", "true"); + await expect(page.locator("#lname")).toHaveAttribute("aria-describedby", "lname-error-message"); + await expect(page.locator("//*[@id='lname']//parent::div")).toHaveClass(/is--invalid/); + + await page.click('#resetBtn'); + + await expect(fnameErrorNode).toBeEmpty(); + await expect(lnameErrorNode).toBeEmpty(); + await expect(page.locator("#fname")).not.toHaveAttribute("aria-invalid"); + await expect(page.locator("#fname")).not.toHaveAttribute("aria-describedby"); + await expect(page.locator("//*[@id='fname']//parent::div")).not.toHaveClass(/is--invalid/); + await expect(page.locator("#lname")).not.toHaveAttribute("aria-invalid"); + await expect(page.locator("#lname")).not.toHaveAttribute("aria-describedby"); + await expect(page.locator("//*[@id='lname']//parent::div")).not.toHaveClass(/is--invalid/); + }); +}); diff --git a/packages/validate/__tests__/unit/dom/errors.js b/packages/validate/__tests__/unit/dom/errors.js deleted file mode 100644 index 8e4caef0..00000000 --- a/packages/validate/__tests__/unit/dom/errors.js +++ /dev/null @@ -1,396 +0,0 @@ -import { - h, - clearError, - clearErrors, - renderError, - renderErrors, - updateMessageValues -} from '../../../src/lib/dom'; -import { DOTNET_CLASSNAMES } from '../../../src/lib/constants'; - -//clearError -describe('Validate > Unit > DOM > clearError', () => { - - it('should remove a client-side rendered errorNode container, remove invalid classNames and aria, and deletes the errorNode for the group from state', async () => { - document.body.innerHTML = ` -
- - - This field is required -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')) - } - }, - errors: { - group1: document.getElementById('test-error-node') - } - }; - //all side effects to test - clearError('group1')(mockState); - expect(document.getElementById('test-error-node')).toEqual(null); - expect(mockState.groups.group1.fields[0].classList.contains('is--invalid')).toEqual(false); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual(null); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual(null); - expect(mockState.errors.group1).toBeUndefined(); - }); - - it('should remove the aria-describedby attribute relating to the error, but preserve other aria-describedby values', async () => { - document.body.innerHTML = `
-

Title

-
- - - This field is required -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')) - } - }, - errors: { - group1: document.getElementById('test-error-node') - } - }; - clearError('group1')(mockState); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual('form-title'); - }); - - it('should remove a server-side rendered text node, toggle serverNode classNames, remove invalid classNames and aria, and deletes the errorNode for the group from state', async () => { - document.body.innerHTML = `
-
- - - -
-
`; - //have to create a text node and append it to the serverError node to test fn this in isolation - const errorNode = document.createTextNode('This field is required'); - const serverErrorNode = document.getElementById('test-server-error-node'); - serverErrorNode.appendChild(errorNode); - const mockState = { - groups: { - group1: { - serverErrorNode, - fields: Array.from(document.getElementsByName('group1')) - } - }, - errors: { - group1: errorNode - } - }; - - clearError('group1')(mockState); - expect(document.getElementById('test-server-error-node').firstElementChild).toEqual(null); - expect(mockState.groups.group1.fields[0].classList.contains('is--invalid')).toEqual(false); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual(null); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual(null); - expect(mockState.groups.group1.serverErrorNode.classList.contains(DOTNET_CLASSNAMES.ERROR)).toEqual(false); - expect(mockState.groups.group1.serverErrorNode.classList.contains(DOTNET_CLASSNAMES.VALID)).toEqual(true); - expect(mockState.groups.group1.serverErrorNode.getAttribute('role')).toEqual(null); - expect(mockState.errors.group1).toBeUndefined(); - }); -}); - -//clearErrors -describe('Validate > Unit > DOM > clearErrors', () => { - - it('should all errors and update DOM via clearError for each validation group', async () => { - document.body.innerHTML = `
-
- - - This field is required -
-
- - - This field is required -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')) - }, - group2: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group2')) - } - }, - errors: { - group1: document.getElementById('test-error-node-1'), - group2: document.getElementById('test-error-node-2') - } - }; - //all side effects to test - clearErrors(mockState); - expect(document.getElementById('test-error-node-1')).toEqual(null); - expect(mockState.groups.group1.fields[0].classList.contains('is--invalid')).toEqual(false); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual(null); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual(null); - expect(mockState.errors.group1).toBeUndefined(); - expect(document.getElementById('test-error-node-2')).toEqual(null); - expect(mockState.groups.group2.fields[0].classList.contains('is--invalid')).toEqual(false); - expect(mockState.groups.group2.fields[0].getAttribute('aria-invalid')).toEqual(null); - expect(mockState.groups.group2.fields[0].getAttribute('aria-describedby')).toEqual(null); - expect(mockState.errors.group2).toBeUndefined(); - }); - - it('should not change state if there are no errors', async () => { - document.body.innerHTML = `
-
- - -
-
- - -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')) - }, - group2: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group2')) - } - }, - errors: {} - }; - //all side effects to test - const copy = Object.assign({}, mockState); - clearErrors(mockState); - expect(copy).toEqual(mockState); - }); -}); - -//renderError -describe('Validate > Unit > DOM > renderError', () => { - - //add error message container client-side - it('Should add an error message container if there is no serverErrorNode, and attributes to reflect invalidity', async () => { - - document.body.innerHTML = `
- - -
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['This field is required'] - } - }, - errors: {} - }; - renderError('group1')(mockState); - const errorContainer = document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`); - expect(errorContainer).not.toBeUndefined(); - expect(errorContainer.textContent).toEqual('This field is required'); - expect(errorContainer.id).toEqual('group1-error-message'); - expect(mockState.groups.group1.fields[0].parentNode.classList.contains('is--invalid')).toEqual(true); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual('true'); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual(errorContainer.id); - }); - - //add error to serverErrorNode - it('Should add an error message text node to a serverErrorNode, and attributes to reflect invalidity', async () => { - - document.body.innerHTML = `
-

Test

- - - -
`; - const serverErrorNode = document.getElementById('test-server-error-node'); - const mockState = { - groups: { - group1: { - serverErrorNode, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['This field is required'] - } - }, - errors: {} - }; - renderError('group1')(mockState); - expect(serverErrorNode.textContent).toEqual('This field is required'); - expect(mockState.groups.group1.fields[0].parentNode.classList.contains('is--invalid')).toEqual(true); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual('true'); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual(`title ${serverErrorNode.id}`); - }); - - //remove existing error and add new one - it('Should remove existing server-side rendered error before adding new one', async () => { - - document.body.innerHTML = `
- - - -
`; - //have to create a text node and append it to the serverError node to test fn this in isolation - const errorNode = document.createTextNode('The server dislikes the valule of this field'); - const serverErrorNode = document.getElementById('test-server-error-node'); - serverErrorNode.appendChild(errorNode); - const mockState = { - groups: { - group1: { - serverErrorNode, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['This field is required'] - } - }, - errors: { - group1: errorNode - } - }; - renderError('group1')(mockState); - expect(serverErrorNode.textContent).toEqual('This field is required'); - expect(mockState.groups.group1.fields[0].parentNode.classList.contains('is--invalid')).toEqual(true); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual('true'); - expect(mockState.errors.group1).not.toEqual(errorNode); - }); -}); - -//renderErrors -describe('Validate > Unit > DOM > renderErrors', () => { - - - it('Should add error messages for every invalid group in state', async () => { - document.body.innerHTML = `
-
- - -
-
- - -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['This field is required'], - valid: false - }, - group2: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group2')), - errorMessages: [], - valid: true - } - }, - errors: {} - }; - renderErrors(mockState); - const errorContainer = document.querySelector(`.${DOTNET_CLASSNAMES.ERROR}`); - expect(errorContainer).not.toBeUndefined(); - expect(errorContainer.id).toEqual('group1-error-message'); - expect(errorContainer.textContent).toEqual('This field is required'); - expect(mockState.groups.group1.fields[0].parentNode.classList.contains('is--invalid')).toEqual(true); - expect(mockState.groups.group1.fields[0].getAttribute('aria-invalid')).toEqual('true'); - expect(mockState.groups.group2.fields[0].parentNode.classList.contains('is--invalid')).toEqual(false); - expect(mockState.groups.group2.fields[0].getAttribute('aria-invalid')).toEqual(null); - expect(mockState.groups.group1.fields[0].getAttribute('aria-describedby')).toEqual(errorContainer.id); - }); - -}); - - -//updateMessageValues -describe('Validate > Unit > DOM > updateMessageValues', () => { - - it('Should return an error message string containing the input value if the {{value}} token is found in the error message', async () => { - document.body.innerHTML = `
-
- - -
- -
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['{{value}} is not a valid email address'], - valid: false - } - }, - errors: {} - }; - let message = updateMessageValues(mockState, 'group1'); - expect(message).toEqual('test is not a valid email address'); - - }); - - it('Should return an error message with a comma delimited string of values if more than one field is in a group', async () => { - document.body.innerHTML = `
-
- - -
-
- - -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['{{value}} are not valid inputs'], - valid: false - } - }, - errors: {} - }; - let message = updateMessageValues(mockState, 'group1'); - expect(message).toEqual('test, test2 are not valid inputs'); - - }); - - it('Should leave the error message unchanged if the {{value}} token is not found', async () => { - document.body.innerHTML = `
-
- - -
-
- - -
-
`; - const mockState = { - groups: { - group1: { - serverErrorNode: false, - fields: Array.from(document.getElementsByName('group1')), - errorMessages: ['These are not valid inputs'], - valid: false - } - }, - errors: {} - }; - let message = updateMessageValues(mockState, 'group1'); - expect(message).toEqual('These are not valid inputs'); - - }); - -}); \ No newline at end of file diff --git a/packages/validate/__tests__/unit/dom/index.js b/packages/validate/__tests__/unit/dom/index.js deleted file mode 100644 index 1f571689..00000000 --- a/packages/validate/__tests__/unit/dom/index.js +++ /dev/null @@ -1,191 +0,0 @@ -import { - h, - createErrorTextNode, - focusFirstInvalidField, - createButtonValueNode, - addAXAttributes -} from '../../../src/lib/dom'; -import { DOTNET_CLASSNAMES } from '../../../src/lib/constants'; - -describe('Validate > Unit > DOM > h', () => { - - - it('should return a DOM node for given vNode arguments', async () => { - expect.assertions(1); - document.body.innerHTML = `
`; - expect(h('div', { class: 'test' })).toEqual(document.body.firstElementChild); - }); - - it('should return a DOM node for given vNode arguments with text nodes', async () => { - expect.assertions(1); - document.body.innerHTML = `
Lorem ipsum
`; - expect(h('div', { class: 'test' }, 'Lorem ipsum')).toEqual(document.body.firstElementChild); - }); - -}); - -//createErrorTextNode -describe('Validate > Unit > DOM > createErrorTextNode', () => { - - it('should append a child text node to a group serverErrorNode for a given invalid group', async () => { - expect.assertions(2); - document.body.innerHTML = `
- - - -
`; - const serverErrorNode = document.querySelector('[data-valmsg-for="group1"]'); - const mockGroup = { serverErrorNode }; - const errorMessage = 'This field is required'; - createErrorTextNode(mockGroup, errorMessage); - expect(serverErrorNode.textContent).toEqual('This field is required'); - expect(document.querySelector('[data-valmsg-for="group1"]').classList.contains(DOTNET_CLASSNAMES.ERROR)).toEqual(true); - }); - -}); - -//focusFirstInvalidField -describe('Validate > Unit > DOM > focusFirstInvalidField', () => { - it('should focus on the first invalid field in a form post-validation', async () => { - expect.assertions(1); - document.body.innerHTML = `
- - - - - - -
`; - const field = document.querySelector('#group2'); - const mockState = { - groups: { - group1: { - valid: true, - fields: [] - }, - group2: { - valid: false, - fields: [field] - } - } - }; - focusFirstInvalidField(mockState); - expect(document.activeElement).toEqual(field); - }); -}); - -//createButtonValueNode -describe('Validate > Unit > DOM > createButtonValueNode', () => { - it('should a hidden field duplicate of a given field, for conferring submit button values', async () => { - expect.assertions(3); - document.body.innerHTML = `
- -
`; - const node = document.getElementsByName('continue')[0]; - const form = document.querySelector('.form'); - createButtonValueNode(node, form); - const lastElement = form.lastElementChild; - expect(lastElement.tagName).toEqual('INPUT'); - expect(lastElement.getAttribute('name')).toEqual('continue'); - expect(lastElement.getAttribute('value')).toEqual('1'); - }); -}); - - -//addAXAttributes -describe('Validate > Unit > DOM > addAXAttributes', () => { - - it('should add attribute to the input and server-rendered error container to improve accessibility', async () => { - document.body.innerHTML = `
- - - -
`; - const field = document.getElementById('group1'); - const errorContainer = document.querySelector('[data-valmsg-for="group1"]'); - const state = { - groups: { - group1: { - serverErrorNode: errorContainer, - fields: [field] - } - } - }; - addAXAttributes(state); - //ensure error message has an id for aria-describedby - expect(errorContainer.getAttribute('id')).toEqual(`group1-error-message`); - //add aria-required=true to required and data-val-required fields - expect(field.getAttribute('aria-required')).toEqual(`true`); - }); - - it('should not add aria-required attribute to radio inputs', async () => { - // expect.assertions(3); - document.body.innerHTML = `
- - - -
`; - const field = document.getElementById('group1'); - const errorContainer = document.querySelector('[data-valmsg-for="group1"]'); - const state = { - groups: { - group1: { - serverErrorNode: errorContainer, - fields: [field] - } - } - }; - addAXAttributes(state); - expect(field.hasAttribute('aria-required')).toEqual(false); - }); - - - it('should not add aria-required attribute to multiple checkboxes', async () => { - document.body.innerHTML = `
- - - - - - - -
`; - const fields = Array.from(document.querySelectorAll('checkbox')); - const errorContainer = document.querySelector('[data-valmsg-for="group1"]'); - const state = { - groups: { - checkbox: { - serverErrorNode: errorContainer, - fields - } - } - }; - addAXAttributes(state); - fields.forEach(field => expect(field.hasAttribute('aria-required')).toEqual(false)); - - }); - - - //single checkbox - it('should add aria-required attribute to a single checkbox inputs', async () => { - // expect.assertions(3); - document.body.innerHTML = `
- - - -
`; - const field = document.getElementById('group1'); - const errorContainer = document.querySelector('[data-valmsg-for="group1"]'); - const state = { - groups: { - group1: { - serverErrorNode: errorContainer, - fields: [field] - } - } - }; - addAXAttributes(state); - expect(field.getAttribute('aria-required')).toEqual('true'); - }); - -}); \ No newline at end of file diff --git a/packages/validate/__tests__/unit/validator/post-validation.js b/packages/validate/__tests__/unit/validator/post-validation.js deleted file mode 100644 index d2efa429..00000000 --- a/packages/validate/__tests__/unit/validator/post-validation.js +++ /dev/null @@ -1,75 +0,0 @@ -import validate from '../../../src/'; - -//isSubmitButton -describe('Validate > Unit > postValidation', () => { - - it('should add name/value to the form data if the submit button clicked has a name and value', async () => { - document.body.innerHTML = `
- - - - -
`; - const form = document.querySelector('form'); - const mockSubmit = jest.fn(() => { - const data = new FormData(form); - let body = {}; - for (let kv of data.entries()) { - body[kv[0]] = kv[1]; - } - expect(body).toEqual({ tautology: 'value', continue: '1' }); - }); - const [ validator ] = validate(document.querySelector('form'), { submit: mockSubmit }); - // const submitBtn = document.querySelector('.submit-btn'); - const continueBtn = document.querySelector('.continue-btn'); - continueBtn.focus(); - await validator.validate({ - target: form, - preventDefault(){} - }); - expect(mockSubmit).toBeCalled(); - }); - - it('should mutate the action attribute of the form if the submit button clicked has a formaction', async () => { - document.body.innerHTML = `
- - - - -
`; - const form = document.querySelector('form'); - const mockSubmit = jest.fn(() => { - expect(form.getAttribute('action')).toEqual('/alternative'); - }); - const [ validator ] = validate(document.querySelector('form'), { submit: mockSubmit }); - // const submitBtn = document.querySelector('.submit-btn'); - const altBtn = document.querySelector('.alt-btn'); - altBtn.focus(); - await validator.validate({ - target: form, - preventDefault(){} - }); - expect(mockSubmit).toBeCalled(); - expect(form.getAttribute('action')).toEqual('/default'); - }); - - it('should call the presubmit hook pre-submit', async () => { - document.body.innerHTML = `
- - - -
`; - const form = document.querySelector('form'); - // const mockSubmit = jest.fn(); - const mockPreSubmit = jest.fn(); - const [ validator ] = validate(document.querySelector('form'), { - preSubmitHook: mockPreSubmit - }); - await validator.validate({ - target: form, - preventDefault(){} - }); - expect(mockPreSubmit).toBeCalled(); - }); - -}); \ No newline at end of file diff --git a/packages/validate/example/src/index.html b/packages/validate/example/src/index.html index 76f44b5e..81a50b6c 100644 --- a/packages/validate/example/src/index.html +++ b/packages/validate/example/src/index.html @@ -1,278 +1,762 @@ - - + + + StormID - - - - - - - - -
-
- Radios - -
- - -
-
- - -
-
- - -
-
- - -
-
-
- Checkboxes - -
- - -
-
- - -
-
- - -
-
- - -
-
-
- Checkbox - -
- - -
-
-
- - Date - - - - - -
- - - -
-
- -
- - + + + +
+

Validate example

+ +
+

All fields are required unless marked as optional.

+
+ +

Your details

+
+
+ + + +
+
+ + + +
+
+ + +
+
+ + + +
+
+ + + +
+
+
+ Your preferences +
Please tick at least one option below.
+ +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ Radios + +
+ + +
+
+ + +
+
+ + +
+
+ + +
+
+
+ + Date + + + + + +
+
+ + +
+
+ + +
+
+ + +
+
+
+
+ Testing grouped validation +
+ + +
+
+ + +
+
+
+ Terms and conditions +
+ + + +
+
+ +
+ + +
+ + + \ No newline at end of file diff --git a/packages/validate/example/src/js/index.js b/packages/validate/example/src/js/index.js index 638b035f..0352aabe 100644 --- a/packages/validate/example/src/js/index.js +++ b/packages/validate/example/src/js/index.js @@ -2,44 +2,39 @@ import validate from '../../../src'; import { isValidDate, isFutureDate, isPastDate } from '../../../src/lib/plugins/methods/date'; { - const [ validator ] = validate('form'); + const formToValidate = document.querySelector('.js-validate'); + const resetBtn = document.getElementById('resetBtn'); - validator.addMethod( - 'date', //name of custom validation group - isValidDate, // date validation method imported from the library - 'Enter a valid date', // error message - [ document.getElementById('dateDay'), document.getElementById('dateMonth'), document.getElementById('dateYear') ] //date fields array [day, month, year] - ); + if(resetBtn) resetBtn.addEventListener('click', () => { + const event = new Event('reset'); + formToValidate.dispatchEvent(event); + }); + + const [ validator ] = validate(formToValidate, { + preSubmitHook: () => { + const hiddenCheck = document.createElement('input'); + hiddenCheck.setAttribute('type', 'hidden'); + hiddenCheck.setAttribute('name', 'hiddenCheck'); + hiddenCheck.setAttribute('value', 'true'); + formToValidate.appendChild(hiddenCheck); + } + }); - validator.addMethod( - 'date', //name of custom validation group - isFutureDate, // date validation method imported from the library - 'Enter a valid date in the future', // error message - [ document.getElementById('dateDay'), document.getElementById('dateMonth'), document.getElementById('dateYear') ] //date fields array [day, month, year] - ); + if(document.getElementById('dateDay') && document.getElementById('dateMonth') && document.getElementById('dateYear')) { + validator.addMethod( + 'date', + isValidDate, + 'Enter a valid date', + [ document.getElementById('dateDay'), document.getElementById('dateMonth'), document.getElementById('dateYear') ] + ); - // const later = document.getElementById('Later'); - // document.querySelector('.js-add').addEventListener('click', e => { - // if (later.hasAttribute('required')) { - // later.removeAttribute('required'); - // validator[0].removeGroup(later.getAttribute('name')); - // } else { - // later.setAttribute('required', 'required'); - // validator[0].addGroup([later]); - // } - // }); - // const inputs = [ document.querySelector('#f1'), document.querySelector('#f2') ]; - // validator.addMethod( - // 'CustomGroup', - // (value, fields) => { - // console.log(value); - // console.log(inputs); - // return inputs[0].value.trim() === 'potato' || inputs[1].value.trim() === 'potato'; - // }, - // 'One of the inputs must be the word "potato"', - // inputs - // ); - - console.log(validator.getState()); + validator.addMethod( + 'date', + isFutureDate, + 'Enter a valid date in the future', + [ document.getElementById('dateDay'), document.getElementById('dateMonth'), document.getElementById('dateYear') ] + ); + } + window.validator = validator; }; \ No newline at end of file diff --git a/packages/validate/example/src/mini-no-server-errors.html b/packages/validate/example/src/mini-no-server-errors.html new file mode 100644 index 00000000..be490414 --- /dev/null +++ b/packages/validate/example/src/mini-no-server-errors.html @@ -0,0 +1,637 @@ + + + + + StormID + + + + +
+
+

All fields are required unless marked as optional.

+
+ +

Your details

+
+
+ + +
+
+ + +
+
+ +
+
+ + + \ No newline at end of file diff --git a/packages/validate/example/src/mini.html b/packages/validate/example/src/mini.html new file mode 100644 index 00000000..8e7b18ac --- /dev/null +++ b/packages/validate/example/src/mini.html @@ -0,0 +1,642 @@ + + + + + StormID + + + + +
+

Validate example

+ +
+

All fields are required unless marked as optional.

+
+ +

Your details

+
+
+ + + +
+
+ + Existing server error + +
+
+ + +
+
+ + + \ No newline at end of file diff --git a/packages/validate/package.json b/packages/validate/package.json index fe3092fd..e57ac058 100644 --- a/packages/validate/package.json +++ b/packages/validate/package.json @@ -27,9 +27,9 @@ ], "scripts": { "build": "microbundle --name Validate", - "test": "jest --coverage", - "dev": "webpack-dev-server --config example/webpack.config.js", - "prod": "webpack --config example/webpack.config.js --mode production", + "test": "jest --coverage & npx playwright test", + "dev": "webpack-dev-server --config tools/webpack.config.js", + "prod": "webpack --config tools/webpack.config.js --mode production", "prepublish": "npm run -s build" }, "gitHead": "946d630c5e4305c47fedab448cb135d95c7b03af" diff --git a/packages/validate/playwright.config.js b/packages/validate/playwright.config.js new file mode 100644 index 00000000..0968cfa7 --- /dev/null +++ b/packages/validate/playwright.config.js @@ -0,0 +1,16 @@ + +const { defineConfig } = require('@playwright/test'); +const baseConfig = require('../../tools/playwright/config.base.js'); +const server = require('./tools/playwright.webpack.config.js'); + +module.exports = defineConfig({ + ...baseConfig, + use: { + ...baseConfig.use, + baseURL: `http://localhost:${server.devServer.port}/`, + }, + webServer: { + ...baseConfig.webServer, + url: `http://localhost:${server.devServer.port}/`, + }, +}); \ No newline at end of file diff --git a/packages/validate/src/lib/validator/post-validation.js b/packages/validate/src/lib/validator/post-validation.js index 61ad8d69..c4efe536 100644 --- a/packages/validate/src/lib/validator/post-validation.js +++ b/packages/validate/src/lib/validator/post-validation.js @@ -12,23 +12,28 @@ export const postValidation = (event, resolve, store) => { const submit = () => { if (settings.submit) settings.submit(); else form.submit(); + + buttonValueNode && cleanupButtonValueNode(buttonValueNode); + cachedAction && form.setAttribute('action', cachedAction); }; - if (isSubmitButton(document.activeElement)) { - if (hasNameValue(document.activeElement)) { - buttonValueNode = createButtonValueNode(document.activeElement, form); + + const formSubmitButtons = Array.from(form.querySelectorAll('[type="submit"]')); + formSubmitButtons.forEach(formSubmitButton => { + if (hasNameValue(formSubmitButton)) { + buttonValueNode = createButtonValueNode(formSubmitButton, form); } - if (hasFormactionValue(document.activeElement)) { + if (hasFormactionValue(formSubmitButton)) { cachedAction = form.getAttribute('action'); - form.setAttribute('action', document.activeElement.getAttribute('formaction')); + form.setAttribute('action', formSubmitButton.getAttribute('formaction')); } - } + }); + if (event && event.target) { if (settings.preSubmitHook) { settings.preSubmitHook(); window.setTimeout(submit, PREHOOK_DELAY); } else submit(); } - buttonValueNode && cleanupButtonValueNode(buttonValueNode); - cachedAction && form.setAttribute('action', cachedAction); + return resolve(true); }; \ No newline at end of file diff --git a/packages/validate/tools/playwright.webpack.config.js b/packages/validate/tools/playwright.webpack.config.js new file mode 100644 index 00000000..f1f51782 --- /dev/null +++ b/packages/validate/tools/playwright.webpack.config.js @@ -0,0 +1,8 @@ +const baseConfig = require('./webpack.config'); + +module.exports = { + ...baseConfig, + devServer: { + port: 8092 + } +}; diff --git a/packages/validate/example/webpack.config.js b/packages/validate/tools/webpack.config.js similarity index 75% rename from packages/validate/example/webpack.config.js rename to packages/validate/tools/webpack.config.js index a2d72d75..57b23866 100644 --- a/packages/validate/example/webpack.config.js +++ b/packages/validate/tools/webpack.config.js @@ -22,6 +22,16 @@ module.exports = { title: pkg.name, template: './example/src/index.html', filename: 'index.html' + }), + new HtmlWebpackPlugin({ + title: pkg.name, + template: './example/src/mini.html', + filename: 'mini.html' + }), + new HtmlWebpackPlugin({ + title: pkg.name, + template: './example/src/mini-no-server-errors.html', + filename: 'mini-no-server-errors.html' }) ], module: { diff --git a/tools/playwright/config.base.js b/tools/playwright/config.base.js index c9c41a3b..120edecb 100644 --- a/tools/playwright/config.base.js +++ b/tools/playwright/config.base.js @@ -1,5 +1,7 @@ const { devices } = require('@playwright/test'); +// CURRENT MAX PORT NUMBER IN USE: 8092 + module.exports = { testDir: './__tests__/playwright', fullyParallel: true,