mirror of
https://github.com/Studio-Saelix/sencho.git
synced 2026-08-28 11:17:07 +00:00
feat(scheduler): flag one-shot tasks in the Scheduled Operations table (#1433)
A one-shot task (delete after successful run) self-deletes only on a successful run; a failed one-shot is kept so it can be retried or debugged. The table gave no signal for this, so a lingering failed one-shot was indistinguishable from a stuck recurring task. Add a "One-shot" chip to the status cell for every delete-after-run task, with a tooltip that explains the keep-on-failure behavior when the task has failed.
This commit is contained in:
@@ -79,6 +79,37 @@ describe('ScheduledOperationsView', () => {
|
||||
expect(await screen.findByText('nightly-prune')).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it('marks a one-shot task with a chip and leaves recurring tasks unmarked', async () => {
|
||||
tasksFixture = [
|
||||
makeTask({ id: 1, name: 'recurring-task' }),
|
||||
makeTask({ id: 2, name: 'one-shot-task', delete_after_run: 1 }),
|
||||
];
|
||||
render(<ScheduledOperationsView />);
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: /All tasks/ }));
|
||||
await screen.findByText('recurring-task');
|
||||
|
||||
// A single One-shot chip, scoped to the one-shot row.
|
||||
const chips = screen.getAllByText('One-shot');
|
||||
expect(chips).toHaveLength(1);
|
||||
// A pending one-shot carries the plain lifecycle tooltip, not the failure copy.
|
||||
expect(chips[0]).toHaveAttribute('title', expect.stringContaining('Deletes itself after a successful run'));
|
||||
expect(chips[0]).toHaveAttribute('title', expect.not.stringContaining('kept after a failed run'));
|
||||
const oneShotRow = screen.getByText('one-shot-task').closest('tr');
|
||||
expect(oneShotRow).toContainElement(chips[0]);
|
||||
const recurringRow = screen.getByText('recurring-task').closest('tr');
|
||||
expect(recurringRow?.textContent).not.toContain('One-shot');
|
||||
});
|
||||
|
||||
it('explains a failed one-shot was kept to debug', async () => {
|
||||
tasksFixture = [makeTask({ id: 1, name: 'failed-one-shot', delete_after_run: 1, last_status: 'failure' })];
|
||||
render(<ScheduledOperationsView />);
|
||||
|
||||
await userEvent.click(await screen.findByRole('button', { name: /All tasks/ }));
|
||||
const chip = await screen.findByText('One-shot');
|
||||
expect(chip).toHaveAttribute('title', expect.stringContaining('kept after a failed run'));
|
||||
});
|
||||
|
||||
it('opens the create modal from a prefill and consumes it once', async () => {
|
||||
const onPrefillConsumed = vi.fn();
|
||||
render(
|
||||
|
||||
Reference in New Issue
Block a user