From e1902188409388c7997937f5a6ff33a9862ca614 Mon Sep 17 00:00:00 2001 From: Oliver Eyton-Williams Date: Wed, 1 Oct 2025 21:17:27 +0200 Subject: [PATCH] fix(api): adjust daily-challenge time from UTC (#62444) --- .../routes/daily-coding-challenge.test.ts | 63 ++++++++++++------- .../daily-coding-challenge/utils/helpers.ts | 5 +- 2 files changed, 43 insertions(+), 25 deletions(-) diff --git a/api/src/daily-coding-challenge/routes/daily-coding-challenge.test.ts b/api/src/daily-coding-challenge/routes/daily-coding-challenge.test.ts index 2fe0baec688..5d96df67845 100644 --- a/api/src/daily-coding-challenge/routes/daily-coding-challenge.test.ts +++ b/api/src/daily-coding-challenge/routes/daily-coding-challenge.test.ts @@ -1,26 +1,23 @@ -import { describe, it, expect, beforeEach, afterEach } from 'vitest'; +import { describe, it, expect, beforeEach, afterEach, vi } from 'vitest'; import { addDays } from 'date-fns'; import { setupServer, superRequest } from '../../../vitest.utils.js'; -import { getNowUsCentral, getUtcMidnight } from '../utils/helpers.js'; function dateToDateParam(date: Date): string { return date.toISOString().split('T')[0] as string; } -const todayUsCentral = getNowUsCentral(); -const todayUtcMidnight = getUtcMidnight(todayUsCentral); +const todayUsCentral = new Date(Date.UTC(2025, 9, 2, 5)); // 2025-10-02 00:00:00 in US Central +const todayUtcMidnight = new Date(Date.UTC(2025, 9, 2, 0, 0, 0)); + const todayDateParam = dateToDateParam(todayUtcMidnight); -const yesterdayUsCentral = addDays(todayUsCentral, -1); -const yesterdayUtcMidnight = getUtcMidnight(yesterdayUsCentral); +const yesterdayUtcMidnight = addDays(todayUtcMidnight, -1); -const twoDaysAgoUsCentral = addDays(todayUsCentral, -2); -const twoDaysAgoUtcMidnight = getUtcMidnight(twoDaysAgoUsCentral); +const twoDaysAgoUtcMidnight = addDays(todayUtcMidnight, -2); const twoDaysAgoDateParam = dateToDateParam(twoDaysAgoUtcMidnight); -const tomorrowUsCentral = addDays(todayUsCentral, 1); -const tomorrowUtcMidnight = getUtcMidnight(tomorrowUsCentral); +const tomorrowUtcMidnight = addDays(todayUtcMidnight, 1); const tomorrowDateParam = dateToDateParam(tomorrowUtcMidnight); const yesterdaysChallenge = { @@ -79,6 +76,13 @@ const mockChallenges = [ describe('/daily-coding-challenge', () => { setupServer(); + // This has to happen after setupServer since it needs real timers. + beforeEach(() => { + vi.useFakeTimers({ now: todayUsCentral }); + }); + afterEach(() => { + vi.useRealTimers(); + }); describe('GET /daily-coding-challenge/date/:date', () => { beforeEach(async () => { @@ -229,18 +233,10 @@ describe('/daily-coding-challenge', () => { } }); - it('should return { id, date, challengeNumber, title } for all available challenges of the given month up to today US Central', async () => { - const currentMonth = todayUsCentral.toISOString().slice(0, 7); - - const res = await superRequest( - `/daily-coding-challenge/month/${currentMonth}`, - { - method: 'GET' - } - ).send({}); - - expect(res.status).toBe(200); - expect(Array.isArray(res.body)).toBe(true); + it('should return two challenges on the second day of the month', async () => { + const res = await superRequest(`/daily-coding-challenge/month/2025-10`, { + method: 'GET' + }).send({}); // Should include yesterday's and today's challenges, but not tomorrow's const expectedResponse = [ @@ -258,8 +254,29 @@ describe('/daily-coding-challenge', () => { } ]; - expect(res.body).toHaveLength(2); expect(res.body).toEqual(expectedResponse); + expect(res.status).toBe(200); + }); + + it('should return one challenge on the first day of the month', async () => { + vi.setSystemTime(new Date(Date.UTC(2025, 9, 1, 5))); // 2025-10-01 00:00:00 in US Central + + const res = await superRequest(`/daily-coding-challenge/month/2025-10`, { + method: 'GET' + }).send({}); + + // Should include yesterday's challenges + const expectedResponse = [ + { + id: yesterdaysChallenge.id, + challengeNumber: yesterdaysChallenge.challengeNumber, + date: yesterdaysChallenge.date.toISOString(), + title: yesterdaysChallenge.title + } + ]; + + expect(res.body).toEqual(expectedResponse); + expect(res.status).toBe(200); }); it('should return 404 when no challenges exist for the given month', async () => { diff --git a/api/src/daily-coding-challenge/utils/helpers.ts b/api/src/daily-coding-challenge/utils/helpers.ts index a5dccc65040..242d9fc4f73 100644 --- a/api/src/daily-coding-challenge/utils/helpers.ts +++ b/api/src/daily-coding-challenge/utils/helpers.ts @@ -1,10 +1,11 @@ -import { toZonedTime } from 'date-fns-tz'; +import { getTimezoneOffset } from 'date-fns-tz'; /** * @returns Now US Central time. */ export function getNowUsCentral() { - return toZonedTime(new Date(), 'America/Chicago'); + const offset = getTimezoneOffset('America/Chicago', new Date()); + return new Date(Date.now() + offset); } /**