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: to fetch booking with user as attendee in bookings list (user) filter #19376

Closed
124 changes: 124 additions & 0 deletions apps/web/playwright/bookings-list.e2e.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { prisma } from "@calcom/prisma";
import { BookingStatus } from "@calcom/prisma/client";
import { MembershipRole } from "@calcom/prisma/enums";

import { createTeamEventType } from "./fixtures/users";
import type { Fixtures } from "./lib/fixtures";
import { test } from "./lib/fixtures";
import { localize, setupManagedEvent } from "./lib/testUtils";
Expand Down Expand Up @@ -298,6 +299,129 @@ test.describe("Bookings", () => {
firstUpcomingBooking.locator(`text=${firstUserBooking!.title}`)
).toBeVisible();
});

test("People filter includes bookings where filtered person is attendee", async ({
page,
users,
bookings,
}) => {
const firstUser = await users.create(
{ name: "First", email: "first@cal.com" },
{
hasTeam: true,
teamRole: MembershipRole.ADMIN,
}
);
const teamId = (await firstUser.getFirstTeamMembership()).teamId;
const secondUser = await users.create({ name: "Second", email: "second@cal.com" });
const thirdUser = await users.create({ name: "Third", email: "third@cal.com" });
// Add teammates to the team
await prisma.membership.createMany({
data: [
{
teamId: teamId,
userId: secondUser.id,
role: MembershipRole.MEMBER,
accepted: true,
},
{
teamId: teamId,
userId: thirdUser.id,
role: MembershipRole.MEMBER,
accepted: true,
},
],
});
const teamEvent = await createTeamEventType(
{ id: firstUser.id },
{ id: teamId },
{ teamEventSlug: "team-event-slug" }
);

//Create a TeamEventType booking where ThirdUser is attendee
const thirdUserAttendeeTeamEventBookingFixture = await createBooking({
title: "ThirdUser is Attendee for TeamEvent",
bookingsFixture: bookings,
relativeDate: 6,
organizer: firstUser,
organizerEventType: teamEvent,
attendees: [{ name: "Third", email: thirdUser.email, timeZone: "Europe/Berlin" }],
});
const thirdUserAttendeeTeamEvent = await thirdUserAttendeeTeamEventBookingFixture.self();

//Create a IndividualEventType booking where ThirdUser,SecondUser are attendees and FirstUser is organizer
const thirdUserAttendeeIndividualBookingFixture = await createBooking({
title: "ThirdUser is Attendee and FirstUser is Organizer",
bookingsFixture: bookings,
relativeDate: 3,
organizer: firstUser,
organizerEventType: firstUser.eventTypes[0],
attendees: [
{ name: "Third", email: thirdUser.email, timeZone: "Europe/Berlin" },
{ name: "Second", email: secondUser.email, timeZone: "Europe/Berlin" },
],
});
const thirdUserAttendeeIndividualBooking = await thirdUserAttendeeIndividualBookingFixture.self();

//Create a IndividualEventType booking where ThirdUser is organizer and FirstUser,SecondUser are attendees
const thirdUserOrganizerBookingFixture = await createBooking({
title: "ThirdUser is Organizer and FirstUser is Attendee",
bookingsFixture: bookings,
organizer: thirdUser,
relativeDate: 2,
organizerEventType: thirdUser.eventTypes[0],
attendees: [
{ name: "First", email: firstUser.email, timeZone: "Europe/Berlin" },
{ name: "Second", email: secondUser.email, timeZone: "Europe/Berlin" },
],
});
const thirdUserOrganizerBooking = await thirdUserOrganizerBookingFixture.self();

//Create a booking where FirstUser is organizer and SecondUser is attendee
await createBooking({
title: "FirstUser is Organizer and SecondUser is Attendee",
bookingsFixture: bookings,
organizer: firstUser,
relativeDate: 4,
organizerEventType: firstUser.eventTypes[0],
attendees: [{ name: "Second", email: secondUser.email, timeZone: "Europe/Berlin" }],
});

//admin login
//Select 'ThirdUser' in people filter
await firstUser.apiLogin();
await Promise.all([
page.waitForResponse((response) => /\/api\/trpc\/bookings\/get.*/.test(response.url())),
page.waitForResponse((response) => /\/api\/trpc\/bookings\/get.*/.test(response.url())),
page.goto(`/bookings/upcoming?status=upcoming&userIds=${thirdUser.id}`),
]);

//expect only 3 bookings (out of 4 total) to be shown in list.
//where ThirdUser is either organizer or attendee
const upcomingBookingsTable = page.locator('[data-testid="upcoming-bookings"]');
const bookingListItems = upcomingBookingsTable.locator('[data-testid="booking-item"]');
const bookingListCount = await bookingListItems.count();
expect(bookingListCount).toBe(3);

//verify with the booking titles
const firstUpcomingBooking = bookingListItems.nth(0);
await expect(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
firstUpcomingBooking.locator(`text=${thirdUserOrganizerBooking!.title}`)
).toBeVisible();

const secondUpcomingBooking = bookingListItems.nth(1);
await expect(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
secondUpcomingBooking.locator(`text=${thirdUserAttendeeIndividualBooking!.title}`)
).toBeVisible();

const thirdUpcomingBooking = bookingListItems.nth(2);
await expect(
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
thirdUpcomingBooking.locator(`text=${thirdUserAttendeeTeamEvent!.title}`)
).toBeVisible();
});
});

async function createBooking({
Expand Down
2 changes: 1 addition & 1 deletion apps/web/playwright/fixtures/users.ts
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ const createTeamWorkflow = async (user: { id: number }, team: { id: number }) =>
});
};

const createTeamEventType = async (
export const createTeamEventType = async (
user: { id: number },
team: { id: number },
scenario?: {
Expand Down
2 changes: 2 additions & 0 deletions packages/app-store/intercom/api/initialize.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import type { NextApiRequest, NextApiResponse } from "next";

import { WEBAPP_URL } from "@calcom/lib/constants";

import type { NewCanvas } from "../lib";

export default async function handler(req: NextApiRequest, res: NextApiResponse) {
Expand Down
23 changes: 23 additions & 0 deletions packages/trpc/server/routers/viewer/bookings/get.handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,18 @@ export async function getBookings({
}

if (filters?.userIds && filters.userIds.length > 0) {
const users = await prisma.user.findMany({
where: {
id: {
in: filters.userIds,
},
},
select: {
email: true,
},
});
const attendeeEmailIds = users && users.length > 0 ? users.map((user) => user.email) : [];

bookingWhereInputFilters.userIds = {
AND: [
{
Expand Down Expand Up @@ -134,6 +146,17 @@ export async function getBookings({
},
},
},
...(attendeeEmailIds.length > 0
? [
{
attendees: {
some: {
email: { in: attendeeEmailIds },
},
},
},
]
: []),
],
},
],
Expand Down
Loading