From 9b7d7f5c8fc9fc7e8d369fc8004d544d2f408bc0 Mon Sep 17 00:00:00 2001 From: Christopher <131207452+PetrefiedThunder@users.noreply.github.com> Date: Sun, 25 Oct 2026 03:08:54 -0700 Subject: [PATCH] fix(suppliers): refresh late CTE records when agreed hours change --- .../components/supplier-data-quality.test.tsx | 63 +++++++++++++++---- .../app/dashboard/suppliers/data-quality.tsx | 2 +- 2 files changed, 52 insertions(+), 13 deletions(-) diff --git a/frontend/src/__tests__/components/supplier-data-quality.test.tsx b/frontend/src/__tests__/components/supplier-data-quality.test.tsx index af48ad555..1f9c21199 100644 --- a/frontend/src/__tests__/components/supplier-data-quality.test.tsx +++ b/frontend/src/__tests__/components/supplier-data-quality.test.tsx @@ -1,6 +1,11 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'; import { fireEvent, render, screen, waitFor } from '@testing-library/react'; -import type { SupplierDataQuality, SupplierQualityMetric, SupplierQualityRecordsResponse } from '@/types/api'; +import type { + SupplierDataQuality, + SupplierQualityMetric, + SupplierQualityRecordItem, + SupplierQualityRecordsResponse, +} from '@/types/api'; const mocks = vi.hoisted(() => ({ getSupplierDataQualityRecords: vi.fn(), @@ -68,6 +73,21 @@ const lateMeasured = summary( AGREED_HOURS, ); +const lateRecordItem = (recordId: string, agreedHours: number): SupplierQualityRecordItem => { + const eventTime = new Date(); + const receivedTime = new Date(eventTime); + receivedTime.setUTCHours(receivedTime.getUTCHours() + agreedHours + 1); + return { + record_id: recordId, + lot_id: null, + lot_code: crypto.randomUUID(), + cte_type: 'shipping', + event_time: eventTime.toISOString(), + received_at: receivedTime.toISOString(), + missing_kdes: [], + }; +}; + function renderQuality(data: SupplierDataQuality | null = fourMetrics, unavailable = false) { return render( { page({ metric: 'late_cte', total: [lateId].length, - items: [ - { - record_id: lateId, - lot_id: null, - lot_code: crypto.randomUUID(), - cte_type: 'shipping', - event_time: null, - received_at: null, - missing_kdes: [], - }, - ], + items: [lateRecordItem(lateId, AGREED_HOURS)], }), ); renderQuality(lateMeasured); @@ -282,6 +292,35 @@ describe('DataQuality', () => { expect(mocks.getSupplierDataQualityRecords).toHaveBeenCalledWith(FACILITY_ID, 'late_cte', expect.anything()); }); + it('clears late records from the prior agreement when the hours change', async () => { + const [oldRecordId, updatedRecordId] = uuids(2); + const updatedHours = AGREED_HOURS + 1; + mocks.getSupplierDataQualityRecords + .mockResolvedValueOnce(page({ metric: 'late_cte', total: [oldRecordId].length, items: [lateRecordItem(oldRecordId, AGREED_HOURS)] })) + .mockResolvedValueOnce(page({ metric: 'late_cte', total: [updatedRecordId].length, items: [lateRecordItem(updatedRecordId, updatedHours)] })); + + const { rerender } = renderQuality(lateMeasured); + fireEvent.click(screen.getByRole('button', { name: 'View records' })); + await waitFor(() => expect(screen.getByText(oldRecordId)).toBeInTheDocument()); + + rerender( + , + ); + expect(screen.queryByText(oldRecordId)).not.toBeInTheDocument(); + expect(screen.getByText(`Agreed sending time: ${updatedHours} hours after the event`)).toBeInTheDocument(); + + fireEvent.click(screen.getByRole('button', { name: 'View records' })); + await waitFor(() => expect(screen.getByText(updatedRecordId)).toBeInTheDocument()); + expect(mocks.getSupplierDataQualityRecords).toHaveBeenCalledTimes(2); + }); + it('offers no late drill down without an agreed sending time', () => { renderQuality(summary([fourMetrics.metrics[2]])); expect(screen.getByText('Agreed sending time: Not set')).toBeInTheDocument(); diff --git a/frontend/src/app/dashboard/suppliers/data-quality.tsx b/frontend/src/app/dashboard/suppliers/data-quality.tsx index faec056cf..16d33ca35 100644 --- a/frontend/src/app/dashboard/suppliers/data-quality.tsx +++ b/frontend/src/app/dashboard/suppliers/data-quality.tsx @@ -221,7 +221,7 @@ export function DataQuality({