Skip to content

Add Jest unit tests and CI workflow for TypeScript services#2

Open
Copilot wants to merge 4 commits into
mainfrom
copilot/create-unit-tests-workflow
Open

Add Jest unit tests and CI workflow for TypeScript services#2
Copilot wants to merge 4 commits into
mainfrom
copilot/create-unit-tests-workflow

Conversation

Copy link
Copy Markdown

Copilot AI commented Feb 10, 2026

Adds unit test coverage across all TypeScript packages/services and a GitHub Actions workflow to run them on push/PR to main.

CI Workflow (.github/workflows/test.yml)

  • Three parallel jobs: @mono/shared, @mono/github, @mono/api-gateway
  • pnpm + Node 20, frozen lockfile, scoped contents: read permissions

Test Infrastructure

  • Added jest.config.js, test/test:coverage scripts, and jest/ts-jest devDeps to @mono/shared and @mono/github (api-gateway already had them)

Unit Tests (56 total, all mocked — no DB/network)

  • @mono/shared (24 tests): successResponse, errorResponse, sleep, generateId, HTTP_STATUS, ENVIRONMENTS, paginationSchema validation
  • @mono/github (16 tests): getAuthorizationUrl, exchangeCodeForToken, getGitHubUser (fetch mocked), verifyWebhookSignature (valid/invalid/tampered), createAppOctokit, createInstallationOctokit, createUserOctokit
  • @mono/api-gateway (8 new + 8 existing): requireAuth middleware (missing header, bad token, valid token flow), signToken JWT structure, errorHandler (default/custom status codes, empty message fallback)
# Each service tested independently via pnpm filter
- run: pnpm --filter @mono/shared test
- run: pnpm --filter @mono/github test
- run: pnpm --filter @mono/api-gateway test

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 2 commits February 10, 2026 22:53
…rvices

Co-authored-by: Basil-Ismail <107148738+Basil-Ismail@users.noreply.github.com>
Co-authored-by: Basil-Ismail <107148738+Basil-Ismail@users.noreply.github.com>
Copilot AI changed the title [WIP] Add workflow for unit testing services with Jest Add Jest unit tests and CI workflow for TypeScript services Feb 10, 2026
Copilot AI requested a review from Basil-Ismail February 10, 2026 22:58
@Basil-Ismail Basil-Ismail marked this pull request as ready for review February 10, 2026 23:05
@Basil-Ismail Basil-Ismail requested a review from Copilot February 10, 2026 23:06
Copy link
Copy Markdown

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

Adds Jest-based unit test coverage for TypeScript packages in the monorepo and introduces a GitHub Actions workflow to run those tests on pushes/PRs to main.

Changes:

  • Added Jest/ts-jest configs and test / test:coverage scripts for @mono/shared and @mono/github.
  • Introduced new unit tests across @mono/shared, @mono/github, and @mono/api-gateway middleware.
  • Added a CI workflow that runs tests for @mono/shared, @mono/github, and @mono/api-gateway in parallel jobs.

Reviewed changes

Copilot reviewed 14 out of 15 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pnpm-lock.yaml Locks newly added Jest-related dev dependencies for the updated packages.
packages/shared/package.json Adds Jest scripts and devDependencies to enable running unit tests in @mono/shared.
packages/shared/jest.config.js Introduces ts-jest configuration for @mono/shared test execution and coverage.
packages/shared/src/utils/utils.test.ts Adds unit tests for shared utility helpers (successResponse, errorResponse, sleep, generateId).
packages/shared/src/types/types.test.ts Adds tests around pagination schema behavior and (attempted) typing checks.
packages/shared/src/constants/constants.test.ts Adds tests for shared constant objects and environment typing.
packages/github/package.json Adds Jest scripts and devDependencies to enable running unit tests in @mono/github.
packages/github/jest.config.js Introduces ts-jest configuration for @mono/github test execution and coverage.
packages/github/src/oauth.test.ts Adds tests for OAuth URL building and fetch-based token/user flows.
packages/github/src/webhook.test.ts Adds tests for webhook signature verification logic.
packages/github/src/app-auth.test.ts Adds tests for Octokit factory helpers using module mocks.
packages/github/src/user-auth.test.ts Adds tests for user-auth Octokit creation using module mocks.
apps/api-gateway/src/middleware/auth.test.ts Adds tests for JWT signing and requireAuth middleware behavior.
apps/api-gateway/src/middleware/error-handler.test.ts Adds tests for error handler status/message behavior.
.github/workflows/test.yml Adds CI workflow to run Jest tests for each package/app on push/PR.
Files not reviewed (1)
  • pnpm-lock.yaml: Language not supported

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +13 to +29
test-shared:
name: Test @mono/shared
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4

- uses: pnpm/action-setup@v4
with:
version: 9.1.0

- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'pnpm'

- run: pnpm install --frozen-lockfile
- run: pnpm --filter @mono/shared test
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

The workflow repeats the same checkout/pnpm setup/install steps across three jobs. A matrix job (or a reusable composite action) would reduce duplication and make future changes (Node/pnpm version bumps, install flags) less error-prone.

Copilot uses AI. Check for mistakes.
Comment on lines +45 to +48
const start = Date.now();
await sleep(50);
const elapsed = Date.now() - start;
expect(elapsed).toBeGreaterThanOrEqual(40);
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

The sleep test uses real timers (Date.now + awaiting sleep(50)), which slows the suite and can be brittle if the environment is under heavy load. Prefer Jest fake timers (useFakeTimers/advanceTimersByTime) to assert the promise resolves after advancing time instead of waiting in real time.

Suggested change
const start = Date.now();
await sleep(50);
const elapsed = Date.now() - start;
expect(elapsed).toBeGreaterThanOrEqual(40);
jest.useFakeTimers();
const sleepPromise = sleep(50);
jest.advanceTimersByTime(50);
await expect(sleepPromise).resolves.toBeUndefined();
jest.useRealTimers();

Copilot uses AI. Check for mistakes.
Comment on lines +32 to +76

describe('ApiResponse type', () => {
it('should allow creating a typed success response', () => {
const response: ApiResponse<string> = {
success: true,
data: 'hello',
};
expect(response.success).toBe(true);
expect(response.data).toBe('hello');
});

it('should allow creating a typed error response', () => {
const response: ApiResponse = {
success: false,
error: 'something failed',
};
expect(response.success).toBe(false);
expect(response.error).toBe('something failed');
});
});

describe('PaginationParams type', () => {
it('should allow creating pagination params', () => {
const params: PaginationParams = { page: 1, limit: 20 };
expect(params.page).toBe(1);
expect(params.limit).toBe(20);
});
});

describe('PaginatedResponse type', () => {
it('should allow creating a paginated response', () => {
const response: PaginatedResponse<number> = {
success: true,
data: [1, 2, 3],
pagination: {
page: 1,
limit: 20,
total: 3,
totalPages: 1,
},
};
expect(response.data).toHaveLength(3);
expect(response.pagination.total).toBe(3);
});
});
Copy link

Copilot AI Feb 10, 2026

Choose a reason for hiding this comment

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

These tests under "ApiResponse/PaginationParams/PaginatedResponse type" don’t actually validate TypeScript types at runtime (types are erased), so they add coverage without catching type regressions. Consider removing these runtime assertions or replacing them with compile-time type tests (e.g., tsd or @ts-expect-error based checks) that fail when the types change incorrectly.

Suggested change
describe('ApiResponse type', () => {
it('should allow creating a typed success response', () => {
const response: ApiResponse<string> = {
success: true,
data: 'hello',
};
expect(response.success).toBe(true);
expect(response.data).toBe('hello');
});
it('should allow creating a typed error response', () => {
const response: ApiResponse = {
success: false,
error: 'something failed',
};
expect(response.success).toBe(false);
expect(response.error).toBe('something failed');
});
});
describe('PaginationParams type', () => {
it('should allow creating pagination params', () => {
const params: PaginationParams = { page: 1, limit: 20 };
expect(params.page).toBe(1);
expect(params.limit).toBe(20);
});
});
describe('PaginatedResponse type', () => {
it('should allow creating a paginated response', () => {
const response: PaginatedResponse<number> = {
success: true,
data: [1, 2, 3],
pagination: {
page: 1,
limit: 20,
total: 3,
totalPages: 1,
},
};
expect(response.data).toHaveLength(3);
expect(response.pagination.total).toBe(3);
});
});

Copilot uses AI. Check for mistakes.
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