- Add PromptFormatterService for formatting system prompts based on personality - Support context variable interpolation (userName, workspaceName, etc.) - Add formality level modifiers (VERY_CASUAL to VERY_FORMAL) - Add template validation for custom variables - Add preview endpoint for formatted prompts - Fix UpdatePersonalityDto to avoid @nestjs/mapped-types dependency - Update PersonalitiesController with new endpoints - Add comprehensive tests (33 passing tests) Closes #82
140 lines
5.0 KiB
TypeScript
140 lines
5.0 KiB
TypeScript
import { describe, it, expect, beforeEach, vi } from "vitest";
|
|
import { Test, TestingModule } from "@nestjs/testing";
|
|
import { PersonalitiesController } from "./personalities.controller";
|
|
import { PersonalitiesService } from "./personalities.service";
|
|
import { PromptFormatterService } from "./services/prompt-formatter.service";
|
|
import { AuthGuard } from "../auth/guards/auth.guard";
|
|
|
|
describe("PersonalitiesController", () => {
|
|
let controller: PersonalitiesController;
|
|
let service: PersonalitiesService;
|
|
let promptFormatter: PromptFormatterService;
|
|
|
|
const mockWorkspaceId = "workspace-123";
|
|
const mockPersonalityId = "personality-123";
|
|
const mockRequest = { user: { id: "user-123" }, workspaceId: mockWorkspaceId };
|
|
|
|
const mockPersonality = {
|
|
id: mockPersonalityId,
|
|
workspaceId: mockWorkspaceId,
|
|
name: "Professional",
|
|
tone: "professional",
|
|
formalityLevel: "FORMAL",
|
|
systemPromptTemplate: "You are a professional assistant.",
|
|
isDefault: true,
|
|
isActive: true,
|
|
createdAt: new Date(),
|
|
updatedAt: new Date(),
|
|
};
|
|
|
|
const mockPersonalitiesService = {
|
|
findAll: vi.fn(),
|
|
findOne: vi.fn(),
|
|
findDefault: vi.fn(),
|
|
create: vi.fn(),
|
|
update: vi.fn(),
|
|
remove: vi.fn(),
|
|
};
|
|
|
|
const mockPromptFormatterService = {
|
|
formatPrompt: vi.fn(),
|
|
getFormalityLevels: vi.fn(),
|
|
};
|
|
|
|
beforeEach(async () => {
|
|
const module: TestingModule = await Test.createTestingModule({
|
|
controllers: [PersonalitiesController],
|
|
providers: [
|
|
{ provide: PersonalitiesService, useValue: mockPersonalitiesService },
|
|
{ provide: PromptFormatterService, useValue: mockPromptFormatterService },
|
|
],
|
|
})
|
|
.overrideGuard(AuthGuard)
|
|
.useValue({ canActivate: () => true })
|
|
.compile();
|
|
|
|
controller = module.get<PersonalitiesController>(PersonalitiesController);
|
|
service = module.get<PersonalitiesService>(PersonalitiesService);
|
|
promptFormatter = module.get<PromptFormatterService>(PromptFormatterService);
|
|
vi.clearAllMocks();
|
|
});
|
|
|
|
describe("findAll", () => {
|
|
it("should return all personalities", async () => {
|
|
mockPersonalitiesService.findAll.mockResolvedValue([mockPersonality]);
|
|
const result = await controller.findAll(mockRequest);
|
|
expect(result).toEqual([mockPersonality]);
|
|
expect(service.findAll).toHaveBeenCalledWith(mockWorkspaceId, undefined);
|
|
});
|
|
});
|
|
|
|
describe("findOne", () => {
|
|
it("should return a personality by id", async () => {
|
|
mockPersonalitiesService.findOne.mockResolvedValue(mockPersonality);
|
|
const result = await controller.findOne(mockRequest, mockPersonalityId);
|
|
expect(result).toEqual(mockPersonality);
|
|
});
|
|
});
|
|
|
|
describe("findDefault", () => {
|
|
it("should return the default personality", async () => {
|
|
mockPersonalitiesService.findDefault.mockResolvedValue(mockPersonality);
|
|
const result = await controller.findDefault(mockRequest);
|
|
expect(result).toEqual(mockPersonality);
|
|
});
|
|
});
|
|
|
|
describe("getFormalityLevels", () => {
|
|
it("should return formality levels", () => {
|
|
const levels = [{ level: "FORMAL", description: "Professional" }];
|
|
mockPromptFormatterService.getFormalityLevels.mockReturnValue(levels);
|
|
const result = controller.getFormalityLevels();
|
|
expect(result).toEqual(levels);
|
|
});
|
|
});
|
|
|
|
describe("create", () => {
|
|
it("should create a new personality", async () => {
|
|
const createDto = {
|
|
name: "Casual",
|
|
tone: "casual",
|
|
formalityLevel: "CASUAL" as const,
|
|
systemPromptTemplate: "You are a casual assistant.",
|
|
};
|
|
mockPersonalitiesService.create.mockResolvedValue({ ...mockPersonality, ...createDto });
|
|
await controller.create(mockRequest, createDto);
|
|
expect(service.create).toHaveBeenCalledWith(mockWorkspaceId, createDto);
|
|
});
|
|
});
|
|
|
|
describe("update", () => {
|
|
it("should update a personality", async () => {
|
|
const updateDto = { description: "Updated" };
|
|
mockPersonalitiesService.update.mockResolvedValue({ ...mockPersonality, ...updateDto });
|
|
await controller.update(mockRequest, mockPersonalityId, updateDto);
|
|
expect(service.update).toHaveBeenCalledWith(mockWorkspaceId, mockPersonalityId, updateDto);
|
|
});
|
|
});
|
|
|
|
describe("remove", () => {
|
|
it("should delete a personality", async () => {
|
|
mockPersonalitiesService.remove.mockResolvedValue(mockPersonality);
|
|
await controller.remove(mockRequest, mockPersonalityId);
|
|
expect(service.remove).toHaveBeenCalledWith(mockWorkspaceId, mockPersonalityId);
|
|
});
|
|
});
|
|
|
|
describe("previewPrompt", () => {
|
|
it("should return formatted system prompt", async () => {
|
|
const context = { userName: "John" };
|
|
mockPersonalitiesService.findOne.mockResolvedValue(mockPersonality);
|
|
mockPromptFormatterService.formatPrompt.mockReturnValue({
|
|
systemPrompt: "Formatted prompt",
|
|
metadata: {},
|
|
});
|
|
const result = await controller.previewPrompt(mockRequest, mockPersonalityId, context);
|
|
expect(result.systemPrompt).toBe("Formatted prompt");
|
|
});
|
|
});
|
|
});
|