quality: web debt batch (tests runner, FireContainer, rate-limit, maps, i18n)

Independent-of-prod quality debt from PENDIENTE.md §2:

- test: migrate broken Jest -> meteortesting:mocha. Tests rewritten to chai +
  Meteor 3 async APIs, moved to test/server/ (server-only). test/server/
  00-setup.test.js re-runs the collection2/accounts init that `meteor test`
  skips (no server/main.js). New comments method + mediaAnalyzers coverage.
  Dropped rest.test.js (removed meteor/http; covered by smoke/). 36 passing.
- fix: scope FireContainer read by the URL _id on the archive route instead of
  a selector-less FiresCollection.findOne() (imports/ui/pages/Fires/Fires.js).
- feat: rate-limit abusable publications via rateLimitSubscriptions (fireFrom*
  and comments.forReference 5/1000ms; geo subs 10/1000ms).
- perf: append loading=async to the Google Maps loader URL (Gkeys.js).
- deps: meteor-accounts-t9n 2.0 -> 2.6 (no gl build -> keep gl->es fallback,
  documented); add 3 missing gl/common.json keys (0 missing now).
- deps: drop jest/babel/enzyme, add chai.
This commit is contained in:
vjrj 2026-07-21 22:59:06 +02:00
parent bc778bfd97
commit 6b6f02d92d
27 changed files with 602 additions and 7042 deletions

View file

@ -290,7 +290,22 @@ const FireContainer = withTracker(({ match }) => {
// console.log(`Type of '${fireType}' fire, active: ${active}, archive: ${archive}, fromHash: ${fromHash}`);
// console.log(`Subs ready: ${subscription.ready()}, fire: ${JSON.stringify(FiresCollection.findOne())}`);
const loading = !subscription.ready();
const notfound = !loading && FiresCollection.find().count() === 0;
// Scope the client-side read to the fire named in the URL. Only the archive
// route's param is a Fires `_id` (as 24-char hex, per hexId()); active/alert
// params are ActiveFire/Alert ids and hash is an encrypted blob, so their
// publications each put exactly one Fires doc in minimongo and an empty
// selector is the correct read. Scoping archive by _id stops a lingering doc
// from a previously-viewed fire being returned by a selector-less findOne().
let selector = {};
if (archive && id) {
try {
selector = new Meteor.Collection.ObjectID(id);
} catch (e) {
selector = {};
}
}
const fire = FiresCollection.findOne(selector);
const notfound = !loading && !fire;
/* console.log(`loading fire: ${loading}`);
* console.log(`Not found fire: ${notfound}`); */
const falsePositives = FalsePositivesCollection.find().fetch().map(falsePositivesRemap);
@ -302,9 +317,9 @@ const FireContainer = withTracker(({ match }) => {
fromHash,
falsePositives,
industries,
fire: FiresCollection.findOne(),
fire,
notfound,
when: subscription.ready() && FiresCollection.findOne() ? FiresCollection.findOne().when : null
when: fire ? fire.when : null
};
})(Fire);