feat(task-005): complete article intake dashboard detail flow
This commit is contained in:
@@ -0,0 +1,63 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import ts from "typescript";
|
||||
|
||||
const testDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const sourcePath = path.resolve(
|
||||
testDir,
|
||||
"../src/features/article-dashboard/model.ts",
|
||||
);
|
||||
const source = readFileSync(sourcePath, "utf8");
|
||||
const compiled = ts.transpileModule(source, {
|
||||
compilerOptions: { module: ts.ModuleKind.CommonJS, target: ts.ScriptTarget.ES2022 },
|
||||
});
|
||||
|
||||
const moduleExports = {};
|
||||
new Function("exports", compiled.outputText)(moduleExports);
|
||||
|
||||
const { buildDashboardRows } = moduleExports;
|
||||
|
||||
const rows = buildDashboardRows(
|
||||
[
|
||||
{
|
||||
id: "11111111-1111-1111-1111-111111111111",
|
||||
target_site_id: "22222222-2222-2222-2222-222222222222",
|
||||
status: "ARTICLE_BRIEF_CREATED",
|
||||
publishing_status: "PUBLISH_NOT_STARTED",
|
||||
brief_description: "Build AI article intake shell",
|
||||
working_title: "AI Intake Shell",
|
||||
language: "en",
|
||||
content_type: "longform_guide",
|
||||
primary_keyword: "AI workflow",
|
||||
assigned_editor_id: null,
|
||||
created_at: "2025-01-01T00:00:00Z",
|
||||
updated_at: "2025-01-01T00:00:00Z",
|
||||
},
|
||||
],
|
||||
[
|
||||
{
|
||||
id: "22222222-2222-2222-2222-222222222222",
|
||||
name: "Editorial site",
|
||||
slug: "editorial-site",
|
||||
publishing_type: "git_next",
|
||||
default_language: "en",
|
||||
brand_voice: "Balanced",
|
||||
audience: "Editor teams",
|
||||
seo_rules: {},
|
||||
visual_rules: {},
|
||||
source_rules: {},
|
||||
publishing_rules: {},
|
||||
active_script_config_version_id: null,
|
||||
created_at: "2025-01-01T00:00:00Z",
|
||||
updated_at: "2025-01-01T00:00:00Z",
|
||||
},
|
||||
],
|
||||
);
|
||||
|
||||
assert.equal(rows.length, 1, "one row should be built");
|
||||
assert.equal(rows[0].targetSiteName, "Editorial site", "target site name should map");
|
||||
assert.equal(rows[0].nextAction, "Create plan", "next action should match status mapping");
|
||||
assert.equal(rows[0].assignedEditor, "Unassigned", "missing editor id should render Unassigned");
|
||||
@@ -0,0 +1,45 @@
|
||||
import assert from "node:assert/strict";
|
||||
import { readFileSync } from "node:fs";
|
||||
import path from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
import ts from "typescript";
|
||||
|
||||
const testDir = path.dirname(fileURLToPath(import.meta.url));
|
||||
const sourcePath = path.resolve(
|
||||
testDir,
|
||||
"../src/features/article-intake/model.ts",
|
||||
);
|
||||
const source = readFileSync(sourcePath, "utf8");
|
||||
const compiled = ts.transpileModule(source, {
|
||||
compilerOptions: {
|
||||
module: ts.ModuleKind.CommonJS,
|
||||
target: ts.ScriptTarget.ES2022,
|
||||
},
|
||||
});
|
||||
|
||||
const moduleExports = {};
|
||||
new Function("exports", compiled.outputText)(moduleExports);
|
||||
|
||||
const validateArticleDraft = moduleExports.validateArticleDraft;
|
||||
const initialDraft = moduleExports.initialDraft;
|
||||
|
||||
const draft = {
|
||||
targetSiteId: "",
|
||||
briefDescription: "Keep this text intact",
|
||||
workingTitle: "",
|
||||
contentType: "longform_guide",
|
||||
primaryKeyword: "",
|
||||
};
|
||||
|
||||
const errors = validateArticleDraft(draft);
|
||||
assert.ok(errors.targetSiteId, "validation should require target site");
|
||||
|
||||
assert.equal(
|
||||
draft.briefDescription,
|
||||
"Keep this text intact",
|
||||
"brief description value should remain in form state when validation fails",
|
||||
);
|
||||
|
||||
const fallbackDraft = initialDraft([]);
|
||||
assert.equal(fallbackDraft.contentType, "longform_guide", "default content type preserved");
|
||||
Reference in New Issue
Block a user