Rocky_Mountain_Vending/app/api/contact/route.test.ts

154 lines
4.5 KiB
TypeScript

import assert from "node:assert/strict";
import test from "node:test";
import {
processLeadSubmission,
type ContactLeadPayload,
type RequestMachineLeadPayload,
} from "@/lib/server/contact-submission";
test("processLeadSubmission stores and syncs a contact lead", async () => {
const calls: string[] = [];
const payload: ContactLeadPayload = {
kind: "contact",
firstName: "John",
lastName: "Doe",
email: "john@example.com",
phone: "(435) 555-1212",
company: "ACME",
intent: "Repairs",
message: "Need vending help for our office.",
serviceTextConsent: true,
marketingTextConsent: false,
consentVersion: "sms-consent-v1-2026-03-26",
consentCapturedAt: "2026-03-25T00:00:00.000Z",
consentSourcePage: "/contact-us",
source: "website",
page: "/contact",
timestamp: "2026-03-25T00:00:00.000Z",
url: "https://rmv.example/contact",
};
const result = await processLeadSubmission(payload, "rmv.example", {
storageConfigured: true,
emailConfigured: true,
ghlConfigured: true,
tenantSlug: "rocky_mountain_vending",
tenantName: "Rocky Mountain Vending",
tenantDomains: ["rockymountainvending.com"],
ingest: async () => {
calls.push("ingest");
return {
inserted: true,
leadId: "lead_123",
idempotencyKey: "abc",
tenantId: "tenant_123",
};
},
updateLeadStatus: async () => {
calls.push("update");
return { ok: true };
},
sendEmail: async () => {
calls.push("email");
return {};
},
createContact: async () => {
calls.push("ghl");
return { contact: { id: "ghl_123" } };
},
logger: console,
});
assert.equal(result.status, 200);
assert.equal(result.body.success, true);
assert.deepEqual(result.body.deliveredVia, ["convex", "email", "ghl"]);
assert.equal(calls.filter((call) => call === "email").length, 2);
assert.ok(calls.includes("ingest"));
assert.ok(calls.includes("update"));
assert.ok(calls.includes("ghl"));
});
test("processLeadSubmission validates request-machine submissions", async () => {
const payload: RequestMachineLeadPayload = {
kind: "request-machine",
firstName: "Jane",
lastName: "Smith",
email: "jane@example.com",
phone: "4352339668",
company: "Warehouse Co",
employeeCount: "0",
machineType: "snack",
machineCount: "2",
serviceTextConsent: true,
marketingTextConsent: false,
consentVersion: "sms-consent-v1-2026-03-26",
consentCapturedAt: "2026-03-25T00:00:00.000Z",
consentSourcePage: "/",
};
const result = await processLeadSubmission(payload, "rmv.example", {
storageConfigured: false,
emailConfigured: false,
ghlConfigured: false,
tenantSlug: "rocky_mountain_vending",
tenantName: "Rocky Mountain Vending",
tenantDomains: [],
ingest: async () => {
throw new Error("should not run");
},
updateLeadStatus: async () => {
throw new Error("should not run");
},
sendEmail: async () => {
throw new Error("should not run");
},
createContact: async () => {
throw new Error("should not run");
},
logger: console,
});
assert.equal(result.status, 400);
assert.equal(result.body.success, false);
assert.match(result.body.error || "", /Invalid number of employees/);
});
test("processLeadSubmission returns deduped success when Convex already has the lead", async () => {
const payload: ContactLeadPayload = {
kind: "contact",
firstName: "John",
lastName: "Doe",
email: "john@example.com",
phone: "(435) 555-1212",
message: "Need vending help for our office.",
serviceTextConsent: true,
marketingTextConsent: false,
consentVersion: "sms-consent-v1-2026-03-26",
consentCapturedAt: "2026-03-25T00:00:00.000Z",
consentSourcePage: "/contact-us",
};
const result = await processLeadSubmission(payload, "rmv.example", {
storageConfigured: true,
emailConfigured: false,
ghlConfigured: false,
tenantSlug: "rocky_mountain_vending",
tenantName: "Rocky Mountain Vending",
tenantDomains: [],
ingest: async () => ({
inserted: false,
leadId: "lead_123",
idempotencyKey: "abc",
tenantId: "tenant_123",
}),
updateLeadStatus: async () => ({ ok: true }),
sendEmail: async () => ({}),
createContact: async () => null,
logger: console,
});
assert.equal(result.status, 200);
assert.equal(result.body.success, true);
assert.equal(result.body.deduped, true);
assert.deepEqual(result.body.deliveredVia, ["convex"]);
});