feat(#82): implement Personality Module
- Add Personality model to Prisma schema with FormalityLevel enum - Create migration and seed with 6 default personalities - Implement CRUD API with TDD approach (97.67% coverage) * PersonalitiesService: findAll, findOne, findDefault, create, update, remove * PersonalitiesController: REST endpoints with auth guards * Comprehensive test coverage (21 passing tests) - Add Personality types to shared package - Create frontend components: * PersonalitySelector: dropdown for choosing personality * PersonalityPreview: preview personality style and system prompt * PersonalityForm: create/edit personalities with validation * Settings page: manage personalities with CRUD operations - Integrate with Ollama API: * Support personalityId in chat endpoint * Auto-inject system prompt from personality * Fall back to default personality if not specified - API client for frontend personality management All tests passing with 97.67% backend coverage (exceeds 85% requirement)
This commit is contained in:
93
apps/web/src/components/domains/DomainList.test.tsx
Normal file
93
apps/web/src/components/domains/DomainList.test.tsx
Normal file
@@ -0,0 +1,93 @@
|
||||
import { describe, it, expect, vi } from "vitest";
|
||||
import { render, screen } from "@testing-library/react";
|
||||
import { DomainList } from "./DomainList";
|
||||
import type { Domain } from "@mosaic/shared";
|
||||
|
||||
describe("DomainList", () => {
|
||||
const mockDomains: Domain[] = [
|
||||
{
|
||||
id: "domain-1",
|
||||
workspaceId: "workspace-1",
|
||||
name: "Work",
|
||||
slug: "work",
|
||||
description: "Work-related tasks",
|
||||
color: "#3B82F6",
|
||||
icon: "💼",
|
||||
sortOrder: 0,
|
||||
metadata: {},
|
||||
createdAt: new Date("2026-01-28"),
|
||||
updatedAt: new Date("2026-01-28"),
|
||||
},
|
||||
{
|
||||
id: "domain-2",
|
||||
workspaceId: "workspace-1",
|
||||
name: "Personal",
|
||||
slug: "personal",
|
||||
description: "Personal tasks and projects",
|
||||
color: "#10B981",
|
||||
icon: "🏠",
|
||||
sortOrder: 1,
|
||||
metadata: {},
|
||||
createdAt: new Date("2026-01-28"),
|
||||
updatedAt: new Date("2026-01-28"),
|
||||
},
|
||||
];
|
||||
|
||||
it("should render empty state when no domains", () => {
|
||||
render(<DomainList domains={[]} isLoading={false} />);
|
||||
expect(screen.getByText(/no domains created yet/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render loading state", () => {
|
||||
render(<DomainList domains={[]} isLoading={true} />);
|
||||
expect(screen.getByText(/loading domains/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should render domains list", () => {
|
||||
render(<DomainList domains={mockDomains} isLoading={false} />);
|
||||
expect(screen.getByText("Work")).toBeInTheDocument();
|
||||
expect(screen.getByText("Personal")).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should call onEdit when edit button clicked", () => {
|
||||
const onEdit = vi.fn();
|
||||
render(
|
||||
<DomainList
|
||||
domains={mockDomains}
|
||||
isLoading={false}
|
||||
onEdit={onEdit}
|
||||
/>
|
||||
);
|
||||
|
||||
const editButtons = screen.getAllByRole("button", { name: /edit/i });
|
||||
editButtons[0].click();
|
||||
expect(onEdit).toHaveBeenCalledWith(mockDomains[0]);
|
||||
});
|
||||
|
||||
it("should call onDelete when delete button clicked", () => {
|
||||
const onDelete = vi.fn();
|
||||
render(
|
||||
<DomainList
|
||||
domains={mockDomains}
|
||||
isLoading={false}
|
||||
onDelete={onDelete}
|
||||
/>
|
||||
);
|
||||
|
||||
const deleteButtons = screen.getAllByRole("button", { name: /delete/i });
|
||||
deleteButtons[0].click();
|
||||
expect(onDelete).toHaveBeenCalledWith(mockDomains[0]);
|
||||
});
|
||||
|
||||
it("should handle undefined domains gracefully", () => {
|
||||
// @ts-expect-error Testing error state
|
||||
render(<DomainList domains={undefined} isLoading={false} />);
|
||||
expect(screen.getByText(/no domains created yet/i)).toBeInTheDocument();
|
||||
});
|
||||
|
||||
it("should handle null domains gracefully", () => {
|
||||
// @ts-expect-error Testing error state
|
||||
render(<DomainList domains={null} isLoading={false} />);
|
||||
expect(screen.getByText(/no domains created yet/i)).toBeInTheDocument();
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user