Fix flexible time scrim notif time and sidebar show logic

This commit is contained in:
Kalle
2026-09-02 20:57:05 +03:00
parent adb2a5c9e7
commit fdbeffc305
3 changed files with 108 additions and 4 deletions

View File

@@ -20,6 +20,40 @@ const WINDOW = {
endTime: dbTs(add(BOOKED_AT, { hours: 1 })),
};
/**
* A "flexible time" post whose window opened `windowOpensInMinutes` from now,
* booked by a request that picked a start `bookedInMinutes` from now.
*/
async function createBookedRangeScrim({
windowOpensInMinutes,
bookedInMinutes,
}: {
windowOpensInMinutes: number;
bookedInMinutes: number;
}) {
const now = new Date();
const bookedAt = add(now, { minutes: bookedInMinutes });
const { id } = await ScrimPostFactory.create(
{
startsAt: dbTs(add(now, { minutes: windowOpensInMinutes })),
rangeEndsAt: dbTs(add(now, { minutes: windowOpensInMinutes + 120 })),
users: [{ userId: users.id(1), isOwner: 1 }],
},
{
requests: [
{
startsAt: dbTs(bookedAt),
users: [{ userId: users.id(2), isOwner: 1 }],
isAccepted: true,
},
],
},
);
return { id, bookedAt: dbTs(bookedAt) };
}
describe("findPendingOverlapsForUsers", () => {
beforeEach(async () => {
await users.create(5);
@@ -251,6 +285,68 @@ describe("findUserScrims", () => {
expect(postOwnerScrims).toHaveLength(1);
expect(postOwnerScrims[0]!.status).toBe("booked");
});
test("lists a booked range scrim whose post window opened before the booked start", async () => {
const { id } = await createBookedRangeScrim({
windowOpensInMinutes: -30,
bookedInMinutes: 45,
});
const scrims = await ScrimPostRepository.findUserScrims(users.id(1));
expect(scrims.map((scrim) => scrim.id)).toContain(id);
});
test("reports the booked start of a range scrim, not the start of its window", async () => {
const { id, bookedAt } = await createBookedRangeScrim({
windowOpensInMinutes: 30,
bookedInMinutes: 90,
});
const scrims = await ScrimPostRepository.findUserScrims(users.id(2));
const scrim = scrims.find((scrim) => scrim.id === id);
expect(scrim?.status).toBe("booked");
expect(scrim?.startsAt).toBe(bookedAt);
});
});
describe("findAcceptedScrimsBetweenTwoTimestamps", () => {
beforeEach(async () => {
await users.create(2);
});
const startingWithinTheHour = async () => {
const now = new Date();
return ScrimPostRepository.findAcceptedScrimsBetweenTwoTimestamps({
startTime: now,
endTime: add(now, { hours: 1 }),
excludeRecentlyCreated: add(now, { minutes: 1 }),
});
};
test("finds a range scrim booked to start inside the window", async () => {
const { id } = await createBookedRangeScrim({
windowOpensInMinutes: -30,
bookedInMinutes: 45,
});
const scrims = await startingWithinTheHour();
expect(scrims.map((scrim) => scrim.id)).toContain(id);
});
test("leaves out a range scrim booked to start after the window", async () => {
const { id } = await createBookedRangeScrim({
windowOpensInMinutes: 30,
bookedInMinutes: 120,
});
const scrims = await startingWithinTheHour();
expect(scrims.map((scrim) => scrim.id)).not.toContain(id);
});
});
describe("insertRequest", () => {

View File

@@ -239,6 +239,9 @@ const baseFindQuery = db
).as("requests"),
]);
/** The booked start of a scrim: the accepted request's chosen time for a range post, the post's own otherwise. */
const bookedStartsAt = sql<number>`coalesce((select "ScrimPostRequest"."startsAt" from "ScrimPostRequest" where "ScrimPostRequest"."scrimPostId" = "ScrimPost"."id" and "ScrimPostRequest"."isAccepted" = 1), "ScrimPost"."startsAt")`;
function findMany() {
const min = sub(new Date(), { hours: 3 });
@@ -541,8 +544,8 @@ export async function findAcceptedScrimsBetweenTwoTimestamps({
excludeRecentlyCreated: Date;
}) {
const rows = await baseFindQuery
.where("ScrimPost.startsAt", ">=", dateToDatabaseTimestamp(startTime))
.where("ScrimPost.startsAt", "<", dateToDatabaseTimestamp(endTime))
.where(bookedStartsAt, ">=", dateToDatabaseTimestamp(startTime))
.where(bookedStartsAt, "<", dateToDatabaseTimestamp(endTime))
.where("ScrimPost.canceledAt", "is", null)
.where(
"ScrimPost.createdAt",
@@ -711,7 +714,7 @@ export async function findUserScrims(userId: number): Promise<SidebarScrim[]> {
const rows = await baseFindQuery
.where("ScrimPost.canceledAt", "is", null)
.where("ScrimPost.startsAt", ">=", now)
.where(bookedStartsAt, ">=", now)
.where((eb) =>
eb.or([
eb.exists(
@@ -735,7 +738,7 @@ export async function findUserScrims(userId: number): Promise<SidebarScrim[]> {
),
]),
)
.orderBy("ScrimPost.startsAt", "asc")
.orderBy(bookedStartsAt, "asc")
.execute();
return rows

View File

@@ -0,0 +1,5 @@
---
navItem: scrims
type: bug
---
Booked scrims from "flexible time" posts now stay on your events list until their booked start, and the "starting soon" notification is sent at the right time