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
This commit is contained in:
parent
39415808bf
commit
296dab4f38
18 changed files with 539 additions and 4 deletions
96
smoke/seed.js
Normal file
96
smoke/seed.js
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
/*
|
||||
* 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/ }));
|
||||
Loading…
Add table
Add a link
Reference in a new issue