diff --git a/src-ui/src/app/components/admin/tasks/tasks.component.spec.ts b/src-ui/src/app/components/admin/tasks/tasks.component.spec.ts index cf17b411a..161f3cdbd 100644 --- a/src-ui/src/app/components/admin/tasks/tasks.component.spec.ts +++ b/src-ui/src/app/components/admin/tasks/tasks.component.spec.ts @@ -306,6 +306,12 @@ describe('TasksComponent', () => { ).toBe(false) }) + it('should fall back to the raw selected task type label when no option matches', () => { + component.selectedTaskType = 'unknown_task_type' as PaperlessTaskType + + expect(component.selectedTaskTypeLabel).toBe('unknown_task_type') + }) + it('should expose stable trigger source options and disable empty ones', () => { expect( component.triggerSourceOptions.map((option) => option.value) @@ -322,6 +328,13 @@ describe('TasksComponent', () => { ).toBe(false) }) + it('should fall back to the raw selected trigger source label when no option matches', () => { + component.selectedTriggerSource = + 'unknown_trigger_source' as PaperlessTaskTriggerSource + + expect(component.selectedTriggerSourceLabel).toBe('unknown_trigger_source') + }) + it('should support expanding / collapsing one task at a time', () => { component.expandTask(tasks[0]) expect(component.expandedTask).toEqual(tasks[0].id) @@ -451,6 +464,17 @@ describe('TasksComponent', () => { expect(component.selectedTasks).toEqual(new Set([467, 466])) }) + it('should remove a full section from selection when toggled off', () => { + component.setSection(TaskSection.NeedsAttention) + component.selectedTasks = new Set([467, 466]) + + component.toggleSection(TaskSection.NeedsAttention, { + target: { checked: false }, + } as PointerEvent) + + expect(component.selectedTasks).toEqual(new Set()) + }) + it('should support dismiss and open a document', () => { const routerSpy = jest.spyOn(router, 'navigate') component.dismissAndGo(tasks[3]) @@ -529,6 +553,42 @@ describe('TasksComponent', () => { ) }) + it('should prefer explicit reason in the result message', () => { + expect( + component.taskResultMessage({ + ...tasks[0], + result_data: { reason: 'Manual review required', duplicate_of: 311 }, + }) + ).toBe('Manual review required') + }) + + it('should return null preview and popover text when there is no result message', () => { + expect(component.taskResultPreview(tasks[2])).toBeNull() + expect(component.taskResultPopoverMessage(tasks[2])).toBe('') + expect(component.taskResultMessageOverflowsPopover(tasks[2])).toBe(false) + }) + + it('should navigate to a duplicate document details page', () => { + const routerSpy = jest.spyOn(router, 'navigate') + + component.openDuplicateDocument(99) + + expect(routerSpy).toHaveBeenCalledWith(['documents', 99, 'details']) + }) + + it('should report when a result message overflows the popover limit', () => { + const longMessage = 'x'.repeat(350) + const task = { + ...tasks[0], + result_data: { error_message: longMessage }, + } + + expect(component.taskResultPopoverMessage(task)).toBe( + longMessage.slice(0, 300) + ) + expect(component.taskResultMessageOverflowsPopover(task)).toBe(true) + }) + it('should support keyboard events for filtering', () => { fixture.detectChanges() const input = fixture.debugElement.query( diff --git a/src-ui/src/app/services/tasks.service.spec.ts b/src-ui/src/app/services/tasks.service.spec.ts index 37038bee3..922ab103f 100644 --- a/src-ui/src/app/services/tasks.service.spec.ts +++ b/src-ui/src/app/services/tasks.service.spec.ts @@ -136,6 +136,57 @@ describe('TasksService', () => { expect(tasksService.startedFileTasks).toHaveLength(1) }) + it('includes revoked tasks in needs attention', () => { + const mockTasks = [ + { + task_type: PaperlessTaskType.SanityCheck, + trigger_source: PaperlessTaskTriggerSource.System, + status: PaperlessTaskStatus.Failure, + acknowledged: false, + task_id: '1235', + input_data: {}, + date_created: new Date(), + related_document_ids: [], + }, + { + task_type: PaperlessTaskType.MailFetch, + trigger_source: PaperlessTaskTriggerSource.Scheduled, + status: PaperlessTaskStatus.Revoked, + acknowledged: false, + task_id: '1236', + input_data: {}, + date_created: new Date(), + related_document_ids: [], + }, + { + task_type: PaperlessTaskType.EmptyTrash, + trigger_source: PaperlessTaskTriggerSource.Manual, + status: PaperlessTaskStatus.Success, + acknowledged: false, + task_id: '1238', + input_data: {}, + date_created: new Date(), + related_document_ids: [], + }, + ] + + tasksService.reload() + + const req = httpTestingController.expectOne( + `${environment.apiBaseUrl}tasks/?acknowledged=false` + ) + + req.flush(mockTasks) + + expect(tasksService.needsAttentionTasks).toHaveLength(2) + expect(tasksService.needsAttentionTasks.map((task) => task.status)).toEqual( + expect.arrayContaining([ + PaperlessTaskStatus.Failure, + PaperlessTaskStatus.Revoked, + ]) + ) + }) + it('supports running tasks', () => { tasksService.run(PaperlessTaskType.SanityCheck).subscribe((res) => { expect(res).toEqual({