todos-contra-el-fuego-web/smoke/seed.js
vjrj 296dab4f38 smoke: REST API regression harness + baseline snapshots (Meteor 1.6.1.1)
Adds a standalone Node smoke test (smoke/) that exercises every REST endpoint
consumed by the Flutter app against a seeded local dev server and compares
responses to committed snapshots. This is the safety net for the Meteor upgrade:
it must stay byte-identical after every escala.

- smoke/seed.js: deterministic Mongo seed (fixed ObjectIds, geo indexes)
- smoke/run.js: calls endpoints, normalizes volatile fields, diffs snapshots
- smoke/smoke.sh: seed + run wrapper
- smoke/snapshots/: baseline captured on Meteor 1.6.1.1
- IPGeocoder.js: degrade gracefully when MaxMind DB absent (dev boot)
- settings-development.json: dev-only internalApiToken to enable the REST API
- .meteorignore: exclude smoke/ from the Meteor server build
2026-07-13 19:42:55 +02:00

96 lines
3.7 KiB
JavaScript

/*
* Deterministic seed for the REST smoke test.
* Run against the local Mongo used by the dev Meteor server, e.g.:
* docker exec -i tcef-mongo32 mongo fuegos < smoke/seed.js
*
* It resets the collections the REST API reads/writes to a fixed, known state
* so that endpoint responses are reproducible across Meteor upgrade escalas.
* Only test-owned documents are touched.
*/
// --- Fixed identifiers (24-hex ObjectIds) -------------------------------
var FIRE_A = ObjectId('a0000000000000000000000a');
var FIRE_B = ObjectId('b0000000000000000000000b');
var ARCHIVE_FIRE = ObjectId('c0000000000000000000000c');
var MOBILE_TOKEN = 'smoke-mobile-token';
// Madrid-ish coordinates
var LAT = 40.41;
var LON = -3.70;
var WHEN = ISODate('2024-01-01T00:00:00.000Z');
var WHEN_B = ISODate('2024-01-02T00:00:00.000Z'); // later, so last-fire-detected is deterministic
var FIXED = ISODate('2024-01-01T00:00:00.000Z');
// --- activefires --------------------------------------------------------
db.activefires.deleteMany({});
db.activefires.insertMany([
{
_id: FIRE_A,
ourid: { type: 'Point', coordinates: [LON, LAT] },
lat: LAT, lon: LON, type: 'viirs', when: WHEN,
scan: 0.5, track: 0.4, acq_date: '2024-01-01', acq_time: '00:00',
satellite: 'N', confidence: 50, version: '1.0NRT', frp: 4.3,
daynight: 'N', bright_ti4: 330.2, bright_ti5: 291,
createdAt: FIXED, updatedAt: FIXED
},
{
_id: FIRE_B,
ourid: { type: 'Point', coordinates: [LON + 0.02, LAT + 0.02] },
lat: LAT + 0.02, lon: LON + 0.02, type: 'viirs', when: WHEN_B,
scan: 0.5, track: 0.4, acq_date: '2024-01-01', acq_time: '00:05',
satellite: 'N', confidence: 60, version: '1.0NRT', frp: 6.1,
daynight: 'N', bright_ti4: 331.0, bright_ti5: 292,
createdAt: FIXED, updatedAt: FIXED
}
]);
db.activefires.createIndex({ ourid: '2dsphere' });
// --- fires (archive) — must match the sealed fire used by mobile/falsepositive
db.fires.deleteMany({});
db.fires.insertOne({
_id: ARCHIVE_FIRE,
ourid: { type: 'Point', coordinates: [LON, LAT] },
lat: LAT, lon: LON, type: 'viirs', when: WHEN,
scan: 0.5, track: 0.4, address: 'Madrid, Spain',
createdAt: FIXED, updatedAt: FIXED
});
db.fires.createIndex({ ourid: '2dsphere' });
// --- falsePositives / industries: empty so "real fire" counting is stable
db.falsePositives.deleteMany({});
db.industries.deleteMany({});
db.industries.createIndex({ geo: '2dsphere' });
// --- subscriptions: clean; index for geo queries
db.subscriptions.deleteMany({});
db.subscriptions.createIndex({ geo: '2dsphere' });
// --- siteSettings consumed by status endpoints --------------------------
db.siteSettings.deleteMany({ name: { $in: ['last-fire-check', 'subs-public-union', 'subs-public-union-bounds'] } });
db.siteSettings.insertMany([
{ _id: ObjectId('51e00000000000000000000c'), name: 'last-fire-check', value: FIXED, createdAt: FIXED, updatedAt: FIXED },
{
_id: ObjectId('51e0000000000000000000a1'),
name: 'subs-public-union',
value: JSON.stringify({
type: 'Feature',
geometry: {
type: 'MultiPolygon',
coordinates: [[[[LON - 1, LAT - 1], [LON + 1, LAT - 1], [LON + 1, LAT + 1], [LON - 1, LAT + 1], [LON - 1, LAT - 1]]]]
}
}),
createdAt: FIXED, updatedAt: FIXED
},
{
_id: ObjectId('51e0000000000000000000b2'),
name: 'subs-public-union-bounds',
value: JSON.stringify({ ne: { lat: LAT + 1, lon: LON + 1 }, sw: { lat: LAT - 1, lon: LON - 1 } }),
createdAt: FIXED, updatedAt: FIXED
}
]);
// --- users: remove any previous smoke user so mobile/users creates fresh
db.users.deleteMany({ fireBaseToken: MOBILE_TOKEN });
print('seed OK: activefires=' + db.activefires.count() + ' fires=' + db.fires.count() + ' siteSettings=' + db.siteSettings.count({ name: /fire|union/ }));