feat(scaffolder): Allow sorting by status in scaffolderService.listTasks.
Added optional `status` filter to `ScaffolderService.listTasks`, by exposing the `status` query parameter, allowing callers to retrieve tasks of a specific status. Also updated the `list-scaffolder-tasks` action to support this parameter. Signed-off-by: John Collier <jcollier@redhat.com>
This commit is contained in:
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-backend': minor
|
||||
---
|
||||
|
||||
Updated the `list-scaffolder-tasks` action to support the new "status" filter paramter, allowing the action to return tasks matching a specific status.
|
||||
@@ -0,0 +1,5 @@
|
||||
---
|
||||
'@backstage/plugin-scaffolder-node': minor
|
||||
---
|
||||
|
||||
Added optional `status` filter to `ScaffolderService.listTasks`, allowing callers to retrieve tasks matching a specific status.
|
||||
@@ -63,7 +63,12 @@ describe('createListScaffolderTasksAction', () => {
|
||||
totalTasks: mockTasks.totalTasks ?? 0,
|
||||
});
|
||||
expect(mockScaffolderService.listTasks).toHaveBeenCalledWith(
|
||||
{ createdBy: undefined, limit: undefined, offset: undefined },
|
||||
{
|
||||
createdBy: undefined,
|
||||
limit: undefined,
|
||||
offset: undefined,
|
||||
status: undefined,
|
||||
},
|
||||
expect.objectContaining({ credentials: expect.anything() }),
|
||||
);
|
||||
});
|
||||
@@ -106,7 +111,7 @@ describe('createListScaffolderTasksAction', () => {
|
||||
});
|
||||
|
||||
expect(mockScaffolderService.listTasks).toHaveBeenCalledWith(
|
||||
{ createdBy: undefined, limit: 2, offset: 1 },
|
||||
{ createdBy: undefined, limit: 2, offset: 1, status: undefined },
|
||||
expect.objectContaining({ credentials: expect.anything() }),
|
||||
);
|
||||
|
||||
@@ -188,11 +193,57 @@ describe('createListScaffolderTasksAction', () => {
|
||||
createdBy: 'user:default/alice',
|
||||
limit: undefined,
|
||||
offset: undefined,
|
||||
status: undefined,
|
||||
},
|
||||
expect.objectContaining({ credentials: expect.anything() }),
|
||||
);
|
||||
});
|
||||
|
||||
it('should filter tasks by status when status is provided', async () => {
|
||||
const mockActionsRegistry = actionsRegistryServiceMock();
|
||||
const mockAuth = mockServices.auth.mock();
|
||||
const mockScaffolderService = scaffolderServiceMock.mock();
|
||||
const completedTasks = generateMockTasks().tasks.filter(
|
||||
t => t.status === 'completed',
|
||||
);
|
||||
|
||||
mockScaffolderService.listTasks.mockResolvedValue({
|
||||
items: completedTasks as ScaffolderTask[],
|
||||
totalItems: completedTasks.length,
|
||||
});
|
||||
|
||||
createListScaffolderTasksAction({
|
||||
actionsRegistry: mockActionsRegistry,
|
||||
auth: mockAuth,
|
||||
scaffolderService: mockScaffolderService,
|
||||
});
|
||||
|
||||
const result = await mockActionsRegistry.invoke({
|
||||
id: 'test:list-scaffolder-tasks',
|
||||
input: { status: 'completed' },
|
||||
});
|
||||
|
||||
expect(mockScaffolderService.listTasks).toHaveBeenCalledWith(
|
||||
{
|
||||
createdBy: undefined,
|
||||
limit: undefined,
|
||||
offset: undefined,
|
||||
status: 'completed',
|
||||
},
|
||||
expect.objectContaining({ credentials: expect.anything() }),
|
||||
);
|
||||
expect(result.output).toEqual({
|
||||
tasks: completedTasks.map(task => ({
|
||||
id: task.id,
|
||||
spec: task.spec,
|
||||
status: task.status,
|
||||
createdAt: task.createdAt,
|
||||
lastHeartbeatAt: task.lastHeartbeatAt,
|
||||
})),
|
||||
totalTasks: completedTasks.length,
|
||||
});
|
||||
});
|
||||
|
||||
it('should throw NotAllowedError when owned is true without user identity', async () => {
|
||||
const mockActionsRegistry = actionsRegistryServiceMock();
|
||||
const mockAuth = mockServices.auth.mock();
|
||||
|
||||
@@ -65,6 +65,17 @@ Pagination is supported via limit and offset.
|
||||
.min(0)
|
||||
.describe('The offset to start from for pagination')
|
||||
.optional(),
|
||||
status: z
|
||||
.enum([
|
||||
'open',
|
||||
'processing',
|
||||
'completed',
|
||||
'failed',
|
||||
'cancelled',
|
||||
'skipped',
|
||||
])
|
||||
.optional()
|
||||
.describe('Filter tasks by status'),
|
||||
}),
|
||||
output: z =>
|
||||
z
|
||||
@@ -112,6 +123,7 @@ Pagination is supported via limit and offset.
|
||||
createdBy,
|
||||
limit: input.limit,
|
||||
offset: input.offset,
|
||||
status: input.status,
|
||||
},
|
||||
{ credentials },
|
||||
);
|
||||
|
||||
@@ -83,6 +83,7 @@ export interface ScaffolderService {
|
||||
createdBy?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
status?: ScaffolderTaskStatus;
|
||||
},
|
||||
options: ScaffolderServiceRequestOptions,
|
||||
): Promise<{ items: ScaffolderTask[]; totalItems: number }>;
|
||||
@@ -185,6 +186,7 @@ class DefaultScaffolderService implements ScaffolderService {
|
||||
createdBy?: string;
|
||||
limit?: number;
|
||||
offset?: number;
|
||||
status?: ScaffolderTaskStatus;
|
||||
},
|
||||
options: ScaffolderServiceRequestOptions,
|
||||
): Promise<{ items: ScaffolderTask[]; totalItems: number }> {
|
||||
@@ -201,6 +203,9 @@ class DefaultScaffolderService implements ScaffolderService {
|
||||
if (request.offset !== undefined) {
|
||||
params.set('offset', String(request.offset));
|
||||
}
|
||||
if (request.status !== undefined) {
|
||||
params.set('status', request.status);
|
||||
}
|
||||
|
||||
const query = params.toString();
|
||||
const url = `${baseUrl}/v2/tasks${query ? `?${query}` : ''}`;
|
||||
|
||||
Reference in New Issue
Block a user