Skip to content

Add integration tests with mock GitHub API server and recorded fixtures#574

Draft
Copilot wants to merge 3 commits into
mainfrom
copilot/implement-integration-tests-with-jest
Draft

Add integration tests with mock GitHub API server and recorded fixtures#574
Copilot wants to merge 3 commits into
mainfrom
copilot/implement-integration-tests-with-jest

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented May 4, 2026

Implements extensive integration tests for the export and import commands using recorded API fixtures and a local mock server — no network access or tokens required at test time.

Approach

Fixtures were recorded from the real gh-migrate-project-sandbox project #1026, then a lightweight MockGitHubServer (plain http.Server) replays those responses by routing on GraphQL query content. The CLI is spawned as an async child process pointing --base-url at the mock server.

spawn (not spawnSync) is required because the mock server runs in-process — sync spawn blocks the event loop and prevents the server from responding.

Changes

  • tests/fixtures/recorded-api-responses.json — Real API responses captured from the sandbox org
  • tests/fixtures/graphql-responses.ts — Typed exports that load and re-export the recorded data + synthetic import-flow responses
  • tests/integration/mock-server.ts — Routes REST (/meta) and GraphQL requests to fixture responses based on query content matching
  • tests/integration/commands.test.ts — 29 tests across export (14), import (12), and error handling (3)
  • jest.config.ts / package.json — Jest 30 + ts-jest ESM config, npm run test:integration script
  • .github/workflows/ci.ymlintegration_tests job added to CI (no secrets needed)

Coverage

Area What's tested
Export Project structure, fields/options, views, items with field values, CSV generation, content types, error cases
Import Full round-trip, project creation, custom fields, status field config, item creation (issues + drafts), field value setting, assignee resolution, custom title, error cases
// Example: tests spawn CLI against mock server
const result = await runCli(
  ['export', '--base-url', server.getBaseUrl(), '--project-owner', 'org', ...],
  { EXPORT_GITHUB_TOKEN: 'fake-token' },
);
expect(result.exitCode).toBe(0);
const data = JSON.parse(readFileSync(projectOutput, 'utf-8'));
expect(data.project.title).toBe('Source project to be migrated');

Copilot AI and others added 2 commits May 4, 2026 21:41
- Record real API fixtures from gh-migrate-project-sandbox project #1026
- Create mock HTTP server that replays recorded GraphQL/REST responses
- Write 29 integration tests covering export, import, and error handling
- Tests run entirely offline using local mock server (no token needed)
- Add Jest config, test scripts, and CI workflow job
- All tests pass, lint clean, typecheck clean

Agent-Logs-Url: https://github.com/timrogers/gh-migrate-project/sessions/547b51ff-f3f9-4e2d-b7df-4320441150f6

Co-authored-by: timrogers <116134+timrogers@users.noreply.github.com>
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 a Jest-based integration test suite for gh-migrate-project that runs the real CLI (export/import) against an in-process mock GitHub API server, replaying recorded fixtures so tests require no network access or secrets.

Changes:

  • Introduce a MockGitHubServer that serves /meta + routes GraphQL queries to recorded/synthetic fixture responses.
  • Add integration tests that spawn the CLI asynchronously against the mock server and assert export/import behavior.
  • Add Jest + ts-jest ESM config, wire integration tests into CI, and update ignore/typecheck config to include tests.
Show a summary per file
File Description
tsconfig.json Includes tests/ in TS compilation/typecheck scope.
tests/integration/mock-server.ts New in-process HTTP server that replays REST/GraphQL fixtures.
tests/integration/commands.test.ts New integration tests that spawn the CLI against the mock server.
tests/fixtures/graphql-responses.ts Loads recorded fixture JSON and exports typed responses + synthetic import responses.
tests/fixtures/recorded-api-responses.json Recorded GitHub API responses used by the mock server.
package.json Adds Jest/ts-jest deps + test/test:integration scripts.
jest.config.ts New Jest config for TS + ESM via ts-jest.
eslint.config.mjs Ignores jest.config.ts and relaxes a test-only lint rule.
.gitignore Ignores .test-output created by integration tests.
.github/workflows/ci.yml Adds an integration_tests job and includes it in release gating.

Copilot's findings

Tip

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

  • Files reviewed: 7/11 changed files
  • Comments generated: 5

Comment thread tests/integration/commands.test.ts Outdated
Comment on lines +15 to +17
import { join } from 'path';
import { MockGitHubServer } from './mock-server.js';

Comment thread tests/fixtures/graphql-responses.ts Outdated
Comment on lines +11 to +14
import { join } from 'path';

const rawFixtures = JSON.parse(
readFileSync(join(__dirname, 'recorded-api-responses.json'), 'utf-8'),
Comment on lines +30 to +52
return new Promise((resolve) => {
const child = spawn(TSX_BIN, [CLI_ENTRY, ...args], {
env: {
...process.env,
...env,
NODE_NO_WARNINGS: '1',
},
stdio: ['pipe', 'pipe', 'pipe'],
});

let stdout = '';
let stderr = '';

child.stdout.on('data', (data: Buffer) => {
stdout += data.toString();
});
child.stderr.on('data', (data: Buffer) => {
stderr += data.toString();
});

child.on('close', (code) => {
resolve({ stdout, stderr, exitCode: code ?? 1 });
});
Comment thread package.json
Comment on lines +17 to +18
"test": "NODE_OPTIONS='--experimental-vm-modules' npx jest",
"test:integration": "NODE_OPTIONS='--experimental-vm-modules' npx jest --testPathPatterns=tests/integration"
return ORGANIZATION_ID_RESPONSE;
}

// Create project field (must be checked BEFORE createProjectV2 since the query contains that substring)
Copilot AI requested a review from timrogers May 4, 2026 22:46
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