130 lines
3.1 KiB
TypeScript
130 lines
3.1 KiB
TypeScript
import { describe, expect, it } from "vitest";
|
|
|
|
import type { ProjectResponse } from "@/lib/api/types";
|
|
import {
|
|
filterProjects,
|
|
formatProjectUpdatedAt,
|
|
pendingReviewCount,
|
|
} from "./projects";
|
|
|
|
const projects: ProjectResponse[] = [
|
|
{
|
|
id: "1",
|
|
title: "逐光而行",
|
|
genre: "玄幻",
|
|
logline: "少年逆袭",
|
|
premise: null,
|
|
theme: "抗争",
|
|
selling_points: [],
|
|
structure: null,
|
|
updated_at: "2026-06-27T10:00:00Z",
|
|
pending_review_count: 0,
|
|
},
|
|
{
|
|
id: "2",
|
|
title: "城南旧案",
|
|
genre: null,
|
|
logline: "悬疑调查",
|
|
premise: null,
|
|
theme: null,
|
|
selling_points: [],
|
|
structure: null,
|
|
updated_at: "2026-06-28T08:00:00Z",
|
|
pending_review_count: 2,
|
|
},
|
|
{
|
|
id: "3",
|
|
title: "星港来信",
|
|
genre: "科幻",
|
|
logline: "远航与归乡",
|
|
premise: null,
|
|
theme: null,
|
|
selling_points: [],
|
|
structure: null,
|
|
updated_at: "2026-06-26T09:00:00Z",
|
|
pending_review_count: 1,
|
|
},
|
|
];
|
|
|
|
describe("filterProjects", () => {
|
|
it("searches title, genre, logline and theme", () => {
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "悬疑",
|
|
filter: "all",
|
|
sort: "title",
|
|
}).map((p) => p.title),
|
|
).toEqual(["城南旧案"]);
|
|
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "抗争",
|
|
filter: "all",
|
|
sort: "title",
|
|
}).map((p) => p.title),
|
|
).toEqual(["逐光而行"]);
|
|
});
|
|
|
|
it("filters by categorization state", () => {
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "",
|
|
filter: "with_genre",
|
|
sort: "title",
|
|
}),
|
|
).toHaveLength(2);
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "",
|
|
filter: "uncategorized",
|
|
sort: "title",
|
|
}).map((p) => p.title),
|
|
).toEqual(["城南旧案"]);
|
|
});
|
|
|
|
it("filters projects waiting for review", () => {
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "",
|
|
filter: "pending_review",
|
|
sort: "title",
|
|
}).map((p) => p.title),
|
|
).toEqual(["城南旧案", "星港来信"]);
|
|
});
|
|
|
|
it("sorts by recently edited first", () => {
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "",
|
|
filter: "all",
|
|
sort: "updated_at",
|
|
}).map((p) => p.title),
|
|
).toEqual(["城南旧案", "逐光而行", "星港来信"]);
|
|
});
|
|
|
|
it("sorts by genre with title fallback", () => {
|
|
expect(
|
|
filterProjects(projects, {
|
|
search: "",
|
|
filter: "all",
|
|
sort: "genre",
|
|
}).map((p) => p.title),
|
|
).toEqual(["星港来信", "逐光而行", "城南旧案"]);
|
|
});
|
|
});
|
|
|
|
describe("project metadata helpers", () => {
|
|
it("normalizes pending review count", () => {
|
|
expect(pendingReviewCount(projects[1]!)).toBe(2);
|
|
expect(pendingReviewCount({ ...projects[1]!, pending_review_count: -1 })).toBe(0);
|
|
});
|
|
|
|
it("formats updated_at with a fallback", () => {
|
|
expect(formatProjectUpdatedAt(null)).toBe("暂无编辑记录");
|
|
expect(formatProjectUpdatedAt("bad")).toBe("暂无编辑记录");
|
|
expect(formatProjectUpdatedAt("2026-06-28T08:00:00Z")).not.toBe(
|
|
"暂无编辑记录",
|
|
);
|
|
});
|
|
});
|