0d3cb498a3
Deploy local.promptfoo.app / Deploy to Cloudflare Pages (push) Waiting to run
Test and Publish Multi-arch Docker Image / test (push) Waiting to run
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-amd64 platform:linux/amd64 runner:ubuntu-latest]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / build-docker-and-push-digests (map[digest-suffix:linux-arm64 platform:linux/arm64 runner:ubuntu-24.04-arm]) (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / merge-docker-digests (push) Blocked by required conditions
Test and Publish Multi-arch Docker Image / Attest Multi-arch Image (push) Blocked by required conditions
Validate Renovate Config / Validate Renovate Configuration (push) Waiting to run
CI / Shell Format Check (push) Has been cancelled
CI / Check Ruby (3.4) (push) Has been cancelled
CI / CI Config (push) Has been cancelled
CI / Test on Node ${{ matrix.node }} and ${{ matrix.os }}${{ matrix.shard && format(' (shard {0}/3)', matrix.shard) || '' }} (push) Has been cancelled
CI / Build on Node ${{ matrix.node }} (push) Has been cancelled
CI / Style Check (push) Has been cancelled
CI / Generate Assets (push) Has been cancelled
CI / Check Python (3.14) (push) Has been cancelled
CI / Check Python (3.9) (push) Has been cancelled
CI / Build Docs (push) Has been cancelled
CI / Code Scan Action (push) Has been cancelled
CI / Site tests (push) Has been cancelled
CI / webui tests (push) Has been cancelled
CI / Run Integration Tests (push) Has been cancelled
CI / Run Smoke Tests (push) Has been cancelled
CI / Go Tests (push) Has been cancelled
CI / Share Test (push) Has been cancelled
CI / Redteam (Production API) (push) Has been cancelled
CI / Redteam (Staging API) (push) Has been cancelled
CI / GitHub Actions Lint (push) Has been cancelled
CI / Check Ruby (3.0) (push) Has been cancelled
release-please / release-please (push) Has been cancelled
release-please / build (push) Has been cancelled
release-please / publish-npm (push) Has been cancelled
release-please / publish-npm-backfill (push) Has been cancelled
release-please / docker (push) Has been cancelled
release-please / publish-code-scan-action (push) Has been cancelled
release-please / attest-code-scan-action (push) Has been cancelled
181 lines
4.5 KiB
TypeScript
181 lines
4.5 KiB
TypeScript
/**
|
|
* GitHub API Client Tests
|
|
*/
|
|
|
|
import * as github from '@actions/github';
|
|
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
import { getGitHubContext, partitionReviewCommentsByDiff } from '../../code-scan-action/src/github';
|
|
import type { Octokit } from '@octokit/rest';
|
|
|
|
const mocks = vi.hoisted(() => {
|
|
// Mock diff that includes src/auth.ts with lines 40-100 in scope
|
|
const mockDiff = `diff --git a/src/auth.ts b/src/auth.ts
|
|
index abc123..def456 100644
|
|
--- a/src/auth.ts
|
|
+++ b/src/auth.ts
|
|
@@ -40,60 +40,60 @@
|
|
context line 40
|
|
context line 41
|
|
context line 42
|
|
+added line 43
|
|
context line 44
|
|
context line 45
|
|
context line 46
|
|
context line 47
|
|
context line 48
|
|
context line 49
|
|
context line 50
|
|
context line 51
|
|
context line 52
|
|
context line 53
|
|
context line 54
|
|
context line 55
|
|
context line 56
|
|
context line 57
|
|
context line 58
|
|
context line 59
|
|
context line 60
|
|
`;
|
|
|
|
return {
|
|
core: {
|
|
info: vi.fn(),
|
|
warning: vi.fn(),
|
|
error: vi.fn(),
|
|
},
|
|
github: {
|
|
context: {
|
|
repo: {
|
|
owner: 'test-owner',
|
|
repo: 'test-repo',
|
|
},
|
|
payload: {
|
|
pull_request: {
|
|
number: 123,
|
|
head: {
|
|
sha: 'abc123',
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
mockDiff,
|
|
Octokit: vi.fn().mockImplementation(() => ({
|
|
pulls: {
|
|
createReview: vi.fn().mockResolvedValue({}),
|
|
get: vi.fn().mockResolvedValue({ data: mockDiff }),
|
|
},
|
|
issues: {
|
|
createComment: vi.fn().mockResolvedValue({}),
|
|
},
|
|
})),
|
|
};
|
|
});
|
|
|
|
// Mock @actions/core
|
|
vi.mock('@actions/core', () => mocks.core);
|
|
vi.mock('../../code-scan-action/node_modules/@actions/core/lib/core.js', () => mocks.core);
|
|
|
|
// Mock both the root specifiers and the nested package entries resolved from code-scan-action.
|
|
vi.mock('@actions/github', () => mocks.github);
|
|
vi.mock('../../code-scan-action/node_modules/@actions/github/lib/github.js', () => mocks.github);
|
|
|
|
// Mock Octokit
|
|
vi.mock('@octokit/rest', () => ({ Octokit: mocks.Octokit }));
|
|
vi.mock('../../code-scan-action/node_modules/@octokit/rest/dist-src/index.js', () => ({
|
|
Octokit: mocks.Octokit,
|
|
}));
|
|
|
|
const mockDiff = mocks.mockDiff;
|
|
|
|
describe('GitHub API Client', () => {
|
|
beforeEach(() => {
|
|
vi.resetAllMocks();
|
|
mocks.github.context.repo = {
|
|
owner: 'test-owner',
|
|
repo: 'test-repo',
|
|
};
|
|
mocks.github.context.payload = {
|
|
pull_request: {
|
|
number: 123,
|
|
head: {
|
|
sha: 'abc123',
|
|
},
|
|
},
|
|
};
|
|
mocks.Octokit.mockImplementation(function () {
|
|
return {
|
|
pulls: {
|
|
createReview: vi.fn().mockResolvedValue({}),
|
|
get: vi.fn().mockResolvedValue({ data: mockDiff }),
|
|
},
|
|
issues: {
|
|
createComment: vi.fn().mockResolvedValue({}),
|
|
},
|
|
} as unknown as Octokit;
|
|
});
|
|
});
|
|
|
|
describe('getGitHubContext', () => {
|
|
it('should extract context from github.context', async () => {
|
|
const context = await getGitHubContext('test-token');
|
|
|
|
expect(context).toEqual({
|
|
owner: 'test-owner',
|
|
repo: 'test-repo',
|
|
number: 123,
|
|
sha: 'abc123',
|
|
});
|
|
});
|
|
|
|
it('should throw error when not in PR context', async () => {
|
|
const originalPayload = github.context.payload;
|
|
github.context.payload = {};
|
|
|
|
await expect(getGitHubContext('test-token')).rejects.toThrow(
|
|
'This action requires a pull_request event or workflow_dispatch with pr_number input',
|
|
);
|
|
|
|
github.context.payload = originalPayload;
|
|
});
|
|
});
|
|
|
|
describe('partitionReviewCommentsByDiff', () => {
|
|
const mockContext = {
|
|
owner: 'test-owner',
|
|
repo: 'test-repo',
|
|
number: 123,
|
|
sha: 'abc123',
|
|
};
|
|
|
|
it('clamps comments to visible diff lines and routes unmapped files to general comments', async () => {
|
|
const result = await partitionReviewCommentsByDiff('fake-token', mockContext, [
|
|
{
|
|
file: 'src/auth.ts',
|
|
line: 500,
|
|
finding: 'Finding in a changed file',
|
|
},
|
|
{
|
|
file: 'src/outside-diff.ts',
|
|
line: 12,
|
|
finding: 'Finding outside the diff',
|
|
},
|
|
]);
|
|
|
|
expect(result.lineComments).toEqual([
|
|
expect.objectContaining({
|
|
file: 'src/auth.ts',
|
|
line: 61,
|
|
}),
|
|
]);
|
|
expect(result.generalComments).toEqual([]);
|
|
expect(result.invalidLineComments).toEqual([
|
|
expect.objectContaining({
|
|
file: 'src/outside-diff.ts',
|
|
line: 12,
|
|
}),
|
|
]);
|
|
});
|
|
});
|
|
});
|