mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-21 22:31:46 +00:00
fix(atlas): add A3 fallback when ISO_A2 is invalid
This commit is contained in:
@@ -127,6 +127,23 @@ const geoJsonWithFR = {
|
|||||||
],
|
],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const geoJsonWithFranceA3Fallback = {
|
||||||
|
type: 'FeatureCollection',
|
||||||
|
features: [
|
||||||
|
{
|
||||||
|
type: 'Feature',
|
||||||
|
properties: {
|
||||||
|
ISO_A2: '-99',
|
||||||
|
ADM0_A3: 'FRA',
|
||||||
|
ISO_A3: 'FRA',
|
||||||
|
NAME: 'France',
|
||||||
|
ADMIN: 'France',
|
||||||
|
},
|
||||||
|
geometry: null,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
|
||||||
// ── Atlas API response fixture ────────────────────────────────────────────────
|
// ── Atlas API response fixture ────────────────────────────────────────────────
|
||||||
const atlasStatsResponse = {
|
const atlasStatsResponse = {
|
||||||
countries: [{ code: 'FR', tripCount: 2, placeCount: 5, firstVisit: '2023-01-01', lastVisit: '2024-06-01' }],
|
countries: [{ code: 'FR', tripCount: 2, placeCount: 5, firstVisit: '2023-01-01', lastVisit: '2024-06-01' }],
|
||||||
@@ -1323,6 +1340,33 @@ describe('AtlasPage', () => {
|
|||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
describe('FE-PAGE-ATLAS-041: country search falls back from A3 when ISO_A2 is invalid', () => {
|
||||||
|
it('returns France in search results when GeoJSON provides ADM0_A3 but ISO_A2 is -99', async () => {
|
||||||
|
vi.spyOn(global, 'fetch').mockImplementation((url) => {
|
||||||
|
const urlStr = String(url);
|
||||||
|
if (urlStr.includes('geojson') || urlStr.includes('githubusercontent')) {
|
||||||
|
return Promise.resolve({ ok: true, json: () => Promise.resolve(geoJsonWithFranceA3Fallback) } as Response);
|
||||||
|
}
|
||||||
|
return Promise.reject(new Error(`Unmocked fetch: ${urlStr}`));
|
||||||
|
});
|
||||||
|
|
||||||
|
const user = userEvent.setup();
|
||||||
|
render(<AtlasPage />);
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
expect(screen.getByPlaceholderText(/search a country/i)).toBeInTheDocument();
|
||||||
|
});
|
||||||
|
|
||||||
|
const searchInput = screen.getByPlaceholderText(/search a country/i);
|
||||||
|
await user.type(searchInput, 'france');
|
||||||
|
|
||||||
|
await waitFor(() => {
|
||||||
|
const franceButton = screen.getAllByRole('button').find((button) => button.textContent?.includes('France'));
|
||||||
|
expect(franceButton).toBeTruthy();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
describe('FE-PAGE-ATLAS-042: bucket form submit with actual name value', () => {
|
describe('FE-PAGE-ATLAS-042: bucket form submit with actual name value', () => {
|
||||||
it('submitting bucket form with a non-empty name covers handleAddBucketItem', async () => {
|
it('submitting bucket form with a non-empty name covers handleAddBucketItem', async () => {
|
||||||
server.use(
|
server.use(
|
||||||
|
|||||||
@@ -189,8 +189,15 @@ export default function AtlasPage(): React.ReactElement {
|
|||||||
const opts: { code: string; label: string }[] = []
|
const opts: { code: string; label: string }[] = []
|
||||||
const seen = new Set<string>()
|
const seen = new Set<string>()
|
||||||
for (const f of (geoData as any).features || []) {
|
for (const f of (geoData as any).features || []) {
|
||||||
const a2 = f?.properties?.ISO_A2
|
let a2 = f?.properties?.ISO_A2
|
||||||
if (!a2 || a2 === '-99' || typeof a2 !== 'string' || a2.length !== 2) continue
|
if (!a2 || a2 === '-99' || typeof a2 !== 'string' || a2.length !== 2) {
|
||||||
|
const a3 = f?.properties?.ADM0_A3 || f?.properties?.ISO_A3 || f?.properties?.['ISO3166-1-Alpha-3'] || null
|
||||||
|
if (a3 && a3 !== '-99') {
|
||||||
|
const a3ToA2Entry = Object.entries(A2_TO_A3).find(([, v]) => v === a3)
|
||||||
|
a2 = a3ToA2Entry ? a3ToA2Entry[0] : null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!a2 || typeof a2 !== 'string' || a2.length !== 2) continue
|
||||||
if (seen.has(a2)) continue
|
if (seen.has(a2)) continue
|
||||||
seen.add(a2)
|
seen.add(a2)
|
||||||
const label = String(resolveName(a2) || f?.properties?.NAME || f?.properties?.ADMIN || a2)
|
const label = String(resolveName(a2) || f?.properties?.NAME || f?.properties?.ADMIN || a2)
|
||||||
|
|||||||
Reference in New Issue
Block a user