diff --git a/app/features/scrims/ScrimPostRepository.server.test.ts b/app/features/scrims/ScrimPostRepository.server.test.ts index d577b9e63..cce116bf1 100644 --- a/app/features/scrims/ScrimPostRepository.server.test.ts +++ b/app/features/scrims/ScrimPostRepository.server.test.ts @@ -314,6 +314,56 @@ describe("findUserScrims", () => { }); }); +describe("findById", () => { + const WINDOW_OPENS_AT = dbTs(BOOKED_AT) - 3600; + const WINDOW_CLOSES_AT = dbTs(BOOKED_AT) + 3600; + + beforeEach(async () => { + await users.create(2); + }); + + test.each([ + { + why: "the accepted request's chosen start", + request: { isAccepted: true, startsAt: dbTs(BOOKED_AT) }, + expected: { + startsAt: dbTs(BOOKED_AT), + rangeEndsAt: null, + }, + }, + { + why: "the window start when the accepted request chose none", + request: { isAccepted: true, startsAt: undefined }, + expected: { startsAt: WINDOW_OPENS_AT, rangeEndsAt: null }, + }, + { + why: "the window while no request is accepted", + request: { isAccepted: false, startsAt: dbTs(BOOKED_AT) }, + expected: { + startsAt: WINDOW_OPENS_AT, + rangeEndsAt: WINDOW_CLOSES_AT, + }, + }, + ])("starts at $why", async ({ request, expected }) => { + const { id } = await ScrimPostFactory.create( + { + startsAt: WINDOW_OPENS_AT, + rangeEndsAt: WINDOW_CLOSES_AT, + users: [{ userId: users.id(1), isOwner: 1 }], + }, + { + requests: [ + { ...request, users: [{ userId: users.id(2), isOwner: 1 }] }, + ], + }, + ); + + const post = await ScrimPostRepository.findById(id); + + expect(post).toMatchObject(expected); + }); +}); + describe("findAcceptedScrimsBetweenTwoTimestamps", () => { beforeEach(async () => { await users.create(2); diff --git a/app/features/scrims/ScrimPostRepository.server.ts b/app/features/scrims/ScrimPostRepository.server.ts index 8c0e0d790..4c1a3d963 100644 --- a/app/features/scrims/ScrimPostRepository.server.ts +++ b/app/features/scrims/ScrimPostRepository.server.ts @@ -432,13 +432,14 @@ const mapDBRowToScrimPost = ( canceled, }; - if (!Scrim.isAccepted(result)) { + const acceptedRequest = result.requests.find((r) => r.isAccepted); + if (!acceptedRequest) { return result; } return { ...result, - startsAt: Scrim.getStartTime(result), + startsAt: acceptedRequest.startsAt ?? result.startsAt, rangeEndsAt: null, }; }; diff --git a/app/features/scrims/actions/scrims.$id.server.ts b/app/features/scrims/actions/scrims.$id.server.ts index c9bb5bfd3..7f9ad7393 100644 --- a/app/features/scrims/actions/scrims.$id.server.ts +++ b/app/features/scrims/actions/scrims.$id.server.ts @@ -37,7 +37,7 @@ export const action = defineAction( errorToastIfFalsy(Scrim.isAccepted(post), "Scrim is not accepted"); errorToastIfFalsy(!post.canceled, "Scrim is already canceled"); - if (databaseTimestampToDate(Scrim.getStartTime(post)) < new Date()) { + if (databaseTimestampToDate(post.startsAt) < new Date()) { errorToast( "Cannot cancel a scrim that was already scheduled to start", ); @@ -226,7 +226,7 @@ async function loadMapByMapContext({ if ( Scrim.isTrackingLocked({ - startTime: Scrim.getStartTime(post), + startTime: post.startsAt, maps, mapLists, }) diff --git a/app/features/scrims/actions/scrims.server.ts b/app/features/scrims/actions/scrims.server.ts index de66ca426..91cbe657d 100644 --- a/app/features/scrims/actions/scrims.server.ts +++ b/app/features/scrims/actions/scrims.server.ts @@ -190,9 +190,7 @@ export const action = defineAction( ); try { - const bookedAt = databaseTimestampToDate( - Scrim.getStartTime(fullPost), - ); + const bookedAt = databaseTimestampToDate(fullPost.startsAt); const startTime = dateToDatabaseTimestamp( sub(bookedAt, { hours: SCRIM.AUTO_CANCEL_WINDOW_HOURS }), ); diff --git a/app/features/scrims/components/ScrimMatchBanner.tsx b/app/features/scrims/components/ScrimMatchBanner.tsx index 705290c97..206e1a78b 100644 --- a/app/features/scrims/components/ScrimMatchBanner.tsx +++ b/app/features/scrims/components/ScrimMatchBanner.tsx @@ -76,10 +76,7 @@ export function ScrimMatchBanner() { function ScrimMatchBannerTopRow() { const data = useLoaderData(); - const acceptedRequest = data.post.requests.find((r) => r.isAccepted); - const scheduledAt = databaseTimestampToDate( - acceptedRequest?.startsAt ?? data.post.startsAt, - ); + const scheduledAt = databaseTimestampToDate(data.post.startsAt); return ( diff --git a/app/features/scrims/core/Scrim.test.ts b/app/features/scrims/core/Scrim.test.ts index d6efb6bf0..45e76f199 100644 --- a/app/features/scrims/core/Scrim.test.ts +++ b/app/features/scrims/core/Scrim.test.ts @@ -6,7 +6,6 @@ import { applyFilters, defaultFilters, filtersAreDefault, - getStartTime, isAccepted, isParticipating, isTrackingLocked, @@ -1024,40 +1023,6 @@ describe("Scrim.resolvePoolCode", () => { }); }); -describe("Scrim.getStartTime", () => { - const POST_STARTS_AT = 1_000; - const REQUEST_STARTS_AT = 2_000; - - const postWithRequest = (request: { - isAccepted: boolean; - startsAt: number | null; - }) => - ({ - ...createPost([{ id: 1 }], [{ ...request, users: [{ id: 2 }] }]), - startsAt: POST_STARTS_AT, - }) as ScrimPost; - - test.each([ - { - why: "the accepted request's chosen start", - request: { isAccepted: true, startsAt: REQUEST_STARTS_AT }, - expected: REQUEST_STARTS_AT, - }, - { - why: "the post's start when the accepted request chose none", - request: { isAccepted: true, startsAt: null }, - expected: POST_STARTS_AT, - }, - { - why: "the post's start while no request is accepted", - request: { isAccepted: false, startsAt: REQUEST_STARTS_AT }, - expected: POST_STARTS_AT, - }, - ])("$why", ({ request, expected }) => { - expect(getStartTime(postWithRequest(request))).toBe(expected); - }); -}); - describe("Scrim.defaultFilters", () => { test("sets no filter", () => { expect(defaultFilters()).toEqual({ diff --git a/app/features/scrims/core/Scrim.ts b/app/features/scrims/core/Scrim.ts index 35a17a473..fc6d512a6 100644 --- a/app/features/scrims/core/Scrim.ts +++ b/app/features/scrims/core/Scrim.ts @@ -65,12 +65,6 @@ export function participantIdsListFromAccepted(post: ScrimPost) { .concat(acceptedRequest?.users.map((u) => u.id) ?? []); } -/** The scrim's actual start: the accepted request's time when the post has a range (rangeEndsAt set), else the post's start. */ -export function getStartTime(post: ScrimPost): number { - const acceptedRequest = post.requests.find((r) => r.isAccepted); - return acceptedRequest?.startsAt ?? post.startsAt; -} - /** Display name of a scrim side: the team name, else "{ownerUsername}'s pickup". */ export function sideDisplayName(side: { team: { name: string } | null; diff --git a/app/features/scrims/loaders/scrims.$id.server.ts b/app/features/scrims/loaders/scrims.$id.server.ts index c04cfe5c4..1bbf7b536 100644 --- a/app/features/scrims/loaders/scrims.$id.server.ts +++ b/app/features/scrims/loaders/scrims.$id.server.ts @@ -87,7 +87,7 @@ async function resolveMapByMap({ const currentMap = maps.find((m) => m.reportedAt === null) ?? null; const viewerSide = Scrim.sideOfUser(post, user.id); const locked = Scrim.isTrackingLocked({ - startTime: Scrim.getStartTime(post), + startTime: post.startsAt, maps, mapLists, }); diff --git a/app/features/scrims/scrims-types.ts b/app/features/scrims/scrims-types.ts index 2d62788a2..49e2dffc7 100644 --- a/app/features/scrims/scrims-types.ts +++ b/app/features/scrims/scrims-types.ts @@ -7,6 +7,7 @@ export type ScrimSide = "ALPHA" | "BRAVO"; export interface ScrimPost { id: number; + /** When the scrim starts. For an accepted post this is the booked time, not the window start. */ startsAt: number; rangeEndsAt: number | null; createdAt: number;