2023-10-11 14:09:13 +00:00
// TODO: Fix tests (These test were never running due to the vitest workspace config)
2023-10-03 18:52:19 +00:00
import prismaMock from "../../../../../tests/libs/__mocks__/prisma" ;
2023-02-16 21:01:40 +00:00
import type { Request , Response } from "express" ;
import type { NextApiRequest , NextApiResponse } from "next" ;
2022-10-06 20:40:41 +00:00
import { createMocks } from "node-mocks-http" ;
2023-05-26 21:14:49 +00:00
import { describe , expect , test , vi } from "vitest" ;
2022-10-06 20:40:41 +00:00
import dayjs from "@calcom/dayjs" ;
2022-10-13 18:29:30 +00:00
import sendPayload from "@calcom/features/webhooks/lib/sendPayload" ;
2022-11-23 02:50:00 +00:00
import { buildBooking , buildEventType , buildWebhook } from "@calcom/lib/test/builder" ;
2022-10-06 20:40:41 +00:00
import prisma from "@calcom/prisma" ;
2022-10-13 18:29:30 +00:00
import handler from "../../../pages/api/bookings/_post" ;
2022-10-06 20:40:41 +00:00
type CustomNextApiRequest = NextApiRequest & Request ;
type CustomNextApiResponse = NextApiResponse & Response ;
2023-05-26 21:14:49 +00:00
vi . mock ( "@calcom/features/webhooks/lib/sendPayload" ) ;
vi . mock ( "@calcom/lib/server/i18n" , ( ) = > {
2022-10-13 18:29:30 +00:00
return {
getTranslation : ( key : string ) = > key ,
} ;
} ) ;
2022-10-06 20:40:41 +00:00
2023-10-11 14:09:13 +00:00
describe . skipIf ( true ) ( "POST /api/bookings" , ( ) = > {
2022-10-06 20:40:41 +00:00
describe ( "Errors" , ( ) = > {
test ( "Missing required data" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : { } ,
} ) ;
await handler ( req , res ) ;
2023-10-11 14:09:13 +00:00
expect ( res . statusCode ) . toBe ( 400 ) ;
2022-10-06 20:40:41 +00:00
expect ( JSON . parse ( res . _getData ( ) ) ) . toEqual (
expect . objectContaining ( {
2022-10-06 21:27:49 +00:00
message :
2022-11-18 19:19:33 +00:00
"invalid_type in 'eventTypeId': Required; invalid_type in 'title': Required; invalid_type in 'startTime': Required; invalid_type in 'startTime': Required; invalid_type in 'endTime': Required; invalid_type in 'endTime': Required" ,
2022-10-06 20:40:41 +00:00
} )
) ;
} ) ;
test ( "Invalid eventTypeId" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
title : "test" ,
eventTypeId : 2 ,
startTime : dayjs ( ) . toDate ( ) ,
endTime : dayjs ( ) . add ( 1 , "day" ) . toDate ( ) ,
} ,
prisma ,
} ) ;
2022-10-06 21:27:49 +00:00
prismaMock . eventType . findUnique . mockResolvedValue ( null ) ;
2022-10-06 20:40:41 +00:00
await handler ( req , res ) ;
expect ( res . _getStatusCode ( ) ) . toBe ( 400 ) ;
expect ( JSON . parse ( res . _getData ( ) ) ) . toEqual (
expect . objectContaining ( {
2022-10-13 18:29:30 +00:00
message :
"'invalid_type' in 'email': Required; 'invalid_type' in 'end': Required; 'invalid_type' in 'location': Required; 'invalid_type' in 'name': Required; 'invalid_type' in 'start': Required; 'invalid_type' in 'timeZone': Required; 'invalid_type' in 'language': Required; 'invalid_type' in 'customInputs': Required; 'invalid_type' in 'metadata': Required" ,
2022-10-06 20:40:41 +00:00
} )
) ;
} ) ;
test ( "Missing recurringCount" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
title : "test" ,
eventTypeId : 2 ,
startTime : dayjs ( ) . toDate ( ) ,
endTime : dayjs ( ) . add ( 1 , "day" ) . toDate ( ) ,
} ,
prisma ,
} ) ;
prismaMock . eventType . findUnique . mockResolvedValue (
buildEventType ( { recurringEvent : { freq : 2 , count : 12 , interval : 1 } } )
) ;
await handler ( req , res ) ;
expect ( res . _getStatusCode ( ) ) . toBe ( 400 ) ;
expect ( JSON . parse ( res . _getData ( ) ) ) . toEqual (
expect . objectContaining ( {
2022-10-13 18:29:30 +00:00
message :
"'invalid_type' in 'email': Required; 'invalid_type' in 'end': Required; 'invalid_type' in 'location': Required; 'invalid_type' in 'name': Required; 'invalid_type' in 'start': Required; 'invalid_type' in 'timeZone': Required; 'invalid_type' in 'language': Required; 'invalid_type' in 'customInputs': Required; 'invalid_type' in 'metadata': Required" ,
2022-10-06 20:40:41 +00:00
} )
) ;
} ) ;
test ( "Invalid recurringCount" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
title : "test" ,
eventTypeId : 2 ,
startTime : dayjs ( ) . toDate ( ) ,
endTime : dayjs ( ) . add ( 1 , "day" ) . toDate ( ) ,
recurringCount : 15 ,
} ,
prisma ,
} ) ;
prismaMock . eventType . findUnique . mockResolvedValue (
buildEventType ( { recurringEvent : { freq : 2 , count : 12 , interval : 1 } } )
) ;
await handler ( req , res ) ;
expect ( res . _getStatusCode ( ) ) . toBe ( 400 ) ;
expect ( JSON . parse ( res . _getData ( ) ) ) . toEqual (
expect . objectContaining ( {
2022-10-13 18:29:30 +00:00
message :
"'invalid_type' in 'email': Required; 'invalid_type' in 'end': Required; 'invalid_type' in 'location': Required; 'invalid_type' in 'name': Required; 'invalid_type' in 'start': Required; 'invalid_type' in 'timeZone': Required; 'invalid_type' in 'language': Required; 'invalid_type' in 'customInputs': Required; 'invalid_type' in 'metadata': Required" ,
} )
) ;
} ) ;
test ( "No available users" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
name : "test" ,
start : dayjs ( ) . format ( ) ,
end : dayjs ( ) . add ( 1 , "day" ) . format ( ) ,
eventTypeId : 2 ,
email : "test@example.com" ,
location : "Cal.com Video" ,
timeZone : "America/Montevideo" ,
language : "en" ,
customInputs : [ ] ,
metadata : { } ,
userId : 4 ,
} ,
prisma ,
} ) ;
2022-11-23 02:50:00 +00:00
prismaMock . eventType . findUniqueOrThrow . mockResolvedValue ( buildEventType ( ) ) ;
2022-10-13 18:29:30 +00:00
await handler ( req , res ) ;
console . log ( { statusCode : res._getStatusCode ( ) , data : JSON.parse ( res . _getData ( ) ) } ) ;
expect ( res . _getStatusCode ( ) ) . toBe ( 500 ) ;
expect ( JSON . parse ( res . _getData ( ) ) ) . toEqual (
expect . objectContaining ( {
message : "No available users found." ,
2022-10-06 20:40:41 +00:00
} )
) ;
} ) ;
} ) ;
2023-05-26 21:14:49 +00:00
describe ( "Success" , ( ) = > {
2022-10-06 20:40:41 +00:00
describe ( "Regular event-type" , ( ) = > {
test ( "Creates one single booking" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
2022-10-13 18:29:30 +00:00
name : "test" ,
start : dayjs ( ) . format ( ) ,
end : dayjs ( ) . add ( 1 , "day" ) . format ( ) ,
2022-10-06 20:40:41 +00:00
eventTypeId : 2 ,
2022-10-13 18:29:30 +00:00
email : "test@example.com" ,
location : "Cal.com Video" ,
timeZone : "America/Montevideo" ,
language : "en" ,
customInputs : [ ] ,
metadata : { } ,
userId : 4 ,
2022-10-06 20:40:41 +00:00
} ,
prisma ,
} ) ;
2022-11-23 02:50:00 +00:00
prismaMock . eventType . findUniqueOrThrow . mockResolvedValue ( buildEventType ( ) ) ;
2022-10-13 18:29:30 +00:00
prismaMock . booking . findMany . mockResolvedValue ( [ ] ) ;
2022-10-06 20:40:41 +00:00
await handler ( req , res ) ;
2022-10-13 18:29:30 +00:00
console . log ( { statusCode : res._getStatusCode ( ) , data : JSON.parse ( res . _getData ( ) ) } ) ;
2022-10-06 20:40:41 +00:00
expect ( prismaMock . booking . create ) . toHaveBeenCalledTimes ( 1 ) ;
} ) ;
} ) ;
describe ( "Recurring event-type" , ( ) = > {
test ( "Creates multiple bookings" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
title : "test" ,
eventTypeId : 2 ,
startTime : dayjs ( ) . toDate ( ) ,
endTime : dayjs ( ) . add ( 1 , "day" ) . toDate ( ) ,
recurringCount : 12 ,
} ,
prisma ,
} ) ;
prismaMock . eventType . findUnique . mockResolvedValue (
buildEventType ( { recurringEvent : { freq : 2 , count : 12 , interval : 1 } } )
) ;
Array . from ( Array ( 12 ) . keys ( ) ) . map ( async ( ) = > {
prismaMock . booking . create . mockResolvedValue ( buildBooking ( ) ) ;
} ) ;
prismaMock . webhook . findMany . mockResolvedValue ( [ ] ) ;
await handler ( req , res ) ;
const data = JSON . parse ( res . _getData ( ) ) ;
expect ( prismaMock . booking . create ) . toHaveBeenCalledTimes ( 12 ) ;
expect ( res . _getStatusCode ( ) ) . toBe ( 201 ) ;
expect ( data . message ) . toEqual ( "Bookings created successfully." ) ;
expect ( data . bookings . length ) . toEqual ( 12 ) ;
} ) ;
} ) ;
test ( "Notifies multiple bookings" , async ( ) = > {
const { req , res } = createMocks < CustomNextApiRequest , CustomNextApiResponse > ( {
method : "POST" ,
body : {
title : "test" ,
eventTypeId : 2 ,
startTime : dayjs ( ) . toDate ( ) ,
endTime : dayjs ( ) . add ( 1 , "day" ) . toDate ( ) ,
recurringCount : 12 ,
} ,
prisma ,
} ) ;
prismaMock . eventType . findUnique . mockResolvedValue (
buildEventType ( { recurringEvent : { freq : 2 , count : 12 , interval : 1 } } )
) ;
const createdAt = new Date ( ) ;
Array . from ( Array ( 12 ) . keys ( ) ) . map ( async ( ) = > {
prismaMock . booking . create . mockResolvedValue ( buildBooking ( { createdAt } ) ) ;
} ) ;
const mockedWebhooks = [
buildWebhook ( {
subscriberUrl : "http://mockedURL1.com" ,
createdAt ,
eventTypeId : 1 ,
secret : "secret1" ,
} ) ,
buildWebhook ( {
subscriberUrl : "http://mockedURL2.com" ,
createdAt ,
eventTypeId : 2 ,
secret : "secret2" ,
} ) ,
] ;
prismaMock . webhook . findMany . mockResolvedValue ( mockedWebhooks ) ;
await handler ( req , res ) ;
const data = JSON . parse ( res . _getData ( ) ) ;
expect ( sendPayload ) . toHaveBeenCalledTimes ( 24 ) ;
expect ( data . message ) . toEqual ( "Bookings created successfully." ) ;
expect ( data . bookings . length ) . toEqual ( 12 ) ;
} ) ;
} ) ;
} ) ;