fix: not able to mark no show (#17980)

* fix: not able to mark no show

* add test

* Update bookings-list.e2e.ts
This commit is contained in:
Anik Dhabal Babu
2024-12-09 14:02:45 -05:00
committed by GitHub
parent 45f8ecbab7
commit cbb1b285f5
4 changed files with 100 additions and 29 deletions
+56
View File
@@ -4,6 +4,7 @@ import { BookingStatus } from "@calcom/prisma/client";
import type { Fixtures } from "./lib/fixtures";
import { test } from "./lib/fixtures";
import { setupManagedEvent } from "./lib/testUtils";
test.afterEach(({ users }) => users.deleteAll());
@@ -150,6 +151,61 @@ test.describe("Bookings", () => {
await moreGuests.click();
await expect(firstGuestInMore).toBeChecked({ checked: true });
});
test("Team admin/owner can mark first attendee as no-show", async ({
page,
users,
bookings,
webhooks,
}) => {
const { adminUser, memberUser, managedEvent } = await setupManagedEvent({ users });
const bookingFixture = await createBooking({
title: "Managed Event Booking",
bookingsFixture: bookings,
// Create a booking 3 days ago
relativeDate: -3,
organizer: memberUser,
organizerEventType: managedEvent,
attendees: [
{ name: "First Guest", email: "first@cal.com", timeZone: "Europe/Berlin" },
{ name: "Second Guest", email: "second@cal.com", timeZone: "Europe/Berlin" },
{ name: "Third Guest", email: "third@cal.com", timeZone: "Europe/Berlin" },
],
});
const booking = await bookingFixture.self();
await adminUser.apiLogin();
const { webhookReceiver, teamId } = await webhooks.createTeamReceiver();
await page.goto(`/bookings/past`);
const pastBookings = page.locator('[data-testid="past-bookings"]');
const firstPastBooking = pastBookings.locator('[data-testid="booking-item"]').nth(0);
const titleAndAttendees = firstPastBooking.locator('[data-testid="title-and-attendees"]');
const firstGuest = firstPastBooking.locator('[data-testid="guest"]').nth(0);
await firstGuest.click();
await expect(titleAndAttendees.locator('[data-testid="mark-no-show"]')).toBeVisible();
await titleAndAttendees.locator('[data-testid="mark-no-show"]').click();
await firstGuest.click();
await expect(titleAndAttendees.locator('[data-testid="unmark-no-show"]')).toBeVisible();
await expect(titleAndAttendees.locator('[data-testid="mark-no-show"]')).toBeHidden();
await webhookReceiver.waitForRequestCount(1);
const [request] = webhookReceiver.requestList;
const body = request.body;
const dynamic = "[redacted/dynamic]";
// @ts-expect-error we are modifying the object
body.createdAt = dynamic;
expect(body).toMatchObject({
triggerEvent: "BOOKING_NO_SHOW_UPDATED",
createdAt: "[redacted/dynamic]",
payload: {
message: "first@cal.com marked as no-show",
attendees: [{ email: "first@cal.com", noShow: true }],
bookingUid: booking?.uid,
bookingId: booking?.id,
},
});
// Close webhook receiver
webhookReceiver.close();
});
});
});
+25
View File
@@ -175,6 +175,31 @@ export const createNewEventType = async (page: Page, args: { eventTitle: string
});
};
export async function setupManagedEvent({
users,
unlockedFields,
}: {
users: Fixtures["users"];
unlockedFields?: Record<string, boolean>;
}) {
const teamMateName = "teammate-1";
const teamEventTitle = "Managed";
const adminUser = await users.create(null, {
hasTeam: true,
teammates: [{ name: teamMateName }],
teamEventTitle,
teamEventSlug: "managed",
schedulingType: "MANAGED",
addManagedEventToTeamMates: true,
managedEventUnlockedFields: unlockedFields,
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const memberUser = users.get().find((u) => u.name === teamMateName)!;
const { team } = await adminUser.getFirstTeamMembership();
const managedEvent = await adminUser.getFirstTeamEvent(team.id, SchedulingType.MANAGED);
return { adminUser, memberUser, managedEvent, teamMateName, teamEventTitle, teamId: team.id };
}
export const createNewSeatedEventType = async (page: Page, args: { eventTitle: string }) => {
const eventTitle = args.eventTitle;
await createNewEventType(page, { eventTitle });
+2 -29
View File
@@ -1,46 +1,19 @@
import type { Locator, Page } from "@playwright/test";
import { expect } from "@playwright/test";
import { SchedulingType } from "@calcom/prisma/enums";
import { test, type Fixtures } from "./lib/fixtures";
import { test } from "./lib/fixtures";
import {
bookTimeSlot,
localize,
submitAndWaitForResponse,
selectFirstAvailableTimeSlotNextMonth,
setupManagedEvent,
} from "./lib/testUtils";
test.afterEach(async ({ users }) => {
await users.deleteAll();
});
/** So we can test different areas in parallel and avoiding the creation flow each time */
async function setupManagedEvent({
users,
unlockedFields,
}: {
users: Fixtures["users"];
unlockedFields?: Record<string, boolean>;
}) {
const teamMateName = "teammate-1";
const teamEventTitle = "Managed";
const adminUser = await users.create(null, {
hasTeam: true,
teammates: [{ name: teamMateName }],
teamEventTitle,
teamEventSlug: "managed",
schedulingType: "MANAGED",
addManagedEventToTeamMates: true,
managedEventUnlockedFields: unlockedFields,
});
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const memberUser = users.get().find((u) => u.name === teamMateName)!;
const { team } = await adminUser.getFirstTeamMembership();
const managedEvent = await adminUser.getFirstTeamEvent(team.id, SchedulingType.MANAGED);
return { adminUser, memberUser, managedEvent, teamMateName, teamEventTitle, teamId: team.id };
}
/** Short hand to get elements by translation key */
const getByKey = async (page: Page, key: string) => page.getByText((await localize("en"))(key));
+17
View File
@@ -337,6 +337,23 @@ export class BookingRepository {
},
},
},
{
eventType: {
parent: {
team: {
members: {
some: {
userId,
accepted: true,
role: {
in: ["ADMIN", "OWNER"],
},
},
},
},
},
},
},
],
},
});