Files
PolyWeather/frontend/components/dashboard/scan-terminal/__tests__/sourceFreshness.test.ts
T

113 lines
3.1 KiB
TypeScript

import assert from "node:assert/strict";
import {
buildObservationFreshness,
getMonitorFreshnessLevel,
getMonitorRefreshCadenceMs,
getObservationFreshness,
getObservationSourceProfile,
shouldRefreshMonitorCity,
} from "@/lib/source-freshness";
import type { CityDetail } from "@/lib/dashboard-types";
function detail(extra: Partial<CityDetail>): CityDetail {
return {
current: { temp: null },
display_name: "Test",
lat: 0,
local_date: "2026-05-14",
local_time: "12:00",
lon: 0,
name: "test",
risk: { level: "low" },
temp_symbol: "°C",
...extra,
} as CityDetail;
}
export function runTests() {
const now = new Date("2026-05-14T12:00:00Z");
assert.equal(getObservationSourceProfile("amos").nativeUpdateIntervalSec, 60);
assert.equal(getObservationSourceProfile("metar").nativeUpdateIntervalSec, 900);
const amosFresh = buildObservationFreshness({
now,
observedAt: "2026-05-14T11:59:10Z",
sourceCode: "amos",
sourceLabel: "AMOS",
});
assert.equal(amosFresh.freshness_status, "fresh");
assert.equal(getMonitorFreshnessLevel(amosFresh, null), "fresh");
assert.equal(
shouldRefreshMonitorCity({
detail: detail({ airport_current: { freshness: amosFresh, obs_time: "11:59", temp: 20 } }),
now,
trigger: "interval",
}),
false,
);
const metarStillExpected = buildObservationFreshness({
now,
observedAt: "2026-05-14T11:48:00Z",
sourceCode: "metar",
sourceLabel: "METAR",
});
assert.equal(metarStillExpected.freshness_status, "expected_wait");
assert.equal(getMonitorFreshnessLevel(metarStillExpected, null), "aging");
const metarOld = buildObservationFreshness({
now,
observedAt: "2026-05-14T10:50:00Z",
sourceCode: "metar",
sourceLabel: "METAR",
});
assert.equal(metarOld.freshness_status, "stale");
assert.equal(getMonitorFreshnessLevel(metarOld, null), "stale");
assert.equal(
shouldRefreshMonitorCity({
detail: detail({ airport_current: { freshness: metarOld, obs_time: "10:50", temp: 20 } }),
now,
trigger: "interval",
}),
true,
);
assert.equal(
shouldRefreshMonitorCity({ detail: undefined, now, trigger: "interval" }),
true,
"missing city detail should always be fetched",
);
assert.equal(
shouldRefreshMonitorCity({
detail: detail({ airport_current: { obs_age_min: 5, obs_time: "11:55", temp: 20 } }),
now,
trigger: "interval",
}),
false,
"legacy METAR age under native cadence should not be force-refreshed every minute",
);
assert.equal(getMonitorRefreshCadenceMs(["amos", "metar"]), 60_000);
assert.equal(getMonitorRefreshCadenceMs(["metar"]), 300_000);
const amosDetail = detail({
airport_current: {
obs_age_min: 30,
obs_time: "11:30",
source_label: "METAR",
temp: 26,
},
amos: {
observation_time: "2026-05-14T11:59:00Z",
runway_obs: {
runway_pairs: [["18L", "36R"]],
temperatures: [[25.2, 18.1]],
},
source: "amos",
temp_source: "metar",
},
});
assert.equal(getObservationFreshness(amosDetail)?.source_code, "amos");
}