2
0

first commit

This commit is contained in:
2024-08-09 00:39:27 +02:00
commit 79688abe2e
5698 changed files with 497838 additions and 0 deletions

View File

@@ -0,0 +1,88 @@
import prismaMock from "../../../../../tests/libs/__mocks__/prisma";
import type { Payment, Prisma, PaymentOption, Booking } from "@prisma/client";
import { v4 as uuidv4 } from "uuid";
import "vitest-fetch-mock";
import { sendAwaitingPaymentEmail } from "@calcom/emails";
import logger from "@calcom/lib/logger";
import type { CalendarEvent } from "@calcom/types/Calendar";
import type { IAbstractPaymentService } from "@calcom/types/PaymentService";
export function getMockPaymentService() {
function createPaymentLink(/*{ paymentUid, name, email, date }*/) {
return "http://mock-payment.example.com/";
}
const paymentUid = uuidv4();
const externalId = uuidv4();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
class MockPaymentService implements IAbstractPaymentService {
// TODO: We shouldn't need to implement adding a row to Payment table but that's a requirement right now.
// We should actually delegate table creation to the core app. Here, only the payment app specific logic should come
async create(
payment: Pick<Prisma.PaymentUncheckedCreateInput, "amount" | "currency">,
bookingId: Booking["id"],
userId: Booking["userId"],
username: string | null,
bookerName: string | null,
bookerEmail: string,
paymentOption: PaymentOption
) {
const paymentCreateData = {
id: 1,
uid: paymentUid,
appId: null,
bookingId,
// booking Booking? @relation(fields: [bookingId], references: [id], onDelete: Cascade)
fee: 10,
success: true,
refunded: false,
data: {},
externalId,
paymentOption,
amount: payment.amount,
currency: payment.currency,
};
const paymentData = prismaMock.payment.create({
data: paymentCreateData,
});
logger.silly("Created mock payment", JSON.stringify({ paymentData }));
return paymentData;
}
async afterPayment(
event: CalendarEvent,
booking: {
user: { email: string | null; name: string | null; timeZone: string } | null;
id: number;
startTime: { toISOString: () => string };
uid: string;
},
paymentData: Payment
): Promise<void> {
// TODO: App implementing PaymentService is supposed to send email by itself at the moment.
await sendAwaitingPaymentEmail({
...event,
paymentInfo: {
link: createPaymentLink(/*{
paymentUid: paymentData.uid,
name: booking.user?.name,
email: booking.user?.email,
date: booking.startTime.toISOString(),
}*/),
paymentOption: paymentData.paymentOption || "ON_BOOKING",
amount: paymentData.amount,
currency: paymentData.currency,
},
});
}
}
return {
paymentUid,
externalId,
MockPaymentService,
};
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,10 @@
import { createMocks } from "node-mocks-http";
import type {
CustomNextApiRequest,
CustomNextApiResponse,
} from "@calcom/features/bookings/lib/handleNewBooking/test/fresh-booking.test";
export function createMockNextJsRequest(...args: Parameters<typeof createMocks>) {
return createMocks<CustomNextApiRequest, CustomNextApiResponse>(...args);
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,42 @@
import { getDate } from "@calcom/web/test/utils/bookingScenario/bookingScenario";
import type { SchedulingType } from "@calcom/prisma/client";
export const DEFAULT_TIMEZONE_BOOKER = "Asia/Kolkata";
export function getBasicMockRequestDataForBooking() {
return {
start: `${getDate({ dateIncrement: 1 }).dateString}T04:00:00.000Z`,
end: `${getDate({ dateIncrement: 1 }).dateString}T04:30:00.000Z`,
eventTypeSlug: "no-confirmation",
timeZone: DEFAULT_TIMEZONE_BOOKER,
language: "en",
user: "teampro",
metadata: {},
hasHashedBookingLink: false,
hashedLink: null,
};
}
export function getMockRequestDataForBooking({
data,
}: {
data: Partial<ReturnType<typeof getBasicMockRequestDataForBooking>> & {
eventTypeId: number;
user?: string;
rescheduleUid?: string;
bookingUid?: string;
recurringEventId?: string;
recurringCount?: number;
schedulingType?: SchedulingType;
responses: {
email: string;
name: string;
location: { optionValue: ""; value: string };
smsReminderNumber?: string;
};
};
}) {
return {
...getBasicMockRequestDataForBooking(),
...data,
};
}

View File

@@ -0,0 +1,7 @@
import type z from "zod";
import type { schemaBookingCancelParams } from "@calcom/prisma/zod-utils";
export function getMockRequestDataForCancelBooking(data: z.infer<typeof schemaBookingCancelParams>) {
return data;
}

View File

@@ -0,0 +1,46 @@
import { UserPermissionRole } from "@calcom/prisma/client";
import { IdentityProvider } from "@calcom/prisma/enums";
export const getSampleUserInSession = function () {
return {
locale: "",
avatar: "",
organization: {
isOrgAdmin: false,
metadata: null,
id: 1,
requestedSlug: null,
},
profile: null,
defaultScheduleId: null,
name: "",
defaultBookerLayouts: null,
timeZone: "Asia/Kolkata",
selectedCalendars: [],
destinationCalendar: null,
emailVerified: new Date(),
allowDynamicBooking: false,
bio: "",
weekStart: "",
startTime: 0,
endTime: 0,
bufferTime: 0,
hideBranding: false,
timeFormat: 12,
twoFactorEnabled: false,
identityProvider: IdentityProvider.CAL,
brandColor: "#292929",
darkBrandColor: "#fafafa",
metadata: null,
role: UserPermissionRole.USER,
disableImpersonation: false,
organizationId: null,
theme: "",
appTheme: "",
createdDate: new Date(),
trialEndsAt: new Date(),
completedOnboarding: false,
allowSEOIndexing: false,
receiveMonthlyDigestEmail: false,
};
};

View File

@@ -0,0 +1,36 @@
import {
enableEmailFeature,
mockNoTranslations,
} from "@calcom/web/test/utils/bookingScenario/bookingScenario";
import { beforeEach, afterEach } from "vitest";
export function setupAndTeardown() {
beforeEach(() => {
// Required to able to generate token in email in some cases
//@ts-expect-error - It is a readonly variable
process.env.CALENDSO_ENCRYPTION_KEY = "abcdefghjnmkljhjklmnhjklkmnbhjui";
//@ts-expect-error - It is a readonly variable
process.env.STRIPE_WEBHOOK_SECRET = "MOCK_STRIPE_WEBHOOK_SECRET";
// We are setting it in vitest.config.ts because otherwise it's too late to set it.
// process.env.DAILY_API_KEY = "MOCK_DAILY_API_KEY";
// Ensure that Rate Limiting isn't enforced for tests
delete process.env.UNKEY_ROOT_KEY;
mockNoTranslations();
// mockEnableEmailFeature();
enableEmailFeature();
globalThis.testEmails = [];
fetchMock.resetMocks();
});
afterEach(() => {
//@ts-expect-error - It is a readonly variable
delete process.env.CALENDSO_ENCRYPTION_KEY;
//@ts-expect-error - It is a readonly variable
delete process.env.STRIPE_WEBHOOK_SECRET;
delete process.env.DAILY_API_KEY;
globalThis.testEmails = [];
fetchMock.resetMocks();
// process.env.DAILY_API_KEY = "MOCK_DAILY_API_KEY";
});
}

View File

@@ -0,0 +1,81 @@
import { createOrganization } from "@calcom/web/test/utils/bookingScenario/bookingScenario";
import type { TestFunction } from "vitest";
import { WEBSITE_URL } from "@calcom/lib/constants";
import { test } from "@calcom/web/test/fixtures/fixtures";
import type { Fixtures } from "@calcom/web/test/fixtures/fixtures";
const WEBSITE_PROTOCOL = new URL(WEBSITE_URL).protocol;
const _testWithAndWithoutOrg = (
description: Parameters<typeof testWithAndWithoutOrg>[0],
fn: Parameters<typeof testWithAndWithoutOrg>[1],
timeout: Parameters<typeof testWithAndWithoutOrg>[2],
mode: "only" | "skip" | "run" = "run"
) => {
const t = mode === "only" ? test.only : mode === "skip" ? test.skip : test;
t(
`${description} - With org`,
async ({ emails, sms, meta, task, onTestFailed, expect, skip }) => {
const org = await createOrganization({
name: "Test Org",
slug: "testorg",
});
await fn({
meta,
task,
onTestFailed,
expect,
emails,
sms,
skip,
org: {
organization: org,
urlOrigin: `${WEBSITE_PROTOCOL}//${org.slug}.cal.local:3000`,
},
});
},
timeout
);
t(
`${description}`,
async ({ emails, sms, meta, task, onTestFailed, expect, skip }) => {
await fn({
emails,
sms,
meta,
task,
onTestFailed,
expect,
skip,
org: null,
});
},
timeout
);
};
export const testWithAndWithoutOrg = (
description: string,
fn: TestFunction<
Fixtures & {
org: {
organization: { id: number | null };
urlOrigin?: string;
} | null;
}
>,
timeout?: number
) => {
_testWithAndWithoutOrg(description, fn, timeout, "run");
};
testWithAndWithoutOrg.only = ((description, fn, timeout) => {
_testWithAndWithoutOrg(description, fn, timeout, "only");
}) as typeof _testWithAndWithoutOrg;
testWithAndWithoutOrg.skip = ((description, fn, timeout) => {
_testWithAndWithoutOrg(description, fn, timeout, "skip");
}) as typeof _testWithAndWithoutOrg;