mirror of
https://github.com/n8n-io/n8n.git
synced 2024-12-24 20:24:05 -08:00
fix(public-api): fix issue paginating executions
* 🐛 Fix pagination issue in /executions * ⚡ Enable all executions tests Co-authored-by: Iván Ovejero <ivov.src@gmail.com>
This commit is contained in:
parent
c1451d2688
commit
b9fe707cbd
|
@ -1,5 +1,5 @@
|
||||||
import { parse } from 'flatted';
|
import { parse } from 'flatted';
|
||||||
import { In, Not, ObjectLiteral, LessThan, IsNull } from 'typeorm';
|
import { In, Not, Raw, ObjectLiteral, LessThan, IsNull } from 'typeorm';
|
||||||
|
|
||||||
import { Db, IExecutionFlattedDb, IExecutionResponseApi } from '../../../..';
|
import { Db, IExecutionFlattedDb, IExecutionResponseApi } from '../../../..';
|
||||||
import { ExecutionStatus } from '../../../types';
|
import { ExecutionStatus } from '../../../types';
|
||||||
|
@ -59,14 +59,23 @@ export async function getExecutions(data: {
|
||||||
status?: ExecutionStatus;
|
status?: ExecutionStatus;
|
||||||
excludedExecutionsIds?: number[];
|
excludedExecutionsIds?: number[];
|
||||||
}): Promise<IExecutionResponseApi[]> {
|
}): Promise<IExecutionResponseApi[]> {
|
||||||
|
const where = {
|
||||||
|
...(data.lastId && { id: LessThan(data.lastId) }),
|
||||||
|
...(data.status && { ...getStatusCondition(data.status) }),
|
||||||
|
...(data.workflowIds && { workflowId: In(data.workflowIds.map(String)) }),
|
||||||
|
...(data.excludedExecutionsIds && { id: Not(In(data.excludedExecutionsIds)) }),
|
||||||
|
};
|
||||||
|
|
||||||
|
if (data.lastId && data.excludedExecutionsIds) {
|
||||||
|
where.id = Raw((id) => `${id} < :lastId AND ${id} NOT IN (:...excludedExecutionsIds)`, {
|
||||||
|
lastId: data.lastId,
|
||||||
|
excludedExecutionsIds: data.excludedExecutionsIds,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
const executions = await Db.collections.Execution.find({
|
const executions = await Db.collections.Execution.find({
|
||||||
select: getExecutionSelectableProperties(data.includeData),
|
select: getExecutionSelectableProperties(data.includeData),
|
||||||
where: {
|
where,
|
||||||
...(data.lastId && { id: LessThan(data.lastId) }),
|
|
||||||
...(data.status && { ...getStatusCondition(data.status) }),
|
|
||||||
...(data.workflowIds && { workflowId: In(data.workflowIds.map(String)) }),
|
|
||||||
...(data.excludedExecutionsIds && { id: Not(In(data.excludedExecutionsIds)) }),
|
|
||||||
},
|
|
||||||
order: { id: 'DESC' },
|
order: { id: 'DESC' },
|
||||||
take: data.limit,
|
take: data.limit,
|
||||||
});
|
});
|
||||||
|
|
|
@ -279,6 +279,71 @@ test('GET /executions should retrieve all successfull executions', async () => {
|
||||||
expect(waitTill).toBeNull();
|
expect(waitTill).toBeNull();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('GET /executions should paginate two executions', async () => {
|
||||||
|
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
||||||
|
|
||||||
|
const authOwnerAgent = utils.createAgent(app, {
|
||||||
|
apiPath: 'public',
|
||||||
|
auth: true,
|
||||||
|
user: owner,
|
||||||
|
version: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
const workflow = await testDb.createWorkflow({}, owner);
|
||||||
|
|
||||||
|
const fistSuccessfullExecution = await testDb.createSuccessfulExecution(workflow);
|
||||||
|
|
||||||
|
const secondSuccessfullExecution = await testDb.createSuccessfulExecution(workflow);
|
||||||
|
|
||||||
|
await testDb.createErrorExecution(workflow);
|
||||||
|
|
||||||
|
const firstExecutionResponse = await authOwnerAgent.get(`/executions`).query({
|
||||||
|
status: 'success',
|
||||||
|
limit: 1,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(firstExecutionResponse.statusCode).toBe(200);
|
||||||
|
expect(firstExecutionResponse.body.data.length).toBe(1);
|
||||||
|
expect(firstExecutionResponse.body.nextCursor).toBeDefined();
|
||||||
|
|
||||||
|
const secondExecutionResponse = await authOwnerAgent.get(`/executions`).query({
|
||||||
|
status: 'success',
|
||||||
|
limit: 1,
|
||||||
|
cursor: firstExecutionResponse.body.nextCursor,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(secondExecutionResponse.statusCode).toBe(200);
|
||||||
|
expect(secondExecutionResponse.body.data.length).toBe(1);
|
||||||
|
expect(secondExecutionResponse.body.nextCursor).toBeNull();
|
||||||
|
|
||||||
|
const successfullExecutions = [fistSuccessfullExecution, secondSuccessfullExecution];
|
||||||
|
const executions = [...firstExecutionResponse.body.data, ...secondExecutionResponse.body.data];
|
||||||
|
|
||||||
|
for (let i = 0; i < executions.length; i++) {
|
||||||
|
const {
|
||||||
|
id,
|
||||||
|
finished,
|
||||||
|
mode,
|
||||||
|
retryOf,
|
||||||
|
retrySuccessId,
|
||||||
|
startedAt,
|
||||||
|
stoppedAt,
|
||||||
|
workflowId,
|
||||||
|
waitTill,
|
||||||
|
} = executions[i]
|
||||||
|
|
||||||
|
expect(id).toBeDefined();
|
||||||
|
expect(finished).toBe(true);
|
||||||
|
expect(mode).toEqual(successfullExecutions[i].mode);
|
||||||
|
expect(retrySuccessId).toBeNull();
|
||||||
|
expect(retryOf).toBeNull();
|
||||||
|
expect(startedAt).not.toBeNull();
|
||||||
|
expect(stoppedAt).not.toBeNull();
|
||||||
|
expect(workflowId).toBe(successfullExecutions[i].workflowId);
|
||||||
|
expect(waitTill).toBeNull();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
test('GET /executions should retrieve all error executions', async () => {
|
test('GET /executions should retrieve all error executions', async () => {
|
||||||
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
const owner = await testDb.createUser({ globalRole: globalOwnerRole, apiKey: randomApiKey() });
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue