Skip to content

Commit 9fe5ff7

Browse files
anikdhabalemrysal
andauthored
test: Fix duplicate API calls test to handle date-based conditional logic (calcom#24472)
Co-authored-by: Alex van Andel <me@alexvanandel.com>
1 parent 3076aca commit 9fe5ff7

1 file changed

Lines changed: 143 additions & 53 deletions

File tree

Lines changed: 143 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,87 @@
11
import { expect } from "@playwright/test";
2+
import type { Page } from "@playwright/test";
23

34
import { createTeamEventType } from "./fixtures/users";
45
import { test } from "./lib/fixtures";
56

7+
async function testDuplicateAPICalls(
8+
page: Page,
9+
url: string,
10+
testDate?: Date
11+
): Promise<{ totalCalls: number; trpcCalls: number; apiV2Calls: number }> {
12+
const trpcCalls: string[] = [];
13+
const apiV2Calls: string[] = [];
14+
15+
if (testDate) {
16+
await page.clock.install({ time: testDate });
17+
}
18+
19+
await page.route("**/api/trpc/slots/getSchedule**", async (route) => {
20+
trpcCalls.push(route.request().url());
21+
await route.continue();
22+
});
23+
24+
await page.route("**/api/v2/slots/available**", async (route) => {
25+
apiV2Calls.push(route.request().url());
26+
await route.continue();
27+
});
28+
29+
await page.goto(url);
30+
await page.waitForTimeout(5000);
31+
32+
return {
33+
totalCalls: trpcCalls.length + apiV2Calls.length,
34+
trpcCalls: trpcCalls.length,
35+
apiV2Calls: apiV2Calls.length,
36+
};
37+
}
38+
639
test.describe("Duplicate API Calls Prevention", () => {
740
test.afterEach(({ users }) => users.deleteAll());
841

9-
test("should detect when schedule endpoints are called multiple times for individual user events", async ({
42+
test("should detect when schedule endpoints are called multiple times for individual user events - beginning of month", async ({
1043
page,
1144
users,
1245
}) => {
1346
const user = await users.create();
1447
const eventType = user.eventTypes.find((e) => e.slug === "30-min");
48+
const beginningOfMonth = new Date();
49+
beginningOfMonth.setDate(5);
1550

16-
const trpcCalls: string[] = [];
17-
const apiV2Calls: string[] = [];
18-
19-
// Intercept tRPC getSchedule calls - pattern matches /api/trpc/slots/getSchedule
20-
await page.route("**/api/trpc/slots/getSchedule**", async (route) => {
21-
trpcCalls.push(route.request().url());
22-
await route.continue();
23-
});
24-
25-
await page.route("**/api/v2/slots/available**", async (route) => {
26-
apiV2Calls.push(route.request().url());
27-
await route.continue();
28-
});
51+
const { totalCalls, trpcCalls, apiV2Calls } = await testDuplicateAPICalls(
52+
page,
53+
`/${user.username}/${eventType?.slug}`,
54+
beginningOfMonth
55+
);
2956

30-
await page.goto(`/${user.username}/${eventType?.slug}`);
57+
expect(totalCalls).toBeGreaterThan(0);
58+
expect(totalCalls).toBeLessThanOrEqual(1);
59+
expect(trpcCalls).toBeLessThanOrEqual(1);
60+
expect(apiV2Calls).toBeLessThanOrEqual(1);
61+
});
3162

32-
await page.waitForTimeout(5000);
63+
test("should detect when schedule endpoints are called multiple times for individual user events - end of month", async ({
64+
page,
65+
users,
66+
}) => {
67+
const user = await users.create();
68+
const eventType = user.eventTypes.find((e) => e.slug === "30-min");
69+
const endOfMonth = new Date();
70+
endOfMonth.setDate(20);
3371

34-
const totalCalls = trpcCalls.length + apiV2Calls.length;
72+
const { totalCalls, trpcCalls, apiV2Calls } = await testDuplicateAPICalls(
73+
page,
74+
`/${user.username}/${eventType?.slug}`,
75+
endOfMonth
76+
);
3577

3678
expect(totalCalls).toBeGreaterThan(0);
3779
expect(totalCalls).toBeLessThanOrEqual(1);
38-
expect(trpcCalls.length).toBeLessThanOrEqual(1);
39-
expect(apiV2Calls.length).toBeLessThanOrEqual(1);
80+
expect(trpcCalls).toBeLessThanOrEqual(1);
81+
expect(apiV2Calls).toBeLessThanOrEqual(1);
4082
});
4183

42-
test("should detect when schedule endpoints are called multiple times for team events", async ({
84+
test("should detect when schedule endpoints are called multiple times for team events - beginning of month", async ({
4385
page,
4486
users,
4587
}) => {
@@ -50,6 +92,8 @@ test.describe("Duplicate API Calls Prevention", () => {
5092
teammates: [{ name: "teammate-1" }],
5193
}
5294
);
95+
const beginningOfMonth = new Date();
96+
beginningOfMonth.setDate(5);
5397

5498
const { team } = await teamOwner.getFirstTeamMembership();
5599
const teamEvent = await createTeamEventType(
@@ -58,32 +102,52 @@ test.describe("Duplicate API Calls Prevention", () => {
58102
{ teamEventSlug: "team-event-test", teamEventTitle: "Team Event Test" }
59103
);
60104

61-
const trpcCalls: string[] = [];
62-
const apiV2Calls: string[] = [];
63-
64-
await page.route("**/api/trpc/slots/getSchedule**", async (route) => {
65-
trpcCalls.push(route.request().url());
66-
await route.continue();
67-
});
105+
const { totalCalls, trpcCalls, apiV2Calls } = await testDuplicateAPICalls(
106+
page,
107+
`/team/${team.slug}/${teamEvent.slug}`,
108+
beginningOfMonth
109+
);
68110

69-
await page.route("**/api/v2/slots/available**", async (route) => {
70-
apiV2Calls.push(route.request().url());
71-
await route.continue();
72-
});
111+
expect(totalCalls).toBeGreaterThan(0);
112+
expect(totalCalls).toBeLessThanOrEqual(1);
113+
expect(trpcCalls).toBeLessThanOrEqual(1);
114+
expect(apiV2Calls).toBeLessThanOrEqual(1);
115+
});
73116

74-
await page.goto(`/team/${team.slug}/${teamEvent.slug}`);
117+
test("should detect when schedule endpoints are called multiple times for team events - end of month", async ({
118+
page,
119+
users,
120+
}) => {
121+
const teamOwner = await users.create(
122+
{ name: "Team Owner" },
123+
{
124+
hasTeam: true,
125+
teammates: [{ name: "teammate-1" }],
126+
}
127+
);
75128

76-
await page.waitForTimeout(5000);
129+
const { team } = await teamOwner.getFirstTeamMembership();
130+
const teamEvent = await createTeamEventType(
131+
{ id: teamOwner.id },
132+
{ id: team.id },
133+
{ teamEventSlug: "team-event-test", teamEventTitle: "Team Event Test" }
134+
);
135+
const endOfMonth = new Date();
136+
endOfMonth.setDate(20);
77137

78-
const totalCalls = trpcCalls.length + apiV2Calls.length;
138+
const { totalCalls, trpcCalls, apiV2Calls } = await testDuplicateAPICalls(
139+
page,
140+
`/team/${team.slug}/${teamEvent.slug}`,
141+
endOfMonth
142+
);
79143

80144
expect(totalCalls).toBeGreaterThan(0);
81145
expect(totalCalls).toBeLessThanOrEqual(1);
82-
expect(trpcCalls.length).toBeLessThanOrEqual(1);
83-
expect(apiV2Calls.length).toBeLessThanOrEqual(1);
146+
expect(trpcCalls).toBeLessThanOrEqual(1);
147+
expect(apiV2Calls).toBeLessThanOrEqual(1);
84148
});
85149

86-
test("should detect when schedule endpoints are called multiple times for organization team events", async ({
150+
test("should detect when schedule endpoints are called multiple times for organization team events - beginning of month", async ({
87151
page,
88152
users,
89153
}) => {
@@ -105,29 +169,55 @@ test.describe("Duplicate API Calls Prevention", () => {
105169
{ id: team.id },
106170
{ teamEventSlug: "org-team-event", teamEventTitle: "Org Team Event" }
107171
);
172+
const beginningOfMonth = new Date();
173+
beginningOfMonth.setDate(5);
108174

109-
const trpcCalls: string[] = [];
110-
const apiV2Calls: string[] = [];
111-
112-
await page.route("**/api/trpc/slots/getSchedule**", async (route) => {
113-
trpcCalls.push(route.request().url());
114-
await route.continue();
115-
});
175+
const { totalCalls, trpcCalls, apiV2Calls } = await testDuplicateAPICalls(
176+
page,
177+
`/org/${org.slug}/${team.slug}/${teamEvent.slug}`,
178+
beginningOfMonth
179+
);
116180

117-
await page.route("**/api/v2/slots/available**", async (route) => {
118-
apiV2Calls.push(route.request().url());
119-
await route.continue();
120-
});
181+
expect(totalCalls).toBeGreaterThan(0);
182+
expect(totalCalls).toBeLessThanOrEqual(1);
183+
expect(trpcCalls).toBeLessThanOrEqual(1);
184+
expect(apiV2Calls).toBeLessThanOrEqual(1);
185+
});
121186

122-
await page.goto(`/org/${org.slug}/${team.slug}/${teamEvent.slug}`);
187+
test("should detect when schedule endpoints are called multiple times for organization team events - end of month", async ({
188+
page,
189+
users,
190+
}) => {
191+
const orgOwner = await users.create(
192+
{ name: "Org Owner" },
193+
{
194+
hasTeam: true,
195+
teammates: [{ name: "teammate-1" }],
196+
isOrg: true,
197+
isOrgVerified: true,
198+
hasSubteam: true,
199+
}
200+
);
123201

124-
await page.waitForTimeout(5000);
202+
const { team } = await orgOwner.getFirstTeamMembership();
203+
const { team: org } = await orgOwner.getOrgMembership();
204+
const teamEvent = await createTeamEventType(
205+
{ id: orgOwner.id },
206+
{ id: team.id },
207+
{ teamEventSlug: "org-team-event", teamEventTitle: "Org Team Event" }
208+
);
209+
const endOfMonth = new Date();
210+
endOfMonth.setDate(20);
125211

126-
const totalCalls = trpcCalls.length + apiV2Calls.length;
212+
const { totalCalls, trpcCalls, apiV2Calls } = await testDuplicateAPICalls(
213+
page,
214+
`/org/${org.slug}/${team.slug}/${teamEvent.slug}`,
215+
endOfMonth
216+
);
127217

128218
expect(totalCalls).toBeGreaterThan(0);
129219
expect(totalCalls).toBeLessThanOrEqual(1);
130-
expect(trpcCalls.length).toBeLessThanOrEqual(1);
131-
expect(apiV2Calls.length).toBeLessThanOrEqual(1);
220+
expect(trpcCalls).toBeLessThanOrEqual(1);
221+
expect(apiV2Calls).toBeLessThanOrEqual(1);
132222
});
133223
});

0 commit comments

Comments
 (0)