feat(cyclones): publish explicit selection to shared context

This commit is contained in:
Kevin Rajan committed 2026-09-29 00:20:16 -05:00
1 parent e7707d9a0f
commit 28f3243090
5 files changed
+138 -3

No files matched your search

+71 -1
View File
@@ -338,7 +338,7 @@ test('a click on a storm card or lead-hour label selects that storm without pick
});
function harness(
feed = { getSnapshot: async () => snapshot() },
{ reducedMotion = false } = {},
{ reducedMotion = false, context = null } = {},
) {
const applied = [],
navigation = [],
@@ -368,6 +368,7 @@ function harness(
};
const layer = createCyclonesLayer({
feed,
context,
createRendering: () => rendering,
matchMedia: () => ({ matches: reducedMotion }),
openLink: (url) => opened.push(url),
@@ -401,6 +402,75 @@ function harness(
},
};
}
test('explicit cyclone selection publishes shared context without auto-claiming it', async () => {
let next = snapshot([storm(), storm('ep162026')]);
const records = new Map();
let selectedContext = null;
let selectedEvents = 0;
const context = {
registerEntityContext(entity, metadata) {
entity.__gevContextId = metadata.id;
const record = { ...metadata, entity };
records.set(metadata.id, record);
return record;
},
selectEntityContext(entity) {
selectedContext = records.get(entity.__gevContextId) || null;
selectedEvents += 1;
return selectedContext;
},
removeEntityContextsForLayer(layerId) {
for (const [id, record] of records) {
if (record.layerId === layerId) records.delete(id);
}
if (selectedContext?.layerId === layerId) selectedContext = null;
},
};
const h = harness({ getSnapshot: async () => next }, { context });
h.layer.enable();
await h.layer.update();
assert.equal(
selectedEvents,
0,
'the automatic first-storm row selection must not claim shared context',
);
assert.equal(records.size, 0);
h.layer.setParams({ stormId: 'ep162026' });
assert.equal(selectedEvents, 1);
assert.equal(selectedContext?.layerId, 'weather-cyclones');
assert.equal(selectedContext?.source, 'NOAA NHC / CPHC');
assert.equal(selectedContext?.label, 'Cyclone · Another system');
assert.equal(selectedContext?.latitude, 15.5);
assert.equal(selectedContext?.longitude, -125.8);
assert.equal(selectedContext?.properties.advisoryNumber, '10');
await h.layer.update();
assert.equal(
selectedEvents,
1,
'refresh updates the selected record without re-announcing the click',
);
next = snapshot([storm()]);
await h.layer.update();
assert.equal(
selectedContext,
null,
'a vanished user-selected storm must clear instead of transferring context to the fallback row',
);
assert.equal(records.size, 0);
h.layer.setParams({ stormId: 'ep152026' });
assert.equal(selectedEvents, 2);
h.layer.setParams({ clear: true });
assert.equal(selectedContext, null);
assert.equal(records.size, 0);
h.layer.destroy();
});
test('refresh preserves selection intent, including explicit clears and missing storms', async () => {
let next = snapshot([storm(), storm('ep162026')]);
const h = harness({ getSnapshot: async () => next });