UNPKG

@defra-fish/gafl-webapp-service

Version:

The websales frontend for the GAFL service

293 lines (258 loc) • 10.3 kB
import Joi from 'joi' import { dateOfBirthValidator, startDateValidator, getDateErrorFlags, renewalStartDateValidator } from '../validators.js' import moment from 'moment-timezone' const dateSchema = require('../../date.schema.js') const setupMocks = () => { Joi.originalAssert = Joi.assert dateSchema.originalDateSchema = dateSchema.dateSchema dateSchema.originalDateSchemaInput = dateSchema.dateSchemaInput Joi.assert = jest.fn() dateSchema.dateSchema = Symbol('dateSchema') dateSchema.dateSchemaInput = jest.fn() } const tearDownMocks = () => { Joi.assert = Joi.originalAssert dateSchema.dateSchema = dateSchema.originalDateSchema dateSchema.dateSchemaInput = dateSchema.originalDateSchemaInput } describe('dateOfBirth validator', () => { beforeEach(jest.clearAllMocks) const getSamplePayload = ({ day = '', month = '', year = '' } = {}) => ({ 'date-of-birth-day': day, 'date-of-birth-month': month, 'date-of-birth-year': year }) it('throws an error for anyone over 120 years old', () => { const invalidDoB = moment().subtract(120, 'years').subtract(1, 'day') const samplePayload = getSamplePayload({ day: invalidDoB.format('DD'), month: invalidDoB.format('MM'), year: invalidDoB.format('YYYY') }) expect(() => dateOfBirthValidator(samplePayload)).toThrow() }) it('validates for anyone 120 years old', () => { const validDoB = moment().subtract(120, 'years') const samplePayload = getSamplePayload({ day: validDoB.format('DD'), month: validDoB.format('MM'), year: validDoB.format('YYYY') }) expect(() => dateOfBirthValidator(samplePayload)).not.toThrow() }) it.each([ ['today', moment()], ['tomorrow', moment().add(1, 'day')], ['in the future', moment().add(1, 'month')] ])('throws an error for a date of birth %s', (_desc, invalidDoB) => { const samplePayload = getSamplePayload({ day: invalidDoB.format('DD'), month: invalidDoB.format('MM'), year: invalidDoB.format('YYYY') }) expect(() => dateOfBirthValidator(samplePayload)).toThrow() }) it.each([ ['1-3-2004', '1', '3', '2004'], ['12-1-1999', '12', '1', '1999'], ['1-12-2006', '1', '12', '2006'] ])('handles single digit date %s', (_desc, day, month, year) => { const samplePayload = getSamplePayload({ day, month, year }) expect(() => dateOfBirthValidator(samplePayload)).not.toThrow() }) it.each([ ['01', '03', '1994'], ['10', '12', '2004'] ])('passes date of birth day (%s), month (%s) and year (%s) to dateSchemaInput', (day, month, year) => { setupMocks() dateOfBirthValidator(getSamplePayload({ day, month, year })) expect(dateSchema.dateSchemaInput).toHaveBeenCalledWith(day, month, year) tearDownMocks() }) it('passes dateSchemaInput output and dateSchema to Joi.assert', () => { setupMocks() const dsi = Symbol('dsi') dateSchema.dateSchemaInput.mockReturnValueOnce(dsi) dateOfBirthValidator(getSamplePayload()) expect(Joi.assert).toHaveBeenCalledWith(dsi, dateSchema.dateSchema) tearDownMocks() }) }) describe('startDate validator', () => { beforeEach(jest.clearAllMocks) const getSamplePayload = ({ day = '', month = '', year = '' } = {}) => ({ 'licence-start-date-day': day, 'licence-start-date-month': month, 'licence-start-date-year': year, 'licence-to-start': 'another-date' }) it('throws an error for a licence starting before today', () => { const invalidStartDate = moment().subtract(1, 'day') const samplePayload = getSamplePayload({ day: invalidStartDate.format('DD'), month: invalidStartDate.format('MM'), year: invalidStartDate.format('YYYY') }) expect(() => startDateValidator(samplePayload)).toThrow() }) it('throws an error for a licence starting more than 30 days hence', () => { const invalidStartDate = moment().add(31, 'days') const samplePayload = getSamplePayload({ day: invalidStartDate.format('DD'), month: invalidStartDate.format('MM'), year: invalidStartDate.format('YYYY') }) expect(() => startDateValidator(samplePayload)).toThrow() }) it('validates for a date within the next 30 days', () => { const validStartDate = moment().add(4, 'days') const samplePayload = getSamplePayload({ day: validStartDate.format('DD'), month: validStartDate.format('MM'), year: validStartDate.format('YYYY') }) expect(() => startDateValidator(samplePayload)).not.toThrow() }) it.each([ ['1-3-2024', moment('2024-02-28')], ['9-7-2024', moment('2024-07-08')] ])('handles single digit date %s', (date, now) => { jest.useFakeTimers() jest.setSystemTime(now.toDate()) const [day, month, year] = date.split('-') const samplePayload = getSamplePayload({ day, month, year }) expect(() => startDateValidator(samplePayload)).not.toThrow() jest.useRealTimers() }) it.each([ ['01', '03', '1994'], ['10', '12', '2004'] ])('passes start date day (%s), month (%s) and year (%s) to dateSchemaInput', (day, month, year) => { setupMocks() startDateValidator(getSamplePayload({ day, month, year })) expect(dateSchema.dateSchemaInput).toHaveBeenCalledWith(day, month, year) tearDownMocks() }) it('passes dateSchemaInput output and dateSchema to Joi.assert', () => { setupMocks() const dsi = Symbol('dsi') dateSchema.dateSchemaInput.mockReturnValueOnce(dsi) startDateValidator(getSamplePayload()) expect(Joi.assert).toHaveBeenCalledWith(dsi, dateSchema.dateSchema) tearDownMocks() }) it('passes validation if licence is set to start after payment', () => { const samplePayload = { 'licence-to-start': 'after-payment' } expect(() => startDateValidator(samplePayload)).not.toThrow() }) it('throws an error if licence-to-start is set to an invalid value', () => { const samplePayload = { 'licence-to-start': '12th-of-never' } expect(() => startDateValidator(samplePayload)).toThrow() }) }) describe('getErrorFlags', () => { it('sets all error flags to be false when there are no errors', () => { const result = getDateErrorFlags() expect(result).toEqual({ isDayError: false, isMonthError: false, isYearError: false }) }) it.each([ ['full-date', { isDayError: true, isMonthError: true, isYearError: true }], ['day-and-month', { isDayError: true, isMonthError: true, isYearError: false }], ['month-and-year', { isDayError: false, isMonthError: true, isYearError: true }], ['day-and-year', { isDayError: true, isMonthError: false, isYearError: true }], ['day', { isDayError: true, isMonthError: false, isYearError: false }], ['month', { isDayError: false, isMonthError: true, isYearError: false }], ['year', { isDayError: false, isMonthError: false, isYearError: true }], ['invalid-date', { isDayError: true, isMonthError: true, isYearError: true }], ['date-range', { isDayError: true, isMonthError: true, isYearError: true }], ['non-numeric', { isDayError: true, isMonthError: true, isYearError: true }] ])('when error is %s, should set %o in flags', (errorKey, expected) => { const error = { [errorKey]: 'anything.at.all' } const result = getDateErrorFlags(error) expect(result).toEqual(expect.objectContaining(expected)) }) }) describe('renewalStartDateValidator', () => { beforeEach(jest.clearAllMocks) const getSamplePayload = ({ day = '', month = '', year = '' } = {}) => ({ 'licence-start-date-day': day, 'licence-start-date-month': month, 'licence-start-date-year': year }) const renewedEndDate = moment() const options = { context: { app: { request: { permission: { renewedEndDate: renewedEndDate.toISOString() } } } } } it('throws an error for a licence starting before today', () => { const renewedDate = moment().subtract(1, 'day') const samplePayload = getSamplePayload({ day: renewedDate.format('DD'), month: renewedDate.format('MM'), year: renewedDate.format('YYYY') }) expect(() => renewalStartDateValidator(samplePayload, options)).toThrow() }) it('throws an error for a licence starting more than 30 days hence', () => { const renewedDate = moment().add(31, 'days') const samplePayload = getSamplePayload({ day: renewedDate.format('DD'), month: renewedDate.format('MM'), year: renewedDate.format('YYYY') }) expect(() => renewalStartDateValidator(samplePayload, options)).toThrow() }) it('validates for a date within the next 30 days', () => { const renewedDate = moment().add(4, 'days') const samplePayload = getSamplePayload({ day: renewedDate.format('DD'), month: renewedDate.format('MM'), year: renewedDate.format('YYYY') }) expect(() => renewalStartDateValidator(samplePayload, options)).not.toThrow() }) it.each([ ['01', '03', '1994'], ['10', '12', '2004'] ])('passes start date day (%s), month (%s) and year (%s) to dateSchemaInput', (day, month, year) => { setupMocks() renewalStartDateValidator(getSamplePayload({ day, month, year }), options) expect(dateSchema.dateSchemaInput).toHaveBeenCalledWith(day, month, year) tearDownMocks() }) it('passes dateSchemaInput output and dateSchema to Joi.assert', () => { setupMocks() const dsi = Symbol('dsi') dateSchema.dateSchemaInput.mockReturnValueOnce(dsi) renewalStartDateValidator(getSamplePayload(), options) expect(Joi.assert).toHaveBeenCalledWith(dsi, dateSchema.dateSchema) tearDownMocks() }) it('passes validation if licence is set to start after payment', () => { const samplePayload = getSamplePayload({ day: moment().format('DD'), month: moment().format('MM'), year: moment().format('YYYY') }) expect(() => renewalStartDateValidator(samplePayload, options)).not.toThrow() }) it('throws an error if licence-to-start is set to an invalid value', () => { const samplePayload = { 'licence-to-start': '12th-of-never' } expect(() => renewalStartDateValidator(samplePayload, options)).toThrow() }) })