81 lines
3.8 KiB
JavaScript
81 lines
3.8 KiB
JavaScript
import assert from "node:assert/strict";
|
|
import { dbRun, withTransaction } from "../server/db.mjs";
|
|
|
|
const api = process.env.AI_DRAMA_API_BASE || "http://127.0.0.1:8787";
|
|
const scope = {
|
|
"x-organization-id": "org-studio-lab",
|
|
"x-workspace-id": "ws-local-aidrama",
|
|
"x-project-id": "thunder-mouth"
|
|
};
|
|
|
|
async function request(path, options = {}) {
|
|
const response = await fetch(`${api}${path}`, {
|
|
...options,
|
|
headers: { "content-type": "application/json", ...(options.headers || {}) }
|
|
});
|
|
const payload = await response.json().catch(() => ({}));
|
|
return { response, payload };
|
|
}
|
|
|
|
const login = await request("/api/auth/login", {
|
|
method: "POST",
|
|
body: JSON.stringify({ email: "producer@local.test", password: "Demo@123456" })
|
|
});
|
|
assert.equal(login.response.ok, true, "catalog smoke login failed");
|
|
const headers = { authorization: `Bearer ${login.payload.session.token}`, ...scope };
|
|
let seasonId = "";
|
|
let episodeId = "";
|
|
|
|
try {
|
|
const catalog = await request("/api/production/catalog", { headers });
|
|
assert.equal(catalog.response.ok, true, "production catalog must be readable");
|
|
assert.ok(catalog.payload.catalog.seasons.length >= 1, "catalog must include at least one season");
|
|
assert.ok(catalog.payload.catalog.seasons[0].episodes.length >= 1, "catalog must include at least one episode");
|
|
|
|
const createdSeason = await request("/api/production/seasons", {
|
|
method: "POST",
|
|
headers,
|
|
body: JSON.stringify({ title: `Smoke Season ${Date.now()}` })
|
|
});
|
|
assert.equal(createdSeason.response.status, 201, "season creation must return 201");
|
|
seasonId = createdSeason.payload.season.id;
|
|
|
|
const createdEpisode = await request("/api/production/episodes", {
|
|
method: "POST",
|
|
headers,
|
|
body: JSON.stringify({ seasonId, title: "Smoke Episode" })
|
|
});
|
|
assert.equal(createdEpisode.response.status, 201, "episode creation must return 201");
|
|
episodeId = createdEpisode.payload.episode.id;
|
|
assert.equal(createdEpisode.payload.episode.shotCount, 1, "new episode must initialize one shot draft");
|
|
|
|
const graph = await request(`/api/production/graph?episodeId=${encodeURIComponent(episodeId)}`, { headers });
|
|
assert.equal(graph.response.ok, true, "episode graph must be readable");
|
|
assert.equal(graph.payload.graph.episode.id, episodeId, "graph must switch to requested episode");
|
|
assert.equal(graph.payload.graph.shots.length, 1, "new episode graph must contain starter shot");
|
|
assert.equal(graph.payload.graph.catalog.activeEpisodeId, episodeId, "catalog must reflect active episode");
|
|
|
|
const updated = await request(`/api/production/episodes/${encodeURIComponent(episodeId)}`, {
|
|
method: "PATCH",
|
|
headers,
|
|
body: JSON.stringify({ status: "production", hook: "Smoke hook" })
|
|
});
|
|
assert.equal(updated.response.ok, true, "episode update must succeed");
|
|
assert.equal(updated.payload.episode.status, "production", "episode status must persist");
|
|
console.log("production catalog smoke passed");
|
|
} finally {
|
|
if (seasonId) {
|
|
withTransaction(() => {
|
|
dbRun("DELETE FROM review_comments WHERE review_id IN (SELECT id FROM reviews WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?))", [episodeId]);
|
|
dbRun("DELETE FROM reviews WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?)", [episodeId]);
|
|
dbRun("DELETE FROM voice_lines WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?)", [episodeId]);
|
|
dbRun("DELETE FROM shot_versions WHERE shot_id IN (SELECT id FROM shots WHERE episode_id = ?)", [episodeId]);
|
|
dbRun("DELETE FROM shots WHERE episode_id = ?", [episodeId]);
|
|
dbRun("DELETE FROM script_documents WHERE episode_id = ?", [episodeId]);
|
|
dbRun("DELETE FROM episodes WHERE id = ?", [episodeId]);
|
|
dbRun("DELETE FROM seasons WHERE id = ?", [seasonId]);
|
|
dbRun("DELETE FROM audit_logs WHERE target_id IN (?, ?)", [seasonId, episodeId]);
|
|
});
|
|
}
|
|
}
|