mirror of
https://gitlab.com/PronounsPage/PronounsPage.git
synced 2025-09-26 14:32:04 -04:00

- Adds a new test suite with Docker-based smoke tests for all locales. Can be run using the ./smoketest.sh script. - Replaces all calls to Math.random() with a new helper that returns 0.5 in snapshot testing mode, ensuring deterministic snapshots. - Similarly replaces all calls to new Date() and Date.now() with new helpers that return a fixed date in snapshot testing mode. - Replaces checks against NODE_ENV with APP_ENV, to ensure that the bundles can be built with Nuxt for testing without losing code that would otherwise be stripped out by production optimizations. - Adds a database init script that can be used to initialize the database with a single admin user and a long-lived JWT token for use in automation tests. - Adds a JWT decoding/encoding CLI tool for debugging JWTs. Note: Snapshots are not checked in, and must be generated manually. See test/__snapshots__/.gitignore for more information.
70 lines
2.7 KiB
JavaScript
70 lines
2.7 KiB
JavaScript
import './setup.ts';
|
|
|
|
import { newDate, isGrantedForUser } from '../src/helpers.ts';
|
|
|
|
import dbConnection from './db.ts';
|
|
import mailer from './mailer.ts';
|
|
|
|
const shouldNotify = (frequency) => {
|
|
if (frequency === 0) {
|
|
return false;
|
|
}
|
|
|
|
if (frequency === 7) {
|
|
return newDate().getDay() === 6; // Saturdays
|
|
}
|
|
|
|
return true;
|
|
};
|
|
|
|
async function notify() {
|
|
const db = await dbConnection();
|
|
|
|
const awaitingModeration = [
|
|
...await db.all('SELECT \'nouns\' as type, locale, count(*) as c FROM nouns WHERE approved = 0 AND deleted=0 GROUP BY locale'),
|
|
...await db.all('SELECT \'inclusive\' as type, locale, count(*) as c FROM inclusive WHERE approved = 0 AND deleted=0 GROUP BY locale'),
|
|
...await db.all('SELECT \'terms\' as type, locale, count(*) as c FROM terms WHERE approved = 0 AND deleted=0 GROUP BY locale'),
|
|
...await db.all('SELECT \'sources\' as type, locale, count(*) as c FROM sources WHERE approved = 0 AND deleted=0 GROUP BY locale'),
|
|
...await db.all('SELECT \'names\' as type, locale, count(*) as c FROM names WHERE approved = 0 AND deleted=0 GROUP BY locale'),
|
|
...await db.all('SELECT \'translations\' as type, locale, count(*) as c FROM translations WHERE status = 0 OR status = 1 GROUP BY locale'),
|
|
...await db.all('SELECT \'reports\' as type, null as locale, count(*) as c FROM reports WHERE isHandled = 0'),
|
|
...await db.all('SELECT \'ban-proposals\' as type, null as locale, (SELECT count(*) FROM ban_proposals p LEFT JOIN users u ON p.userId = u.id WHERE u.bannedBy IS NULL) as c'),
|
|
].filter((r) => r.c > 0);
|
|
if (!awaitingModeration.length) {
|
|
console.log('No entries awaiting moderation');
|
|
return;
|
|
}
|
|
|
|
const admins = await db.all('SELECT email, roles, adminNotifications FROM users WHERE roles != \'\'');
|
|
|
|
const awaitingModerationGrouped = {};
|
|
let count = 0;
|
|
for (const m of awaitingModeration) {
|
|
for (const admin of admins) {
|
|
if (isGrantedForUser(admin, m.locale, m.type) && shouldNotify(admin.adminNotifications)) {
|
|
if (awaitingModerationGrouped[admin.email] === undefined) {
|
|
awaitingModerationGrouped[admin.email] = {};
|
|
}
|
|
awaitingModerationGrouped[admin.email][`${m.locale || '*'}-${m.type}`] = m.c;
|
|
}
|
|
}
|
|
count += m.c;
|
|
}
|
|
|
|
console.log('Entries awaiting moderation: ', count);
|
|
|
|
for (const email in awaitingModerationGrouped) {
|
|
if (!Object.hasOwn(awaitingModerationGrouped, email)) {
|
|
continue;
|
|
}
|
|
const stats = awaitingModerationGrouped[email];
|
|
console.log('Sending email:', email, stats);
|
|
|
|
mailer(email, 'notify', { stats });
|
|
}
|
|
|
|
await db.close();
|
|
}
|
|
|
|
notify();
|