Skip to content

Setup Jest tests for tRPC API with GitHub Actions#21

Merged
SimonLoir merged 3 commits intomainfrom
copilot/setup-jest-tests-trpc-api
Nov 8, 2025
Merged

Setup Jest tests for tRPC API with GitHub Actions#21
SimonLoir merged 3 commits intomainfrom
copilot/setup-jest-tests-trpc-api

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Nov 8, 2025

Adds Jest testing infrastructure to the tRPC API package (packages/api) and integrates it with GitHub Actions CI.

Changes

Testing Setup

  • Jest 30.2.0 with ts-jest for TypeScript + ESM support
  • Test scripts: test, test:watch, test:coverage
  • Coverage reporting configured

Test Utilities

  • createMockContext() - Generates mock tRPC context for public procedures
  • createAuthenticatedMockContext() - Generates authenticated context for protected procedures
  • createCaller() - Invokes tRPC procedures in tests

Example Tests

  • Health router tests (public procedure)
  • Protected procedure middleware tests (authorization checks)

Configuration

  • Fixed tsconfig.json composite/incremental conflict
  • Excluded test files from production builds

GitHub Actions Integration

  • Added test script to root package.json using Turbo
  • Added test task to turbo.json for monorepo test orchestration
  • Created .github/workflows/test.yml workflow that runs on pull requests to main branch

Usage

import { createCaller, createAuthenticatedMockContext } from '../utils';
import { projectsRouter } from '../../routers/projects';

it('lists projects for authenticated user', async () => {
  const ctx = createAuthenticatedMockContext('org-id', 'user-id');
  ctx.prisma.project.findMany = jest.fn().mockResolvedValue([]);
  
  const caller = createCaller(projectsRouter, ctx);
  const result = await caller.list();
  
  expect(result).toEqual([]);
});

See TESTING.md for complete guide.

Original prompt

setup tests using jest in the tRPC API


✨ 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

    • Automated testing infrastructure integrated into the CI/CD pipeline for pull requests.
  • Documentation

    • Added comprehensive testing guide with examples and utilities for developers.
  • Tests

    • Established test framework and utilities for API validation and routing procedures.
  • Chores

    • Configured testing tools and build processes for continuous integration.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 8, 2025

Walkthrough

Introduces 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

Cohort / File(s) Summary
CI/CD Automation
\.github/workflows/test\.yml
New GitHub Actions workflow running tests on pull requests to main, configured with Node.js v24.8.0 and pnpm v9.0.0
Root Configuration
package\.json, turbo\.json
Root package.json adds test script; turbo.json introduces test task with upstream dependency declaration
API Testing Configuration
packages/api/jest\.config\.cjs, packages/api/package\.json, packages/api/tsconfig\.json
Jest configuration with ts-jest and ESM support; package.json adds test/test:watch/test:coverage scripts and testing dependencies (@testing-library/jest-dom, @types/jest, jest, ts-jest); tsconfig.json adjusts composite/incremental flags and adds test exclusion
API Test Utilities
packages/api/src/__tests__/utils/mockContext\.ts, packages/api/src/__tests__/utils/createCaller\.ts, packages/api/src/__tests__/utils/index\.ts
Helper functions createMockContext and createAuthenticatedMockContext for context construction; createCaller utility for tRPC router instantiation; index re-exports all utilities
API Test Suites
packages/api/src/__tests__/routers/health\.test\.ts, packages/api/src/__tests__/routers/trpc\.test\.ts
Tests for health router ping endpoint validation; protectedProcedure tests covering unauthorized and authenticated access scenarios
API Testing Documentation
packages/api/TESTING\.md
Guide documenting test execution commands, structure, test utilities, examples for public/protected procedures, Prisma mocking guidance, and technical notes

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

  • Jest configuration correctness: Verify ts-jest settings, module resolution, and coverage configuration align with project standards
  • Test utilities implementation: Ensure mock context creation properly handles Prisma mocking and optional parameter overrides
  • tsconfig.json changes: Confirm composite/incremental and test exclusion paths are correct and won't cause build issues
  • Test examples: Validate test patterns for procedures match intended error handling and validation logic

Poem

🐰 Hops of joy through testing paths so new,
Jest and mocks in every avenue,
Procedures tested, contexts mock with care,
CI checks quality everywhere!
Ready, set, test—let's hop and bound,
Where reliable code is always found!

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: setting up Jest tests for the tRPC API and integrating them with GitHub Actions CI.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch copilot/setup-jest-tests-trpc-api

Comment @coderabbitai help to get the list of available commands and usage tips.

- 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 AI changed the title [WIP] Setup tests using Jest in the tRPC API Setup Jest tests for tRPC API Nov 8, 2025
Copilot AI requested a review from SimonLoir November 8, 2025 12:16
@SimonLoir SimonLoir marked this pull request as ready for review November 8, 2025 12:17
Copilot AI review requested due to automatic review settings November 8, 2025 12:17
@SimonLoir
Copy link
Copy Markdown
Contributor

@copilot great, now add it to the github actions

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@SimonLoir SimonLoir changed the title Setup Jest tests for tRPC API test: add support for tests in the tRPC API Nov 8, 2025
- 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>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Nov 8, 2025

@copilot great, now add it to the github actions

Added test workflow to GitHub Actions in commit 8feeb88. The workflow runs on pull requests to main and executes pnpm test using the same setup as the existing lint and build workflows.

Copilot AI changed the title test: add support for tests in the tRPC API Setup Jest tests for tRPC API with GitHub Actions Nov 8, 2025
@SimonLoir
Copy link
Copy Markdown
Contributor

@coderabbitai review

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Nov 8, 2025

✅ Actions performed

Review triggered.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 testPathIgnorePatterns on line 8 excludes the utils directory, but this is redundant since utility files don't match the testMatch patterns (they don't have .test.ts or .spec.ts suffixes). 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., tree or text) 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 documented createCaller utility.

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

📥 Commits

Reviewing files that changed from the base of the PR and between 896dda6 and 8feeb88.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is 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 from composite: true to false is 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 ^test to 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 createCaller helper 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 any assertion for prisma is acceptable for test utilities.

Comment thread packages/api/package.json
Comment thread packages/api/src/__tests__/routers/trpc.test.ts
Comment thread packages/api/src/__tests__/routers/trpc.test.ts
@SimonLoir SimonLoir merged commit 7d2ea1c into main Nov 8, 2025
7 checks passed
@SimonLoir SimonLoir deleted the copilot/setup-jest-tests-trpc-api branch November 8, 2025 12:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants