@@ -15,7 +15,7 @@ import { expectBookingToBeInDatabase } from "@calcom/web/test/utils/bookingScena
1515import { getMockRequestDataForBooking } from "@calcom/web/test/utils/bookingScenario/getMockRequestDataForBooking" ;
1616import { setupAndTeardown } from "@calcom/web/test/utils/bookingScenario/setupAndTeardown" ;
1717
18- import { describe , expect , test } from "vitest" ;
18+ import { describe , expect , test , vi } from "vitest" ;
1919
2020import { BookingStatus } from "@calcom/prisma/enums" ;
2121
@@ -465,6 +465,7 @@ describe("handleNewBooking - Booking Flags", () => {
465465
466466 const createdBooking = await handleNewBooking ( {
467467 bookingData : mockBookingData ,
468+ userId : 101 , // Owner
468469 } ) ;
469470
470471 expect ( createdBooking . responses ) . toEqual (
@@ -474,7 +475,7 @@ describe("handleNewBooking - Booking Flags", () => {
474475 } )
475476 ) ;
476477
477- // Even though requiresConfirmation is true, forceConfirm=true should produce ACCEPTED
478+ // Even though requiresConfirmation is true, forceConfirm=true from owner should produce ACCEPTED
478479 expect ( createdBooking . status ) . toBe ( BookingStatus . ACCEPTED ) ;
479480
480481 await expectBookingToBeInDatabase ( {
@@ -577,5 +578,66 @@ describe("handleNewBooking - Booking Flags", () => {
577578 status : BookingStatus . PENDING ,
578579 } ) ;
579580 } ) ;
581+
582+ test ( "should NOT honor forceConfirm if caller is NOT owner/admin" , async ( ) => {
583+ const handleNewBooking = getNewBookingHandler ( ) ;
584+ const booker = getBooker ( {
585+ email : "booker@example.com" ,
586+ name : "Booker" ,
587+ } ) ;
588+
589+ const organizer = getOrganizer ( {
590+ name : "Organizer" ,
591+ email : "organizer@example.com" ,
592+ id : 101 ,
593+ schedules : [ TestData . schedules . IstWorkHours ] ,
594+ credentials : [ getGoogleCalendarCredential ( ) ] ,
595+ selectedCalendars : [ TestData . selectedCalendars . google ] ,
596+ } ) ;
597+
598+ const { dateString : plus1DateString } = getDate ( { dateIncrement : 1 } ) ;
599+
600+ await createBookingScenario (
601+ getScenarioData ( {
602+ eventTypes : [
603+ {
604+ id : 1 ,
605+ slotInterval : 45 ,
606+ length : 45 ,
607+ requiresConfirmation : true ,
608+ users : [ { id : 101 } ] ,
609+ userId : 101 , // eventType owner
610+ } ,
611+ ] ,
612+ organizer,
613+ } )
614+ ) ;
615+
616+ vi . spyOn ( prismaMock . user , "findUnique" ) . mockResolvedValueOnce ( {
617+ id : 999 ,
618+ role : "USER" , // Not an admin
619+ } as Awaited < ReturnType < typeof prismaMock . user . findUnique > > ) ;
620+
621+ const mockBookingData = getMockRequestDataForBooking ( {
622+ data : {
623+ eventTypeId : 1 ,
624+ responses : {
625+ email : booker . email ,
626+ name : booker . name ,
627+ } ,
628+ start : `${ plus1DateString } T05:00:00.000Z` ,
629+ end : `${ plus1DateString } T05:45:00.000Z` ,
630+ forceConfirm : true ,
631+ } ,
632+ } ) ;
633+
634+ const createdBooking = await handleNewBooking ( {
635+ bookingData : mockBookingData ,
636+ userId : 999 , // Unauthorized caller
637+ } ) ;
638+
639+ // forceConfirm should be ignored, status should be PENDING
640+ expect ( createdBooking . status ) . toBe ( BookingStatus . PENDING ) ;
641+ } ) ;
580642 } ) ;
581643} ) ;
0 commit comments