- 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)
128 lines
3.3 KiB
TypeScript
128 lines
3.3 KiB
TypeScript
import { describe, it, expect, vi } from "vitest";
|
|
import { render, screen } from "@testing-library/react";
|
|
import userEvent from "@testing-library/user-event";
|
|
import { DomainSelector } from "./DomainSelector";
|
|
import type { Domain } from "@mosaic/shared";
|
|
|
|
describe("DomainSelector", () => {
|
|
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: null,
|
|
color: "#10B981",
|
|
icon: null,
|
|
sortOrder: 1,
|
|
metadata: {},
|
|
createdAt: new Date("2026-01-28"),
|
|
updatedAt: new Date("2026-01-28"),
|
|
},
|
|
];
|
|
|
|
it("should render with default placeholder", () => {
|
|
const onChange = vi.fn();
|
|
render(
|
|
<DomainSelector domains={mockDomains} value={null} onChange={onChange} />
|
|
);
|
|
expect(screen.getByText("Select a domain")).toBeInTheDocument();
|
|
});
|
|
|
|
it("should render with custom placeholder", () => {
|
|
const onChange = vi.fn();
|
|
render(
|
|
<DomainSelector
|
|
domains={mockDomains}
|
|
value={null}
|
|
onChange={onChange}
|
|
placeholder="Choose domain"
|
|
/>
|
|
);
|
|
expect(screen.getByText("Choose domain")).toBeInTheDocument();
|
|
});
|
|
|
|
it("should render all domains as options", () => {
|
|
const onChange = vi.fn();
|
|
render(
|
|
<DomainSelector domains={mockDomains} value={null} onChange={onChange} />
|
|
);
|
|
expect(screen.getByText("💼 Work")).toBeInTheDocument();
|
|
expect(screen.getByText("Personal")).toBeInTheDocument();
|
|
});
|
|
|
|
it("should call onChange when selection changes", async () => {
|
|
const user = userEvent.setup();
|
|
const onChange = vi.fn();
|
|
|
|
render(
|
|
<DomainSelector domains={mockDomains} value={null} onChange={onChange} />
|
|
);
|
|
|
|
const select = screen.getByRole("combobox");
|
|
await user.selectOptions(select, "domain-1");
|
|
|
|
expect(onChange).toHaveBeenCalledWith("domain-1");
|
|
});
|
|
|
|
it("should call onChange with null when cleared", async () => {
|
|
const user = userEvent.setup();
|
|
const onChange = vi.fn();
|
|
|
|
render(
|
|
<DomainSelector
|
|
domains={mockDomains}
|
|
value="domain-1"
|
|
onChange={onChange}
|
|
/>
|
|
);
|
|
|
|
const select = screen.getByRole("combobox");
|
|
await user.selectOptions(select, "");
|
|
|
|
expect(onChange).toHaveBeenCalledWith(null);
|
|
});
|
|
|
|
it("should show selected value", () => {
|
|
const onChange = vi.fn();
|
|
render(
|
|
<DomainSelector
|
|
domains={mockDomains}
|
|
value="domain-1"
|
|
onChange={onChange}
|
|
/>
|
|
);
|
|
|
|
const select = screen.getByRole("combobox") as HTMLSelectElement;
|
|
expect(select.value).toBe("domain-1");
|
|
});
|
|
|
|
it("should apply custom className", () => {
|
|
const onChange = vi.fn();
|
|
render(
|
|
<DomainSelector
|
|
domains={mockDomains}
|
|
value={null}
|
|
onChange={onChange}
|
|
className="custom-class"
|
|
/>
|
|
);
|
|
|
|
const select = screen.getByRole("combobox");
|
|
expect(select.className).toContain("custom-class");
|
|
});
|
|
});
|