mirror of
https://github.com/MeshCore-Beacon/beacon-web.git
synced 2026-10-23 11:02:24 +00:00
Add a toggleable IATA border layer to the map
Draw each active IATA's GeoJSON region border as an outline over a faint fill beneath the node markers, behind a Map Settings toggle that's off by default and shareable via a URL param. IATAs with no border answer 204 and are skipped.
This commit is contained in:
1 parent
8baa562794
commit
464e701f76
10 files changed
+305
-4
No files matched your search
@@ -1,5 +1,6 @@
|
||||
import { afterEach, describe, expect, it, vi } from "vitest";
|
||||
import { getPackets, getNodesPage, getObserversPage, getScopes, getKnownRoutesPage, searchKnownRoutes, getChannels, getChannelMessagesPage, getTraces, getTraceDetail, getStatsOverview, getTopObservers, getTopAdvertisers, getTopTalkers, getStatsNodeTypes, getClockDrift } from "../../src/api/client";
|
||||
import { getPackets, getNodesPage, getObserversPage, getScopes, getKnownRoutesPage, searchKnownRoutes, getChannels, getChannelMessagesPage, getTraces, getTraceDetail, getStatsOverview, getTopObservers, getTopAdvertisers, getTopTalkers, getStatsNodeTypes, getClockDrift, getIataBorder } from "../../src/api/client";
|
||||
import type { Feature, Polygon } from "geojson";
|
||||
import type { NodeSummary } from "../../src/features/nodes/types";
|
||||
import type { ObserverSummary } from "../../src/features/observers/types";
|
||||
import type { ChannelMessage, ChannelSummary } from "../../src/features/channels/types";
|
||||
@@ -436,3 +437,52 @@ describe("stats endpoints", () => {
|
||||
expect(url.searchParams.get("limit")).toBe("100");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getIataBorder", () => {
|
||||
// this endpoint can 204 (empty body) or send a literal `null`, so mock the status explicitly
|
||||
function mockStatus(status: number, body: unknown): () => string {
|
||||
let calledUrl = "";
|
||||
vi.stubGlobal(
|
||||
"fetch",
|
||||
vi.fn(async (url: string) => {
|
||||
calledUrl = url;
|
||||
return {
|
||||
ok: status >= 200 && status < 300,
|
||||
status,
|
||||
json: async () => {
|
||||
if (status === 204) throw new Error("no body to parse");
|
||||
return body;
|
||||
},
|
||||
} as Response;
|
||||
}),
|
||||
);
|
||||
return () => calledUrl;
|
||||
}
|
||||
|
||||
const feature: Feature<Polygon> = {
|
||||
type: "Feature",
|
||||
properties: {},
|
||||
geometry: { type: "Polygon", coordinates: [[[0, 0], [1, 0], [1, 1], [0, 0]]] },
|
||||
};
|
||||
|
||||
it("requests /iatas/{iata}/border", async () => {
|
||||
const getUrl = mockStatus(200, feature);
|
||||
await getIataBorder("YOW");
|
||||
expect(new URL(getUrl()).pathname).toContain("/iatas/YOW/border");
|
||||
});
|
||||
|
||||
it("returns null for a 204 (no border configured) without parsing a body", async () => {
|
||||
mockStatus(204, undefined);
|
||||
await expect(getIataBorder("YOW")).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it("treats a literal null body as no border", async () => {
|
||||
mockStatus(200, null);
|
||||
await expect(getIataBorder("YOW")).resolves.toBeNull();
|
||||
});
|
||||
|
||||
it("returns the GeoJSON Feature when a border exists", async () => {
|
||||
mockStatus(200, feature);
|
||||
await expect(getIataBorder("YOW")).resolves.toEqual(feature);
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user