DEV Community

Cover image for Test Cal.com booking flows without calendar chaos
FetchSandbox
FetchSandbox

Posted on

Test Cal.com booking flows without calendar chaos

Scheduling integrations do not usually break on the first request.

They break after the booking exists.

The user gets an email. The host has Google Calendar connected. Your app sends its own ICS file. Then somebody reschedules or cancels and suddenly there are two calendar events, or one event refuses to disappear.

That is not a generic "calendar APIs are hard" problem.

It is a workflow identity problem.

The specific workflow

The narrow Cal.com flow I care about is:

  1. Get available slots
  2. Create a booking
  3. Fetch the booking
  4. Reschedule it
  5. Cancel it
  6. Verify the calendar and webhook side effects still point at the same booking

In API terms, the happy path looks like this:

GET  /v2/slots
POST /v2/bookings
GET  /v2/bookings/{bookingUid}
POST /v2/bookings/{bookingUid}/reschedule
POST /v2/bookings/{bookingUid}/cancel
Enter fullscreen mode Exit fullscreen mode

That is the test.

Not just "can I create a booking?"

The real question is:

slot -> booking -> calendar event -> reschedule -> cancel
Enter fullscreen mode Exit fullscreen mode

Do all of those still refer to the same thing?

The bug shape

Here is the kind of bug this flow catches.

Your app creates a booking through Cal.com. The attendee has a connected Google Calendar. Cal.com syncs the event into Google.

But your app also sends custom emails with its own ICS attachment.

If the ICS UID from the Booking API and the synced Google Calendar event identity do not line up, the user can end up with two events:

event from Cal.com sync
event from your custom ICS invite
Enter fullscreen mode Exit fullscreen mode

Then cancellation gets messy because your app cancels one identity while the other one remains in the calendar.

This is the kind of integration bug that is easy to miss if you only test POST /bookings in isolation.

What I would assert

For a scheduling API, I want the test to preserve identity across the whole lifecycle.

The assertions should be closer to this:

booking created -> booking uid exists
calendar reference exists -> external event id is attached
reschedule uses same booking identity
cancel removes or updates the same calendar event
webhook events describe the same lifecycle
Enter fullscreen mode Exit fullscreen mode

And if your product sends custom ICS files, there is one extra check:

Booking API iCalUID matches the calendar event your user will update/cancel
Enter fullscreen mode Exit fullscreen mode

That last part is where teams usually learn the hard way that a "successful booking" does not mean a safe scheduling integration.

Why static mocks miss it

A static mock can return:

POST /bookings -> 201
Enter fullscreen mode Exit fullscreen mode

That is not enough.

It cannot easily prove that a later reschedule call still points at the booking created two steps earlier. It cannot prove that your cancellation code is updating the same calendar event your invite email created. It cannot prove that webhook handlers and calendar references agree about the booking identity.

The state between calls is the product.

Where FetchSandbox fits

FetchSandbox has a Cal.com sandbox flow for the booking lifecycle:

https://fetchsandbox.com/cal-com/test-booking-lifecycle-locally

The broader Cal.com sandbox is here:

https://fetchsandbox.com/cal-com

The workflow is intentionally narrow because that is where integration bugs hide: slots, booking creation, booking lookup, reschedule, cancel, and the events around those changes.

You can also connect your IDE to FetchSandbox through MCP:

{
  "mcpServers": {
    "fetchsandbox": {
      "command": "npx",
      "args": ["-y", "fetchsandbox-mcp"]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then ask an agent something like:

Use FetchSandbox MCP to run the Cal.com booking lifecycle workflow.
Explain which identifiers my app should preserve across create, reschedule, cancel, and calendar sync.
Enter fullscreen mode Exit fullscreen mode

That is the direction I think API testing should move:

not just docs,
not just static responses,
but runnable workflow behavior from inside the developer's own environment.

For Cal.com-style integrations, the useful question is simple:

Can my app create, move, and cancel a booking without leaving calendar ghosts behind?

That should be testable before production users find it.

Top comments (0)