Testing and Booking Scenarios
Purpose and Scope
The @calcom/testing workspace package is the shared place for test support code that should not live inside a single application or feature package. It gives contributors stable import paths for Vitest setup, library test helpers, Prisma mocks, fixtures, and booking-scenario utilities. That matters in Cal.diy because booking is the central product journey, and many tests need repeatable users, event types, calendars, database state, and request assumptions without duplicating setup logic in every package. The package is private, so it is intended for monorepo use rather than publication as an external SDK.
Sources: packages/testing/package.json, packages/testing/src/lib/mocks/prisma.ts, packages/testing/src/lib/bookingScenario/bookingScenario.ts
This page is for contributors who need to add or debug tests around scheduling behavior. It explains the boundary between unit-test utilities, database mocking, performance tests, and booking-scenario helpers. A unit or integration-style test usually imports from the package exports and runs under Vitest. A performance test is a k6 script that exercises a running Cal.diy instance through HTTP. A booking scenario helper is source-level test infrastructure for constructing realistic booking conditions, while the Prisma mock makes database access deterministic inside Vitest without connecting to a live PostgreSQL database.
Sources: packages/testing/package.json, packages/testing/performance/README.md, packages/testing/src/lib/mocks/prisma.ts
Relevant Source Files
packages/testing/package.json— declares the private@calcom/testingworkspace package, its exported helper namespaces, lint scripts, and dependencies on@calcom/i18n,@calcom/lib, and@calcom/prisma.packages/testing/performance/README.md— documents the k6 booking-flow performance suite, including smoke, load, stress, and spike test categories plus environment-variable configuration.packages/testing/src/lib/__mocks__/prisma.ts— implements the Vitest Prisma mock using Prismock, a generated DMMF frompackages/prisma/schema.prisma, a proxy-backed Prisma client, and reset behavior before each test.packages/testing/src/lib/bookingScenario/bookingScenario.ts— contains the booking-scenario helper implementation exposed through the package’s./lib/bookingScenario/*export namespace.
Package Surface and Public Imports
The package export map is the best starting point when deciding how to import test utilities. @calcom/testing/setupVitest points to the shared Vitest setup file. @calcom/testing/lib/* exposes general library helpers. @calcom/testing/lib/__mocks__/* exposes mocks such as the Prisma mock. @calcom/testing/lib/bookingScenario/* exposes booking scenario helpers, and @calcom/testing/lib/fixtures/* provides fixture-oriented helpers. These exports keep tests from reaching into arbitrary internal file paths and make refactors safer because package consumers depend on a declared namespace.
Sources: packages/testing/package.json
The package also makes its dependency assumptions explicit. It depends on workspace packages @calcom/i18n, @calcom/lib, and @calcom/prisma, which indicates that shared testing utilities can use translation support, common library behavior, and generated Prisma types or selects. Its development dependencies include vitest and prismock, so the default unit-test runtime is Vitest and the in-memory Prisma behavior is provided by Prismock. The only package scripts shown are lint-oriented: lint, lint:fix, and lint:report, each using Biome, with the report written to ../../lint-results/testing.json.
Sources: packages/testing/package.json
Compact reference
| Surface | Source contract | Use it when |
|---|---|---|
@calcom/testing/setupVitest | Exported as ./setupVitest | A test project needs the shared Vitest setup entrypoint. |
@calcom/testing/lib/* | Exported as ./lib/* | A test needs general reusable testing helpers. |
@calcom/testing/lib/__mocks__/* | Exported as ./lib/__mocks__/* | A test needs a declared mock module such as the Prisma mock. |
@calcom/testing/lib/bookingScenario/* | Exported as ./lib/bookingScenario/* | A test needs reusable booking-flow scenario setup. |
@calcom/testing/lib/fixtures/* | Exported as ./lib/fixtures/* | A test needs shared fixture data or fixture factories. |
Prisma Mock Implementation
The Prisma mock is designed to replace @calcom/prisma during Vitest runs. It first stubs DATABASE_URL to a local PostgreSQL-style test URL, then uses vi.mock to intercept imports of @calcom/prisma. Inside the mock factory, it reads packages/prisma/schema.prisma, generates the Prisma DMMF through getDMMF, creates a Prismock client class, and instantiates it. The returned module exposes default, prisma, and readonlyPrisma as the same proxy-backed mock client, and it spreads Prisma select helpers from @calcom/prisma/selects.
Sources: packages/testing/src/lib/mocks/prisma.ts
The proxy is important because imports may access Prisma properties before or after the Prismock instance is initialized. If a test tries to use the proxy before initialization, the get and set traps throw Prismock not initialized yet, making the failure explicit instead of silently returning undefined behavior. Once initialized, property reads fall through to the Prismock instance unless the property has been set directly on the proxy target. The mock also implements descriptor, membership, key enumeration, and assignment traps so it behaves more like a real Prisma client object under introspection and spying.
Sources: packages/testing/src/lib/mocks/prisma.ts
The mock includes two pragmatic safeguards for gaps between real Prisma and Prismock. First, it patches webhook.findMany when a query combines OR and AND conditions that Prismock cannot handle; the patch clears the where clause and logs a silly-level message through @calcom/lib/logger. Second, if Prismock does not implement $queryRaw, the mock defines it as an async function that throws a clear error instructing the test author to use vi.spyOn for that behavior. Before every test, the mock resets the Prismock instance and reapplies the webhook workaround.
Sources: packages/testing/src/lib/mocks/prisma.ts
Booking Scenario Helpers
Booking scenario helpers sit at a higher level than a raw Prisma mock. The package export map gives them a dedicated namespace, ./lib/bookingScenario/*, and the targeted implementation path is packages/testing/src/lib/bookingScenario/bookingScenario.ts. Use this namespace when a test needs to express a booking situation rather than individually create every database row and domain object. In practice, that distinction keeps tests focused on the behavior under test: availability resolution, event-type behavior, attendee data, or booking creation expectations, instead of the incidental setup required to reach that state.
Sources: packages/testing/package.json, packages/testing/src/lib/bookingScenario/bookingScenario.ts
A good rule is to choose the lowest-level helper that still communicates the intent of the test. If a test only needs to assert code behavior against a mocked Prisma model, import the Prisma mock surface. If it needs a realistic booking context shared across multiple suites, prefer the booking scenario namespace. That creates a consistent vocabulary for scheduling tests and makes future changes to the underlying data model easier, because the helper can absorb schema changes while individual tests continue to describe scenarios in booking terms.
Sources: packages/testing/package.json, packages/testing/src/lib/mocks/prisma.ts, packages/testing/src/lib/bookingScenario/bookingScenario.ts
Performance Test Flow
The performance suite is separate from Vitest because it measures a running Cal.diy deployment, not isolated TypeScript functions. The README identifies Grafana k6 as the runner and focuses the suite on the booking flow, specifically the booking page view. It organizes scenarios by load shape: smoke/ for minimal functionality checks, load/ for expected normal load, stress/ for finding breaking points, spike/ for sudden traffic increases, and utils/ for shared k6 helpers. The documented target scale reaches thousands to tens of thousands of requests per minute.
Sources: packages/testing/performance/README.md
By default, k6 tests run against http://localhost:3000, but the README documents BASE_URL for testing another local, staging, or deployed instance. It also describes a Docker wrapper script, ./tests/scripts/run-k6-local.sh, that detects Linux or macOS Docker flags and presents an interactive menu for smoke, load, stress, spike, all, or exit. The same script can run directly with an argument such as smoke or all, and the documented environment overrides include BASE_URL, TOKEN, TEST_USER_FREE, TEST_PASSWORD_FREE, TEST_USER_PRO, and TEST_PASSWORD_PRO.
Sources: packages/testing/performance/README.md
# Run against the default local web app
k6 run tests/performance/smoke/booking.js
# Run against another environment
BASE_URL=https://your-cal-instance.com k6 run tests/performance/smoke/booking.js
# Use the Docker helper from the repository root
./tests/scripts/run-k6-local.sh smoke
./tests/scripts/run-k6-local.sh allExecution Flow for Contributors
When adding a normal test, start by deciding whether the test needs a real service, a mocked database, or a constructed booking scenario. For Vitest-based code, import from @calcom/testing exports instead of hard-coding deep paths. If the code imports @calcom/prisma, include the Prisma mock so the test uses the Prismock-backed client and gets automatic reset behavior before each test. If the test setup describes a reusable scheduling situation, place that setup behind the booking scenario helper surface so other booking suites can share it.
Sources: packages/testing/package.json, packages/testing/src/lib/mocks/prisma.ts, packages/testing/src/lib/bookingScenario/bookingScenario.ts
When adding a performance check, first run Cal.diy locally or identify the deployed instance that should receive test traffic. Use smoke tests to validate that the flow still works before running load, stress, or spike tests, because the heavier categories intentionally create much more traffic. Then tune the documented environment variables rather than editing scripts for each environment. The README states that thresholds live in utils/config.js and differ by test type, with smoke thresholds being strictest and spike thresholds being most lenient, so interpret failures in the context of the selected load profile.
Sources: packages/testing/performance/README.md
Testing Signals and Next Steps
The main quality signals for this package are import stability, deterministic database behavior, and booking-flow realism. Import stability comes from the package export map. Deterministic behavior comes from the Prismock-backed Prisma module, the explicit test database URL stub, and beforeEach reset. Booking-flow realism comes from concentrating scenario setup under the booking scenario namespace and using k6 for end-to-end performance pressure on a running application. Together, these layers let contributors test small units, complex scheduling states, and production-like traffic patterns without treating every test as the same kind of problem.
Sources: packages/testing/package.json, packages/testing/performance/README.md, packages/testing/src/lib/mocks/prisma.ts, packages/testing/src/lib/bookingScenario/bookingScenario.ts
Next, read the booking feature documentation when you need domain context for what the scenarios should represent, and read the monorepo architecture documentation when you need to understand how workspace exports and scripts fit into the larger repository. For test implementation, keep imports within the declared @calcom/testing namespaces, mock raw SQL behavior explicitly with vi.spyOn when needed, and run k6 smoke tests before escalating to load, stress, or spike profiles against any shared environment.