import assert from "node:assert/strict"; import test from "node:test"; import { buildLeadDiscoveryLeadRecord, buildLeadDiscoveryCounters, canStartAgentRun, isStalePendingAgentRun, getLeadDiscoveryContactStatus, getLeadDiscoveryPriority, shouldScheduleWebsiteEnrichment, } from "../lib/lead-discovery-run"; test("agent run guard ignores stale pending runs but blocks active runs", () => { const now = Date.UTC(2026, 5, 4, 13, 20, 0); assert.equal(canStartAgentRun([{ status: "succeeded" }], now), true); assert.equal( canStartAgentRun([{ status: "pending", updatedAt: now - 20 * 60 * 1000 }], now), true, ); assert.equal( canStartAgentRun([{ status: "pending", updatedAt: now - 30_000 }], now), false, ); assert.equal( canStartAgentRun([{ status: "failed" }, { status: "running" }], now), false, ); }); test("stale pending runs are older than the discovery startup grace period", () => { const now = Date.UTC(2026, 5, 4, 13, 20, 0); assert.equal( isStalePendingAgentRun({ status: "pending", updatedAt: now - 11 * 60 * 1000 }, now), true, ); assert.equal( isStalePendingAgentRun({ status: "pending", updatedAt: now - 9 * 60 * 1000 }, now), false, ); assert.equal( isStalePendingAgentRun({ status: "running", updatedAt: now - 60 * 60 * 1000 }, now), false, ); }); test("lead discovery counters preserve audit and outreach counters", () => { const counters = buildLeadDiscoveryCounters({ leadsFound: 12, leadsCreated: 3, errors: 1, }); assert.deepEqual(counters, { leadsFound: 12, leadsCreated: 3, auditsCreated: 0, outreachPrepared: 0, errors: 1, }); }); test("lead discovery contact status separates leads without any contact route", () => { assert.equal( getLeadDiscoveryContactStatus({ usableEmail: null }), "missing_contact", ); assert.equal( getLeadDiscoveryContactStatus({ usableEmail: "info@example.de" }), "new", ); assert.equal( getLeadDiscoveryContactStatus({ usableEmail: null }), "missing_contact", ); }); test("lead discovery lead record marks contact missing when no usable email exists", () => { const record = buildLeadDiscoveryLeadRecord({ campaignId: "campaign-1", runId: "run-1", niche: "Restaurant", postalCode: "10115", now: 1717480000000, candidate: { placeId: "place-2", businessName: "Kontaktlos GmbH", address: "Hauptstraße 2", websiteUrl: "https://www.beispiel.de", websiteDomain: "example.de", phone: "+49 30 123", rating: 3.9, userRatingCount: 9, businessStatus: "OPERATIONAL", googleTypes: ["consulting"], googlePrimaryType: "consulting", googleMapsUrl: "https://maps.google.com/place-2", sourceProvider: "google_places", sourceFetchedAt: 1717480001000, contactEmails: [{ email: "Herr.Bewerber@Beispiel.de", isBusinessContactAddress: false }], }, }); assert.equal(record.contactStatus, "missing_contact"); assert.equal(record.phone, "+49 30 123"); assert.equal(record.websiteDomain, "example.de"); assert.equal(record.email, undefined); }); test("lead discovery lead record keeps raw website url and normalized domain", () => { const record = buildLeadDiscoveryLeadRecord({ campaignId: "campaign-1", runId: "run-1", niche: "Restaurant", postalCode: "10115", now: 1717480000000, candidate: { placeId: "place-1", businessName: "Beispiel GmbH", address: "Hauptstraße 1", websiteUrl: "https://www.example.de/path", websiteDomain: "example.de", phone: "+49 30 123", rating: 4.5, userRatingCount: 12, businessStatus: "OPERATIONAL", googleTypes: ["restaurant"], googlePrimaryType: "restaurant", googleMapsUrl: "https://maps.google.com/place-1", sourceProvider: "google_places", sourceFetchedAt: 1717480001000, }, }); assert.equal(record.websiteUrl, "https://www.example.de/path"); assert.equal(record.websiteDomain, "example.de"); assert.equal(record.googleRating, 4.5); assert.equal(record.googleUserRatingCount, 12); assert.equal(record.sourceFetchedAt, 1717480001000); }); test("lead discovery lead record stores valid email and sets contactStatus to new", () => { const record = buildLeadDiscoveryLeadRecord({ campaignId: "campaign-1", runId: "run-1", niche: "Restaurant", postalCode: "10115", now: 1717480000000, candidate: { placeId: "place-3", businessName: "Beispiel GmbH", address: "Hauptstraße 1", websiteUrl: "https://www.example.de/path", websiteDomain: "example.de", phone: "+49 30 123", rating: 4.5, userRatingCount: 12, businessStatus: "OPERATIONAL", googleTypes: ["restaurant"], googlePrimaryType: "restaurant", googleMapsUrl: "https://maps.google.com/place-3", sourceProvider: "google_places", sourceFetchedAt: 1717480001000, contactEmails: [ { email: "Herr@Beispiel.de", isBusinessContactAddress: false, }, { email: "info@beispiel.de", isBusinessContactAddress: false, }, ], }, }); assert.equal(record.contactStatus, "new"); assert.equal(record.email, "info@beispiel.de"); assert.equal(record.contactPerson, undefined); }); test("scheduling helper triggers website enrichment for missing contact leads with website data", () => { assert.equal( shouldScheduleWebsiteEnrichment({ websiteUrl: "https://www.example.de", websiteDomain: "example.de", contactStatus: "missing_contact", }), true, ); }); test("scheduling helper does not trigger without website data", () => { assert.equal( shouldScheduleWebsiteEnrichment({ websiteUrl: null, websiteDomain: "", contactStatus: "missing_contact", }), false, ); }); test("scheduling helper does not trigger when contact status is already usable", () => { assert.equal( shouldScheduleWebsiteEnrichment({ websiteUrl: "https://www.example.de", websiteDomain: "example.de", contactStatus: "new", }), false, ); }); test("scheduling helper does not trigger for audit-ready leads", () => { assert.equal( shouldScheduleWebsiteEnrichment({ websiteUrl: "https://www.example.de", websiteDomain: "example.de", contactStatus: "audit_ready", }), false, ); }); test("scheduling helper preserves existing contact-status behavior beyond TASK-7", () => { assert.equal( shouldScheduleWebsiteEnrichment({ websiteUrl: "https://www.example.de", websiteDomain: "example.de", contactStatus: "outreach_ready", }), false, ); assert.equal( shouldScheduleWebsiteEnrichment({ websiteUrl: "https://www.example.de", websiteDomain: "example.de", contactStatus: "do_not_contact", }), false, ); }); test("lead discovery lead record stores normalized matching fields", () => { const record = buildLeadDiscoveryLeadRecord({ campaignId: "campaign-1", runId: "run-1", niche: "Restaurant", postalCode: "10115", now: 1717480000000, candidate: { placeId: "place-4", businessName: "Muster GmbH", address: "Hauptstraße 1 60311 Berlin", websiteUrl: "https://www.example.de/", websiteDomain: "Example.de", phone: "+49 30 123 456", rating: 4.5, userRatingCount: 12, businessStatus: "OPERATIONAL", googleTypes: ["restaurant"], googlePrimaryType: "restaurant", googleMapsUrl: "https://maps.google.com/place-4", sourceProvider: "google_places", sourceFetchedAt: 1717480001000, email: "Info@Example.de", contactEmails: [ { email: "Info@Example.de", isBusinessContactAddress: false, }, ], }, }); assert.equal(record.normalizedEmail, "info@example.de"); assert.equal(record.normalizedPhone, "4930123456"); assert.equal(record.normalizedCompanyName, "muster gmbh"); assert.equal(record.normalizedAddress, "hauptstraße 1 60311 berlin"); }); test("lead discovery priority helper classifies blocked, deferred, and low-potential leads", () => { assert.deepEqual(getLeadDiscoveryPriority({ isBlacklisted: true }), { priority: "blocked", reason: "Lead ist auf der Sperrliste.", }); assert.deepEqual(getLeadDiscoveryPriority({ isDuplicate: true }), { priority: "defer", reason: "Dublettenprüfung oder Reviewpause.", }); assert.deepEqual(getLeadDiscoveryPriority({ hasWebsite: false }), { priority: "high", reason: "Kein Website-Indikator vorhanden.", }); assert.deepEqual(getLeadDiscoveryPriority({ hasWebsite: true, hasWebsiteSignal: true }), { priority: "low", reason: "Website vorhanden: geringer Kontaktaufwand.", }); assert.deepEqual(getLeadDiscoveryPriority({ hasWebsite: true, hasWebsiteSignal: false }), { priority: "medium", reason: "Standardpriorität.", }); assert.deepEqual(getLeadDiscoveryPriority({ hasWebsite: true }), { priority: "medium", reason: "Standardpriorität.", }); });