43 lines
3.0 KiB
TypeScript
43 lines
3.0 KiB
TypeScript
import { test } from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { randomUUID } from 'node:crypto';
|
|
import { mkdtemp, readFile, rm } from 'node:fs/promises';
|
|
import { tmpdir } from 'node:os';
|
|
import { join, resolve, sep } from 'node:path';
|
|
import { BSON, MongoClient } from 'mongodb';
|
|
import { cleanupLegacyData } from '../scripts/cleanup-legacy-data.js';
|
|
|
|
test('legacy cleanup backs up removed data, preserves current data and is repeatable', { skip: !process.env.TEST_MONGODB_URI }, async () => {
|
|
const client = await new MongoClient(process.env.TEST_MONGODB_URI!).connect();
|
|
const db = client.db(`dragon_ball_test_cleanup_${randomUUID().replaceAll('-', '')}`);
|
|
const directory = await mkdtemp(join(tmpdir(), 'dragon-ball-cleanup-'));
|
|
try {
|
|
const date = new Date();
|
|
await db.collection('matches').insertOne({ endedAt: date });
|
|
await db.collection('players').insertOne({ firstMatchAt: date, firstVisitAt: date, guestTokenHash: 'keep-identity' });
|
|
await db.collection('analytics_events').insertMany([{ eventType: 'match_started' }, { eventType: 'page_view' }, { eventType: 'game_finished', source: 'client' }]);
|
|
await db.collection('analytics_presence_samples').insertMany([{ connected: 2 }, { source: 'activity_reports', active: 1 }]);
|
|
for (const name of ['game_sessions', 'rooms', 'analytics_sessions', 'analytics_metadata']) await db.collection(name).insertOne({ keep: true });
|
|
const before = await cleanupLegacyData(db);
|
|
assert.equal(before.applied, false); assert.deepEqual(before.counts, { matches: 1, events: 1, samples: 1, playerFields: 1 });
|
|
assert.equal(await db.collection('matches').countDocuments(), 1);
|
|
const path = join(directory, 'backup.ejson');
|
|
await cleanupLegacyData(db, path);
|
|
const backup = BSON.EJSON.parse(await readFile(path, 'utf8'));
|
|
assert.equal(+backup.matches[0].endedAt, +date); assert.equal(backup.players.length, 1);
|
|
assert.equal((await db.listCollections({ name: 'matches' }).toArray()).length, 0);
|
|
assert.equal(await db.collection('analytics_events').countDocuments(), 2);
|
|
assert.equal(await db.collection('analytics_presence_samples').countDocuments(), 1);
|
|
const player = await db.collection('players').findOne();
|
|
assert.equal(player?.firstMatchAt, undefined); assert.equal(player?.guestTokenHash, 'keep-identity'); assert.equal(+player!.firstVisitAt, +date);
|
|
for (const name of ['game_sessions', 'rooms', 'analytics_sessions', 'analytics_metadata']) assert.equal(await db.collection(name).countDocuments({ keep: true }), 1);
|
|
const again = await cleanupLegacyData(db, join(directory, 'second.ejson'));
|
|
assert.deepEqual(again.counts, { matches: 0, events: 0, samples: 0, playerFields: 0 });
|
|
await assert.rejects(cleanupLegacyData(db, path), { code: 'EEXIST' });
|
|
} finally {
|
|
await db.dropDatabase(); await client.close();
|
|
assert.ok(resolve(directory).startsWith(resolve(tmpdir()) + sep + 'dragon-ball-cleanup-'));
|
|
await rm(directory, { recursive: true });
|
|
}
|
|
});
|