From 09e4b3a1b802e93d094e4353197850a7624645f2 Mon Sep 17 00:00:00 2001 From: Collin Duncan <3679940+cgduncan7@users.noreply.github.com> Date: Fri, 20 Jan 2023 15:31:04 +0100 Subject: [PATCH] Adding dayjs module to allow timezone handling by default and replaced node_module with this module --- docker/docker-compose.yml | 2 +- src/common/dayjs.ts | 20 +++++++ src/common/request.ts | 9 +--- src/common/reservation.ts | 11 ++-- src/common/reserver.ts | 5 +- src/common/runner.ts | 38 ++++++++----- src/local/index.ts | 2 +- .../__snapshots__/scheduler.test.ts.snap | 53 ++++++++++++++----- tests/unit/common/request.test.ts | 8 +-- tests/unit/common/reservation.test.ts | 5 +- tests/unit/common/scheduler.test.ts | 2 +- 11 files changed, 108 insertions(+), 47 deletions(-) create mode 100644 src/common/dayjs.ts diff --git a/docker/docker-compose.yml b/docker/docker-compose.yml index 60cd053..1b4cde0 100644 --- a/docker/docker-compose.yml +++ b/docker/docker-compose.yml @@ -8,7 +8,7 @@ services: - 3306:3306 healthcheck: test: ["CMD", "mysqladmin" ,"ping", "-h", "localhost"] - timeout: 20s + timeout: 5s retries: 10 http: diff --git a/src/common/dayjs.ts b/src/common/dayjs.ts new file mode 100644 index 0000000..97e310a --- /dev/null +++ b/src/common/dayjs.ts @@ -0,0 +1,20 @@ +import dayjs from 'dayjs' +import isSameOrBefore from 'dayjs/plugin/isSameOrBefore' +import utc from 'dayjs/plugin/utc' +import timezone from 'dayjs/plugin/timezone' +import 'dayjs/locale/nl' + +dayjs.extend(isSameOrBefore) +dayjs.extend(utc) +dayjs.extend(timezone) +dayjs.locale('nl') + +dayjs.tz.setDefault('Europe/Amsterdam') + +const dayjsTz = ( + date?: string | number | Date | dayjs.Dayjs | null | undefined +) => { + return dayjs(date).tz() +} + +export default dayjsTz diff --git a/src/common/request.ts b/src/common/request.ts index 068e4df..ad6c483 100644 --- a/src/common/request.ts +++ b/src/common/request.ts @@ -1,8 +1,4 @@ -import dayjs from 'dayjs' -import isSameOrBefore from 'dayjs/plugin/isSameOrBefore' -import { hashPassword } from './password' -dayjs.extend(isSameOrBefore) - +import dayjs from './dayjs' import { DateRange, Opponent, Reservation } from './reservation' export enum ValidationErrorCode { @@ -61,9 +57,8 @@ const validateRequestBody = async ( ) } - const hashedPassword = await hashPassword(password) const reservation = new Reservation( - { username, password: hashedPassword }, + { username, password }, convertDateRangeStringToObject(dateRange), opponent ) diff --git a/src/common/reservation.ts b/src/common/reservation.ts index 041c93d..9dcc63a 100644 --- a/src/common/reservation.ts +++ b/src/common/reservation.ts @@ -1,7 +1,6 @@ -import dayjs, { Dayjs } from 'dayjs' -import isSameOrBefore from 'dayjs/plugin/isSameOrBefore' +import { Dayjs } from 'dayjs' +import dayjs from './dayjs' import { query } from './database' -dayjs.extend(isSameOrBefore) const RESERVATION_AVAILABLE_WITHIN_DAYS = 7 @@ -16,8 +15,8 @@ export interface Opponent { } export interface DateRange { - start: dayjs.Dayjs - end: dayjs.Dayjs + start: Dayjs + end: Dayjs } export class Reservation { @@ -81,7 +80,7 @@ export class Reservation { return { user: { username: this.user.username, - password: this.user.password ? '?' : null, + password: this.user.password, }, opponent: this.opponent, booked: this.booked, diff --git a/src/common/reserver.ts b/src/common/reserver.ts index 4ce5f3a..685457c 100644 --- a/src/common/reserver.ts +++ b/src/common/reserver.ts @@ -4,7 +4,10 @@ import { Runner } from './runner' let runner: Runner | undefined const getRunner = () => { if (!runner) { - runner = new Runner({ headless: true, args: ['--no-sandbox', '--disable-setuid-sandbox'] }) + runner = new Runner({ + headless: true, + args: ['--no-sandbox', '--disable-setuid-sandbox'], + }) } return runner } diff --git a/src/common/runner.ts b/src/common/runner.ts index 6fd2512..a614f2d 100644 --- a/src/common/runner.ts +++ b/src/common/runner.ts @@ -1,4 +1,5 @@ -import dayjs, { Dayjs } from 'dayjs' +import { Dayjs } from 'dayjs' +import dayjs from './dayjs' import puppeteer, { Browser, BrowserConnectOptions, @@ -36,7 +37,7 @@ export class Runner { } private async login(username: string, password: string) { - asyncLocalStorage.getStore()?.debug('Logging in') + asyncLocalStorage.getStore()?.debug('Logging in', { username }) await this.page?.goto('https://squashcity.baanreserveren.nl/') await this.page ?.waitForSelector('input[name=username]') @@ -53,10 +54,11 @@ export class Runner { await this.confirmReservation() reservation.booked = true return true - } catch (err) { - asyncLocalStorage - .getStore() - ?.error('Error making reservation', reservation.format()) + } catch (err: unknown) { + asyncLocalStorage.getStore()?.error('Error making reservation', { + reservation: reservation.format(), + error: err, + }) return false } } @@ -82,7 +84,12 @@ export class Runner { asyncLocalStorage .getStore() ?.debug('Date is on different page, increase month') - await this.page?.waitForSelector('td.month.next').then((d) => d?.click()) + await this.page + ?.waitForSelector('td.month.next') + .then((d) => d?.click()) + .catch(() => { + throw new Error('Could not click correct month') + }) } await this.page @@ -92,11 +99,18 @@ export class Runner { )}` ) .then((d) => d?.click()) - await this.page?.waitForSelector( - `td#cal_${date.get('year')}_${date.get('month') + 1}_${date.get( - 'date' - )}.selected` - ) + .catch(() => { + throw new Error('Could not click correct day') + }) + await this.page + ?.waitForSelector( + `td#cal_${date.get('year')}_${date.get('month') + 1}_${date.get( + 'date' + )}.selected` + ) + .catch(() => { + throw new Error("Selected day didn't change") + }) } private async selectAvailableTime(res: Reservation): Promise { diff --git a/src/local/index.ts b/src/local/index.ts index 011850f..595df5c 100644 --- a/src/local/index.ts +++ b/src/local/index.ts @@ -1,4 +1,4 @@ -import dayjs from 'dayjs' +import dayjs from '../common/dayjs' import { Reservation } from '../common/reservation' import { Runner } from '../common/runner' diff --git a/tests/unit/common/__snapshots__/scheduler.test.ts.snap b/tests/unit/common/__snapshots__/scheduler.test.ts.snap index c69c53f..1b6a655 100644 --- a/tests/unit/common/__snapshots__/scheduler.test.ts.snap +++ b/tests/unit/common/__snapshots__/scheduler.test.ts.snap @@ -9,27 +9,35 @@ exports[`scheduler should handle valid requests outside of reservation window 1` "end": { "$D": 16, "$H": 1, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 0, "$d": {}, "$m": 15, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$u": false, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, "start": { "$D": 16, "$H": 1, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 0, "$d": {}, "$m": 0, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$u": false, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, }, @@ -41,27 +49,33 @@ exports[`scheduler should handle valid requests outside of reservation window 1` { "$D": 16, "$H": 1, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 0, "$d": {}, "$m": 0, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, { "$D": 16, "$H": 1, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 0, "$d": {}, "$m": 15, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, ], @@ -73,14 +87,17 @@ exports[`scheduler should handle valid requests outside of reservation window 1` "scheduledFor": { "$D": 9, "$H": 0, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 0, "$d": {}, "$m": 0, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, }, @@ -96,27 +113,35 @@ exports[`scheduler should handle valid requests within reservation window 1`] = "end": { "$D": 1, "$H": 1, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 6, "$d": {}, "$m": 30, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$u": false, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, "start": { "$D": 1, "$H": 1, - "$L": "en", + "$L": "nl", "$M": 0, "$W": 6, "$d": {}, "$m": 15, "$ms": 0, + "$offset": 60, "$s": 0, - "$x": {}, + "$u": false, + "$x": { + "$timezone": "Europe/Amsterdam", + }, "$y": 2022, }, }, diff --git a/tests/unit/common/request.test.ts b/tests/unit/common/request.test.ts index 8575fd2..4b914ba 100644 --- a/tests/unit/common/request.test.ts +++ b/tests/unit/common/request.test.ts @@ -1,4 +1,4 @@ -import dayjs from 'dayjs' +import dayjs from '../../../src/common/dayjs' import { validateJSONRequest, @@ -9,7 +9,7 @@ describe('request', () => { const testDate = dayjs().add(1, 'day') describe('validateJSONRequest', () => { - test('should return ReservationRequest', () => { + test('should return ReservationRequest', async () => { const body = { username: 'collin', password: '123abc', @@ -23,7 +23,9 @@ describe('request', () => { }, } - expect(() => validateJSONRequest(body)).not.toThrow() + const res = await validateJSONRequest(body) + expect(res).toBeDefined() + expect(res.dateRange.start.format()).toEqual(testDate.format()) }) test('should throw error for undefined body', async () => { diff --git a/tests/unit/common/reservation.test.ts b/tests/unit/common/reservation.test.ts index 15d10e9..116f59e 100644 --- a/tests/unit/common/reservation.test.ts +++ b/tests/unit/common/reservation.test.ts @@ -1,4 +1,5 @@ -import dayjs, { Dayjs } from 'dayjs' +import { Dayjs } from 'dayjs' +import dayjs from '../../../src/common/dayjs' import { DateRange, Reservation } from '../../../src/common/reservation' describe('Reservation', () => { @@ -20,6 +21,7 @@ describe('Reservation', () => { expect(res.possibleDates).toHaveLength(5) + console.log(res.possibleDates[0].format()) expect(res.possibleDates[0]).toEqual(startDate) expect(res.possibleDates[1]).toEqual(startDate.add(15, 'minute')) expect(res.possibleDates[2]).toEqual(startDate.add(30, 'minute')) @@ -45,6 +47,7 @@ describe('Reservation', () => { const zeroTime = (date: Dayjs): Dayjs => date.hour(0).minute(0).second(0).millisecond(0) + test.each([ { date: dayjs().add(8, 'days'), diff --git a/tests/unit/common/scheduler.test.ts b/tests/unit/common/scheduler.test.ts index 8874d26..1d11f7f 100644 --- a/tests/unit/common/scheduler.test.ts +++ b/tests/unit/common/scheduler.test.ts @@ -1,4 +1,4 @@ -import dayjs from 'dayjs' +import dayjs from '../../../src/common/dayjs' import { ValidationError, ValidationErrorCode,