diff --git a/packages/lib/server/getDefaultLocations.test.ts b/packages/lib/server/getDefaultLocations.test.ts new file mode 100644 index 0000000000..a29687f56e --- /dev/null +++ b/packages/lib/server/getDefaultLocations.test.ts @@ -0,0 +1,95 @@ +import prismaMock from "../../../tests/libs/__mocks__/prisma"; + +import { getGoogleMeetCredential, TestData } from "@calcom/web/test/utils/bookingScenario/bookingScenario"; + +import { describe, expect, it } from "vitest"; + +import { DailyLocationType, MeetLocationType } from "@calcom/app-store/locations"; + +import { getDefaultLocations } from "./getDefaultLocations"; + +type User = { + id: number; + email?: string; + name?: string; + metadata: { + defaultConferencingApp?: { + appSlug: string; + appLink: string; + }; + }; + credentials?: [ + { + key: { + expiry_date?: number; + token_type?: string; + access_token?: string; + refresh_token?: string; + scope: string; + }; + } + ]; +}; +describe("getDefaultLocation ", async () => { + it("should return location based on user default conferencing app", async () => { + const user: User = { + id: 101, + metadata: { + defaultConferencingApp: { + appSlug: "google-meet", + appLink: "https://example.com", + }, + }, + credentials: [getGoogleMeetCredential()], + }; + await mockUser(user); + await addAppsToDb([TestData.apps["google-meet"]]); + const res = await getDefaultLocations(user); + expect(res[0]).toEqual({ + link: "https://example.com", + type: MeetLocationType, + }); + }); + it("should return calvideo when default conferencing app is not set", async () => { + const user: User = { + id: 101, + metadata: {}, + }; + await mockUser(user); + await addAppsToDb([TestData.apps["daily-video"]]); + await prismaMock.app.create({ + data: { + ...TestData.apps["daily-video"], + enabled: true, + }, + }); + const res = await getDefaultLocations(user); + expect(res[0]).toContain({ + type: DailyLocationType, + }); + }); +}); + +async function mockUser(user: User) { + const userToCreate: any = { + ...TestData.users.example, + ...user, + }; + if (user.credentials) { + userToCreate.credentials = { + createMany: { + data: user.credentials, + }, + }; + } + return await prismaMock.user.create({ + data: userToCreate, + }); +} +async function addAppsToDb(apps: any[]) { + await prismaMock.app.createMany({ + data: apps.map((app) => { + return { ...app, enabled: true }; + }), + }); +} diff --git a/packages/lib/server/getDefaultLocations.ts b/packages/lib/server/getDefaultLocations.ts new file mode 100644 index 0000000000..7d7bdc36ec --- /dev/null +++ b/packages/lib/server/getDefaultLocations.ts @@ -0,0 +1,35 @@ +import getAppKeysFromSlug from "@calcom/app-store/_utils/getAppKeysFromSlug"; +import { DailyLocationType } from "@calcom/app-store/locations"; +import getApps from "@calcom/app-store/utils"; +import { getUsersCredentials } from "@calcom/lib/server/getUsersCredentials"; +import { userMetadata as userMetadataSchema } from "@calcom/prisma/zod-utils"; +import type { EventTypeLocation } from "@calcom/prisma/zod/custom/eventtype"; +import type { TrpcSessionUser } from "@calcom/trpc/server/trpc"; + +type SessionUser = NonNullable; +type User = { + id: SessionUser["id"]; + metadata: SessionUser["metadata"]; +}; + +export async function getDefaultLocations(user: User): Promise { + const defaultConferencingData = userMetadataSchema.parse(user.metadata)?.defaultConferencingApp; + + if (defaultConferencingData && defaultConferencingData.appSlug !== "daily-video") { + const credentials = await getUsersCredentials(user); + + const foundApp = getApps(credentials, true).filter( + (app) => app.slug === defaultConferencingData.appSlug + )[0]; // There is only one possible install here so index [0] is the one we are looking for ; + const locationType = foundApp?.locationOption?.value ?? DailyLocationType; // Default to Daily if no location type is found + return [{ type: locationType, link: defaultConferencingData.appLink }]; + } + + const appKeys = await getAppKeysFromSlug("daily-video"); + + if (typeof appKeys.api_key === "string") { + return [{ type: DailyLocationType }]; + } + + return []; +} diff --git a/packages/lib/server/index.ts b/packages/lib/server/index.ts index 39c8efc9ec..8dacc9c665 100644 --- a/packages/lib/server/index.ts +++ b/packages/lib/server/index.ts @@ -6,4 +6,5 @@ export { defaultResponder } from "./defaultResponder"; export { getLuckyUser } from "./getLuckyUser"; export { getServerErrorFromUnknown } from "./getServerErrorFromUnknown"; export { getTranslation } from "./i18n"; +export { getDefaultLocations } from "./getDefaultLocations"; export { default as perfObserver } from "./perfObserver"; diff --git a/packages/trpc/server/routers/viewer/eventTypes/create.handler.ts b/packages/trpc/server/routers/viewer/eventTypes/create.handler.ts index cae1570a41..112632b36a 100644 --- a/packages/trpc/server/routers/viewer/eventTypes/create.handler.ts +++ b/packages/trpc/server/routers/viewer/eventTypes/create.handler.ts @@ -1,14 +1,10 @@ import type { Prisma } from "@prisma/client"; import { PrismaClientKnownRequestError } from "@prisma/client/runtime/library"; -import getAppKeysFromSlug from "@calcom/app-store/_utils/getAppKeysFromSlug"; -import { DailyLocationType } from "@calcom/app-store/locations"; -import getApps from "@calcom/app-store/utils"; -import { getUsersCredentials } from "@calcom/lib/server/getUsersCredentials"; +import { getDefaultLocations } from "@calcom/lib/server"; import { EventTypeRepository } from "@calcom/lib/server/repository/eventType"; import type { PrismaClient } from "@calcom/prisma"; import { SchedulingType } from "@calcom/prisma/enums"; -import { userMetadata as userMetadataSchema } from "@calcom/prisma/zod-utils"; import type { EventTypeLocation } from "@calcom/prisma/zod/custom/eventtype"; import { TRPCError } from "@trpc/server"; @@ -116,23 +112,3 @@ export const createHandler = async ({ ctx, input }: CreateOptions) => { throw new TRPCError({ code: "BAD_REQUEST" }); } }; - -async function getDefaultLocations(user: User): Promise { - const defaultConferencingData = userMetadataSchema.parse(user.metadata)?.defaultConferencingApp; - const appKeys = await getAppKeysFromSlug("daily-video"); - - if (typeof appKeys.api_key === "string") { - return [{ type: DailyLocationType }]; - } - - if (defaultConferencingData && defaultConferencingData.appSlug !== "daily-video") { - const credentials = await getUsersCredentials(user); - const foundApp = getApps(credentials, true).filter( - (app) => app.slug === defaultConferencingData.appSlug - )[0]; // There is only one possible install here so index [0] is the one we are looking for ; - const locationType = foundApp?.locationOption?.value ?? DailyLocationType; // Default to Daily if no location type is found - return [{ type: locationType, link: defaultConferencingData.appLink }]; - } - - return []; -}