82 lines
4.7 KiB
JavaScript
82 lines
4.7 KiB
JavaScript
import assert from 'node:assert/strict';
|
|
import test from 'node:test';
|
|
import { Sequelize, DataTypes } from 'sequelize';
|
|
import migration from '../migrations-active/20261104000001-add-character-appearance.cjs';
|
|
import developmentMigration from '../migrations-active/20261104000000-add-character-development-ages.cjs';
|
|
|
|
// Only the explicitly supplied disposable database may be changed.
|
|
test('appearance migration persists colors for existing characters, Sequelize and raw daemon inserts', {
|
|
skip: !process.env.TEST_DATABASE_URL,
|
|
}, async () => {
|
|
const db = new Sequelize(process.env.TEST_DATABASE_URL, { logging: false });
|
|
try {
|
|
const [[{ name }]] = await db.query('SELECT current_database() AS name');
|
|
assert.equal(name, 'yourpart_development_test', 'Use the isolated development test database');
|
|
await db.query(`
|
|
DROP SCHEMA IF EXISTS falukant_data CASCADE;
|
|
CREATE SCHEMA falukant_data;
|
|
CREATE TABLE falukant_data.character (
|
|
id SERIAL PRIMARY KEY, gender TEXT, health INT DEFAULT 100,
|
|
hair_color VARCHAR(7), updated_at TIMESTAMPTZ DEFAULT NOW()
|
|
);
|
|
INSERT INTO falukant_data.character (gender, hair_color)
|
|
VALUES ('female', '#AbC123'), ('male', NULL);
|
|
`);
|
|
const qi = db.getQueryInterface();
|
|
await developmentMigration.up(qi);
|
|
const [developmentBefore] = await db.query('SELECT id, health, puberty_start_age, fertile_from_age, updated_at FROM falukant_data.character ORDER BY id');
|
|
await migration.up(qi);
|
|
const [developmentAfter] = await db.query('SELECT id, health, puberty_start_age, fertile_from_age, updated_at FROM falukant_data.character ORDER BY id');
|
|
assert.deepEqual(developmentAfter, developmentBefore, 'Existing character development remains intact');
|
|
const [before] = await db.query('SELECT * FROM falukant_data.character ORDER BY id');
|
|
assert.equal(before[0].hair_color, '#AbC123', 'Keep manually prepared values');
|
|
for (const row of before) {
|
|
assert.match(row.hair_color, /^#[0-9a-fA-F]{6}$/);
|
|
assert.match(row.eye_color, /^#[0-9a-fA-F]{6}$/);
|
|
}
|
|
await migration.up(qi);
|
|
await db.query(`UPDATE falukant_data.character SET hair_color = NULL, eye_color = NULL`);
|
|
const [after] = await db.query('SELECT * FROM falukant_data.character ORDER BY id');
|
|
assert.deepEqual(after, before, 'Repeated migrations and omitted colors keep existing assignments');
|
|
|
|
// NPCs and newborns created with raw Rust SQL also get stable colors.
|
|
const [generated] = await db.query(`INSERT INTO falukant_data.character (gender)
|
|
SELECT CASE WHEN i % 2 = 0 THEN 'female' ELSE 'male' END
|
|
FROM generate_series(1, 1000) i RETURNING hair_color, eye_color`);
|
|
assert.equal(new Set(generated.map(c => c.hair_color)).size, 7);
|
|
assert.equal(new Set(generated.map(c => c.eye_color)).size, 6);
|
|
assert.ok(generated.every(c => /^#[0-9a-fA-F]{6}$/.test(c.hair_color) && /^#[0-9a-fA-F]{6}$/.test(c.eye_color)));
|
|
|
|
const Character = db.define('AppearanceTestCharacter', {
|
|
id: { type: DataTypes.INTEGER, primaryKey: true, autoIncrement: true },
|
|
gender: DataTypes.STRING,
|
|
hairColor: { type: DataTypes.STRING(7), field: 'hair_color' },
|
|
eyeColor: { type: DataTypes.STRING(7), field: 'eye_color' },
|
|
}, { schema: 'falukant_data', tableName: 'character', timestamps: false });
|
|
const character = await Character.create({ gender: 'female', eyeColor: '#123456' });
|
|
assert.match(character.hairColor, /^#[0-9a-fA-F]{6}$/);
|
|
assert.equal(character.eyeColor, '#123456');
|
|
const assigned = character.hairColor;
|
|
await character.update({ gender: 'male' });
|
|
await character.reload();
|
|
assert.equal(character.hairColor, assigned);
|
|
await character.update({ hairColor: '#654321' });
|
|
await character.reload();
|
|
assert.equal(character.hairColor, '#654321');
|
|
assert.equal(character.eyeColor, '#123456');
|
|
for (const color of ['red', '#fff', '#12345z', '']) {
|
|
await assert.rejects(db.query('UPDATE falukant_data.character SET eye_color = :color WHERE id = 1', {
|
|
replacements: { color },
|
|
}));
|
|
}
|
|
|
|
const [[{ count: oldCount }]] = await db.query('SELECT count(*)::int FROM falukant_data.character');
|
|
await migration.down(qi);
|
|
const [[{ count: newCount }]] = await db.query('SELECT count(*)::int FROM falukant_data.character');
|
|
assert.equal(newCount, oldCount, 'Rollback retains characters');
|
|
await migration.up(qi);
|
|
} finally {
|
|
await db.close();
|
|
}
|
|
});
|