Add sortOrder column to diagrams, extend PATCH endpoint with projectId and sortOrder fields, add POST /diagrams/reorder bulk endpoint with ownership verification and duplicate ID validation. Enhance RecentList with lastAiMessage preview subtitle. Implement @dnd-kit drag-and-drop in ProjectTree sidebar with cross-project moves, intra-project reorder, optimistic updates, drag overlay, drop indicators, and keyboard/pointer sensor support. Context-aware GET ordering: sortOrder for project views, updatedAt for recent/all views. 141 tests pass. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
114 lines
2.9 KiB
TypeScript
114 lines
2.9 KiB
TypeScript
import { describe, it, expect } from "vitest";
|
|
|
|
import {
|
|
insertDiagramSchema,
|
|
selectDiagramSchema,
|
|
insertProjectSchema,
|
|
selectProjectSchema,
|
|
} from "@turbostarter/db/schema";
|
|
|
|
describe("insertDiagramSchema", () => {
|
|
it("should accept valid diagram insert data", () => {
|
|
const result = insertDiagramSchema.safeParse({
|
|
title: "Test Diagram",
|
|
type: "flowchart",
|
|
userId: "user-123",
|
|
});
|
|
expect(result.success).toBe(true);
|
|
});
|
|
|
|
it("should reject missing required fields", () => {
|
|
const result = insertDiagramSchema.safeParse({});
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("should reject invalid diagram type", () => {
|
|
const result = insertDiagramSchema.safeParse({
|
|
title: "Test",
|
|
type: "invalid-type",
|
|
userId: "user-123",
|
|
});
|
|
expect(result.success).toBe(false);
|
|
});
|
|
|
|
it("should accept all valid diagram types", () => {
|
|
const types = ["bpmn", "er", "orgchart", "architecture", "sequence", "flowchart"];
|
|
for (const type of types) {
|
|
const result = insertDiagramSchema.safeParse({
|
|
title: "Test",
|
|
type,
|
|
userId: "user-123",
|
|
});
|
|
expect(result.success).toBe(true);
|
|
}
|
|
});
|
|
|
|
it("should accept optional fields", () => {
|
|
const result = insertDiagramSchema.safeParse({
|
|
title: "Test",
|
|
type: "bpmn",
|
|
userId: "user-123",
|
|
projectId: "proj-123",
|
|
lastAiMessage: "Hello",
|
|
graphData: { nodes: [] },
|
|
});
|
|
expect(result.success).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("selectDiagramSchema", () => {
|
|
it("should accept a complete diagram record", () => {
|
|
const result = selectDiagramSchema.safeParse({
|
|
id: "diag-123",
|
|
title: "Test Diagram",
|
|
type: "er",
|
|
graphData: {},
|
|
userId: "user-123",
|
|
projectId: null,
|
|
sortOrder: 0,
|
|
lastAiMessage: null,
|
|
deletedAt: null,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
});
|
|
expect(result.success).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("insertProjectSchema", () => {
|
|
it("should accept valid project insert data with field assertions", () => {
|
|
const result = insertProjectSchema.safeParse({
|
|
name: "My Project",
|
|
userId: "user-123",
|
|
});
|
|
expect(result.success).toBe(true);
|
|
if (result.success) {
|
|
expect(result.data.name).toBe("My Project");
|
|
expect(result.data.userId).toBe("user-123");
|
|
}
|
|
});
|
|
|
|
it("should accept optional sortOrder", () => {
|
|
const result = insertProjectSchema.safeParse({
|
|
name: "My Project",
|
|
userId: "user-123",
|
|
sortOrder: 5,
|
|
});
|
|
expect(result.success).toBe(true);
|
|
});
|
|
});
|
|
|
|
describe("selectProjectSchema", () => {
|
|
it("should accept a complete project record", () => {
|
|
const result = selectProjectSchema.safeParse({
|
|
id: "proj-123",
|
|
name: "My Project",
|
|
userId: "user-123",
|
|
sortOrder: 0,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
});
|
|
expect(result.success).toBe(true);
|
|
});
|
|
});
|