-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
SIR-672: Initial work for service working hours (#89)
* Initial work for service working hours * test for service unavailable page * adding test coverage * github actions timezone * sonarcloud * test coverage increase * taking out commented code * adding some error logging for working hours * linting * adding some date logs * reject error for test coverage * fixing test * testing rejectUnauthorized to false with the bank holiday api * adding in minutes for working hours test just in case business want to use minutes
- Loading branch information
Showing
15 changed files
with
272 additions
and
12 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,6 +19,10 @@ jobs: | |
# See supported Node.js release schedule at https://nodejs.org/en/about/releases/ | ||
|
||
steps: | ||
- name: Set Timezone to London | ||
uses: szenius/[email protected] | ||
with: | ||
timezoneLinux: "Europe/London" | ||
- name: Checkout Repository | ||
uses: actions/checkout@v2 | ||
with: | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import { submitGetRequest } from '../../__test-helpers__/server.js' | ||
import constants from '../../utils/constants.js' | ||
jest.mock('../../utils/is-working-hours', () => ({ | ||
__esModule: true, | ||
default: jest.fn(() => Promise.resolve(false)) // outside of working hours | ||
})) | ||
const url = '/' | ||
|
||
describe(url, () => { | ||
describe('GET', () => { | ||
it('Should Redirect to service unavailable when outside of working hours', async () => { | ||
const response = await submitGetRequest({ url }, '', constants.statusCodes.REDIRECT) | ||
expect(response.headers.location).toEqual(constants.routes.SERVICE_UNAVAILABLE) | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
import { submitGetRequest } from '../../__test-helpers__/server.js' | ||
import constants from '../../utils/constants.js' | ||
|
||
const url = constants.routes.SERVICE_UNAVAILABLE | ||
|
||
describe(url, () => { | ||
describe('GET', () => { | ||
it(`Should return success response and correct view for ${url}`, async () => { | ||
await submitGetRequest({ url }, 'Sorry, the service is unavailable') | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
import constants from '../utils/constants.js' | ||
|
||
const handlers = { | ||
get: (_request, h) => h.view(constants.views.SERVICE_UNAVAILABLE) | ||
} | ||
|
||
export default [ | ||
{ | ||
method: 'GET', | ||
path: constants.routes.SERVICE_UNAVAILABLE, | ||
handler: handlers.get, | ||
options: { | ||
auth: false | ||
} | ||
} | ||
] |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,96 @@ | ||
import wreck from '@hapi/wreck' | ||
jest.mock('@hapi/wreck') | ||
|
||
describe('Is working hours', () => { | ||
it('Test some dates in a single IT to avoid all the hapi server wrapper stuff repeating', done => { | ||
jest.isolateModules(async () => { | ||
try { | ||
process.env.SERVICE_AVAILABLE_CRON = '* * 9-16 * * 1-5' | ||
const isWorkingHours = require('../is-working-hours').default | ||
wreck.get.mockResolvedValue({ | ||
res: { | ||
statusCode: 200 | ||
}, | ||
payload: { | ||
'england-and-wales': { | ||
events: [{ | ||
date: '2024-08-26' | ||
}] | ||
} | ||
} | ||
}) | ||
|
||
// Happy paths | ||
// Standard date within working hours | ||
expect(await isWorkingHours(new Date('2024-08-01T12:00:00.000Z'))).toBeTruthy() | ||
expect(await isWorkingHours(new Date('2024-08-01T15:30:00.000Z'))).toBeTruthy() | ||
|
||
// BST + GMT 16:30 and 08:30 times | ||
expect(await isWorkingHours(new Date('2024-08-01T16:30:00.000Z'))).toBeFalsy() | ||
expect(await isWorkingHours(new Date('2024-08-01T08:30:00.000Z'))).toBeTruthy() | ||
expect(await isWorkingHours(new Date('2024-03-26T16:30:00.000Z'))).toBeTruthy() | ||
expect(await isWorkingHours(new Date('2024-03-26T08:30:00.000Z'))).toBeFalsy() | ||
|
||
// Weekend | ||
expect(await isWorkingHours(new Date('2024-03-30T12:00:00.000Z'))).toBeFalsy() | ||
expect(await isWorkingHours(new Date('2024-03-31T12:00:00.000Z'))).toBeFalsy() | ||
|
||
// Week but outside hours | ||
expect(await isWorkingHours(new Date('2024-03-26T17:00:00.000Z'))).toBeFalsy() | ||
expect(await isWorkingHours(new Date('2024-03-26T08:59:59.999Z'))).toBeFalsy() | ||
|
||
// bank holiday inside hours | ||
expect(await isWorkingHours(new Date('2024-08-26T12:00:00.000Z'))).toBeFalsy() | ||
|
||
// bank holiday outside hours | ||
expect(await isWorkingHours(new Date('2024-08-26T18:00:00.000Z'))).toBeFalsy() | ||
|
||
expect(wreck.get).toHaveBeenCalledTimes(12) | ||
|
||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
}) | ||
|
||
it('Should return true if cron set to * * * * * * and datetime outside working hours', done => { | ||
jest.isolateModules(async () => { | ||
try { | ||
process.env.SERVICE_AVAILABLE_CRON = '* * * * * *' | ||
const isWorkingHours = require('../is-working-hours').default | ||
expect(await isWorkingHours(new Date('2024-03-26T00:00:00.000Z'))).toBeTruthy() | ||
expect(wreck.get).toHaveBeenCalledTimes(0) | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
}) | ||
it('Should return true if cron set to * * * * * * and no datetime provided', done => { | ||
jest.isolateModules(async () => { | ||
try { | ||
process.env.SERVICE_AVAILABLE_CRON = '* * * * * *' | ||
const isWorkingHours = require('../is-working-hours').default | ||
expect(await isWorkingHours()).toBeTruthy() | ||
expect(wreck.get).toHaveBeenCalledTimes(0) | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
}) | ||
it('Should catch error and reject', done => { | ||
jest.isolateModules(async () => { | ||
try { | ||
process.env.SERVICE_AVAILABLE_CRON = '* * 9-16 * * 1-5' | ||
wreck.get = jest.fn().mockImplementation(() => Promise.reject(new Error('test error'))) | ||
const isWorkingHours = require('../is-working-hours').default | ||
await expect(isWorkingHours()).rejects.toEqual(new Error('test error')) | ||
done() | ||
} catch (e) { | ||
done(e) | ||
} | ||
}) | ||
}) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
import Wreck from '@hapi/wreck' | ||
import parser from 'cron-parser' | ||
import config from './config.js' | ||
|
||
const isWorkingHours = async (dateToTest = new Date()) => { | ||
try { | ||
if (config.serviceAvailableCron === '* * * * * *') { | ||
return true | ||
} | ||
|
||
// logging for azure checking timezone correct when BST | ||
console.log(`Testing date: ${dateToTest.toLocaleString()}`) | ||
console.log(`Date TZ: ${dateToTest}`) | ||
console.log(`Date TZ offset: ${dateToTest.getTimezoneOffset()}`) | ||
|
||
// Get bank holiday data | ||
const { payload } = await Wreck.get('https://www.gov.uk/bank-holidays.json', { | ||
json: true, | ||
rejectUnauthorized: false | ||
}) | ||
|
||
const dateString = dateToTest.toLocaleDateString('en-GB', { timeZone: 'Europe/London' }) | ||
|
||
const bankHoliday = payload['england-and-wales'].events.find(event => dateString === new Date(event.date).toLocaleDateString('en-GB', { timeZone: 'Europe/London' })) | ||
|
||
if (bankHoliday) { | ||
return false | ||
} | ||
|
||
const interval = parser.parseExpression(config.serviceAvailableCron, { | ||
currentDate: dateToTest | ||
}) | ||
|
||
return interval.fields.dayOfWeek.includes(dateToTest.getDay()) && | ||
interval.fields.hour.includes(dateToTest.getHours()) && | ||
interval.fields.minute.includes(dateToTest.getMinutes()) | ||
} catch (err) { | ||
console.error(err) | ||
throw err | ||
} | ||
} | ||
|
||
export default isWorkingHours |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.