Files
Haven/test/importAuthors.test.js

64 lines
3.2 KiB
JavaScript

'use strict';
// Imported Discord messages belong to no Haven account (#5771): earlier
// imports are moved over once, and the admin who imported them is not
// suddenly shown them all as unread.
const assert = require('node:assert/strict');
const fs = require('node:fs');
const path = require('node:path');
const test = require('node:test');
const Database = require('better-sqlite3');
const { migrateImportedAuthors } = require('../src/importAuthors');
function freshDb() {
const db = new Database(':memory:');
db.exec(`
CREATE TABLE server_settings (key TEXT PRIMARY KEY, value TEXT);
CREATE TABLE users (id INTEGER PRIMARY KEY, username TEXT);
CREATE TABLE channels (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE messages (id INTEGER PRIMARY KEY AUTOINCREMENT, channel_id INTEGER, user_id INTEGER, content TEXT, imported_from TEXT);
CREATE TABLE read_positions (user_id INTEGER, channel_id INTEGER, last_read_message_id INTEGER NOT NULL DEFAULT 0, PRIMARY KEY (user_id, channel_id));
`);
db.prepare('INSERT INTO users (id, username) VALUES (1, ?), (2, ?)').run('admin', 'bob');
db.prepare('INSERT INTO channels (id, name) VALUES (10, ?), (11, ?)').run('imported', 'native');
const add = db.prepare('INSERT INTO messages (channel_id, user_id, content, imported_from) VALUES (?, ?, ?, ?)');
add.run(10, 1, 'from discord', 'discord');
add.run(10, 1, 'from discord again', 'discord');
add.run(11, 2, 'native', null);
add.run(10, 2, 'native reply in the imported channel', null);
return db;
}
test('imported messages lose the importing admin; native messages keep their author', () => {
const db = freshDb();
migrateImportedAuthors(db);
const rows = db.prepare('SELECT content, user_id FROM messages ORDER BY id').all();
assert.deepEqual(rows.map(r => r.user_id), [null, null, 2, 2]);
});
test('the importing admin has the imported channel read up to the import, not further', () => {
const db = freshDb();
db.prepare('INSERT INTO read_positions (user_id, channel_id, last_read_message_id) VALUES (1, 10, 1)').run();
migrateImportedAuthors(db);
assert.equal(db.prepare('SELECT last_read_message_id AS n FROM read_positions WHERE user_id = 1 AND channel_id = 10').get().n, 2);
// Nobody else gets a read position out of it.
assert.equal(db.prepare('SELECT COUNT(*) AS n FROM read_positions WHERE user_id = 2').get().n, 0);
});
test('it runs once', () => {
const db = freshDb();
migrateImportedAuthors(db);
db.prepare("INSERT INTO messages (channel_id, user_id, content, imported_from) VALUES (10, 1, 'later', 'discord')").run();
migrateImportedAuthors(db);
assert.equal(db.prepare("SELECT user_id FROM messages WHERE content = 'later'").get().user_id, 1);
});
test('new imports are stored with no account, and unread counts include account-less messages', () => {
const importRoute = fs.readFileSync(path.join(__dirname, '..', 'src', 'routes', 'import.js'), 'utf8');
assert.match(importRoute, /INSERT OR IGNORE INTO messages \(channel_id, user_id, content,[^)]*\)\s*VALUES \(\?, NULL,/);
const handlers = fs.readFileSync(path.join(__dirname, '..', 'src', 'socketHandlers', 'index.js'), 'utf8');
assert.match(handlers, /AND \(user_id IS NULL OR user_id != \?\) AND thread_id IS NULL /);
});