Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: event type uses calvideo as location instead of user default #15442

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions packages/lib/server/getDefaultLocations.test.ts
Original file line number Diff line number Diff line change
@@ -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 };
}),
});
}
35 changes: 35 additions & 0 deletions packages/lib/server/getDefaultLocations.ts
Original file line number Diff line number Diff line change
@@ -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<TrpcSessionUser>;
type User = {
id: SessionUser["id"];
metadata: SessionUser["metadata"];
};

export async function getDefaultLocations(user: User): Promise<EventTypeLocation[]> {
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 [];
}
1 change: 1 addition & 0 deletions packages/lib/server/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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";
26 changes: 1 addition & 25 deletions packages/trpc/server/routers/viewer/eventTypes/create.handler.ts
Original file line number Diff line number Diff line change
@@ -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";
Expand Down Expand Up @@ -116,23 +112,3 @@ export const createHandler = async ({ ctx, input }: CreateOptions) => {
throw new TRPCError({ code: "BAD_REQUEST" });
}
};

async function getDefaultLocations(user: User): Promise<EventTypeLocation[]> {
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 [];
}
Loading