test(plan): integration test for the new Gantt view
Two tests against the live database and the seeded project: - loadPlan returns a section containing the seeded project. - GanttPlanView renders the project name and at least one card title to HTML. vitest integration config now picks up .test.tsx too.
This commit is contained in:
parent
5ff12a4ef0
commit
14f6c067c2
2 changed files with 74 additions and 1 deletions
73
tests/integration/plan-gantt.test.tsx
Normal file
73
tests/integration/plan-gantt.test.tsx
Normal file
|
|
@ -0,0 +1,73 @@
|
||||||
|
import { describe, it, expect, beforeAll } from "vitest";
|
||||||
|
import PocketBase from "pocketbase";
|
||||||
|
import { renderToStaticMarkup } from "react-dom/server";
|
||||||
|
|
||||||
|
import { GanttPlanView } from "@/components/roadmap/gantt-plan-view";
|
||||||
|
import { buildPlanSections } from "@/lib/roadmap/load";
|
||||||
|
import type {
|
||||||
|
CardRecord,
|
||||||
|
ClientRecord,
|
||||||
|
ColumnRecord,
|
||||||
|
ProjectRecord,
|
||||||
|
SubtaskRecord,
|
||||||
|
} from "@/lib/pb/types";
|
||||||
|
|
||||||
|
import { DEMO, adminPb, requireServices } from "./helpers";
|
||||||
|
|
||||||
|
let admin: PocketBase;
|
||||||
|
|
||||||
|
beforeAll(async () => {
|
||||||
|
await requireServices();
|
||||||
|
admin = await adminPb();
|
||||||
|
});
|
||||||
|
|
||||||
|
async function loadForProject(slug: string) {
|
||||||
|
const project = await admin
|
||||||
|
.collection("projects")
|
||||||
|
.getFirstListItem<ProjectRecord>(`slug = "${slug}"`);
|
||||||
|
|
||||||
|
const [clients, columns, cards, subtasks] = await Promise.all([
|
||||||
|
admin.collection("clients").getFullList<ClientRecord>(),
|
||||||
|
admin.collection("columns").getFullList<ColumnRecord>({ sort: "position" }),
|
||||||
|
admin
|
||||||
|
.collection("cards")
|
||||||
|
.getFullList<CardRecord>({ filter: `project = "${project.id}" && archived = false` }),
|
||||||
|
admin
|
||||||
|
.collection("subtasks")
|
||||||
|
.getFullList<SubtaskRecord>({
|
||||||
|
filter: `card.project = "${project.id}"`,
|
||||||
|
}),
|
||||||
|
]);
|
||||||
|
|
||||||
|
return buildPlanSections({
|
||||||
|
clients,
|
||||||
|
projects: [project],
|
||||||
|
columns,
|
||||||
|
cards,
|
||||||
|
subtasks,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe("/plan Gantt — seeded project loads", () => {
|
||||||
|
it("returns at least one section containing the seeded project", async () => {
|
||||||
|
const sections = await loadForProject(DEMO.projectSlug);
|
||||||
|
expect(sections.length).toBe(1);
|
||||||
|
expect(sections[0].project.slug).toBe(DEMO.projectSlug);
|
||||||
|
expect(sections[0].cards.length).toBeGreaterThan(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe("/plan Gantt — render", () => {
|
||||||
|
it("renders the project name and at least one card title", async () => {
|
||||||
|
const sections = await loadForProject(DEMO.projectSlug);
|
||||||
|
const html = renderToStaticMarkup(<GanttPlanView sections={sections} />);
|
||||||
|
|
||||||
|
expect(html).toContain(sections[0].project.name);
|
||||||
|
// Pick a card title that contains no characters React will escape
|
||||||
|
// (the seeded titles use ASCII letters and spaces only).
|
||||||
|
const safeTitle =
|
||||||
|
sections[0].cards.find((c) => /^[A-Z0-9 \-]+$/.test(c.title))?.title ??
|
||||||
|
sections[0].cards[0].title.slice(0, 10);
|
||||||
|
expect(html).toContain(safeTitle);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
@ -42,7 +42,7 @@ export default defineConfig({
|
||||||
test: {
|
test: {
|
||||||
name: "integration",
|
name: "integration",
|
||||||
environment: "node",
|
environment: "node",
|
||||||
include: ["tests/integration/**/*.test.ts"],
|
include: ["tests/integration/**/*.test.ts", "tests/integration/**/*.test.tsx"],
|
||||||
hookTimeout: 30_000,
|
hookTimeout: 30_000,
|
||||||
testTimeout: 30_000,
|
testTimeout: 30_000,
|
||||||
poolOptions: { forks: { singleFork: true } },
|
poolOptions: { forks: { singleFork: true } },
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue