Files
MicrOBU/microbu-esp32c5/tools/v2x2map-0.3.0/bridge/tests/dashboard-vam.cjs
T
Ashin Walpola 0e9525162d Keep the colleague's microbu-esp32c5 tree in this repository
obu-firmware builds against vanetza-idf from microbu-esp32c5/external, but
that tree was gitignored, so a clone of this repository could not build the
firmware it ships. It is now committed here as ordinary files in its own
folder, microbu-esp32c5/: the colleague's commit cf4b99f plus the V2X2MAP
bridge's signature verification (--trust) used on the bench. Nothing is
fetched from or pushed to the colleague's repository; this repository and
its remotes carry everything. The folder's own .gitignore keeps build output,
downloaded components and private key material out, as it did there; the
committed file set is identical to that repository's tracked files.

The ESP32-C5 is still flashed from obu-firmware/, which only takes
vanetza-idf from microbu-esp32c5/, so the two stay separate folders.
FLASHING.md says how to take a newer version of the colleague's tree (copy
it over the folder, rebuild, test, commit).
2026-09-23 17:46:40 +02:00

47 lines
2.3 KiB
JavaScript

// TEST-V2X2MAP-VAM-002: exercise the dashboard's actual rendering functions.
const fs = require('node:fs');
const vm = require('node:vm');
const assert = require('node:assert/strict');
const html = fs.readFileSync(require('node:path').join(__dirname, '../dashboard.html'), 'utf8');
const script = html.split('<script>')[1].split('</script>')[0];
new vm.Script(script); // Syntax-check the entire dashboard, not only VAM code.
const slice = (a, b) => script.slice(script.indexOf(a), script.indexOf(b));
const context = vm.createContext({assert, console});
vm.runInContext(slice('const MSG =', '// ─── Map') +
slice('const vehicles ', 'setInterval(()=>{') +
slice('const filterActive=', 'document.querySelectorAll(\'.fchip\')') +
slice('function buildSummary(', 'function etCls('), context);
vm.runInContext(`
const map = {setView() {}};
const L = {
divIcon: x => x,
marker: () => ({addTo() {return this}, bindPopup() {}, on() {},
setLatLng() {}, setIcon() {}, isPopupOpen: () => false})
};
const frame = {msg_type:'VAM', station_id:'1234', lat:53.9, lon:10,
speed_mps:5, heading_deg:90, station_type_label:'cyclist',
vam:{station_id:42, station_type:2, generation_delta_time:65535,
speed_mps:5, altitude_m:12.3, longitudinal_acceleration_mps2:-0.5,
containers:{test:'<img src=x onerror=alert(1)>'}}};
onPositionFrame(frame);
onPositionFrame({...frame, lat:54});
assert.equal(vehicles.size, 1);
const marker = [...vehicles.values()][0];
assert.equal(marker.count, 2);
const popup = popupHtml(marker);
for (const text of ['Vulnerable road user (VAM)', '65535', '18.0 km/h', '12.3 m', '-0.5 m/s²', 'VAM containers'])
assert.ok(popup.includes(text), text);
assert.ok(!popup.includes('<img'));
assert.ok(popup.includes('&lt;img'));
const noValues = popupHtml({lastFrame:{...frame, vam:{station_id:0,station_type:2,generation_delta_time:0}},count:1,lastMs:0});
assert.ok(!noValues.includes('undefined'));
assert.ok(!noValues.includes('NaN'));
assert.ok(isVisible('VAM'));
filterActive.delete('VAM');
assert.ok(!isVisible('VAM'));
assert.ok(isVisible('CAM'));
assert.ok(buildSummary({lastFrame:frame,msgType:'VAM',frameCount:1}).includes('65535'));
assert.ok(buildSummary({lastFrame:{vam_status:'invalid VAM'},msgType:'VAM',frameCount:1}).includes('invalid VAM'));
console.log('PASS: VAM map updates, popups, unavailable fields, escaping, filters and log');
`, context);