@defra-fish/sales-api-service
Version:
Rod Licensing Sales API
224 lines (201 loc) • 8.54 kB
JavaScript
import { generatePermissionNumber, calculateEndDate, generate } from '../permissions.service.js'
import moment from 'moment'
import {
MOCK_12MONTH_SENIOR_PERMIT,
MOCK_1DAY_SENIOR_PERMIT_ENTITY,
MOCK_12MONTH_DISABLED_PERMIT,
MOCK_1DAY_FULL_PERMIT_ENTITY,
MOCK_CONCESSION
} from '../../__mocks__/test-data.js'
import { JUNIOR_MAX_AGE, SENIOR_MIN_AGE } from '@defra-fish/business-rules-lib'
jest.mock('@defra-fish/business-rules-lib', () => {
const brl = jest.requireActual('@defra-fish/business-rules-lib')
return {
...brl,
isSenior: jest.fn(brl.isSenior)
}
})
jest.mock('../reference-data.service.js', () => ({
...jest.requireActual('../reference-data.service.js'),
getReferenceDataForEntityAndId: async (entityType, id) => {
let item = null
if (entityType === MOCK_12MONTH_SENIOR_PERMIT.constructor) {
for (const permit of [
MOCK_12MONTH_DISABLED_PERMIT,
MOCK_12MONTH_SENIOR_PERMIT,
MOCK_1DAY_SENIOR_PERMIT_ENTITY,
MOCK_1DAY_FULL_PERMIT_ENTITY
]) {
if (permit.id === id) {
return permit
}
}
return null
} else if (entityType === MOCK_CONCESSION.constructor) {
item = MOCK_CONCESSION
}
return item
}
}))
const getSamplePermission = ({
permitId = MOCK_1DAY_FULL_PERMIT_ENTITY.id,
birthDate = moment().subtract(SENIOR_MIN_AGE, 'years').format('YYYY-MM-DD')
} = {}) => ({
permitId,
issueDate: moment().toISOString(),
startDate: moment().toISOString(),
licensee: {
firstName: 'Fester',
lastName: 'Tester',
birthDate
}
})
describe('permissions service', () => {
beforeEach(jest.clearAllMocks)
describe('generatePermissionNumber', () => {
describe('adult', () => {
it('generates a permission number for adults', async () => {
const number = await generatePermissionNumber(
getSamplePermission({
permitId: MOCK_12MONTH_DISABLED_PERMIT.id,
birthDate: moment()
.subtract(JUNIOR_MAX_AGE + 1, 'years')
.format('YYYY-MM-DD')
}),
'Telesales'
)
const block1 = moment().subtract(1, 'day').add(1, 'year').endOf('day').format('HHDDMMYY')
const expected = new RegExp(`^${block1}-1TS3FFT-[A-Z0-9]{5}[0-9]$`)
expect(number).toMatch(expected)
})
it('formats as F if startDate is on 17th birthday but issueDate is 1 week before', async () => {
const birthDate = moment().subtract(JUNIOR_MAX_AGE, 'years').format('YYYY-MM-DD')
const issueDate = moment(birthDate).add(JUNIOR_MAX_AGE, 'years').add(1, 'year').subtract(7, 'day').toISOString()
const startDate = moment(birthDate).add(JUNIOR_MAX_AGE, 'years').add(1, 'year').toISOString()
const number = await generatePermissionNumber(
{
...getSamplePermission({
permitId: MOCK_12MONTH_SENIOR_PERMIT.id,
birthDate
}),
startDate,
issueDate
},
'Web Sales'
)
expect(number).toMatch(/-[A-Z0-9]{4}F/)
})
})
describe('senior', () => {
it('generates a permission number for seniors', async () => {
const number = await generatePermissionNumber(getSamplePermission(), 'Web Sales')
const block1 = moment().add(1, 'hour').startOf('hour').add(1, 'day').format('HHDDMMYY')
const expected = new RegExp(`^${block1}-2WC1SFT-[A-Z0-9]{5}[0-9]$`)
expect(number).toMatch(expected)
})
it('formats as S if startDate is on 66th birthday but issueDate is 1 week before', async () => {
const birthDate = moment().subtract(SENIOR_MIN_AGE, 'years').format('YYYY-MM-DD')
const issueDate = moment(birthDate).add(SENIOR_MIN_AGE, 'years').subtract(7, 'day').toISOString()
const startDate = moment(birthDate).add(SENIOR_MIN_AGE, 'years').toISOString()
const number = await generatePermissionNumber(
{
...getSamplePermission({
permitId: MOCK_12MONTH_SENIOR_PERMIT.id,
birthDate
}),
startDate,
issueDate
},
'Web Sales'
)
expect(number).toMatch(/-[A-Z0-9]{4}S/)
})
})
describe('junior', () => {
it('generates a permission number for juniors', async () => {
const number = await generatePermissionNumber(
getSamplePermission({
birthDate: moment()
.subtract(JUNIOR_MAX_AGE - 1, 'years')
.format('YYYY-MM-DD')
}),
'Web Sales'
)
const block1 = moment().add(1, 'hour').startOf('hour').add(1, 'day').format('HHDDMMYY')
const expected = new RegExp(`^${block1}-2WC1JFT-[A-Z0-9]{5}[0-9]$`)
expect(number).toMatch(expected)
})
it('formats as J if startDate is on 16th birthday but issueDate is 1 week before', async () => {
const birthDate = moment().subtract(JUNIOR_MAX_AGE, 'years').format('YYYY-MM-DD')
const startDate = moment(birthDate).add(JUNIOR_MAX_AGE, 'years').toISOString()
const issueDate = moment(startDate).subtract(7, 'day').toISOString()
const number = await generatePermissionNumber(
{
...getSamplePermission({
permitId: MOCK_12MONTH_SENIOR_PERMIT.id,
birthDate
}),
startDate,
issueDate
},
'Web Sales'
)
expect(number).toMatch(/-[A-Z0-9]{4}J/)
})
})
})
describe('calculateEndDate', () => {
it('calculates 364 days for 1 year licences outside of a leap year', async () => {
const startDate = moment('2019-01-01')
const expectedEndDate = moment('2019-12-31').endOf('day')
const endDate = await calculateEndDate({ permitId: 'e11b34a0-0c66-e611-80dc-c4346bad0190', startDate: startDate })
expect(endDate).toEqual(expectedEndDate.toISOString())
})
it('calculates 365 days for 1 year licences in a leap year', async () => {
const startDate = moment('2020-01-01')
const expectedEndDate = moment('2020-12-31').endOf('day')
const endDate = await calculateEndDate({ permitId: 'e11b34a0-0c66-e611-80dc-c4346bad0190', startDate: startDate })
expect(endDate).toEqual(expectedEndDate.toISOString())
})
describe('when the licence starts and finishes during BST', () => {
it('finishes just before midnight in BST', async () => {
const startDate = moment('2020-06-01')
const expectedEndDate = moment.utc('2021-05-31').endOf('day').subtract(1, 'hours')
const endDate = await calculateEndDate({ permitId: 'e11b34a0-0c66-e611-80dc-c4346bad0190', startDate: startDate })
expect(endDate).toEqual(expectedEndDate.toISOString())
})
})
// In 2018, BST starts on 25 March. In 2019, BST starts on 31 March.
describe('when the licence starts during BST and finishes during GMT', () => {
it('finishes just before midnight in GMT', async () => {
const startDate = moment('2018-03-27')
const expectedEndDate = moment.utc('2019-03-26').endOf('day')
const endDate = await calculateEndDate({ permitId: 'e11b34a0-0c66-e611-80dc-c4346bad0190', startDate: startDate })
expect(endDate).toEqual(expectedEndDate.toISOString())
})
})
// In 2020, BST ends on 25 October. In 2021, BST ends on 31 October.
describe('when the licence starts during GMT and finishes during BST', () => {
it('finishes just before midnight in BST', async () => {
const startDate = moment('2020-10-26')
const expectedEndDate = moment.utc('2021-10-25').endOf('day').subtract(1, 'hours')
const endDate = await calculateEndDate({ permitId: 'e11b34a0-0c66-e611-80dc-c4346bad0190', startDate: startDate })
expect(endDate).toEqual(expectedEndDate.toISOString())
})
})
it('returns correct end date on leap year', async () => {
const startDate = moment('2024-02-29')
const endDate = await calculateEndDate({ permitId: 'e11b34a0-0c66-e611-80dc-c4346bad0190', startDate })
expect(endDate).toBe('2025-02-28T23:59:59.999Z')
})
})
describe('sequence generator', () => {
it('generates a rolling sequence', () => {
const results = []
for (let i = 0; i < 12; i++) {
results.push(generate(i, ['AB', '123']))
}
expect(results).toEqual(['A1', 'A2', 'A3', 'B1', 'B2', 'B3', 'A1', 'A2', 'A3', 'B1', 'B2', 'B3'])
})
})
})