test: add test for invalid cal video (#13103)
* test: add test for invalid cal video * chore: add confirm * chore: fix type error * chore: update code * test: add unit test * chore: type error * chore * chore: type * chore: fix test * chore --------- Co-authored-by: Carina Wollendorfer <30310907+CarinaWolli@users.noreply.github.com>
This commit is contained in:
co-authored by
Carina Wollendorfer
parent
13a765e50a
commit
7ec3d04acc
@@ -147,6 +147,7 @@ function BookingListItem(booking: BookingItemProps) {
|
||||
? [
|
||||
{
|
||||
id: "confirm",
|
||||
bookingId: booking.id,
|
||||
label: (isTabRecurring || isTabUnconfirmed) && isRecurring ? t("confirm_all") : t("confirm"),
|
||||
onClick: () => {
|
||||
bookingConfirm(true);
|
||||
|
||||
@@ -8,6 +8,7 @@ import { useState, useEffect, useRef } from "react";
|
||||
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import { getServerSession } from "@calcom/features/auth/lib/getServerSession";
|
||||
import { getCalVideoReference } from "@calcom/features/get-cal-video-reference";
|
||||
import classNames from "@calcom/lib/classNames";
|
||||
import { APP_NAME, SEO_IMG_OGIMG_VIDEO, WEBSITE_URL } from "@calcom/lib/constants";
|
||||
import { formatToLocalizedDate, formatToLocalizedTime } from "@calcom/lib/date-fns";
|
||||
@@ -332,15 +333,13 @@ export async function getServerSideProps(context: GetServerSidePropsContext) {
|
||||
bookRef.meetingPassword = null;
|
||||
});
|
||||
}
|
||||
|
||||
const videoReferences = bookingObj.references.filter((reference) => reference.type.includes("_video"));
|
||||
const latestVideoReference = videoReferences[videoReferences.length - 1];
|
||||
const videoReference = getCalVideoReference(bookingObj.references);
|
||||
|
||||
return {
|
||||
props: {
|
||||
meetingUrl: latestVideoReference.meetingUrl ?? "",
|
||||
...(typeof latestVideoReference.meetingPassword === "string" && {
|
||||
meetingPassword: latestVideoReference.meetingPassword,
|
||||
meetingUrl: videoReference.meetingUrl ?? "",
|
||||
...(typeof videoReference.meetingPassword === "string" && {
|
||||
meetingPassword: videoReference.meetingPassword,
|
||||
}),
|
||||
booking: {
|
||||
...bookingObj,
|
||||
|
||||
@@ -3,9 +3,10 @@ import { expect } from "@playwright/test";
|
||||
import dayjs from "@calcom/dayjs";
|
||||
import prisma from "@calcom/prisma";
|
||||
import { BookingStatus } from "@calcom/prisma/enums";
|
||||
import { bookingMetadataSchema } from "@calcom/prisma/zod-utils";
|
||||
|
||||
import { test } from "./lib/fixtures";
|
||||
import { selectFirstAvailableTimeSlotNextMonth } from "./lib/testUtils";
|
||||
import { selectFirstAvailableTimeSlotNextMonth, bookTimeSlot } from "./lib/testUtils";
|
||||
|
||||
const IS_STRIPE_ENABLED = !!(
|
||||
process.env.STRIPE_CLIENT_ID &&
|
||||
@@ -270,4 +271,64 @@ test.describe("Reschedule Tests", async () => {
|
||||
await page.locator('[data-testid="confirm-reschedule-button"]').click();
|
||||
await expect(page).toHaveURL(/.*booking/);
|
||||
});
|
||||
test("Should load Valid Cal video url after rescheduling Opt in events", async ({
|
||||
page,
|
||||
users,
|
||||
bookings,
|
||||
}) => {
|
||||
const user = await users.create();
|
||||
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
|
||||
const eventType = user.eventTypes.find((e) => e.slug === "opt-in")!;
|
||||
|
||||
const confirmBooking = async (bookingId: number) => {
|
||||
await user.apiLogin();
|
||||
await page.goto("/bookings/upcoming");
|
||||
const elem = await page.locator(`[data-bookingid="${bookingId}"][data-testid="confirm"]`);
|
||||
await elem.click();
|
||||
await page.getByTestId("toast-success").waitFor();
|
||||
await user.logout();
|
||||
};
|
||||
|
||||
await page.goto(`/${user.username}/${eventType.slug}`);
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
await bookTimeSlot(page);
|
||||
await expect(page.locator("[data-testid=success-page]")).toBeVisible();
|
||||
|
||||
const pageUrl = new URL(page.url());
|
||||
const pathSegments = pageUrl.pathname.split("/");
|
||||
const bookingUID = pathSegments[pathSegments.length - 1];
|
||||
|
||||
const currentBooking = await prisma.booking.findFirst({ where: { uid: bookingUID } });
|
||||
expect(currentBooking).not.toBeUndefined();
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if (currentBooking) {
|
||||
await confirmBooking(currentBooking.id);
|
||||
|
||||
await page.goto(`/${user.username}/${eventType.slug}?rescheduleUid=${currentBooking.uid}`);
|
||||
await selectFirstAvailableTimeSlotNextMonth(page);
|
||||
|
||||
await page.locator('[data-testid="confirm-reschedule-button"]').click();
|
||||
await expect(page).toHaveURL(/.*booking/);
|
||||
|
||||
const newBooking = await prisma.booking.findFirst({ where: { fromReschedule: currentBooking.uid } });
|
||||
expect(newBooking).not.toBeUndefined();
|
||||
expect(newBooking?.status).toBe(BookingStatus.PENDING);
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if (newBooking) {
|
||||
await confirmBooking(newBooking?.id);
|
||||
|
||||
const booking = await prisma.booking.findFirst({ where: { id: newBooking.id } });
|
||||
expect(booking).not.toBeUndefined();
|
||||
expect(booking?.status).toBe(BookingStatus.ACCEPTED);
|
||||
const locationVideoCallUrl = bookingMetadataSchema.parse(booking?.metadata || {})?.videoCallUrl;
|
||||
expect(locationVideoCallUrl).not.toBeUndefined();
|
||||
|
||||
// eslint-disable-next-line playwright/no-conditional-in-test
|
||||
if (booking && locationVideoCallUrl) {
|
||||
await page.goto(locationVideoCallUrl);
|
||||
await expect(page.frameLocator("iFrame").locator('text="Continue"')).toBeVisible();
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
|
||||
import { getCalVideoReference } from "./get-cal-video-reference";
|
||||
|
||||
describe("Cal Video", () => {
|
||||
it("should load latest cal video reference", () => {
|
||||
expect(
|
||||
getCalVideoReference([
|
||||
{
|
||||
uid: "UID1",
|
||||
type: "daily_video",
|
||||
meetingUrl: "ID1",
|
||||
meetingPassword: "P1",
|
||||
},
|
||||
{
|
||||
uid: "UID2",
|
||||
type: "daily_video",
|
||||
meetingUrl: "ID2",
|
||||
meetingPassword: "P2",
|
||||
},
|
||||
])
|
||||
).toEqual({
|
||||
uid: "UID2",
|
||||
type: "daily_video",
|
||||
meetingUrl: "ID2",
|
||||
meetingPassword: "P2",
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,12 @@
|
||||
export type Reference = {
|
||||
uid: string;
|
||||
type: string;
|
||||
meetingUrl: string | null;
|
||||
meetingPassword: string | null;
|
||||
};
|
||||
|
||||
export const getCalVideoReference = (references: Reference[]) => {
|
||||
const videoReferences = references.filter((reference) => reference.type.includes("_video"));
|
||||
const latestVideoReference = videoReferences[videoReferences.length - 1];
|
||||
return latestVideoReference;
|
||||
};
|
||||
@@ -21,6 +21,7 @@ export type ActionType = {
|
||||
label: string;
|
||||
disabled?: boolean;
|
||||
color?: ButtonBaseProps["color"];
|
||||
bookingId?: number;
|
||||
} & (
|
||||
| { href: string; onClick?: never; actions?: never }
|
||||
| { href?: never; onClick: (e: React.MouseEvent<HTMLElement, MouseEvent>) => void; actions?: never }
|
||||
@@ -61,6 +62,7 @@ export const DropdownActions = ({
|
||||
data-testid={action.id}
|
||||
StartIcon={action.icon}
|
||||
href={action.href}
|
||||
data-bookingid={action.bookingId}
|
||||
onClick={action.onClick || defaultAction}>
|
||||
{action.label}
|
||||
</DropdownItem>
|
||||
@@ -87,6 +89,7 @@ export const TableActions: FC<Props> = ({ actions }) => {
|
||||
StartIcon={action.icon}
|
||||
{...(action?.actions ? { EndIcon: ChevronDown } : null)}
|
||||
disabled={action.disabled}
|
||||
data-bookingid={action.bookingId}
|
||||
color={action.color || "secondary"}>
|
||||
{action.label}
|
||||
</Button>
|
||||
|
||||
Reference in New Issue
Block a user