refactor: Membership.findByUserIdAndTeamId to instance method (#26628)

* Make  and instance method

* Refactor files

* fix: update MembershipRepository mocks to use vi.hoisted() for proper hoisting

Co-Authored-By: joe@cal.com <j.auyeung419@gmail.com>

---------

Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
Joe Au-Yeung
2026-01-09 22:37:42 -03:00
committed by GitHub
co-authored by joe@cal.com Devin AI
parent 2a26a591a8
commit f6d3b11582
14 changed files with 117 additions and 90 deletions
@@ -4,7 +4,6 @@ import { PaymentServiceMap } from "@calcom/app-store/payment.services.generated"
import { sendNoShowFeeChargedEmail } from "@calcom/emails/billing-email-service";
import { CredentialRepository } from "@calcom/features/credentials/repositories/CredentialRepository";
import { TeamRepository } from "@calcom/features/ee/teams/repositories/TeamRepository";
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
import { ErrorCode } from "@calcom/lib/errorCodes";
import { ErrorWithCode } from "@calcom/lib/errors";
import { getTranslation } from "@calcom/lib/server/i18n";
@@ -14,9 +13,11 @@ import { handleNoShowFee } from "./handleNoShowFee";
vi.mock("@calcom/app-store/payment.services.generated", () => ({
PaymentServiceMap: {
stripepayment: Promise.resolve({
PaymentService: vi.fn().mockImplementation(function() { return {
chargeCard: vi.fn(),
}; }),
PaymentService: vi.fn().mockImplementation(function () {
return {
chargeCard: vi.fn(),
};
}),
}),
},
}));
@@ -36,10 +37,18 @@ vi.mock("@calcom/features/credentials/repositories/CredentialRepository", () =>
},
}));
const { mockFindUniqueByUserIdAndTeamId, MockMembershipRepository } = vi.hoisted(() => {
const mockFindUniqueByUserIdAndTeamId = vi.fn();
class MockMembershipRepository {
findUniqueByUserIdAndTeamId = mockFindUniqueByUserIdAndTeamId;
}
return { mockFindUniqueByUserIdAndTeamId, MockMembershipRepository };
});
vi.mock("@calcom/features/membership/repositories/MembershipRepository", () => ({
MembershipRepository: {
findUniqueByUserIdAndTeamId: vi.fn(),
},
MembershipRepository: MockMembershipRepository,
}));
vi.mock("@calcom/features/ee/teams/repositories/TeamRepository", () => ({
@@ -154,7 +163,7 @@ describe("handleNoShowFee", () => {
mockPaymentService.chargeCard.mockResolvedValue({ success: true, paymentId: "pay_123" });
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
id: 1,
userId: 1,
teamId: 1,
@@ -175,7 +184,7 @@ describe("handleNoShowFee", () => {
});
expect(result).toEqual({ success: true, paymentId: "pay_123" });
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
expect(mockFindUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
userId: 1,
teamId: 1,
});
@@ -192,7 +201,7 @@ describe("handleNoShowFee", () => {
mockPaymentService.chargeCard.mockResolvedValue({ success: true, paymentId: "pay_123" });
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
id: 1,
userId: 1,
teamId: 1,
@@ -251,7 +260,7 @@ describe("handleNoShowFee", () => {
},
};
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue(null);
mockFindUniqueByUserIdAndTeamId.mockResolvedValue(null);
await expect(
handleNoShowFee({
@@ -104,7 +104,8 @@ export const handleNoShowFee = async ({
};
if (teamId) {
const userIsInTeam = await MembershipRepository.findUniqueByUserIdAndTeamId({
const membershipRepository = new MembershipRepository();
const userIsInTeam = await membershipRepository.findUniqueByUserIdAndTeamId({
userId,
teamId,
});
@@ -1,16 +1,23 @@
import { describe, expect, it, vi, beforeEach } from "vitest";
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
import type { Payment } from "@calcom/prisma/client";
import { handleNoShowFee } from "./handleNoShowFee";
import { processNoShowFeeOnCancellation } from "./processNoShowFeeOnCancellation";
import { shouldChargeNoShowCancellationFee } from "./shouldChargeNoShowCancellationFee";
const { mockFindUniqueByUserIdAndTeamId, MockMembershipRepository } = vi.hoisted(() => {
const mockFindUniqueByUserIdAndTeamId = vi.fn();
class MockMembershipRepository {
findUniqueByUserIdAndTeamId = mockFindUniqueByUserIdAndTeamId;
}
return { mockFindUniqueByUserIdAndTeamId, MockMembershipRepository };
});
vi.mock("@calcom/features/membership/repositories/MembershipRepository", () => ({
MembershipRepository: {
findUniqueByUserIdAndTeamId: vi.fn(),
},
MembershipRepository: MockMembershipRepository,
}));
vi.mock("./handleNoShowFee", () => ({
@@ -165,7 +172,7 @@ describe("processNoShowFeeOnCancellation", () => {
},
};
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
id: 1,
userId: 999,
teamId: 1,
@@ -183,7 +190,7 @@ describe("processNoShowFeeOnCancellation", () => {
cancelledByUserId: 999,
});
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
expect(mockFindUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
userId: 999,
teamId: 1,
});
@@ -200,7 +207,7 @@ describe("processNoShowFeeOnCancellation", () => {
},
};
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
id: 1,
userId: 999,
teamId: 1,
@@ -231,7 +238,7 @@ describe("processNoShowFeeOnCancellation", () => {
},
};
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
id: 1,
userId: 999,
teamId: 1,
@@ -264,7 +271,7 @@ describe("processNoShowFeeOnCancellation", () => {
cancelledByUserId: 999,
});
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
expect(mockFindUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
userId: 999,
teamId: 1,
});
@@ -281,7 +288,7 @@ describe("processNoShowFeeOnCancellation", () => {
},
};
vi.mocked(MembershipRepository.findUniqueByUserIdAndTeamId).mockResolvedValue(null);
mockFindUniqueByUserIdAndTeamId.mockResolvedValue(null);
vi.mocked(shouldChargeNoShowCancellationFee).mockReturnValue(true);
vi.mocked(handleNoShowFee).mockResolvedValue({
id: 999,
@@ -28,7 +28,8 @@ export const processNoShowFeeOnCancellation = async ({
// Skip no-show fee if the booking was cancelled by a team/org admin
if (cancelledByUserId && booking.eventType?.teamId) {
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const membershipRepository = new MembershipRepository();
const membership = await membershipRepository.findUniqueByUserIdAndTeamId({
userId: cancelledByUserId,
teamId: booking.eventType.teamId,
});
@@ -424,7 +424,8 @@ export const assignValueToUserInOrgBulk = async ({
attributeLabelToValueMap: AttributeLabelToValueMap;
updater: BulkAttributeAssigner;
}) => {
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({ userId, teamId: orgId });
const membershipRepository = new MembershipRepository();
const membership = await membershipRepository.findUniqueByUserIdAndTeamId({ userId, teamId: orgId });
const defaultReturn = { numOfAttributeOptionsSet: 0, numOfAttributeOptionsDeleted: 0 };
if (!membership) {
console.error(`User ${userId} not a member of org ${orgId}, not assigning attribute options`);
@@ -329,8 +329,8 @@ export class MembershipRepository {
});
}
static async findUniqueByUserIdAndTeamId({ userId, teamId }: { userId: number; teamId: number }) {
return await prisma.membership.findUnique({
async findUniqueByUserIdAndTeamId({ userId, teamId }: { userId: number; teamId: number }) {
return await this.prismaClient.membership.findUnique({
where: {
userId_teamId: {
userId,
@@ -15,7 +15,7 @@ export class MembershipService {
* Checks the membership status of a user within a specific team.
*/
async checkMembership(teamId: number, userId: number): Promise<MembershipCheckResult> {
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({ teamId, userId });
const membership = await this.membershipRepository.findUniqueByUserIdAndTeamId({ teamId, userId });
if (!membership || !membership.accepted) {
return {
@@ -166,7 +166,8 @@ export async function getRoutingFormPermissions({
};
}
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const membershipRepository = new MembershipRepository();
const membership = await membershipRepository.findUniqueByUserIdAndTeamId({
userId,
teamId: formTeamId,
});
@@ -30,6 +30,7 @@ describe("PermissionCheckService", () => {
let mockRepository: MockRepository;
let mockFeaturesRepository: { checkIfTeamHasFeature: Mock };
let mockPermissionService: { validatePermission: Mock; validatePermissions: Mock };
let mockMembershipRepository: { findUniqueByUserIdAndTeamId: Mock };
beforeEach(() => {
vi.clearAllMocks();
@@ -56,14 +57,16 @@ describe("PermissionCheckService", () => {
validatePermissions: vi.fn().mockReturnValue({ isValid: true }),
};
mockMembershipRepository = {
findUniqueByUserIdAndTeamId: vi.fn(),
};
service = new PermissionCheckService(
mockRepository,
mockFeaturesRepository as unknown as FeaturesRepository,
mockPermissionService as unknown as PermissionService
mockPermissionService as unknown as PermissionService,
mockMembershipRepository as unknown as MembershipRepository
);
// Mock MembershipRepository static method
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock) = vi.fn();
});
describe("checkPermission", () => {
@@ -104,7 +107,7 @@ describe("PermissionCheckService", () => {
updatedAt: new Date(),
};
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock).mockResolvedValueOnce(membership);
mockMembershipRepository.findUniqueByUserIdAndTeamId.mockResolvedValueOnce(membership);
mockFeaturesRepository.checkIfTeamHasFeature.mockResolvedValueOnce(false);
const result = await service.checkPermission({
@@ -115,7 +118,7 @@ describe("PermissionCheckService", () => {
});
expect(result).toBe(true);
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
userId: 1,
teamId: 1,
});
@@ -125,7 +128,7 @@ describe("PermissionCheckService", () => {
it("should return false if no team or org membership found when PBAC disabled", async () => {
mockFeaturesRepository.checkIfTeamHasFeature.mockResolvedValueOnce(false);
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock).mockResolvedValue(null);
mockMembershipRepository.findUniqueByUserIdAndTeamId.mockResolvedValue(null);
mockRepository.getTeamById.mockResolvedValueOnce({ id: 1, parentId: 100 });
const result = await service.checkPermission({
@@ -136,7 +139,7 @@ describe("PermissionCheckService", () => {
});
expect(result).toBe(false);
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledTimes(2);
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledTimes(2);
});
it("should use org membership when team membership not found (PBAC disabled)", async () => {
@@ -153,7 +156,7 @@ describe("PermissionCheckService", () => {
};
mockFeaturesRepository.checkIfTeamHasFeature.mockResolvedValueOnce(false);
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock)
mockMembershipRepository.findUniqueByUserIdAndTeamId
.mockResolvedValueOnce(null) // No team membership
.mockResolvedValueOnce(orgMembership); // Has org membership
mockRepository.getTeamById.mockResolvedValueOnce({ id: 1, parentId: 100 });
@@ -167,11 +170,11 @@ describe("PermissionCheckService", () => {
expect(result).toBe(true);
expect(mockRepository.getTeamById).toHaveBeenCalledWith(1);
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(1, {
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(1, {
userId: 1,
teamId: 1,
});
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(2, {
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(2, {
userId: 1,
teamId: 100,
});
@@ -203,7 +206,7 @@ describe("PermissionCheckService", () => {
};
mockFeaturesRepository.checkIfTeamHasFeature.mockResolvedValueOnce(false);
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock)
mockMembershipRepository.findUniqueByUserIdAndTeamId
.mockResolvedValueOnce(teamMembership) // Has team membership as MEMBER
.mockResolvedValueOnce(orgMembership); // Has org membership as ADMIN
mockRepository.getTeamById.mockResolvedValueOnce({ id: 1, parentId: 100 });
@@ -217,11 +220,11 @@ describe("PermissionCheckService", () => {
expect(result).toBe(true);
expect(mockRepository.getTeamById).toHaveBeenCalledWith(1);
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(1, {
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(1, {
userId: 1,
teamId: 1,
});
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(2, {
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(2, {
userId: 1,
teamId: 100,
});
@@ -362,7 +365,7 @@ describe("PermissionCheckService", () => {
updatedAt: new Date(),
};
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock).mockResolvedValueOnce(membership);
mockMembershipRepository.findUniqueByUserIdAndTeamId.mockResolvedValueOnce(membership);
mockFeaturesRepository.checkIfTeamHasFeature.mockResolvedValueOnce(false);
const result = await service.checkPermissions({
@@ -373,7 +376,7 @@ describe("PermissionCheckService", () => {
});
expect(result).toBe(true);
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
userId: 1,
teamId: 1,
});
@@ -395,7 +398,7 @@ describe("PermissionCheckService", () => {
};
mockFeaturesRepository.checkIfTeamHasFeature.mockResolvedValueOnce(false);
(MembershipRepository.findUniqueByUserIdAndTeamId as Mock)
mockMembershipRepository.findUniqueByUserIdAndTeamId
.mockResolvedValueOnce(null) // No team membership
.mockResolvedValueOnce(orgMembership); // Has org membership
mockRepository.getTeamById.mockResolvedValueOnce({ id: 1, parentId: 100 });
@@ -409,11 +412,11 @@ describe("PermissionCheckService", () => {
expect(result).toBe(true);
expect(mockRepository.getTeamById).toHaveBeenCalledWith(1);
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(1, {
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(1, {
userId: 1,
teamId: 1,
});
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(2, {
expect(mockMembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenNthCalledWith(2, {
userId: 1,
teamId: 100,
});
@@ -21,14 +21,17 @@ export class PermissionCheckService {
private readonly logger = logger.getSubLogger({ prefix: ["PermissionCheckService"] });
private readonly featuresRepository: FeaturesRepository;
private readonly permissionService: PermissionService;
private readonly membershipRepository: MembershipRepository;
constructor(
private readonly repository: IPermissionRepository = new PermissionRepository(),
featuresRepository: FeaturesRepository = new FeaturesRepository(prisma),
permissionService: PermissionService = new PermissionService()
permissionService: PermissionService = new PermissionService(),
membershipRepository: MembershipRepository = new MembershipRepository()
) {
this.featuresRepository = featuresRepository;
this.permissionService = permissionService;
this.membershipRepository = membershipRepository;
}
async getUserPermissions(userId: number): Promise<TeamPermissions[]> {
@@ -119,7 +122,7 @@ export class PermissionCheckService {
}
// Fallback to role-based check - use highest role between team and org membership
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const membership = await this.membershipRepository.findUniqueByUserIdAndTeamId({
userId,
teamId,
});
@@ -129,7 +132,7 @@ export class PermissionCheckService {
// Check if team has parent org and get org membership
const team = await this.repository.getTeamById(teamId);
if (team?.parentId) {
const orgMembership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const orgMembership = await this.membershipRepository.findUniqueByUserIdAndTeamId({
userId,
teamId: team.parentId,
});
@@ -183,7 +186,7 @@ export class PermissionCheckService {
}
// Fallback to role-based check - use highest role between team and org membership
const membership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const membership = await this.membershipRepository.findUniqueByUserIdAndTeamId({
userId,
teamId,
});
@@ -193,7 +196,7 @@ export class PermissionCheckService {
// Check if team has parent org and get org membership
const team = await this.repository.getTeamById(teamId);
if (team?.parentId) {
const orgMembership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const orgMembership = await this.membershipRepository.findUniqueByUserIdAndTeamId({
userId,
teamId: team.parentId,
});
@@ -19,7 +19,8 @@ export default async function getAttributesForTeamHandler({
}: GetAttributesForTeamHandlerOptions) {
const { teamId } = input;
const { user } = ctx;
const isMemberOfTeam = await MembershipRepository.findUniqueByUserIdAndTeamId({ userId: user.id, teamId });
const membershipRepository = new MembershipRepository();
const isMemberOfTeam = await membershipRepository.findUniqueByUserIdAndTeamId({ userId: user.id, teamId });
if (!isMemberOfTeam) {
throw new TRPCError({
@@ -12,10 +12,20 @@ vi.mock("@calcom/lib/checkRateLimitAndThrowError", () => ({
checkRateLimitAndThrowError: vi.fn(),
}));
const { mockFindAllByUpIdIncludeTeam, MockMembershipRepository } = vi.hoisted(() => {
const mockFindAllByUpIdIncludeTeam = vi.fn();
const mockFindUniqueByUserIdAndTeamId = vi.fn();
class MockMembershipRepository {
static findAllByUpIdIncludeTeam = mockFindAllByUpIdIncludeTeam;
findUniqueByUserIdAndTeamId = mockFindUniqueByUserIdAndTeamId;
}
return { mockFindAllByUpIdIncludeTeam, MockMembershipRepository };
});
vi.mock("@calcom/features/membership/repositories/MembershipRepository", () => ({
MembershipRepository: {
findAllByUpIdIncludeTeam: vi.fn(),
},
MembershipRepository: MockMembershipRepository,
}));
vi.mock("@calcom/features/profile/repositories/ProfileRepository", () => ({
@@ -99,12 +109,9 @@ describe("getUserEventGroups", () => {
it("should return user event groups when no filters are applied", async () => {
const { ProfileRepository } = await import("@calcom/features/profile/repositories/ProfileRepository");
const { MembershipRepository } = await import(
"@calcom/features/membership/repositories/MembershipRepository"
);
vi.mocked(ProfileRepository.findByUpIdWithAuth).mockResolvedValue(mockProfile);
vi.mocked(MembershipRepository.findAllByUpIdIncludeTeam).mockResolvedValue([]);
mockFindAllByUpIdIncludeTeam.mockResolvedValue([]);
mockFilterTeamsByEventTypeReadPermission.mockResolvedValue([]);
const result = await getUserEventGroups({
@@ -129,9 +136,6 @@ describe("getUserEventGroups", () => {
describe("Team memberships", () => {
it("should include team events when team memberships exist", async () => {
const { ProfileRepository } = await import("@calcom/features/profile/repositories/ProfileRepository");
const { MembershipRepository } = await import(
"@calcom/features/membership/repositories/MembershipRepository"
);
const { getResourcePermissions } = await import("@calcom/features/pbac/lib/resource-permissions");
const mockTeamMembership = {
@@ -162,7 +166,7 @@ describe("getUserEventGroups", () => {
>[0];
vi.mocked(ProfileRepository.findByUpIdWithAuth).mockResolvedValue(mockProfile);
vi.mocked(MembershipRepository.findAllByUpIdIncludeTeam).mockResolvedValue([mockTeamMembership]);
mockFindAllByUpIdIncludeTeam.mockResolvedValue([mockTeamMembership]);
mockFilterTeamsByEventTypeReadPermission.mockResolvedValue([mockTeamMembership]);
vi.mocked(getResourcePermissions).mockResolvedValue({
@@ -191,9 +195,6 @@ describe("getUserEventGroups", () => {
describe("Permissions", () => {
it("should handle PBAC permissions correctly", async () => {
const { ProfileRepository } = await import("@calcom/features/profile/repositories/ProfileRepository");
const { MembershipRepository } = await import(
"@calcom/features/membership/repositories/MembershipRepository"
);
const { getResourcePermissions } = await import("@calcom/features/pbac/lib/resource-permissions");
const mockTeamMembership = {
@@ -224,7 +225,7 @@ describe("getUserEventGroups", () => {
>[0];
vi.mocked(ProfileRepository.findByUpIdWithAuth).mockResolvedValue(mockProfile);
vi.mocked(MembershipRepository.findAllByUpIdIncludeTeam).mockResolvedValue([mockTeamMembership]);
mockFindAllByUpIdIncludeTeam.mockResolvedValue([mockTeamMembership]);
mockFilterTeamsByEventTypeReadPermission.mockResolvedValue([mockTeamMembership]);
vi.mocked(getResourcePermissions).mockResolvedValue({
@@ -247,9 +248,6 @@ describe("getUserEventGroups", () => {
it("should fallback to role-based permissions when PBAC fails", async () => {
const { ProfileRepository } = await import("@calcom/features/profile/repositories/ProfileRepository");
const { MembershipRepository } = await import(
"@calcom/features/membership/repositories/MembershipRepository"
);
const { getResourcePermissions } = await import("@calcom/features/pbac/lib/resource-permissions");
const mockTeamMembership = {
@@ -280,7 +278,7 @@ describe("getUserEventGroups", () => {
>[0];
vi.mocked(ProfileRepository.findByUpIdWithAuth).mockResolvedValue(mockProfile);
vi.mocked(MembershipRepository.findAllByUpIdIncludeTeam).mockResolvedValue([mockTeamMembership]);
mockFindAllByUpIdIncludeTeam.mockResolvedValue([mockTeamMembership]);
mockFilterTeamsByEventTypeReadPermission.mockResolvedValue([mockTeamMembership]);
vi.mocked(getResourcePermissions).mockRejectedValue(new Error("PBAC failed"));
@@ -301,9 +299,6 @@ describe("getUserEventGroups", () => {
describe("Organization handling", () => {
it("should handle organization locked event types", async () => {
const { ProfileRepository } = await import("@calcom/features/profile/repositories/ProfileRepository");
const { MembershipRepository } = await import(
"@calcom/features/membership/repositories/MembershipRepository"
);
const mockProfileWithOrg = {
...mockProfile,
@@ -321,7 +316,7 @@ describe("getUserEventGroups", () => {
>;
vi.mocked(ProfileRepository.findByUpIdWithAuth).mockResolvedValue(mockProfileWithOrg);
vi.mocked(MembershipRepository.findAllByUpIdIncludeTeam).mockResolvedValue([]);
mockFindAllByUpIdIncludeTeam.mockResolvedValue([]);
mockFilterTeamsByEventTypeReadPermission.mockResolvedValue([]);
const result = await getUserEventGroups({
@@ -336,9 +331,6 @@ describe("getUserEventGroups", () => {
describe("Routing forms", () => {
it("should handle routing forms slug format", async () => {
const { ProfileRepository } = await import("@calcom/features/profile/repositories/ProfileRepository");
const { MembershipRepository } = await import(
"@calcom/features/membership/repositories/MembershipRepository"
);
const { getResourcePermissions } = await import("@calcom/features/pbac/lib/resource-permissions");
const mockTeamMembership = {
@@ -369,7 +361,7 @@ describe("getUserEventGroups", () => {
>[0];
vi.mocked(ProfileRepository.findByUpIdWithAuth).mockResolvedValue(mockProfile);
vi.mocked(MembershipRepository.findAllByUpIdIncludeTeam).mockResolvedValue([mockTeamMembership]);
mockFindAllByUpIdIncludeTeam.mockResolvedValue([mockTeamMembership]);
mockFilterTeamsByEventTypeReadPermission.mockResolvedValue([mockTeamMembership]);
vi.mocked(getResourcePermissions).mockResolvedValue({
@@ -1,15 +1,22 @@
import { describe, it, beforeEach, vi, expect } from "vitest";
import { getTeamWithoutMembers } from "@calcom/features/ee/teams/lib/queries";
import { MembershipRepository } from "@calcom/features/membership/repositories/MembershipRepository";
import type { TrpcSessionUser } from "../../../types";
import getTeam from "./get.handler";
const { mockFindUniqueByUserIdAndTeamId, MockMembershipRepository } = vi.hoisted(() => {
const mockFindUniqueByUserIdAndTeamId = vi.fn();
class MockMembershipRepository {
findUniqueByUserIdAndTeamId = mockFindUniqueByUserIdAndTeamId;
}
return { mockFindUniqueByUserIdAndTeamId, MockMembershipRepository };
});
vi.mock("@calcom/features/membership/repositories/MembershipRepository", () => ({
MembershipRepository: {
findUniqueByUserIdAndTeamId: vi.fn(),
},
MembershipRepository: MockMembershipRepository,
}));
vi.mock("@calcom/features/ee/teams/lib/queries", () => ({
@@ -33,7 +40,7 @@ describe("getTeam", () => {
});
it("throws UNAUTHORIZED if user is not a member of the team", async () => {
(MembershipRepository.findUniqueByUserIdAndTeamId as any).mockResolvedValue(null);
mockFindUniqueByUserIdAndTeamId.mockResolvedValue(null);
await expect(getTeam({ ctx: { user }, input })).rejects.toMatchObject({
code: "UNAUTHORIZED",
@@ -42,7 +49,7 @@ describe("getTeam", () => {
});
it("throws NOT_FOUND if team does not exist", async () => {
(MembershipRepository.findUniqueByUserIdAndTeamId as any).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
role: "member",
accepted: true,
});
@@ -60,7 +67,7 @@ describe("getTeam", () => {
organization: { isOrgAdmin: true },
};
(MembershipRepository.findUniqueByUserIdAndTeamId as any).mockResolvedValue({
mockFindUniqueByUserIdAndTeamId.mockResolvedValue({
role: "admin",
accepted: true,
});
@@ -89,7 +96,7 @@ describe("getTeam", () => {
description: "A team",
};
(MembershipRepository.findUniqueByUserIdAndTeamId as any).mockResolvedValue(membershipData);
mockFindUniqueByUserIdAndTeamId.mockResolvedValue(membershipData);
(getTeamWithoutMembers as any).mockResolvedValue(teamData);
const result = await getTeam({ ctx: { user }, input });
@@ -99,7 +106,7 @@ describe("getTeam", () => {
membership: membershipData,
});
expect(MembershipRepository.findUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
expect(mockFindUniqueByUserIdAndTeamId).toHaveBeenCalledWith({
userId: user.id,
teamId: input.teamId,
});
@@ -14,7 +14,8 @@ type GetDataOptions = {
};
export const get = async ({ ctx, input }: GetDataOptions) => {
const teamMembership = await MembershipRepository.findUniqueByUserIdAndTeamId({
const membershipRepository = new MembershipRepository();
const teamMembership = await membershipRepository.findUniqueByUserIdAndTeamId({
userId: ctx.user.id,
teamId: input.teamId,
});