/** * Tests for processSelectedTextContexts in ContextProcessor * * Verifies that note and web selected text contexts are correctly * formatted with appropriate XML tags. */ import { SELECTED_TEXT_TAG, WEB_SELECTED_TEXT_TAG } from "@/constants"; import { NoteSelectedTextContext, WebSelectedTextContext } from "@/types/message"; // Mock the aiParams module const mockSelectedTextContexts: (NoteSelectedTextContext | WebSelectedTextContext)[] = []; jest.mock("@/aiParams", () => ({ getSelectedTextContexts: () => mockSelectedTextContexts, })); // Import after mocking import { ContextProcessor } from "@/contextProcessor"; describe("ContextProcessor.processSelectedTextContexts", () => { let processor: ContextProcessor; beforeEach(() => { // Clear mock data mockSelectedTextContexts.length = 0; // Get singleton instance processor = ContextProcessor.getInstance(); }); it("should return empty string when no selected text contexts", () => { const result = processor.processSelectedTextContexts(); expect(result).toBe(""); }); it("should format note selected text with proper XML tags", () => { const noteContext: NoteSelectedTextContext = { id: "note-1", sourceType: "note", content: "function fibonacci(n) {\n return n <= 1 ? n : fibonacci(n-1) + fibonacci(n-2);\n}", noteTitle: "Algorithms", notePath: "dev/algorithms.md", startLine: 10, endLine: 12, }; mockSelectedTextContexts.push(noteContext); const result = processor.processSelectedTextContexts(); expect(result).toContain(`<${SELECTED_TEXT_TAG}>`); expect(result).toContain(``); expect(result).toContain("Algorithms"); expect(result).toContain("dev/algorithms.md"); expect(result).toContain("10"); expect(result).toContain("12"); expect(result).toContain(""); expect(result).toContain("function fibonacci"); expect(result).toContain(""); // Should NOT contain web-specific tags expect(result).not.toContain(`<${WEB_SELECTED_TEXT_TAG}>`); expect(result).not.toContain(""); }); it("should format web selected text with proper XML tags", () => { const webContext: WebSelectedTextContext = { id: "web-1", sourceType: "web", content: "# React Documentation\n\nReact is a JavaScript library for building user interfaces.", title: "React Docs", url: "https://react.dev/learn", }; mockSelectedTextContexts.push(webContext); const result = processor.processSelectedTextContexts(); expect(result).toContain(`<${WEB_SELECTED_TEXT_TAG}>`); expect(result).toContain(``); expect(result).toContain("React Docs"); expect(result).toContain("https://react.dev/learn"); expect(result).toContain(""); expect(result).toContain("React Documentation"); expect(result).toContain(""); // Should NOT contain note-specific tags expect(result).not.toContain(`<${SELECTED_TEXT_TAG}>`); expect(result).not.toContain(""); expect(result).not.toContain(""); expect(result).not.toContain(""); }); it("should handle mixed note and web selected text contexts", () => { const noteContext: NoteSelectedTextContext = { id: "note-1", sourceType: "note", content: "Local note content about React patterns", noteTitle: "React Patterns", notePath: "dev/react-patterns.md", startLine: 15, endLine: 20, }; const webContext: WebSelectedTextContext = { id: "web-1", sourceType: "web", content: "Web content about React best practices", title: "React Best Practices", url: "https://react.dev/best-practices", }; mockSelectedTextContexts.push(noteContext, webContext); const result = processor.processSelectedTextContexts(); // Verify both context types are present expect(result).toContain(`<${SELECTED_TEXT_TAG}>`); expect(result).toContain(``); expect(result).toContain(`<${WEB_SELECTED_TEXT_TAG}>`); expect(result).toContain(``); // Verify note selection has path and line numbers expect(result).toContain("dev/react-patterns.md"); expect(result).toContain("15"); expect(result).toContain("20"); // Verify web selection has url expect(result).toContain("https://react.dev/best-practices"); // Verify content from both expect(result).toContain("Local note content about React patterns"); expect(result).toContain("Web content about React best practices"); }); it("should escape XML special characters in content", () => { const noteContext: NoteSelectedTextContext = { id: "note-1", sourceType: "note", content: "Code with & special \"chars\"", noteTitle: "Test ", notePath: "test/path&file.md", startLine: 1, endLine: 1, }; mockSelectedTextContexts.push(noteContext); const result = processor.processSelectedTextContexts(); // Title and path should be escaped expect(result).toContain("Test <Note>"); expect(result).toContain("test/path&file.md"); }); it("should escape XML special characters in web context", () => { const webContext: WebSelectedTextContext = { id: "web-1", sourceType: "web", content: "Content with tags", title: "Page ", url: "https://example.com/page?a=1&b=2", }; mockSelectedTextContexts.push(webContext); const result = processor.processSelectedTextContexts(); // Title and URL should be escaped expect(result).toContain("<title>Page <Title>"); expect(result).toContain("https://example.com/page?a=1&b=2"); }); });