Files
pitchfast/tests/ai-schemas.test.ts

138 lines
4.2 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
callScriptSchema,
emailDraftSchema,
emailSubjectSchema,
followUpDraftSchema,
auditSummarySchema,
qualityReviewSchema,
publicAuditTextSchema,
internalFindingsSchema,
type CallScript,
type EmailDraft,
type EmailSubject,
type FollowUpDraft,
type AuditSummary,
type PublicAuditText,
type QualityReview,
type InternalFindings,
} from "../lib/ai/schemas";
test("internal findings schema accepts task-focused evidence", () => {
const parsed = internalFindingsSchema.parse({
findings: [
{
section: "UX",
finding: "Landingpage is not responsive on mobile viewport.",
suggestion: "Add responsive breakpoints for cards and typography.",
},
],
summary: "One high-priority UX gap was found.",
});
assert.equal(parsed.findings.length, 1);
assert.equal(parsed.findings[0].section, "UX");
});
test("audit summary and public text schemas remain intentionally lightweight", () => {
const summaryParsed = auditSummarySchema.parse({
summary: "Kurze Zusammenfassung mit den wichtigsten Verbesserungen.",
keyFindings: ["Fehlende Kontaktmöglichkeit.", "Langsame Ladezeiten."],
});
const publicParsed = publicAuditTextSchema.parse({
publicText: "Dein Shop ist sauber, aber der erste Eindruck lässt Potenzial erkennen.",
});
assert.equal(summaryParsed.keyFindings.length, 2);
assert.equal(typeof publicParsed.publicText, "string");
});
test("outreach schemas parse German customer-facing payloads", () => {
const emailDraftParsed = emailDraftSchema.parse({
body: "Hallo, ich habe mir euer Angebot angesehen...",
});
const subjectParsed = emailSubjectSchema.parse({
subject: "Kurznotiz zu eurem Webauftritt",
});
const callParsed = callScriptSchema.parse({
openingLine: "Guten Tag, ich bin ...",
callScript: [
"Euer Fokus auf Terminbuchung ist stark.",
"Wie läuft eure aktuelle Lead-Generierung?",
],
closeLine: "Ich schicke im Anschluss kurz die wichtigsten Beobachtungen.",
});
const followParsed = followUpDraftSchema.parse({
message: "Kurzer Follow-up-Hinweis für nächste Woche.",
followInDays: 4,
goals: ["Antwort auf Rückmeldung erhalten"],
});
const qualityParsed = qualityReviewSchema.parse({
isValid: true,
issues: [],
suggestions: ["Mehr Kundennutzen konkret beschreiben."],
});
assert.equal(typeof emailDraftParsed.body, "string");
assert.equal(typeof subjectParsed.subject, "string");
assert.equal(Array.isArray(callParsed.callScript), true);
assert.equal(typeof followParsed.message, "string");
assert.equal(Array.isArray(qualityParsed.suggestions), true);
});
test("schema-inferred types are exported for Convex action wiring", () => {
const typedFindings: InternalFindings = {
findings: [
{
section: "Homepage",
finding: "No visible Datenschutzhinweis.",
suggestion: "Bitte Hinweis ergänzen.",
},
],
summary: "One finding identified.",
};
const typedSummary: AuditSummary = {
summary: "Kernbefund mit 2 Punkten.",
keyFindings: ["Kontaktseite fehlt."],
};
const typedPublicText: PublicAuditText = {
publicText: "Starker Start, aber optimierungsfähig.",
};
const typedEmail: EmailDraft = {
body: "Text mit Ich-Perspektive und konkretem Vorschlag.",
};
const typedSubject: EmailSubject = {
subject: "Kurzer Betreff",
};
const typedCall: CallScript = {
openingLine: "Hallo, ich habe euer Shop geprüft.",
callScript: ["Wie gehen die Leads aktuell rein?"],
closeLine: "Ich melde mich nach der Rückfrage erneut.",
};
const typedFollowUp: FollowUpDraft = {
message: "Kurzes Follow-up ohne harte Floskel.",
};
const typedQuality: QualityReview = {
isValid: true,
issues: [],
suggestions: [],
};
assert.equal(typedFindings.findings.length, 1);
assert.equal(typedSummary.keyFindings.length, 1);
assert.equal(typedPublicText.publicText.length > 0, true);
assert.equal(typeof typedEmail.body, "string");
assert.equal(typeof typedSubject.subject, "string");
assert.equal(typedCall.callScript.length, 1);
assert.equal(typedFollowUp.message.length > 0, true);
assert.equal(typedQuality.isValid, true);
});