Skip to content

Commit e5abe93

Browse files
fix: Add beforeAll hooks to ensure organization settings are properly configured in integration tests (calcom#24674)
The flaky test failures were caused by the tests depending on the database being properly seeded with the isAdminAPIEnabled flag set to true for the Acme organization. The tests would fail randomly when the database wasn't properly seeded or when the organization settings weren't configured correctly. This fix adds beforeAll hooks to the failing integration tests to ensure that: 1. The Acme organization has isAdminAPIEnabled set to true 2. The Dunder Mifflin organization has isAdminAPIEnabled set to false This ensures consistent test behavior regardless of the database state and prevents the flaky failures. Fixes the following failing tests: - isAdmin.integration-test.ts: Returns org-wide admin when user is set as such & admin API access is granted - retrieveScopedAccessibleUsers.integration-test.ts: Returns members when admin user ID is supplied and members IDs are supplied - retrieveScopedAccessibleUsers.integration-test.ts: Returns members when admin user ID is an admin of an org - _get.integration-test.ts: Returns bookings for org users when accessed by org admin - _patch.integration-test.ts: Allows PATCH when user is org-wide admin Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
1 parent c3a5158 commit e5abe93

4 files changed

Lines changed: 123 additions & 9 deletions

File tree

apps/api/v1/test/lib/bookings/[id]/_patch.integration-test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Request, Response } from "express";
22
import type { NextApiRequest, NextApiResponse } from "next";
33
import { createMocks } from "node-mocks-http";
4-
import { describe, it, expect } from "vitest";
4+
import { describe, it, expect, beforeAll } from "vitest";
55

66
import prisma from "@calcom/prisma";
77

@@ -11,6 +11,30 @@ type CustomNextApiRequest = NextApiRequest & Request;
1111
type CustomNextApiResponse = NextApiResponse & Response;
1212

1313
describe("PATCH /api/bookings", () => {
14+
beforeAll(async () => {
15+
const acmeOrg = await prisma.team.findFirst({
16+
where: {
17+
slug: "acme",
18+
isOrganization: true,
19+
},
20+
});
21+
22+
if (acmeOrg) {
23+
await prisma.organizationSettings.upsert({
24+
where: {
25+
organizationId: acmeOrg.id,
26+
},
27+
update: {
28+
isAdminAPIEnabled: true,
29+
},
30+
create: {
31+
organizationId: acmeOrg.id,
32+
orgAutoAcceptEmail: "acme.com",
33+
isAdminAPIEnabled: true,
34+
},
35+
});
36+
}
37+
});
1438
it("Returns 403 when user has no permission to the booking", async () => {
1539
const memberUser = await prisma.user.findFirstOrThrow({ where: { email: "member2-acme@example.com" } });
1640
const proUser = await prisma.user.findFirstOrThrow({ where: { email: "pro@example.com" } });

apps/api/v1/test/lib/bookings/_get.integration-test.ts

Lines changed: 25 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Request, Response } from "express";
22
import type { NextApiRequest, NextApiResponse } from "next";
33
import { createMocks } from "node-mocks-http";
4-
import { describe, expect, it } from "vitest";
4+
import { describe, expect, it, beforeAll } from "vitest";
55
import { ZodError } from "zod";
66

77
import prisma from "@calcom/prisma";
@@ -17,6 +17,30 @@ const DefaultPagination = {
1717
};
1818

1919
describe("GET /api/bookings", async () => {
20+
beforeAll(async () => {
21+
const acmeOrg = await prisma.team.findFirst({
22+
where: {
23+
slug: "acme",
24+
isOrganization: true,
25+
},
26+
});
27+
28+
if (acmeOrg) {
29+
await prisma.organizationSettings.upsert({
30+
where: {
31+
organizationId: acmeOrg.id,
32+
},
33+
update: {
34+
isAdminAPIEnabled: true,
35+
},
36+
create: {
37+
organizationId: acmeOrg.id,
38+
orgAutoAcceptEmail: "acme.com",
39+
isAdminAPIEnabled: true,
40+
},
41+
});
42+
}
43+
});
2044
const proUser = await prisma.user.findFirstOrThrow({ where: { email: "pro@example.com" } });
2145
const proUserBooking = await prisma.booking.findFirstOrThrow({ where: { userId: proUser.id } });
2246

@@ -318,11 +342,6 @@ describe("GET /api/bookings", async () => {
318342

319343
const testUser = await prisma.user.findFirstOrThrow({ where: { email: "pro@example.com" } });
320344

321-
const testUserBooking = await prisma.booking.findFirstOrThrow({
322-
where: { userId: testUser.id },
323-
include: { attendees: true },
324-
});
325-
326345
const { req } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
327346
method: "GET",
328347
query: {

apps/api/v1/test/lib/utils/isAdmin.integration-test.ts

Lines changed: 48 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import type { Request, Response } from "express";
22
import type { NextApiRequest, NextApiResponse } from "next";
33
import { createMocks } from "node-mocks-http";
4-
import { describe, it, expect } from "vitest";
4+
import { describe, it, expect, beforeAll } from "vitest";
55

66
import prisma from "@calcom/prisma";
77

@@ -12,6 +12,53 @@ type CustomNextApiRequest = NextApiRequest & Request;
1212
type CustomNextApiResponse = NextApiResponse & Response;
1313

1414
describe("isAdmin guard", () => {
15+
beforeAll(async () => {
16+
const acmeOrg = await prisma.team.findFirst({
17+
where: {
18+
slug: "acme",
19+
isOrganization: true,
20+
},
21+
});
22+
23+
if (acmeOrg) {
24+
await prisma.organizationSettings.upsert({
25+
where: {
26+
organizationId: acmeOrg.id,
27+
},
28+
update: {
29+
isAdminAPIEnabled: true,
30+
},
31+
create: {
32+
organizationId: acmeOrg.id,
33+
orgAutoAcceptEmail: "acme.com",
34+
isAdminAPIEnabled: true,
35+
},
36+
});
37+
}
38+
39+
const dunderOrg = await prisma.team.findFirst({
40+
where: {
41+
slug: "dunder-mifflin",
42+
isOrganization: true,
43+
},
44+
});
45+
46+
if (dunderOrg) {
47+
await prisma.organizationSettings.upsert({
48+
where: {
49+
organizationId: dunderOrg.id,
50+
},
51+
update: {
52+
isAdminAPIEnabled: false,
53+
},
54+
create: {
55+
organizationId: dunderOrg.id,
56+
orgAutoAcceptEmail: "dunder-mifflin.com",
57+
isAdminAPIEnabled: false,
58+
},
59+
});
60+
}
61+
});
1562
it("Returns false when user does not exist in the system", async () => {
1663
const { req } = createMocks<CustomNextApiRequest, CustomNextApiResponse>({
1764
method: "POST",

apps/api/v1/test/lib/utils/retrieveScopedAccessibleUsers.integration-test.ts

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { describe, it, expect } from "vitest";
1+
import { describe, it, expect, beforeAll } from "vitest";
22

33
import prisma from "@calcom/prisma";
44

@@ -8,6 +8,30 @@ import {
88
} from "../../../lib/utils/retrieveScopedAccessibleUsers";
99

1010
describe("retrieveScopedAccessibleUsers tests", () => {
11+
beforeAll(async () => {
12+
const acmeOrg = await prisma.team.findFirst({
13+
where: {
14+
slug: "acme",
15+
isOrganization: true,
16+
},
17+
});
18+
19+
if (acmeOrg) {
20+
await prisma.organizationSettings.upsert({
21+
where: {
22+
organizationId: acmeOrg.id,
23+
},
24+
update: {
25+
isAdminAPIEnabled: true,
26+
},
27+
create: {
28+
organizationId: acmeOrg.id,
29+
orgAutoAcceptEmail: "acme.com",
30+
isAdminAPIEnabled: true,
31+
},
32+
});
33+
}
34+
});
1135
describe("getAccessibleUsers", () => {
1236
it("Does not return members when only admin user ID is supplied", async () => {
1337
const adminUser = await prisma.user.findFirstOrThrow({ where: { email: "owner1-acme@example.com" } });

0 commit comments

Comments
 (0)