mirror of
https://github.com/bilawalsidhu/gods-eye-view.git
synced 2026-11-12 06:12:18 +00:00
Pin that a zero air-quality reading and a missing one give different cards
This commit is contained in:
1 parent
b29e20632b
commit
b62f60482e
1 file changed
+95
@@ -0,0 +1,95 @@
|
|||||||
|
import test from 'node:test';
|
||||||
|
import assert from 'node:assert/strict';
|
||||||
|
import {
|
||||||
|
AIR_QUALITY_BANDS,
|
||||||
|
AIR_QUALITY_UNKNOWN_COLOR,
|
||||||
|
airQualityColor,
|
||||||
|
normalizeAqhiObservations,
|
||||||
|
normalizeAqhiStations,
|
||||||
|
readingsInView,
|
||||||
|
} from './model.js';
|
||||||
|
|
||||||
|
const NOW = Date.parse('2026-01-02T12:00:00Z');
|
||||||
|
const OBSERVED = '2026-01-02T11:00:00Z';
|
||||||
|
|
||||||
|
const stationFeature = (id, lon) => ({
|
||||||
|
geometry: { coordinates: [lon, 50] },
|
||||||
|
properties: { location_id: id, location_name_en: `Station ${id}` },
|
||||||
|
});
|
||||||
|
const observation = (id, aqhi) => ({
|
||||||
|
properties: { location_id: id, aqhi, observation_datetime: OBSERVED },
|
||||||
|
});
|
||||||
|
|
||||||
|
const IDS = ['zero', 'missing', 'blank', 'b3', 'b4', 'b6', 'b7', 'b10', 'b11'];
|
||||||
|
const stations = normalizeAqhiStations({
|
||||||
|
features: IDS.map((id, index) => stationFeature(id, -100 + index)),
|
||||||
|
});
|
||||||
|
|
||||||
|
test('edge:air-quality: a zero reading and a missing one give different cards', () => {
|
||||||
|
const readings = normalizeAqhiObservations(
|
||||||
|
{
|
||||||
|
features: [
|
||||||
|
observation('zero', 0),
|
||||||
|
observation('missing', null),
|
||||||
|
observation('blank', ''),
|
||||||
|
],
|
||||||
|
},
|
||||||
|
stations,
|
||||||
|
NOW,
|
||||||
|
);
|
||||||
|
// Zero is a real low reading, published on ECCC's floor of 1.
|
||||||
|
assert.deepEqual(
|
||||||
|
readings.map(({ id, value, band, label }) => ({ id, value, band, label })),
|
||||||
|
[{ id: 'eccc:zero', value: 1, band: 'low', label: '1' }],
|
||||||
|
);
|
||||||
|
assert.equal(readings[0].color, AIR_QUALITY_BANDS[0].color);
|
||||||
|
// A station that reported nothing never becomes a confident "AQHI 1" row.
|
||||||
|
const card = readingsInView(readings, null).map((reading) => reading.id);
|
||||||
|
assert.deepEqual(card, ['eccc:zero']);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('edge:air-quality: IDs and colour-band boundaries are fixed by the model', () => {
|
||||||
|
const values = { b3: 3, b4: 4, b6: 6, b7: 7, b10: 10, b11: 11 };
|
||||||
|
const readings = normalizeAqhiObservations(
|
||||||
|
{
|
||||||
|
features: Object.entries(values).map(([id, value]) =>
|
||||||
|
observation(id, value),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
stations,
|
||||||
|
NOW,
|
||||||
|
);
|
||||||
|
const byId = Object.fromEntries(readings.map((row) => [row.id, row]));
|
||||||
|
const expected = {
|
||||||
|
'eccc:b3': ['low', '3'],
|
||||||
|
'eccc:b4': ['moderate', '4'],
|
||||||
|
'eccc:b6': ['moderate', '6'],
|
||||||
|
'eccc:b7': ['high', '7'],
|
||||||
|
'eccc:b10': ['high', '10'],
|
||||||
|
'eccc:b11': ['very-high', '10+'],
|
||||||
|
};
|
||||||
|
assert.deepEqual(
|
||||||
|
Object.keys(byId).toSorted(),
|
||||||
|
Object.keys(expected).toSorted(),
|
||||||
|
);
|
||||||
|
for (const [id, [band, label]] of Object.entries(expected)) {
|
||||||
|
assert.equal(byId[id].band, band, id);
|
||||||
|
assert.equal(byId[id].label, label, id);
|
||||||
|
// Both renderers take the colour from the reading itself.
|
||||||
|
assert.equal(byId[id].color, airQualityColor(band), id);
|
||||||
|
assert.notEqual(byId[id].color, AIR_QUALITY_UNKNOWN_COLOR, id);
|
||||||
|
}
|
||||||
|
// A second normalization of the same response is identical.
|
||||||
|
assert.deepEqual(
|
||||||
|
normalizeAqhiObservations(
|
||||||
|
{
|
||||||
|
features: Object.entries(values).map(([id, value]) =>
|
||||||
|
observation(id, value),
|
||||||
|
),
|
||||||
|
},
|
||||||
|
stations,
|
||||||
|
NOW,
|
||||||
|
),
|
||||||
|
readings,
|
||||||
|
);
|
||||||
|
});
|
||||||
Reference in new issue
Block a user