* feat: Cal.diy — community-driven MIT-licensed fork of Cal.com This squashed commit contains all Cal.diy changes applied on top of calcom/cal.com main: - Rebrand Cal.com to Cal.diy across the entire codebase - Remove Enterprise Edition (EE) features, license checks, and AGPL restrictions - Switch license from AGPL-3.0 to MIT - Remove docs/ directory (migrated to Nextra at cal.diy) - Remove dead code: org tests, EE tips, platform nav, premium username, SAML/SSO, etc. - Clean up .env.example for self-hosted Cal.diy - Update Docker image references to calcom/cal.diy - Update README, CONTRIBUTING.md, and issue templates for Cal.diy community fork - Add PR welcome bot for Cal.diy contributors - Fix API v2 breaking changes oasdiff ignore entries - Replace Blacksmith CI runners with default GitHub Actions 3893 files changed, 20789 insertions(+), 411020 deletions(-) Co-Authored-By: benny@cal.com <sldisek783@gmail.com> * refactor: remove org-specific /organizations/:orgId endpoints from API v2 atoms controllers (#1701) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix: revert Cal.diy Inc to Cal.com, Inc. in license files, copyright notices, and package metadata (#1702) Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * rip out org related comments in api v2 --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
233 lines
6.7 KiB
TypeScript
233 lines
6.7 KiB
TypeScript
import { IdentityProvider } from "@calcom/prisma/enums";
|
|
import { beforeEach, describe, expect, it, vi } from "vitest";
|
|
import type { TrpcSessionUser } from "../../../types";
|
|
|
|
const {
|
|
mockFindAllProfilesForUserIncludingMovedUser,
|
|
mockEnrichUserWithTheProfile,
|
|
mockFindUnique,
|
|
mockFindMany,
|
|
mockGetTeamIdsWithPermission,
|
|
MockUserRepository,
|
|
MockPermissionCheckService,
|
|
} = vi.hoisted(() => {
|
|
const mockFindAllProfilesForUserIncludingMovedUser = vi.fn();
|
|
const mockEnrichUserWithTheProfile = vi.fn();
|
|
const mockFindUnique = vi.fn();
|
|
const mockFindMany = vi.fn();
|
|
const mockGetTeamIdsWithPermission = vi.fn();
|
|
|
|
class MockUserRepository {
|
|
enrichUserWithTheProfile = (...args: unknown[]) => mockEnrichUserWithTheProfile(...args);
|
|
}
|
|
|
|
class MockPermissionCheckService {
|
|
getTeamIdsWithPermission = (...args: unknown[]) => mockGetTeamIdsWithPermission(...args);
|
|
}
|
|
|
|
return {
|
|
mockFindAllProfilesForUserIncludingMovedUser,
|
|
mockEnrichUserWithTheProfile,
|
|
mockFindUnique,
|
|
mockFindMany,
|
|
mockGetTeamIdsWithPermission,
|
|
MockUserRepository,
|
|
MockPermissionCheckService,
|
|
};
|
|
});
|
|
|
|
vi.mock("@calcom/features/profile/repositories/ProfileRepository", () => ({
|
|
ProfileRepository: {
|
|
findAllProfilesForUserIncludingMovedUser: (...args: unknown[]) =>
|
|
mockFindAllProfilesForUserIncludingMovedUser(...args),
|
|
buildPersonalProfileFromUser: vi.fn(() => ({ upId: "usr_1" })),
|
|
},
|
|
}));
|
|
|
|
vi.mock("@calcom/features/users/repositories/UserRepository", () => ({
|
|
UserRepository: MockUserRepository,
|
|
}));
|
|
|
|
vi.mock("@calcom/features/pbac/services/permission-check.service", () => ({
|
|
PermissionCheckService: MockPermissionCheckService,
|
|
}));
|
|
|
|
vi.mock("@calcom/lib/getAvatarUrl", () => ({
|
|
getUserAvatarUrl: vi.fn(() => "https://avatar.example.com/1"),
|
|
}));
|
|
|
|
vi.mock("@calcom/prisma", () => ({
|
|
default: {
|
|
secondaryEmail: {
|
|
findMany: (...args: unknown[]) => mockFindMany(...args),
|
|
},
|
|
account: {
|
|
findUnique: (...args: unknown[]) => mockFindUnique(...args),
|
|
},
|
|
user: {
|
|
findUnique: vi.fn(),
|
|
},
|
|
},
|
|
}));
|
|
|
|
import { getHandler } from "./get.handler";
|
|
|
|
describe("getHandler - identity provider email lookup", () => {
|
|
const baseUser = {
|
|
id: 1,
|
|
name: "Test User",
|
|
email: "test@example.com",
|
|
username: "testuser",
|
|
emailVerified: new Date(),
|
|
bufferTime: 0,
|
|
locale: "en",
|
|
timeFormat: 12,
|
|
timeZone: "UTC",
|
|
avatar: null,
|
|
avatarUrl: null,
|
|
createdDate: new Date(),
|
|
trialEndsAt: null,
|
|
defaultScheduleId: null,
|
|
completedOnboarding: true,
|
|
twoFactorEnabled: false,
|
|
brandColor: "#000000",
|
|
darkBrandColor: "#ffffff",
|
|
bio: null,
|
|
weekStart: "Monday",
|
|
theme: null,
|
|
appTheme: null,
|
|
hideBranding: false,
|
|
metadata: null,
|
|
defaultBookerLayouts: null,
|
|
allowDynamicBooking: true,
|
|
allowSEOIndexing: true,
|
|
receiveMonthlyDigestEmail: true,
|
|
requiresBookerEmailVerification: false,
|
|
role: "USER",
|
|
organization: null,
|
|
teams: [],
|
|
};
|
|
|
|
function createCtx(overrides: Partial<typeof baseUser> = {}) {
|
|
return {
|
|
user: { ...baseUser, ...overrides } as unknown as NonNullable<TrpcSessionUser>,
|
|
session: { upId: "usr_1" } as any,
|
|
};
|
|
}
|
|
|
|
beforeEach(() => {
|
|
vi.clearAllMocks();
|
|
|
|
mockFindAllProfilesForUserIncludingMovedUser.mockResolvedValue([]);
|
|
mockEnrichUserWithTheProfile.mockImplementation(({ user }) => ({
|
|
...user,
|
|
profile: null,
|
|
}));
|
|
mockFindMany.mockResolvedValue([]);
|
|
mockGetTeamIdsWithPermission.mockResolvedValue([]);
|
|
mockFindUnique.mockResolvedValue(null);
|
|
});
|
|
|
|
it("maps AZUREAD identity provider to 'azure-ad' in account lookup", async () => {
|
|
const ctx = createCtx({
|
|
identityProvider: IdentityProvider.AZUREAD,
|
|
identityProviderId: "azure-provider-id-123",
|
|
} as any);
|
|
mockEnrichUserWithTheProfile.mockImplementation(({ user }) => ({
|
|
...user,
|
|
identityProvider: IdentityProvider.AZUREAD,
|
|
identityProviderId: "azure-provider-id-123",
|
|
profile: null,
|
|
}));
|
|
mockFindUnique.mockResolvedValue({ providerEmail: "azure@example.com" });
|
|
|
|
const result = await getHandler({ ctx, input: {} });
|
|
|
|
expect(mockFindUnique).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: {
|
|
provider_providerAccountId: {
|
|
provider: "azure-ad",
|
|
providerAccountId: "azure-provider-id-123",
|
|
},
|
|
},
|
|
})
|
|
);
|
|
expect(result.identityProviderEmail).toBe("azure@example.com");
|
|
});
|
|
|
|
it("maps GOOGLE identity provider to 'google' in account lookup", async () => {
|
|
const ctx = createCtx({
|
|
identityProvider: IdentityProvider.GOOGLE,
|
|
identityProviderId: "google-id-456",
|
|
} as any);
|
|
mockEnrichUserWithTheProfile.mockImplementation(({ user }) => ({
|
|
...user,
|
|
identityProvider: IdentityProvider.GOOGLE,
|
|
identityProviderId: "google-id-456",
|
|
profile: null,
|
|
}));
|
|
mockFindUnique.mockResolvedValue({ providerEmail: "google@example.com" });
|
|
|
|
const result = await getHandler({ ctx, input: {} });
|
|
|
|
expect(mockFindUnique).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: {
|
|
provider_providerAccountId: {
|
|
provider: "google",
|
|
providerAccountId: "google-id-456",
|
|
},
|
|
},
|
|
})
|
|
);
|
|
expect(result.identityProviderEmail).toBe("google@example.com");
|
|
});
|
|
|
|
it("maps CAL identity provider to 'cal' in account lookup", async () => {
|
|
const ctx = createCtx({
|
|
identityProvider: IdentityProvider.CAL,
|
|
identityProviderId: "cal-id-789",
|
|
} as any);
|
|
mockEnrichUserWithTheProfile.mockImplementation(({ user }) => ({
|
|
...user,
|
|
identityProvider: IdentityProvider.CAL,
|
|
identityProviderId: "cal-id-789",
|
|
profile: null,
|
|
}));
|
|
mockFindUnique.mockResolvedValue(null);
|
|
|
|
const result = await getHandler({ ctx, input: {} });
|
|
|
|
expect(mockFindUnique).toHaveBeenCalledWith(
|
|
expect.objectContaining({
|
|
where: {
|
|
provider_providerAccountId: {
|
|
provider: "cal",
|
|
providerAccountId: "cal-id-789",
|
|
},
|
|
},
|
|
})
|
|
);
|
|
expect(result.identityProviderEmail).toBe("");
|
|
});
|
|
|
|
it("returns empty string when no account found", async () => {
|
|
const ctx = createCtx({
|
|
identityProvider: IdentityProvider.AZUREAD,
|
|
identityProviderId: "nonexistent-id",
|
|
} as any);
|
|
mockEnrichUserWithTheProfile.mockImplementation(({ user }) => ({
|
|
...user,
|
|
identityProvider: IdentityProvider.AZUREAD,
|
|
identityProviderId: "nonexistent-id",
|
|
profile: null,
|
|
}));
|
|
mockFindUnique.mockResolvedValue(null);
|
|
|
|
const result = await getHandler({ ctx, input: {} });
|
|
|
|
expect(result.identityProviderEmail).toBe("");
|
|
});
|
|
});
|