Setup Jest tests for tRPC API with GitHub Actions#21
Conversation
WalkthroughIntroduces comprehensive testing infrastructure for the API package, including Jest configuration, test utilities for mocking contexts, example test suites for routers and procedures, GitHub Actions CI workflow, and test documentation. Root-level and package-level npm scripts enable test execution via turbo and pnpm. Changes
Sequence DiagramsequenceDiagram
participant Test as Test Suite
participant Utils as Test Utilities
participant Router as tRPC Router
participant Procedure as Procedure Handler
Test->>Utils: createMockContext() or<br/>createAuthenticatedMockContext()
Utils-->>Test: Mock Context (Prisma, User, Org)
Test->>Utils: createCaller(router, ctx)
Utils->>Router: router.createCaller(ctx)
Router-->>Utils: Caller Instance
Utils-->>Test: Caller with Context
Test->>Procedure: caller.query/mutation()
alt Authenticated & Authorized
Procedure-->>Test: ✓ Success Response
else Unauthorized
Procedure-->>Test: ✗ TRPCError
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~22 minutes
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests (beta)
Comment |
- Add Jest, ts-jest, and testing dependencies - Create Jest configuration with ESM support - Add test scripts to package.json - Create test utilities for mocking context and calling procedures - Add example tests for health router and protected procedures - Add TESTING.md documentation - Update tsconfig.json to fix composite/incremental conflict Co-authored-by: SimonLoir <17649337+SimonLoir@users.noreply.github.com>
|
@copilot great, now add it to the github actions |
There was a problem hiding this comment.
Pull Request Overview
This PR adds comprehensive Jest testing infrastructure to the packages/api package, enabling unit testing of tRPC routers and procedures. The changes include Jest configuration, test utilities for mocking contexts, initial test suites for health and authentication procedures, and detailed documentation.
Key Changes:
- Added Jest and ts-jest dependencies with ESM support configuration
- Created test utilities for mocking tRPC contexts and creating callers
- Implemented initial tests for health router and protected procedures
- Updated TypeScript configuration to exclude test files from builds
Reviewed Changes
Copilot reviewed 9 out of 10 changed files in this pull request and generated no comments.
Show a summary per file
| File | Description |
|---|---|
| pnpm-lock.yaml | Added Jest 30.2.0, ts-jest 29.4.5, @testing-library/jest-dom 6.9.1, and related testing dependencies |
| packages/api/package.json | Added test scripts and devDependencies for Jest testing |
| packages/api/jest.config.cjs | Configured Jest with ts-jest preset for ESM modules and TypeScript support |
| packages/api/tsconfig.json | Changed composite: true to false, added incremental: true, and excluded test directories |
| packages/api/src/tests/utils/* | Created reusable test utilities for mocking contexts and creating tRPC callers |
| packages/api/src/tests/routers/*.test.ts | Implemented test suites for health router and protected procedure authentication |
| packages/api/TESTING.md | Added comprehensive testing documentation with examples and best practices |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
- Add test script to root package.json - Add test task to turbo.json - Create test.yml GitHub Actions workflow Co-authored-by: SimonLoir <17649337+SimonLoir@users.noreply.github.com>
|
@coderabbitai review |
✅ Actions performedReview triggered.
|
There was a problem hiding this comment.
Actionable comments posted: 3
🧹 Nitpick comments (6)
packages/api/src/__tests__/routers/health.test.ts (1)
5-41: LGTM! Well-structured test suite.The tests are clear, focused, and properly validate the health endpoint behavior. The timestamp validation approach in the third test is reasonable, though timing-based tests can occasionally be sensitive in slow CI environments.
Consider extracting the repeated context and caller setup to reduce duplication:
describe('health router', () => { describe('ping', () => { + let ctx: ReturnType<typeof createMockContext>; + let caller: ReturnType<typeof createCaller<typeof healthRouter>>; + + beforeEach(() => { + ctx = createMockContext(); + caller = createCaller(healthRouter, ctx); + }); + it('should return ok status', async () => { - const ctx = createMockContext(); - const caller = createCaller(healthRouter, ctx); - const result = await caller.ping(); expect(result).toHaveProperty('status', 'ok'); expect(result).toHaveProperty('timestamp'); });packages/api/jest.config.cjs (1)
1-34: LGTM! Comprehensive Jest configuration for ESM + TypeScript.The configuration correctly:
- Uses ts-jest with ESM preset
- Configures test discovery and coverage collection
- Maps module paths for ESM compatibility
- Overrides incremental/composite settings for test runs
The
testPathIgnorePatternson line 8 excludes the utils directory, but this is redundant since utility files don't match thetestMatchpatterns (they don't have.test.tsor.spec.tssuffixes). You could simplify by removing line 8:testMatch: ['**/__tests__/**/*.test.ts', '**/?(*.)+(spec|test).ts'], - testPathIgnorePatterns: ['<rootDir>/src/__tests__/utils/'], moduleFileExtensions: ['ts', 'tsx', 'js', 'jsx', 'json', 'node'],packages/api/TESTING.md (2)
22-31: Specify language for code fence.The code fence showing the test directory structure should specify a language (e.g.,
treeortext) for proper rendering.Apply this diff:
-``` +```text src/__tests__/ ├── routers/ # Tests for tRPC routers │ ├── health.test.ts
98-105: Consider varying sentence structure.Three consecutive section headings begin with "Creates". While grammatically correct, varying the structure improves readability.
For example:
-### `createCaller(router, ctx)` +### `createCaller(router, ctx)` -Creates a tRPC caller for testing router procedures. +Returns a tRPC caller for testing router procedures.packages/api/src/__tests__/routers/trpc.test.ts (1)
6-93: Consider using the documentedcreateCallerutility.The tests invoke procedures using low-level tRPC options, while TESTING.md demonstrates using
createCaller. If this low-level approach is intentional for unit testing the middleware directly, consider adding a note in the documentation explaining when to use each approach.packages/api/src/__tests__/utils/mockContext.ts (1)
20-32: Authenticated context helper looks good.Provides convenient defaults for authenticated testing scenarios. The type assertions are acceptable for test utilities, though you could consider defining a proper mock user type if more test scenarios require different user properties.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (12)
.github/workflows/test.yml(1 hunks)package.json(1 hunks)packages/api/TESTING.md(1 hunks)packages/api/jest.config.cjs(1 hunks)packages/api/package.json(2 hunks)packages/api/src/__tests__/routers/health.test.ts(1 hunks)packages/api/src/__tests__/routers/trpc.test.ts(1 hunks)packages/api/src/__tests__/utils/createCaller.ts(1 hunks)packages/api/src/__tests__/utils/index.ts(1 hunks)packages/api/src/__tests__/utils/mockContext.ts(1 hunks)packages/api/tsconfig.json(1 hunks)turbo.json(1 hunks)
🧰 Additional context used
🪛 LanguageTool
packages/api/TESTING.md
[style] ~99-~99: Three successive sentences begin with the same word. Consider rewording the sentence or use a thesaurus to find a synonym.
Context: ...; ``` ### createCaller(router, ctx) Creates a tRPC caller for testing router proced...
(ENGLISH_WORD_REPEAT_BEGINNING_RULE)
🪛 markdownlint-cli2 (0.18.1)
packages/api/TESTING.md
22-22: Fenced code blocks should have a language specified
(MD040, fenced-code-language)
🔇 Additional comments (9)
packages/api/tsconfig.json (2)
14-16: LGTM! Tests properly excluded from builds.Excluding the
__tests__directory ensures test files aren't compiled into production builds, which is the correct approach.
8-9: Change is safe — no TypeScript project references exist in the monorepo.Verification shows this monorepo uses Turbo and pnpm workspace protocols for inter-package orchestration, not TypeScript project references. No
"references"field appears in any tsconfig.json file. The change fromcomposite: truetofalseis correct and necessary for this setup, as composite is only meaningful with TypeScript project references. The incremental compilation will now work properly without conflicts.turbo.json (1)
23-27: LGTM! Test task properly configured.The new test task follows the established pattern for other tasks and correctly uses
^testto ensure dependencies are tested first.package.json (1)
8-8: LGTM! Test script properly delegates to Turbo.The test script follows the same pattern as other monorepo-level scripts and correctly delegates to Turbo for orchestration.
.github/workflows/test.yml (1)
1-45: LGTM! Well-configured CI workflow.The workflow correctly:
- Matches Node.js (24.8.0) and pnpm (9.0.0) versions from package.json
- Implements pnpm store caching for faster builds
- Uses minimal permissions (contents: read)
- Runs tests on PRs to main
The configuration aligns well with the monorepo setup and testing infrastructure.
packages/api/src/__tests__/utils/createCaller.ts (1)
1-12: LGTM! Clean and type-safe test utility.The
createCallerhelper is well-implemented with proper TypeScript generics and follows standard tRPC testing patterns. The JSDoc comment clearly describes its purpose.packages/api/package.json (1)
14-16: LGTM! Test scripts properly configured for ESM.The test scripts correctly use
NODE_OPTIONS='--experimental-vm-modules'which is necessary for Jest to work with ES modules. The three variants (test, watch, coverage) provide good developer ergonomics.packages/api/src/__tests__/utils/index.ts (1)
1-2: LGTM!Clean re-export of test utilities for convenient imports.
packages/api/src/__tests__/utils/mockContext.ts (1)
6-15: Well-designed mock context utility.The function provides a clean way to create test contexts with optional overrides. The
as anyassertion for prisma is acceptable for test utilities.
Adds Jest testing infrastructure to the tRPC API package (
packages/api) and integrates it with GitHub Actions CI.Changes
Testing Setup
test,test:watch,test:coverageTest Utilities
createMockContext()- Generates mock tRPC context for public procedurescreateAuthenticatedMockContext()- Generates authenticated context for protected procedurescreateCaller()- Invokes tRPC procedures in testsExample Tests
Configuration
GitHub Actions Integration
testscript to root package.json using Turbotesttask to turbo.json for monorepo test orchestration.github/workflows/test.ymlworkflow that runs on pull requests to main branchUsage
See
TESTING.mdfor complete guide.Original prompt
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.
Summary by CodeRabbit
New Features
Documentation
Tests
Chores