test: flaky unit test (#26310)

* fix: wip

* test

* Change pull_request to pull_request_target in workflow

* test

* update

* fix unit test flakes

* Update cache path to exclude node_modules

Remove node_modules from cache path in action.yml
This commit is contained in:
Anik Dhabal Babu
2025-12-30 14:20:29 -03:00
committed by GitHub
parent bc6ff386a4
commit 77ff8607d1
@@ -1,14 +1,14 @@
import prismock from "../../../../../../tests/libs/__mocks__/prisma";
import { describe, expect, it, vi, beforeEach } from "vitest";
import { intentToCreateOrgHandler } from "./intentToCreateOrg.handler";
import { LicenseKeySingleton } from "@calcom/ee/common/server/LicenseKeyService";
import { OrganizationPaymentService } from "@calcom/features/ee/organizations/lib/OrganizationPaymentService";
import { BillingPeriod, UserPermissionRole, CreationSource } from "@calcom/prisma/enums";
import {
BillingPeriod,
UserPermissionRole,
CreationSource,
} from "@calcom/prisma/enums";
import { TRPCError } from "@trpc/server";
import { intentToCreateOrgHandler } from "./intentToCreateOrg.handler";
import { describe, expect, it, vi, beforeEach } from "vitest";
vi.mock("@calcom/ee/common/server/LicenseKeyService", () => ({
LicenseKeySingleton: {
@@ -18,6 +18,65 @@ vi.mock("@calcom/ee/common/server/LicenseKeyService", () => ({
vi.mock("@calcom/features/ee/organizations/lib/OrganizationPaymentService");
vi.mock("@calcom/features/ee/teams/repositories/TeamRepository", () => ({
TeamRepository: class {
constructor() {}
findOwnedTeamsByUserId() {
return Promise.resolve([]);
}
findById() {
return Promise.resolve({
id: 1,
name: "Test Org",
slug: "test-org",
logoUrl: null,
parentId: null,
metadata: {},
isOrganization: true,
organizationSettings: null,
isPlatform: false,
});
}
},
}));
vi.mock(
"@calcom/trpc/server/routers/viewer/organizations/createTeams.handler",
() => ({
createTeamsHandler: vi.fn().mockResolvedValue({}),
})
);
vi.mock(
"@calcom/trpc/server/routers/viewer/teams/inviteMember/inviteMember.handler",
() => ({
inviteMembersWithNoInviterPermissionCheck: vi.fn().mockResolvedValue({}),
})
);
vi.mock("@calcom/lib/server/i18n", () => ({
getTranslation: vi
.fn()
.mockImplementation(async (locale: string, namespace: string) => {
const t = (key: string) => key;
t.locale = locale;
t.namespace = namespace;
return t;
}),
}));
vi.mock("@calcom/lib/domainManager/organization", () => ({
createDomain: vi.fn().mockResolvedValue({}),
}));
vi.mock("@calcom/emails/organization-email-service", () => ({
sendOrganizationCreationEmail: vi.fn().mockResolvedValue({}),
}));
vi.mock("@calcom/features/auth/lib/verifyEmail", () => ({
sendEmailVerification: vi.fn().mockResolvedValue({}),
}));
const mockInput = {
name: "Test Org",
slug: "test-org",
@@ -57,25 +116,27 @@ describe("intentToCreateOrgHandler", () => {
vi.mocked(OrganizationPaymentService).mockImplementation(() => {
return {
createOrganizationOnboarding: vi.fn().mockImplementation(async (data: any) => {
return await prismock.organizationOnboarding.create({
data: {
id: "onboarding-123",
name: data.name,
slug: data.slug,
orgOwnerEmail: data.orgOwnerEmail,
seats: data.seats ?? 10,
pricePerSeat: data.pricePerSeat ?? 15,
billingPeriod: data.billingPeriod ?? BillingPeriod.MONTHLY,
isComplete: false,
stripeCustomerId: null,
createdById: data.createdByUserId,
teams: data.teams ?? [],
invitedMembers: data.invitedMembers ?? [],
isPlatform: data.isPlatform ?? false,
},
});
}),
createOrganizationOnboarding: vi
.fn()
.mockImplementation(async (data: any) => {
return await prismock.organizationOnboarding.create({
data: {
id: "onboarding-123",
name: data.name,
slug: data.slug,
orgOwnerEmail: data.orgOwnerEmail,
seats: data.seats ?? 10,
pricePerSeat: data.pricePerSeat ?? 15,
billingPeriod: data.billingPeriod ?? BillingPeriod.MONTHLY,
isComplete: false,
stripeCustomerId: null,
createdById: data.createdByUserId,
teams: data.teams ?? [],
invitedMembers: data.invitedMembers ?? [],
isPlatform: data.isPlatform ?? false,
},
});
}),
createPaymentIntent: vi.fn().mockResolvedValue({
checkoutUrl: "https://stripe.com/checkout/session",
organizationOnboarding: {},
@@ -137,20 +198,25 @@ describe("intentToCreateOrgHandler", () => {
organizationOnboardingId: expect.any(String),
checkoutUrl: null,
organizationId: null, // Not created yet - handover flow
handoverUrl: expect.stringContaining("/settings/organizations/new/resume?onboardingId="),
handoverUrl: expect.stringContaining(
"/settings/organizations/new/resume?onboardingId="
),
});
// Verify organization onboarding was created
const organizationOnboarding = await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
const organizationOnboarding =
await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
expect(organizationOnboarding).toBeDefined();
expect(organizationOnboarding?.name).toBe(mockInput.name);
expect(organizationOnboarding?.slug).toBe(mockInput.slug);
expect(organizationOnboarding?.orgOwnerEmail).toBe(mockInput.orgOwnerEmail);
expect(organizationOnboarding?.orgOwnerEmail).toBe(
mockInput.orgOwnerEmail
);
});
it("should allow user to create org for themselves", async () => {
@@ -185,7 +251,12 @@ describe("intentToCreateOrgHandler", () => {
user: null as any,
},
})
).rejects.toThrow(new TRPCError({ code: "UNAUTHORIZED", message: "You are not authorized." }));
).rejects.toThrow(
new TRPCError({
code: "UNAUTHORIZED",
message: "You are not authorized.",
})
);
});
it("should throw forbidden error when non-admin tries to create org for another user", async () => {
@@ -344,20 +415,25 @@ describe("intentToCreateOrgHandler", () => {
organizationOnboardingId: expect.any(String),
checkoutUrl: null,
organizationId: null, // Not created yet - handover flow
handoverUrl: expect.stringContaining("/settings/organizations/new/resume?onboardingId="),
handoverUrl: expect.stringContaining(
"/settings/organizations/new/resume?onboardingId="
),
});
// Verify organization onboarding was created
const organizationOnboarding = await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
const organizationOnboarding =
await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
expect(organizationOnboarding).toBeDefined();
expect(organizationOnboarding?.name).toBe(mockInput.name);
expect(organizationOnboarding?.slug).toBe(mockInput.slug);
expect(organizationOnboarding?.orgOwnerEmail).toBe(mockInput.orgOwnerEmail);
expect(organizationOnboarding?.orgOwnerEmail).toBe(
mockInput.orgOwnerEmail
);
});
it("should handle teams and invites in the request", async () => {
@@ -397,15 +473,20 @@ describe("intentToCreateOrgHandler", () => {
expect(result.organizationOnboardingId).toBeDefined();
const organizationOnboarding = await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
const organizationOnboarding =
await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
expect(organizationOnboarding).toBeDefined();
expect(organizationOnboarding?.teams).toEqual(inputWithTeamsAndInvites.teams);
expect(organizationOnboarding?.invitedMembers).toEqual(inputWithTeamsAndInvites.invitedMembers);
expect(organizationOnboarding?.teams).toEqual(
inputWithTeamsAndInvites.teams
);
expect(organizationOnboarding?.invitedMembers).toEqual(
inputWithTeamsAndInvites.invitedMembers
);
});
it("should preserve teamName, teamId, and role in invites payload", async () => {
@@ -433,7 +514,12 @@ describe("intentToCreateOrgHandler", () => {
],
invitedMembers: [
{ email: "new@new.com", teamName: "new", teamId: -1, role: "ADMIN" },
{ email: "team@new.com", teamName: "team", teamId: -1, role: "ADMIN" },
{
email: "team@new.com",
teamName: "team",
teamId: -1,
role: "ADMIN",
},
],
};
@@ -446,14 +532,17 @@ describe("intentToCreateOrgHandler", () => {
expect(result.organizationOnboardingId).toBeDefined();
const organizationOnboarding = await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
const organizationOnboarding =
await prismock.organizationOnboarding.findFirst({
where: {
slug: mockInput.slug,
},
});
expect(organizationOnboarding).toBeDefined();
expect(organizationOnboarding?.teams).toEqual(inputWithTeamsAndInvites.teams);
expect(organizationOnboarding?.teams).toEqual(
inputWithTeamsAndInvites.teams
);
// Verify invitedMembers are stored with all fields including teamName, teamId, and role
expect(organizationOnboarding?.invitedMembers).toBeDefined();