diff --git a/app/src/components/flagship/CalibrationMatches.tsx b/app/src/components/flagship/CalibrationMatches.tsx
index acb1ffe43..124a026f9 100644
--- a/app/src/components/flagship/CalibrationMatches.tsx
+++ b/app/src/components/flagship/CalibrationMatches.tsx
@@ -211,7 +211,7 @@ export function CalibrationMatchSection({
return card(Calibration checks are temporarily unavailable.);
}
if (matches === undefined) {
- return card(Checking calibration targets…);
+ return card();
}
if (matches.matches.length === 0) {
const where = matches.geography === 'US' ? 'nationally' : `in ${matches.geography}`;
diff --git a/app/src/components/flagship/ReportAdjustPanel.tsx b/app/src/components/flagship/ReportAdjustPanel.tsx
index cccdfb0e2..7fa1ac21f 100644
--- a/app/src/components/flagship/ReportAdjustPanel.tsx
+++ b/app/src/components/flagship/ReportAdjustPanel.tsx
@@ -35,6 +35,11 @@ interface ReportAdjustPanelProps {
year?: string;
/** What the report is compared with, so a recompute is too; current law when unset. */
baseline?: RunReportBaseline;
+ /**
+ * The report's baseline policy could not be loaded. A recompute would
+ * compare with current law instead, so it is off.
+ */
+ baselineUnknown?: boolean;
}
/** True when the reform's parameter set is exactly the given provisions. */
@@ -66,6 +71,7 @@ export default function ReportAdjustPanel({
region,
year,
baseline,
+ baselineUnknown = false,
}: ReportAdjustPanelProps) {
const runReport = useRunFlagshipReport();
const nav = useAppNavigate();
@@ -351,7 +357,15 @@ export default function ReportAdjustPanel({
{reconcileError || runReport.error}
)}
-
-
+
{reforms.length > 0 && (
Current law
- New value
+
+ New value
+
Effective
@@ -84,11 +86,13 @@ function DraftTableSkeleton({ rows }: { rows: number }) {
-
+
+
+
-
+
))}
window.location.reload() : undefined}
+ retryLabel="Reload"
+ actions={
+ <>
+
+ Open without saved details
+
+ nav.push(`/${countryId}/build`)}>
+ Back to Build
+
+ >
+ }
>
-
-
-
-
-
-
- This report's saved details can't be read
-
-
- {newer
- ? 'A newer version of PolicyEngine saved them. Reload to update.'
- : 'They are damaged in this browser.'}
-
-
-
-
-
- {newer && window.location.reload()}>Reload}
-
- Open without saved details
-
- nav.push(`/${countryId}/build`)}>
- Back to Build
-
-
-
-
+
);
}
diff --git a/app/src/components/flagship/report/ReportValidation.tsx b/app/src/components/flagship/report/ReportValidation.tsx
index 9015c3472..3d5417096 100644
--- a/app/src/components/flagship/report/ReportValidation.tsx
+++ b/app/src/components/flagship/report/ReportValidation.tsx
@@ -69,7 +69,7 @@ function ExternalEstimates({
if (!estimates && reforms.length === 0) {
fallback =
scorecard === undefined ? (
- Loading external estimates…
+
) : scorecard === null ? (
External estimates are temporarily unavailable.
) : (
diff --git a/app/src/components/flagship/report/ReportView.tsx b/app/src/components/flagship/report/ReportView.tsx
index efe974e11..6c9f72a98 100644
--- a/app/src/components/flagship/report/ReportView.tsx
+++ b/app/src/components/flagship/report/ReportView.tsx
@@ -84,6 +84,11 @@ export interface ReportViewProps {
provisionsLoading?: boolean;
/** What the results are compared with, by name; current law when unset. */
customBaselineLabel?: string | null;
+ /**
+ * The baseline policy could not be loaded: the adjust panel cannot
+ * recompute against it.
+ */
+ baselineUnknown?: boolean;
/** What the adjust panel's runs compare with; current law when unset. */
baseline?: RunReportBaseline;
year: string;
@@ -133,6 +138,7 @@ export default function ReportView({
priorLawBaseline = false,
provisionsLoading = false,
customBaselineLabel,
+ baselineUnknown = false,
baseline,
year,
region,
@@ -429,6 +435,7 @@ export default function ReportView({
region={region}
year={year}
baseline={baseline}
+ baselineUnknown={baselineUnknown}
/>
diff --git a/app/src/components/flagship/report/household/HouseholdImpactSection.tsx b/app/src/components/flagship/report/household/HouseholdImpactSection.tsx
index d715c8741..07a1297e2 100644
--- a/app/src/components/flagship/report/household/HouseholdImpactSection.tsx
+++ b/app/src/components/flagship/report/household/HouseholdImpactSection.tsx
@@ -1,9 +1,9 @@
import { useState } from 'react';
-import { IconAlertTriangle } from '@tabler/icons-react';
import HouseholdForm from '@/components/flagship/report/household/HouseholdForm';
import HouseholdImpactResult from '@/components/flagship/report/household/HouseholdImpactResult';
import RunProgress from '@/components/flagship/report/RunProgress';
-import { Button, Stack, Text } from '@/components/ui';
+import { ErrorState } from '@/components/flagship/states';
+import { Stack, Text } from '@/components/ui';
import { colors, spacing, typography } from '@/designTokens';
import { useFlagshipHousehold } from '@/hooks/useFlagshipHousehold';
import {
@@ -81,46 +81,17 @@ export default function HouseholdImpactSection({
{running && }
{failed && (
-
-
-
-
- This household could not be calculated.
-
- {run.error?.message && (
-
- {run.error.message}
-
- )}
- void run.refetch()}>
- Try again
-
-
-
+ {run.error.message}
+ )
+ }
+ onRetry={run.refetch}
+ />
)}
{result && requested && (
diff --git a/app/src/hooks/useFlagshipReport.ts b/app/src/hooks/useFlagshipReport.ts
index febbb7c73..9254e883c 100644
--- a/app/src/hooks/useFlagshipReport.ts
+++ b/app/src/hooks/useFlagshipReport.ts
@@ -37,6 +37,11 @@ export interface FlagshipReportData {
error: Error | null;
/** The report id resolves to no report (a bad or deleted link). */
notFound: boolean;
+ /**
+ * The policies that failed to load, with nothing to show. A missing
+ * baseline policy leaves what the report compares with unknown.
+ */
+ failedPolicyIds: string[];
/** Asks again for whatever failed; settles when the answers are in. */
retry: () => Promise;
}
@@ -92,6 +97,10 @@ export function useFlagshipReport(id: string): FlagshipReportData {
structuralSharing: false,
});
const policies = policyResults.queries.map((q) => q.data).filter((p): p is Policy => !!p);
+ const failedPolicyIds = policyIds.filter((_, index) => {
+ const query = policyResults.queries[index];
+ return !!query?.error && !query.data;
+ });
if (!direct) {
return {
@@ -102,6 +111,7 @@ export function useFlagshipReport(id: string): FlagshipReportData {
// A legacy link that resolves to nothing reads as unresolvable.
error: null,
notFound: false,
+ failedPolicyIds: [],
retry: async () => undefined,
};
}
@@ -120,6 +130,7 @@ export function useFlagshipReport(id: string): FlagshipReportData {
isLoading: reportLoading || simulationResults.isLoading || policyResults.isLoading,
error,
notFound: !!unloadedReportError && isNotFoundError(unloadedReportError),
+ failedPolicyIds,
retry: () =>
Promise.all([
reportError ? refetchReport() : null,
diff --git a/app/src/libs/flagship/reportBaseline.ts b/app/src/libs/flagship/reportBaseline.ts
index 8650a10b8..fdef9fd7a 100644
--- a/app/src/libs/flagship/reportBaseline.ts
+++ b/app/src/libs/flagship/reportBaseline.ts
@@ -23,6 +23,28 @@ export function reportBaselineLabel(
: null;
}
+/** What a report compares with when its baseline policy could not be loaded. */
+export const UNKNOWN_BASELINE_LABEL = 'a baseline policy that could not be loaded';
+
+/**
+ * Whether what the report compares with is unknown: no record of the
+ * run's baseline (a shared link), and a baseline policy, not current
+ * law, that failed to load. Read as current law, the report would claim
+ * a comparison that it cannot show.
+ */
+export function reportBaselineUnknown(
+ meta: Pick | null | undefined,
+ baselinePolicyId: string | undefined,
+ { currentLawId, failedPolicyIds }: { currentLawId: number; failedPolicyIds: string[] }
+): boolean {
+ return (
+ !meta?.baseline &&
+ !!baselinePolicyId &&
+ baselinePolicyId !== String(currentLawId) &&
+ failedPolicyIds.includes(baselinePolicyId)
+ );
+}
+
/**
* What a new run from this report compares with: the same baseline
* policy when it is not current law, so an adjusted report keeps its
diff --git a/app/src/pages/flagship/Report.page.tsx b/app/src/pages/flagship/Report.page.tsx
index c3d826b69..024c281a0 100644
--- a/app/src/pages/flagship/Report.page.tsx
+++ b/app/src/pages/flagship/Report.page.tsx
@@ -22,13 +22,33 @@ import { useReportValidationSnapshot } from '@/hooks/useReportValidationSnapshot
import { useStartCalculationOnLoad } from '@/hooks/useStartCalculationOnLoad';
import { useUnreadableReportMeta } from '@/hooks/useUnreadableReportMeta';
import { clearDraftAfterRun, loadProvisionsIntoDraft } from '@/libs/draftReform';
-import { reportBaselineLabel, reportRunBaseline } from '@/libs/flagship/reportBaseline';
+import {
+ reportBaselineLabel,
+ reportBaselineUnknown,
+ reportRunBaseline,
+ UNKNOWN_BASELINE_LABEL,
+} from '@/libs/flagship/reportBaseline';
import { provenanceFromPolicy } from '@/libs/flagship/reportProvenance';
import { readReportMeta } from '@/libs/flagship/runReport';
import { RootState } from '@/store';
import type { CalcStartConfig } from '@/types/calculation';
import { allSimulationsLoaded } from '@/utils/reportSimulations';
+/** A failed load at the top of the overview, in a dashed box. */
+function LeadError({ children }: { children: React.ReactNode }) {
+ return (
+
+ {children}
+
+ );
+}
+
interface FlagshipReportPageProps {
/** Passed by the Next.js route bridge; react-router falls back to params. */
userReportId?: string;
@@ -51,12 +71,14 @@ export default function FlagshipReportPage({ userReportId: propId }: FlagshipRep
isLoading,
error: loadError,
notFound,
+ failedPolicyIds,
retry,
} = useFlagshipReport(userReportId);
// A local association id from another browser resolves to nothing.
const unresolvable = !isLoading && !report && !!userReportId && !isApiReportId(userReportId);
const parameters = useSelector((state: RootState) => state.metadata.parameters);
const economyRegions = useSelector((state: RootState) => state.metadata.economyOptions.region);
+ const currentLawId = useSelector((state: RootState) => state.metadata.currentLawId);
// Provenance: the local stash from the run, else rebuilt from the reform
// policy so a shared link validates like the original.
const reformPolicy = policies.find((policy) => policy.id === simulations?.[1]?.policyId);
@@ -120,9 +142,18 @@ export default function FlagshipReportPage({ userReportId: propId }: FlagshipRep
const reformPolicyId = simulations?.[1]?.policyId;
const baselinePolicyId = simulations?.[0]?.policyId;
const baselinePolicy = policies.find((policy) => policy.id === baselinePolicyId);
- const customBaselineLabel = reportBaselineLabel(meta, baselinePolicy);
- // Adjusted, the report keeps what it was compared with.
- const runBaseline = reportRunBaseline(meta, baselinePolicyId, customBaselineLabel);
+ // A baseline policy that failed to load is unknown, not current law.
+ const baselineUnknown = reportBaselineUnknown(meta, baselinePolicyId, {
+ currentLawId,
+ failedPolicyIds,
+ });
+ const customBaselineLabel = baselineUnknown
+ ? UNKNOWN_BASELINE_LABEL
+ : reportBaselineLabel(meta, baselinePolicy);
+ // Adjusted, the report keeps what it was compared with; an unknown one gives it nothing to keep.
+ const runBaseline = baselineUnknown
+ ? undefined
+ : reportRunBaseline(meta, baselinePolicyId, customBaselineLabel);
const region = simulations?.[0]?.populationId;
// A report on part of the country names it: "California".
const regionLabel =
@@ -269,19 +300,26 @@ export default function FlagshipReportPage({ userReportId: propId }: FlagshipRep
budgetWindow={meta?.budgetWindow}
provisions={meta?.provisions ?? []}
overviewLead={
- !meta && metadata.status === 'error' ? (
-
-
-
- ) : undefined
+ <>
+ {!meta && metadata.status === 'error' && (
+
+
+
+ )}
+ {baselineUnknown && (
+
+
+
+ )}
+ >
}
customBaselineLabel={customBaselineLabel}
+ baselineUnknown={baselineUnknown}
baseline={runBaseline}
year={report?.year ?? ''}
region={region}
diff --git a/app/src/tests/unit/components/flagship/CalibrationMatches.test.tsx b/app/src/tests/unit/components/flagship/CalibrationMatches.test.tsx
index 8dcca7f11..2af77e229 100644
--- a/app/src/tests/unit/components/flagship/CalibrationMatches.test.tsx
+++ b/app/src/tests/unit/components/flagship/CalibrationMatches.test.tsx
@@ -24,7 +24,9 @@ describe('CalibrationMatchSection', () => {
test('given matches are loading then the loading state renders', () => {
render();
- expect(screen.getByRole('status')).toHaveTextContent('Checking calibration targets…');
+ expect(
+ screen.getByRole('status', { name: 'Checking calibration targets' })
+ ).toBeInTheDocument();
});
test('given reached variables but none calibrated then the gap is stated, not hidden', () => {
diff --git a/app/src/tests/unit/components/flagship/ReportAdjustPanel.test.tsx b/app/src/tests/unit/components/flagship/ReportAdjustPanel.test.tsx
index 5ea7d326b..4cb0571a6 100644
--- a/app/src/tests/unit/components/flagship/ReportAdjustPanel.test.tsx
+++ b/app/src/tests/unit/components/flagship/ReportAdjustPanel.test.tsx
@@ -63,7 +63,13 @@ async function renderPanel({
region,
year,
baseline,
-}: { region?: string; year?: string; baseline?: RunReportBaseline } = {}) {
+ baselineUnknown,
+}: {
+ region?: string;
+ year?: string;
+ baseline?: RunReportBaseline;
+ baselineUnknown?: boolean;
+} = {}) {
const queryClient = new QueryClient({ defaultOptions: { queries: { retry: false } } });
const result = render(
@@ -74,6 +80,7 @@ async function renderPanel({
region={region}
year={year}
baseline={baseline}
+ baselineUnknown={baselineUnknown}
/>
);
@@ -365,6 +372,20 @@ describe('ReportAdjustPanel', () => {
expect(screen.getByLabelText(/new value for maximum credit per child/i)).toBeInTheDocument();
});
+ test('given the baseline policy could not be loaded then recompute is off and says why', async () => {
+ const user = userEvent.setup();
+ await renderPanel({ baselineUnknown: true });
+
+ await user.click(screen.getByRole('button', { name: /remove maximum allotment/i }));
+
+ expect(screen.getByRole('button', { name: /recompute/i })).toBeDisabled();
+ expect(
+ screen.getByText(
+ 'The baseline policy could not be loaded, so a recompute cannot compare with it.'
+ )
+ ).toBeInTheDocument();
+ });
+
test('given collapse then the panel shrinks to the adjust tab and reopens', async () => {
const user = userEvent.setup();
await renderPanel();
diff --git a/app/src/tests/unit/components/flagship/ValidationPanel.test.tsx b/app/src/tests/unit/components/flagship/ValidationPanel.test.tsx
index d593c1618..046a9eff2 100644
--- a/app/src/tests/unit/components/flagship/ValidationPanel.test.tsx
+++ b/app/src/tests/unit/components/flagship/ValidationPanel.test.tsx
@@ -110,7 +110,9 @@ describe('BaselineComparisons', () => {
test('given matches are loading then the loading state renders', () => {
render();
- expect(screen.getByText(/loading baseline comparisons/i)).toBeInTheDocument();
+ expect(
+ screen.getByRole('status', { name: 'Loading baseline comparisons' })
+ ).toBeInTheDocument();
});
test('given the reform reaches nothing then a plain line says no comparison covers it', () => {
diff --git a/app/src/tests/unit/components/flagship/report/HouseholdImpactSection.test.tsx b/app/src/tests/unit/components/flagship/report/HouseholdImpactSection.test.tsx
index c61218901..6a67627b4 100644
--- a/app/src/tests/unit/components/flagship/report/HouseholdImpactSection.test.tsx
+++ b/app/src/tests/unit/components/flagship/report/HouseholdImpactSection.test.tsx
@@ -236,7 +236,7 @@ describe('HouseholdImpactSection', () => {
await user.click(screen.getByRole('button', { name: 'Calculate' }));
const alert = await screen.findByRole('alert');
- expect(alert).toHaveTextContent('This household could not be calculated.');
+ expect(alert).toHaveTextContent('This household could not be calculated');
expect(alert).toHaveTextContent('Household calculation failed');
await user.click(within(alert).getByRole('button', { name: 'Try again' }));
diff --git a/app/src/tests/unit/components/flagship/report/ReportDetailsError.test.tsx b/app/src/tests/unit/components/flagship/report/ReportDetailsError.test.tsx
index cfabeed0b..a99ab4ec8 100644
--- a/app/src/tests/unit/components/flagship/report/ReportDetailsError.test.tsx
+++ b/app/src/tests/unit/components/flagship/report/ReportDetailsError.test.tsx
@@ -15,7 +15,7 @@ describe('ReportDetailsError', () => {
render();
expect(
- screen.getByRole('heading', { name: "This report's saved details can't be read" })
+ screen.getByRole('heading', { name: "Could not read this report's saved details" })
).toBeInTheDocument();
expect(screen.getByText('They are damaged in this browser.')).toBeInTheDocument();
expect(screen.getByText('provisions must be an array')).toBeInTheDocument();
diff --git a/app/src/tests/unit/components/flagship/report/ReportValidation.test.tsx b/app/src/tests/unit/components/flagship/report/ReportValidation.test.tsx
index 0269d3603..586cd20ea 100644
--- a/app/src/tests/unit/components/flagship/report/ReportValidation.test.tsx
+++ b/app/src/tests/unit/components/flagship/report/ReportValidation.test.tsx
@@ -128,9 +128,9 @@ describe('ReportValidation', () => {
mockUseScorecardComparisons.mockReturnValue(undefined);
renderValidation();
- expect(within(card('External estimates')).getByRole('status')).toHaveTextContent(
- 'Loading external estimates…'
- );
+ expect(
+ within(card('External estimates')).getByRole('status', { name: 'Loading external estimates' })
+ ).toBeInTheDocument();
});
test('given the scorecard is unavailable then the estimates card says so, not that none exists', () => {
diff --git a/app/src/tests/unit/hooks/useFlagshipReport.test.tsx b/app/src/tests/unit/hooks/useFlagshipReport.test.tsx
index 34a051c79..200b272c2 100644
--- a/app/src/tests/unit/hooks/useFlagshipReport.test.tsx
+++ b/app/src/tests/unit/hooks/useFlagshipReport.test.tsx
@@ -165,6 +165,8 @@ describe('useFlagshipReport', () => {
await waitFor(() => expect(result.current.isLoading).toBe(false));
expect(result.current.simulations).toHaveLength(2);
expect(result.current.error).toBeNull();
+ // Each failed policy is named, so a missing baseline reads as unknown.
+ await waitFor(() => expect(result.current.failedPolicyIds).toEqual(['2', '98557']));
});
test('given a failed simulation then retry asks for it again and the error clears', async () => {
diff --git a/app/src/tests/unit/libs/flagship/reportBaseline.test.ts b/app/src/tests/unit/libs/flagship/reportBaseline.test.ts
index 7af80d3a2..ddbf80d1b 100644
--- a/app/src/tests/unit/libs/flagship/reportBaseline.test.ts
+++ b/app/src/tests/unit/libs/flagship/reportBaseline.test.ts
@@ -3,6 +3,7 @@ import {
baselineProvisions,
customBaseline,
reportBaselineLabel,
+ reportBaselineUnknown,
reportRunBaseline,
} from '@/libs/flagship/reportBaseline';
@@ -39,6 +40,37 @@ describe('reportBaselineLabel', () => {
});
});
+describe('reportBaselineUnknown', () => {
+ const CURRENT_LAW_ID = 2;
+
+ test('given a shared link whose baseline policy failed then the baseline is unknown', () => {
+ expect(
+ reportBaselineUnknown(null, '88', { currentLawId: CURRENT_LAW_ID, failedPolicyIds: ['88'] })
+ ).toBe(true);
+ });
+
+ test('given the baseline policy loaded then the baseline is known', () => {
+ expect(
+ reportBaselineUnknown(null, '88', { currentLawId: CURRENT_LAW_ID, failedPolicyIds: ['99'] })
+ ).toBe(false);
+ });
+
+ test('given current law failed to load then it is still current law', () => {
+ expect(
+ reportBaselineUnknown(null, '2', { currentLawId: CURRENT_LAW_ID, failedPolicyIds: ['2'] })
+ ).toBe(false);
+ });
+
+ test('given the run recorded its baseline then a failed policy leaves it known', () => {
+ expect(
+ reportBaselineUnknown(PLAN_B_META, '88', {
+ currentLawId: CURRENT_LAW_ID,
+ failedPolicyIds: ['88'],
+ })
+ ).toBe(false);
+ });
+});
+
describe('reportRunBaseline', () => {
test('given a report compared with a saved reform then a re-run reuses its baseline policy', () => {
expect(reportRunBaseline(PLAN_B_META, '88', 'Plan B')).toEqual({
diff --git a/app/src/tests/unit/pages/flagship/Report.test.tsx b/app/src/tests/unit/pages/flagship/Report.test.tsx
index 5c5401d20..90625cbf2 100644
--- a/app/src/tests/unit/pages/flagship/Report.test.tsx
+++ b/app/src/tests/unit/pages/flagship/Report.test.tsx
@@ -10,6 +10,9 @@ import { createMockSocietyWideOutput } from '@/tests/fixtures/pages/reportOutput
const mockCalcStatus = vi.fn();
// The report's policies; a baseline policy with parameters is a custom baseline.
const mockPolicies = vi.hoisted(() => ({ current: [] as unknown[] }));
+// The policies that failed to load, by id.
+const mockFailedPolicyIds = vi.hoisted(() => ({ current: [] as string[] }));
+const mockRetry = vi.fn();
const META: FlagshipReportMeta = {
title: 'Test Reform',
@@ -38,6 +41,8 @@ vi.mock('@/hooks/useFlagshipReport', () => ({
],
policies: mockPolicies.current,
isLoading: false,
+ failedPolicyIds: mockFailedPolicyIds.current,
+ retry: mockRetry,
}),
}));
@@ -91,6 +96,8 @@ describe('FlagshipReportPage', () => {
mockCalcStatus.mockReset();
mockMeta = META;
mockPolicies.current = [];
+ mockFailedPolicyIds.current = [];
+ mockRetry.mockReset();
mockStartCalculationOnLoad.mockReset();
});
@@ -218,6 +225,32 @@ describe('FlagshipReportPage', () => {
});
});
+ test('given the baseline policy failed to load then the report does not read as current law', async () => {
+ const user = userEvent.setup();
+ vi.stubGlobal(
+ 'fetch',
+ vi.fn(async () => Response.json({ built: null, rows: [], unmappedCount: 0 }))
+ );
+ mockFailedPolicyIds.current = ['2'];
+ mockCalcStatus.mockReturnValue({
+ status: 'complete',
+ isComplete: true,
+ isError: false,
+ result: createMockSocietyWideOutput(),
+ });
+
+ renderPage();
+
+ expect(
+ screen.getByText('Compared with a baseline policy that could not be loaded')
+ ).toBeInTheDocument();
+ await user.click(screen.getByRole('button', { name: 'Try again' }));
+ expect(mockRetry).toHaveBeenCalledTimes(1);
+
+ await user.click(screen.getByRole('tab', { name: 'Validation' }));
+ expect(within(screen.getByRole('tabpanel')).getAllByText('Not comparable')).toHaveLength(2);
+ });
+
test('given a failed run then Build gets the reform back with the same comparison', async () => {
clearDraftReform();
mockMeta = PLAN_B_META;
diff --git a/app/src/tests/unit/pages/flagship/ReportLoadStates.test.tsx b/app/src/tests/unit/pages/flagship/ReportLoadStates.test.tsx
index 3b315ab2c..995848aee 100644
--- a/app/src/tests/unit/pages/flagship/ReportLoadStates.test.tsx
+++ b/app/src/tests/unit/pages/flagship/ReportLoadStates.test.tsx
@@ -65,6 +65,7 @@ function reportData(overrides: Partial = {}): FlagshipReport
isLoading: false,
error: null,
notFound: false,
+ failedPolicyIds: [],
retry: mockRetry,
...overrides,
};
diff --git a/app/src/tests/unit/pages/flagship/ReportUnreadableMeta.test.tsx b/app/src/tests/unit/pages/flagship/ReportUnreadableMeta.test.tsx
index de78cfa57..74f2b0a85 100644
--- a/app/src/tests/unit/pages/flagship/ReportUnreadableMeta.test.tsx
+++ b/app/src/tests/unit/pages/flagship/ReportUnreadableMeta.test.tsx
@@ -12,7 +12,7 @@ import {
// schema, from real localStorage (Report.test.tsx stubs the read).
const REPORT_ID = 'r1';
-const UNREADABLE_HEADING = "This report's saved details can't be read";
+const UNREADABLE_HEADING = "Could not read this report's saved details";
const WAITING_TEXT = 'Calculating the nationwide results';
vi.mock('@/hooks/useFlagshipReport', () => ({
@@ -25,6 +25,7 @@ vi.mock('@/hooks/useFlagshipReport', () => ({
],
policies: [],
isLoading: false,
+ failedPolicyIds: [],
}),
}));