Files
ForgeFlow/tests/gitea-actions.test.mjs
T
2026-07-24 20:29:23 +02:00

91 lines
4.1 KiB
JavaScript

import test from 'node:test';
import assert from 'node:assert/strict';
import giteaModule from '../src/main/gitea-service.cjs';
const { GiteaService } = giteaModule;
function makeStore() {
return { data: { gitea: { baseUrl: 'https://gitea.example.test' } }, getToken: () => 'demo-token' };
}
test('normalizes run payloads from different Actions API shapes', () => {
const service = new GiteaService(makeStore());
const run = service.normalizeRun({
task_id: 42,
index: 7,
workflow_name: 'Deploy',
status: 'success',
commit: { sha: 'a'.repeat(40) },
ref: 'refs/heads/main',
workflow_file: '.gitea/workflows/deploy.yml',
start_time: '2026-07-24T12:00:00Z'
});
assert.equal(run.id, 42);
assert.equal(run.runNumber, 7);
assert.equal(run.conclusion, 'success');
assert.equal(run.headSha, 'a'.repeat(40));
assert.equal(run.headBranch, 'refs/heads/main');
});
test('retries Actions runs without optional filters when a server rejects them', async () => {
const service = new GiteaService(makeStore());
const calls = [];
service.request = async (pathname) => {
calls.push(pathname);
if (calls.length === 1) {
const error = new Error('Unsupported query');
error.status = 422;
throw error;
}
return { data: { workflow_runs: [{ id: 11, run_number: 11, status: 'queued', head_sha: 'b'.repeat(40), head_branch: 'main' }] } };
};
const result = await service.listWorkflowRuns({ owner: 'jens', repo: 'app', sha: 'b'.repeat(40), branch: 'main' });
assert.equal(calls.length, 2);
assert.match(calls[0], /head_sha=/);
assert.doesNotMatch(calls[1], /head_sha=/);
assert.equal(result.source, 'runs');
assert.equal(result.runs[0].runNumber, 11);
});
test('falls back to legacy Actions tasks endpoint when runs is unavailable', async () => {
const service = new GiteaService(makeStore());
const calls = [];
service.request = async (pathname) => {
calls.push(pathname);
if (pathname.includes('/runs?')) {
const error = new Error('Not found');
error.status = 404;
throw error;
}
return { data: [{ task_id: 9, index: 3, status: 'running', commit_sha: 'c'.repeat(40), branch: 'main' }] };
};
const result = await service.listWorkflowRuns({ owner: 'jens', repo: 'app' });
assert.equal(result.source, 'tasks');
assert.equal(result.runs[0].id, 9);
assert.ok(calls.some((pathname) => pathname.includes('/tasks?')));
});
test('selects the newest matching workflow run', async () => {
const service = new GiteaService(makeStore());
service.listWorkflowRuns = async () => ({ source: 'runs', runs: [
{ id: 1, headSha: 'd'.repeat(40), headBranch: 'main', workflowPath: 'deploy.yml', createdAt: '2026-07-24T10:00:00Z' },
{ id: 2, headSha: 'd'.repeat(40), headBranch: 'main', workflowPath: '.gitea/workflows/deploy.yml', createdAt: '2026-07-24T11:00:00Z' },
{ id: 3, headSha: 'e'.repeat(40), headBranch: 'main', workflowPath: 'deploy.yml', createdAt: '2026-07-24T12:00:00Z' }
] });
const found = await service.findWorkflowRun({ owner: 'jens', repo: 'app', sha: 'd'.repeat(40), branch: 'main', workflowFile: 'deploy.yml' });
assert.equal(found.run.id, 2);
const excludingNewest = await service.findWorkflowRun({ owner: 'jens', repo: 'app', sha: 'd'.repeat(40), branch: 'main', workflowFile: 'deploy.yml', excludeRunIds: [2] });
assert.equal(excludingNewest.run.id, 1);
});
test('checks repository workflow files through the contents API', async () => {
const service = new GiteaService(makeStore());
const calls = [];
service.request = async (pathname) => { calls.push(pathname); return { data: { type: 'file' } }; };
assert.equal(await service.repositoryFileExists({ owner: 'jens', repo: 'app', filePath: '.gitea/workflows/deploy.yml', ref: 'main' }), true);
assert.match(calls[0], /contents\/\.gitea\/workflows\/deploy\.yml\?ref=main/);
service.request = async () => { const error = new Error('missing'); error.status = 404; throw error; };
assert.equal(await service.repositoryFileExists({ owner: 'jens', repo: 'app', filePath: '.gitea/workflows/missing.yml', ref: 'main' }), false);
});