From 1eb6d46c35e45528ad897c7f7f60bf72c4be5fc1 Mon Sep 17 00:00:00 2001 From: "pulse-triage[bot]" <249995291+pulse-triage[bot]@users.noreply.github.com> Date: Sun, 6 Sep 2026 13:27:22 +0100 Subject: [PATCH] test(alerts): preserve uncertainty after queue action refresh failure A successful retry or dismissal does not establish that the queue is healthy when the follow-up read fails. Cover both actions so connection loss cannot silently clear the attention state, and verify the independent evidence refresh still runs and busy flags settle. Change-source: pulse-maintainer --- .../useNotificationDeliveryHealth.test.tsx | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/frontend-modern/src/features/alerts/__tests__/useNotificationDeliveryHealth.test.tsx b/frontend-modern/src/features/alerts/__tests__/useNotificationDeliveryHealth.test.tsx index 51e63180f..d30e03af6 100644 --- a/frontend-modern/src/features/alerts/__tests__/useNotificationDeliveryHealth.test.tsx +++ b/frontend-modern/src/features/alerts/__tests__/useNotificationDeliveryHealth.test.tsx @@ -171,6 +171,37 @@ describe('useNotificationDeliveryHealth', () => { ); describe.each(['dismissTerminalFailures', 'retryTerminalFailures'] as const)('%s', (action) => { + it('reports unavailable rather than healthy when the post-action refresh fails', () => + createRoot(async (dispose) => { + const confirmSpy = vi.spyOn(window, 'confirm').mockReturnValue(true); + const onAfterQueueAction = vi.fn().mockResolvedValue(undefined); + try { + vi.mocked(NotificationsAPI.getHealth) + .mockResolvedValueOnce({ + queue: { status: 'degraded', attentionRequired: 2 }, + } as never) + .mockRejectedValueOnce(new Error('post-action connection lost')); + vi.mocked(NotificationsAPI[action]).mockResolvedValueOnce({ affected: 2 } as never); + const state = useNotificationDeliveryHealth({ onAfterQueueAction }); + await state.loadDeliveryHealth(); + + await state[action](); + + expect(NotificationsAPI[action]).toHaveBeenCalledOnce(); + expect(NotificationsAPI.getHealth).toHaveBeenCalledTimes(2); + expect(onAfterQueueAction).toHaveBeenCalledOnce(); + expect(state.deliveryHealth()).toBeNull(); + expect(state.deliveryHealthUnavailable()).toBe(true); + expect(state.deliveryNeedsAttention()).toBe(true); + expect(state.refreshingDeliveryHealth()).toBe(false); + expect(state.retryingTerminalFailures()).toBe(false); + expect(state.dismissingTerminalFailures()).toBe(false); + } finally { + confirmSpy.mockRestore(); + dispose(); + } + })); + it.each(['cancelled', 'rejected'] as const)( 'preserves retained failure evidence when the action is %s', (outcome) =>