import { describe, expect, it } from "vitest"; import { classifyIntent } from "./classifyIntent"; import type { WorkshopSlug } from "./workshops"; describe("classifyIntent", () => { it("returns null for empty or whitespace-only input", () => { expect(classifyIntent("")).toBeNull(); expect(classifyIntent(" ")).toBeNull(); expect(classifyIntent("\n\t ")).toBeNull(); }); it.each<[string, WorkshopSlug]>([ // Convert — must be checked first ["convert this pdf to markdown", "convert"], ["can you convert it", "convert"], ["from docx to pdf please", "convert"], ["pdf to docx", "convert"], ["transform html to md", "convert"], // Wallpapers ["I need a 1920x1080 wallpaper of a forest", "wallpapers"], ["make a desktop bg with neon lights", "wallpapers"], ["generate wallpapers for my lock screen", "wallpapers"], // Diagrams ["diagram of the auth flow", "diagrams"], ["flowchart for the checkout process", "diagrams"], ["mermaid sequence diagram", "diagrams"], ["architecture diagram of the platform", "diagrams"], // Icons ["I want an icon set for my app", "icons"], ["svg icon of a rocket", "icons"], ["icon pack please", "icons"], // Themes ["build me a theme from #166534", "themes"], ["color palette based on volt", "themes"], ["generate a palette", "themes"], // Brand kits (checked before documents — logo beats document) ["create a brand identity for an AI startup", "brand-kits"], ["I need a logo", "brand-kits"], ["style guide please", "brand-kits"], // Presentations (checked before social — "pitch deck" is presentation, not social) ["build me a pitch deck about our platform", "presentations"], ["slide deck for the board", "presentations"], ["demo video of the onboarding flow", "presentations"], ["keynote-style presentation", "presentations"], // Social ["twitter post about our launch", "social"], ["linkedin carousel on hiring", "social"], ["instagram post for the team", "social"], // Documents (must come after convert/brand) ["generate a quarterly report", "documents"], ["one-pager about the product", "documents"], ["an invoice for client acme", "documents"], ])("routes %j → %s", (prompt, expectedSlug) => { const result = classifyIntent(prompt); expect(result).not.toBeNull(); expect(result?.slug).toBe(expectedSlug); expect(result?.prefilledPrompt).toBe(prompt); }); it.each([ "random musing about life", "what's the weather today", "tell me a joke", "remind me to buy milk", "hello world", ])("returns null for unclassified prompt %j", (prompt) => { expect(classifyIntent(prompt)).toBeNull(); }); it("preserves the original prompt verbatim in prefilledPrompt (no lowercasing)", () => { const prompt = "Diagram Of The Auth Flow, MERMAID style"; const result = classifyIntent(prompt); expect(result?.prefilledPrompt).toBe(prompt); expect(result?.slug).toBe("diagrams"); }); });