Speichere individuelle Haar- und Augenfarben je Charakter
All checks were successful
Deploy to production / deploy (push) Successful in 2m24s
All checks were successful
Deploy to production / deploy (push) Successful in 2m24s
This commit is contained in:
81
backend/tools/characterAppearance.test.mjs
Normal file
81
backend/tools/characterAppearance.test.mjs
Normal file
@@ -0,0 +1,81 @@
|
||||
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();
|
||||
}
|
||||
});
|
||||
Reference in New Issue
Block a user