// ── api.onUserDeleting (MODULE_API 1.20.0, ACCOUNT_DELETION.md AD10) ─────── // // Registration and collection only; what the deletion does with the hook is in // accountDeletion.test.js. Each test builds a throwaway modules directory and // re-requires the loader, as moduleLoader.test.js does. process.env.DB_HOST = '127.0.0.1' process.env.DB_PORT = '59999' const fs = require('fs') const os = require('os') const path = require('path') const { test, after } = require('node:test') const assert = require('node:assert/strict') const express = require('express') const db = require('../src/utils/db') const registries = require('../src/modules/registries') after(() => db.close()) const emptyTiers = () => ({ public: express.Router(), admin: express.Router(), player: express.Router() }) function loadOne(server) { const root = fs.mkdtempSync(path.join(os.tmpdir(), 'rg-deleting-')) const dir = path.join(root, 'rust') fs.mkdirSync(dir) fs.writeFileSync(path.join(dir, 'module.json'), JSON.stringify({ id: 'rust', name: 'Rust', version: '1.0.0', coreApi: '^1.20.0', server: 'index.js', mounts: { admin: ['/rust'] }, })) fs.writeFileSync(path.join(dir, 'index.js'), server) process.env.MODULES_DIR = root registries._reset() delete require.cache[require.resolve('../src/modules/loader')] // eslint-disable-next-line global-require const loader = require('../src/modules/loader') loader.load(emptyTiers()) return loader } const stateOf = (loader) => loader.list().find((m) => m.id === 'rust') test('onUserDeleting is collected once the module is started, and not before', async () => { const loader = loadOne(`module.exports = (ctx, api) => { api.registerRoutes({ admin: { '/rust': ctx.express.Router() } }) api.onUserDeleting(async (p) => { global.__deleting = p }) }`) assert.equal(stateOf(loader).state, 'registered') // A registered module has not booted: it holds no link it could undo yet. assert.deepEqual(loader.userDeletingHooks(), []) loader.setState('rust', 'started') const hooks = loader.userDeletingHooks() assert.deepEqual(hooks.map((h) => h.id), ['rust']) await hooks[0].hook({ userId: 7, deletedBy: 'self' }) assert.deepEqual(global.__deleting, { userId: 7, deletedBy: 'self' }) delete global.__deleting loader.setState('rust', 'disabled') assert.deepEqual(loader.userDeletingHooks(), []) }) test('a module that registers no hook adds nothing', () => { const loader = loadOne(`module.exports = (ctx, api) => { api.registerRoutes({ admin: { '/rust': ctx.express.Router() } }) }`) loader.setState('rust', 'started') assert.deepEqual(loader.userDeletingHooks(), []) }) test('onUserDeleting twice, or with no function, is a registration error', () => { for (const [body, expected] of [ ['api.onUserDeleting(() => {}); api.onUserDeleting(() => {})', /onUserDeleting\(\) called twice/], ['api.onUserDeleting("later")', /onUserDeleting: expected a function/], ]) { const loader = loadOne(`module.exports = (ctx, api) => { api.registerRoutes({ admin: { '/rust': ctx.express.Router() } }) ${body} }`) assert.equal(stateOf(loader).state, 'startup_failed') assert.match(stateOf(loader).reason, expected) } })