diff --git a/frontend/src/energy/CostView.test.tsx b/frontend/src/energy/CostView.test.tsx index bb5eb36..2cede7a 100644 --- a/frontend/src/energy/CostView.test.tsx +++ b/frontend/src/energy/CostView.test.tsx @@ -114,6 +114,12 @@ const THERMAL_DEGRADED_CROSS_EPOCH = { const ACTIVE_HEATING_METER = { id: 10, commodity: 'heating', ended_at: null } const ACTIVE_HOT_WATER_METER = { id: 11, commodity: 'hot_water', ended_at: null } const ENDED_HEATING_METER = { id: 9, commodity: 'heating', ended_at: '2026-06-01T00:00:00Z' } +const CLOSED_THERMAL_RANGE = { + startDate: '2020-01-01', + endDate: '2020-01-02', + start: '2020-01-01T00:00:00.000Z', + end: '2020-01-02T00:00:00.000Z', +} // --------------------------------------------------------------------------- // Import component @@ -297,13 +303,20 @@ describe('CostView', () => { expect(screen.getByTestId('thermal-fixed-breakdown')).toHaveTextContent('summary only') expect(screen.getAllByText(/Fixed subtotal|All-in total/)).toHaveLength(2) expect(screen.getByTestId('thermal-costs-table')).not.toHaveTextContent('Fixed') + await user.click(screen.getByTestId('thermal-cost-range-control')) + await user.click(screen.getByText('Custom')) + expect(screen.getByTestId('thermal-recompute-button')).toBeDisabled() + await user.type(screen.getByTestId('thermal-cost-custom-start'), CLOSED_THERMAL_RANGE.startDate) + await user.type(screen.getByTestId('thermal-cost-custom-end'), CLOSED_THERMAL_RANGE.endDate) + await waitFor(() => expect(screen.getByTestId('thermal-recompute-button')).toBeEnabled()) await user.click(screen.getByTestId('thermal-recompute-button')) expect(screen.getByTestId('thermal-recompute-confirm-modal')).toHaveTextContent('closed 15-minute') await user.click(screen.getByTestId('thermal-recompute-confirm')) - await waitFor(() => expect(mockPost).toHaveBeenCalledWith('/api/energy/meter-costs/recompute', expect.any(Object))) - const options = mockPost.mock.calls.find(([path]) => path === '/api/energy/meter-costs/recompute')?.[1] as { params: { query: { end: string } } } - expect(new Date(options.params.query.end).getTime()).toBeLessThanOrEqual(Date.now()) - expect(new Date(options.params.query.end).getUTCMinutes() % 15).toBe(0) + await waitFor(() => expect(mockPost).toHaveBeenCalledWith( + '/api/energy/meter-costs/recompute', + { params: { query: { scope: 'thermal', start: CLOSED_THERMAL_RANGE.start, end: CLOSED_THERMAL_RANGE.end } } }, + )) + expect(new Date(CLOSED_THERMAL_RANGE.end).getUTCMinutes() % 15).toBe(0) }) it('keeps the thermal confirmation cancellable and surfaces a 422 recompute failure', async () => { @@ -318,9 +331,18 @@ describe('CostView', () => { renderWithProviders() await user.click(screen.getByTestId('costs-scope-selector')); await user.click(screen.getByText('Thermal')) await waitFor(() => expect(screen.getByTestId('thermal-recompute-button')).toBeInTheDocument()) + await user.click(screen.getByTestId('thermal-cost-range-control')); await user.click(screen.getByText('Custom')) + expect(screen.getByTestId('thermal-recompute-button')).toBeDisabled() + await user.type(screen.getByTestId('thermal-cost-custom-start'), CLOSED_THERMAL_RANGE.startDate) + await user.type(screen.getByTestId('thermal-cost-custom-end'), CLOSED_THERMAL_RANGE.endDate) + await waitFor(() => expect(screen.getByTestId('thermal-recompute-button')).toBeEnabled()) await user.click(screen.getByTestId('thermal-recompute-button')); await user.click(screen.getByTestId('thermal-recompute-cancel')) expect(screen.queryByTestId('thermal-recompute-confirm-modal')).not.toBeInTheDocument() await user.click(screen.getByTestId('thermal-recompute-button')); await user.click(screen.getByTestId('thermal-recompute-confirm')) + await waitFor(() => expect(mockPost).toHaveBeenCalledWith( + '/api/energy/meter-costs/recompute', + { params: { query: { scope: 'thermal', start: CLOSED_THERMAL_RANGE.start, end: CLOSED_THERMAL_RANGE.end } } }, + )) await waitFor(() => expect(screen.getByTestId('thermal-recompute-error')).toBeInTheDocument()) })