185 lines
6.4 KiB
JavaScript
185 lines
6.4 KiB
JavaScript
const test = require('node:test');
|
|
const assert = require('node:assert/strict');
|
|
const Database = require('better-sqlite3');
|
|
|
|
const characterLibraryService = require('../src/services/characterLibraryService');
|
|
const sceneLibraryService = require('../src/services/sceneLibraryService');
|
|
const propLibraryService = require('../src/services/propLibraryService');
|
|
|
|
const log = {
|
|
info() {},
|
|
warn() {},
|
|
error() {},
|
|
};
|
|
|
|
function createDb() {
|
|
const db = new Database(':memory:');
|
|
db.exec(`
|
|
CREATE TABLE dramas (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
title TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
|
|
CREATE TABLE characters (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
drama_id INTEGER NOT NULL,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
description TEXT,
|
|
appearance TEXT,
|
|
image_url TEXT,
|
|
local_path TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
|
|
CREATE TABLE scenes (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
drama_id INTEGER NOT NULL,
|
|
location TEXT,
|
|
time TEXT,
|
|
prompt TEXT,
|
|
image_url TEXT,
|
|
local_path TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
|
|
CREATE TABLE props (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
drama_id INTEGER NOT NULL,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
type TEXT,
|
|
description TEXT,
|
|
prompt TEXT,
|
|
image_url TEXT,
|
|
local_path TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
|
|
CREATE TABLE character_libraries (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
drama_id INTEGER,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
category TEXT,
|
|
image_url TEXT,
|
|
local_path TEXT,
|
|
description TEXT,
|
|
tags TEXT,
|
|
source_type TEXT,
|
|
source_id TEXT,
|
|
created_at TEXT,
|
|
updated_at TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
|
|
CREATE TABLE scene_libraries (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
drama_id INTEGER,
|
|
location TEXT NOT NULL DEFAULT '',
|
|
time TEXT,
|
|
prompt TEXT,
|
|
description TEXT,
|
|
image_url TEXT,
|
|
local_path TEXT,
|
|
category TEXT,
|
|
tags TEXT,
|
|
source_type TEXT,
|
|
source_id TEXT,
|
|
created_at TEXT,
|
|
updated_at TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
|
|
CREATE TABLE prop_libraries (
|
|
id INTEGER PRIMARY KEY AUTOINCREMENT,
|
|
drama_id INTEGER,
|
|
name TEXT NOT NULL DEFAULT '',
|
|
description TEXT,
|
|
prompt TEXT,
|
|
image_url TEXT,
|
|
local_path TEXT,
|
|
category TEXT,
|
|
tags TEXT,
|
|
source_type TEXT,
|
|
source_id TEXT,
|
|
created_at TEXT,
|
|
updated_at TEXT,
|
|
deleted_at TEXT
|
|
);
|
|
`);
|
|
db.prepare('INSERT INTO dramas (id, title) VALUES (1, ?)').run('Test drama');
|
|
return db;
|
|
}
|
|
|
|
function countRows(db, table, where) {
|
|
return db.prepare(`SELECT COUNT(*) AS count FROM ${table} WHERE ${where}`).get().count;
|
|
}
|
|
|
|
test('adding the same character to drama and material libraries is idempotent', () => {
|
|
const db = createDb();
|
|
db.prepare(
|
|
'INSERT INTO characters (id, drama_id, name, description, image_url, local_path) VALUES (1, 1, ?, ?, ?, ?)'
|
|
).run('Hero', 'original', '/static/projects/hero.png', 'projects/hero.png');
|
|
|
|
const firstDrama = characterLibraryService.addCharacterToLibrary(db, log, 1);
|
|
db.prepare('UPDATE characters SET name = ?, description = ? WHERE id = 1').run('Hero updated', 'updated');
|
|
const secondDrama = characterLibraryService.addCharacterToLibrary(db, log, 1);
|
|
const firstMaterial = characterLibraryService.addCharacterToMaterialLibrary(db, log, 1);
|
|
const secondMaterial = characterLibraryService.addCharacterToMaterialLibrary(db, log, 1);
|
|
|
|
assert.equal(firstDrama.item.id, secondDrama.item.id);
|
|
assert.equal(firstMaterial.item.id, secondMaterial.item.id);
|
|
assert.equal(countRows(db, 'character_libraries', 'drama_id = 1 AND deleted_at IS NULL'), 1);
|
|
assert.equal(countRows(db, 'character_libraries', 'drama_id IS NULL AND deleted_at IS NULL'), 1);
|
|
assert.equal(secondDrama.item.name, 'Hero updated');
|
|
assert.equal(
|
|
db.prepare('SELECT source_id FROM character_libraries WHERE id = ?').get(secondDrama.item.id).source_id,
|
|
'1'
|
|
);
|
|
});
|
|
|
|
test('adding the same scene to drama and material libraries is idempotent', () => {
|
|
const db = createDb();
|
|
db.prepare(
|
|
'INSERT INTO scenes (id, drama_id, location, time, prompt, image_url, local_path) VALUES (1, 1, ?, ?, ?, ?, ?)'
|
|
).run('Village', 'day', 'quiet street', '/static/projects/village.png', 'projects/village.png');
|
|
|
|
const firstDrama = sceneLibraryService.addSceneToLibrary(db, log, 1);
|
|
db.prepare('UPDATE scenes SET location = ?, prompt = ? WHERE id = 1').run('Village updated', 'busy street');
|
|
const secondDrama = sceneLibraryService.addSceneToLibrary(db, log, 1);
|
|
const firstMaterial = sceneLibraryService.addSceneToMaterialLibrary(db, log, 1);
|
|
const secondMaterial = sceneLibraryService.addSceneToMaterialLibrary(db, log, 1);
|
|
|
|
assert.equal(firstDrama.item.id, secondDrama.item.id);
|
|
assert.equal(firstMaterial.item.id, secondMaterial.item.id);
|
|
assert.equal(countRows(db, 'scene_libraries', 'drama_id = 1 AND deleted_at IS NULL'), 1);
|
|
assert.equal(countRows(db, 'scene_libraries', 'drama_id IS NULL AND deleted_at IS NULL'), 1);
|
|
assert.equal(secondDrama.item.location, 'Village updated');
|
|
assert.equal(
|
|
db.prepare('SELECT source_id FROM scene_libraries WHERE id = ?').get(secondDrama.item.id).source_id,
|
|
'1'
|
|
);
|
|
});
|
|
|
|
test('adding the same prop to drama and material libraries is idempotent', () => {
|
|
const db = createDb();
|
|
db.prepare(
|
|
'INSERT INTO props (id, drama_id, name, description, prompt, image_url, local_path) VALUES (1, 1, ?, ?, ?, ?, ?)'
|
|
).run('Sword', 'old blade', 'silver sword', '/static/projects/sword.png', 'projects/sword.png');
|
|
|
|
const firstDrama = propLibraryService.addPropToLibrary(db, log, 1);
|
|
db.prepare('UPDATE props SET name = ?, description = ? WHERE id = 1').run('Sword updated', 'polished blade');
|
|
const secondDrama = propLibraryService.addPropToLibrary(db, log, 1);
|
|
const firstMaterial = propLibraryService.addPropToMaterialLibrary(db, log, 1);
|
|
const secondMaterial = propLibraryService.addPropToMaterialLibrary(db, log, 1);
|
|
|
|
assert.equal(firstDrama.item.id, secondDrama.item.id);
|
|
assert.equal(firstMaterial.item.id, secondMaterial.item.id);
|
|
assert.equal(countRows(db, 'prop_libraries', 'drama_id = 1 AND deleted_at IS NULL'), 1);
|
|
assert.equal(countRows(db, 'prop_libraries', 'drama_id IS NULL AND deleted_at IS NULL'), 1);
|
|
assert.equal(secondDrama.item.name, 'Sword updated');
|
|
assert.equal(
|
|
db.prepare('SELECT source_id FROM prop_libraries WHERE id = ?').get(secondDrama.item.id).source_id,
|
|
'1'
|
|
);
|
|
});
|