feat(map): add universal subject and station search
This commit is contained in:
@@ -75,5 +75,5 @@ test("facet tree selection focuses the subject without resetting a compatible de
|
||||
assert.match(renderer, /heading: camera\.heading/);
|
||||
assert.match(renderer, /pitch: camera\.pitch/);
|
||||
assert.match(renderer, /roll: camera\.roll/);
|
||||
assert.match(renderer, /duration: 2\.1/);
|
||||
assert.match(renderer, /duration: 0\.45/);
|
||||
});
|
||||
|
||||
@@ -0,0 +1,103 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import { buildMapSearchIndex, searchMapSubjects } from "../apps/catalog/src/mapSearch.mjs";
|
||||
|
||||
const now = "2026-07-25T08:00:00.000Z";
|
||||
const point = (sourceId, semanticType, attributes) => ({
|
||||
sourceId,
|
||||
semanticType,
|
||||
observedAt: now,
|
||||
receivedAt: now,
|
||||
attributes,
|
||||
geometry: { type: "Point", coordinates: [37.62, 55.75] },
|
||||
presentationStatus: "active",
|
||||
});
|
||||
const profile = {
|
||||
id: "map.subject.v1",
|
||||
title: "Транспорт",
|
||||
semanticTypes: ["map.moving_object"],
|
||||
label: { mode: "attributes", fields: ["display_name"] },
|
||||
};
|
||||
|
||||
test("search index uses stable identity, label and explicit field projection only", () => {
|
||||
const index = buildMapSearchIndex({
|
||||
runtimeBindings: [{
|
||||
bindingId: "vehicles",
|
||||
presentationProfileId: profile.id,
|
||||
facts: [point("unit-42", "map.moving_object", {
|
||||
display_name: "Трайк 42",
|
||||
tracker_id: "tracker-77",
|
||||
raw_secret: "must-not-be-indexed",
|
||||
})],
|
||||
}],
|
||||
bindingConfigs: [{
|
||||
id: "vehicles",
|
||||
fieldProjection: ["display_name", "tracker_id"],
|
||||
presentationProfileId: profile.id,
|
||||
}],
|
||||
presentationProfiles: [profile],
|
||||
});
|
||||
|
||||
assert.equal(searchMapSubjects(index, "Трайк").at(0)?.sourceId, "unit-42");
|
||||
assert.equal(searchMapSubjects(index, "tracker-77").at(0)?.sourceId, "unit-42");
|
||||
assert.equal(searchMapSubjects(index, "unit-42").at(0)?.sourceId, "unit-42");
|
||||
assert.deepEqual(searchMapSubjects(index, "must-not-be-indexed"), []);
|
||||
});
|
||||
|
||||
test("authorized joined aspect augments primary subject without creating a second entity", () => {
|
||||
const index = buildMapSearchIndex({
|
||||
runtimeBindings: [
|
||||
{
|
||||
bindingId: "vehicles",
|
||||
presentationProfileId: profile.id,
|
||||
facts: [point("unit-42", "map.moving_object", { display_name: "Трайк 42" })],
|
||||
},
|
||||
{
|
||||
bindingId: "identity",
|
||||
facts: [point("unit-42", "map.moving_object", {
|
||||
imei: "867236078012345",
|
||||
provider_payload: "forbidden",
|
||||
})],
|
||||
},
|
||||
],
|
||||
bindingConfigs: [
|
||||
{ id: "vehicles", fieldProjection: ["display_name"], presentationProfileId: profile.id },
|
||||
{
|
||||
id: "identity",
|
||||
joinToBindingId: "vehicles",
|
||||
fieldProjection: ["imei"],
|
||||
dataClass: "restricted",
|
||||
},
|
||||
],
|
||||
presentationProfiles: [profile],
|
||||
});
|
||||
|
||||
assert.equal(index.length, 1);
|
||||
assert.equal(searchMapSubjects(index, "867236078012345").at(0)?.entityId, "nodedc-runtime:vehicles:map.moving_object:unit-42");
|
||||
assert.deepEqual(searchMapSubjects(index, "forbidden"), []);
|
||||
});
|
||||
|
||||
test("reference subjects remain searchable by profile labels without a provider branch", () => {
|
||||
const stationProfile = {
|
||||
id: "map.reference.station.v1",
|
||||
title: "Метро",
|
||||
semanticTypes: ["map.station"],
|
||||
label: { mode: "attributes", fields: ["name", "official_name"] },
|
||||
};
|
||||
const index = buildMapSearchIndex({
|
||||
runtimeBindings: [{
|
||||
bindingId: "reference.metro",
|
||||
presentationProfileId: stationProfile.id,
|
||||
facts: [point("osm.node.1", "map.station", {
|
||||
name: "Петроградская",
|
||||
provider_note: "not searchable",
|
||||
})],
|
||||
}],
|
||||
presentationProfiles: [stationProfile],
|
||||
});
|
||||
|
||||
assert.equal(searchMapSubjects(index, "петрог").at(0)?.title, "Петроградская");
|
||||
assert.equal(searchMapSubjects(index, "osm.node.1").at(0)?.groupTitle, "Метро");
|
||||
assert.deepEqual(searchMapSubjects(index, "provider_note"), []);
|
||||
});
|
||||
Reference in New Issue
Block a user