wip: add pagination

This commit is contained in:
Eugene Molodkin 2024-11-28 10:50:54 +01:00
parent 70e069910a
commit 3f6cd794a8
No known key found for this signature in database
4 changed files with 61 additions and 6 deletions

View file

@ -1,8 +1,10 @@
import type { FindManyOptions } from '@n8n/typeorm';
import { DataSource, Repository } from '@n8n/typeorm';
import { Service } from 'typedi';
import type { AggregatedTestRunMetrics } from '@/databases/entities/test-run.ee';
import { TestRun } from '@/databases/entities/test-run.ee';
import type { ListQuery } from '@/requests';
@Service()
export class TestRunRepository extends Repository<TestRun> {
@ -26,4 +28,18 @@ export class TestRunRepository extends Repository<TestRun> {
public async markAsCompleted(id: string, metrics: AggregatedTestRunMetrics) {
return await this.update(id, { status: 'completed', completedAt: new Date(), metrics });
}
public async getMany(testDefinitionId: string, options: ListQuery.Options) {
const findManyOptions: FindManyOptions<TestRun> = {
where: { testDefinition: { id: testDefinitionId } },
order: { createdAt: 'DESC' },
};
if (options?.take) {
findManyOptions.skip = options.skip;
findManyOptions.take = options.take;
}
return await this.find(findManyOptions);
}
}

View file

@ -112,7 +112,7 @@ export class TestMetricsController {
}
@Delete('/:testDefinitionId/metrics/:id')
async delete(req: TestMetricsRequest.GetOne) {
async delete(req: TestMetricsRequest.Delete) {
const { id: metricId, testDefinitionId } = req.params;
await this.getTestDefinition(req);

View file

@ -5,6 +5,7 @@ import { TestRunsRequest } from '@/evaluation/test-definitions.types.ee';
import { getSharedWorkflowIds } from '@/public-api/v1/handlers/workflows/workflows.service';
import { TestDefinitionService } from './test-definition.service.ee';
import { listQueryMiddleware } from '@/middlewares';
@RestController('/evaluation/test-definitions')
export class TestRunsController {
@ -32,15 +33,13 @@ export class TestRunsController {
return testDefinition;
}
@Get('/:testDefinitionId/runs')
@Get('/:testDefinitionId/runs', { middlewares: listQueryMiddleware })
async getMany(req: TestRunsRequest.GetMany) {
const { testDefinitionId } = req.params;
await this.getTestDefinition(req);
return await this.testRunRepository.find({
where: { testDefinition: { id: testDefinitionId } },
});
return await this.testRunRepository.getMany(testDefinitionId, req.listQueryOptions);
}
@Get('/:testDefinitionId/runs/:id')
@ -59,7 +58,7 @@ export class TestRunsController {
}
@Delete('/:testDefinitionId/runs/:id')
async delete(req: TestRunsRequest.GetOne) {
async delete(req: TestRunsRequest.Delete) {
const { id: testRunId, testDefinitionId } = req.params;
await this.getTestDefinition(req);

View file

@ -84,6 +84,46 @@ describe('GET /evaluation/test-definitions/:testDefinitionId/runs', () => {
}),
]);
});
test('should retrieve list of runs for a test definition with pagination', async () => {
const testRunRepository = Container.get(TestRunRepository);
const testRun1 = await testRunRepository.createTestRun(testDefinition.id);
// Mark as running just to make a slight delay between the runs
await testRunRepository.markAsRunning(testRun1.id);
const testRun2 = await testRunRepository.createTestRun(testDefinition.id);
// Fetch the first page
const resp = await authOwnerAgent.get(
`/evaluation/test-definitions/${testDefinition.id}/runs?take=1`,
);
expect(resp.statusCode).toBe(200);
expect(resp.body.data).toEqual([
expect.objectContaining({
id: testRun2.id,
status: 'new',
testDefinitionId: testDefinition.id,
runAt: null,
completedAt: null,
}),
]);
// Fetch the second page
const resp2 = await authOwnerAgent.get(
`/evaluation/test-definitions/${testDefinition.id}/runs?take=1&skip=1`,
);
expect(resp2.statusCode).toBe(200);
expect(resp2.body.data).toEqual([
expect.objectContaining({
id: testRun1.id,
status: 'running',
testDefinitionId: testDefinition.id,
runAt: expect.any(String),
completedAt: null,
}),
]);
});
});
describe('GET /evaluation/test-definitions/:testDefinitionId/runs/:id', () => {