Integrate local business workflow and SaaS redesign
This commit is contained in:
152
tests/lead-discovery-local-business.test.ts
Normal file
152
tests/lead-discovery-local-business.test.ts
Normal file
@@ -0,0 +1,152 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
import {
|
||||
LOCAL_BUSINESS_DATA_HOST,
|
||||
buildLocalBusinessSearchUrl,
|
||||
getLocalBusinessSearchSpec,
|
||||
normalizeLocalBusinessSearchResponse,
|
||||
} from "../lib/lead-discovery-local-business";
|
||||
|
||||
test("Local Business Data search URL uses RapidAPI host-compatible query params", () => {
|
||||
const url = new URL(
|
||||
buildLocalBusinessSearchUrl({
|
||||
query: "Anwalt in 10115 Deutschland",
|
||||
limit: 9999,
|
||||
}),
|
||||
);
|
||||
|
||||
assert.equal(url.origin, `https://${LOCAL_BUSINESS_DATA_HOST}`);
|
||||
assert.equal(url.pathname, "/search");
|
||||
assert.equal(url.searchParams.get("query"), "Anwalt in 10115 Deutschland");
|
||||
assert.equal(url.searchParams.get("limit"), "500");
|
||||
assert.equal(url.searchParams.get("language"), "de");
|
||||
assert.equal(url.searchParams.get("region"), "de");
|
||||
assert.equal(url.searchParams.get("extract_emails_and_contacts"), "true");
|
||||
});
|
||||
|
||||
test("Local Business Data campaign spec builds the SaaS lead-discovery query from niche and PLZ", () => {
|
||||
const spec = getLocalBusinessSearchSpec({
|
||||
categoryMode: "custom",
|
||||
category: "Anderes",
|
||||
customSearchTerm: "Webdesigner fuer Restaurants",
|
||||
postalCode: "79098",
|
||||
maxNewLeads: 8,
|
||||
});
|
||||
|
||||
assert.equal(spec.query, "Webdesigner fuer Restaurants in 79098 Deutschland");
|
||||
assert.equal(spec.limit, 8);
|
||||
assert.match(spec.url, /extract_emails_and_contacts=true/);
|
||||
});
|
||||
|
||||
test("Local Business Data response normalizes direct business emails into lead candidates", () => {
|
||||
const candidates = normalizeLocalBusinessSearchResponse(
|
||||
{
|
||||
status: "OK",
|
||||
request_id: "req-123",
|
||||
data: [
|
||||
{
|
||||
business_id: "biz-1",
|
||||
place_id: "place-1",
|
||||
name: "Kanzlei Beispiel",
|
||||
full_address: "Musterstrasse 1, 10115 Berlin",
|
||||
website: "https://www.beispiel-kanzlei.de/kontakt",
|
||||
phone_number: "+49 30 123456",
|
||||
rating: 4.7,
|
||||
review_count: 31,
|
||||
business_status: "OPERATIONAL",
|
||||
types: ["lawyer"],
|
||||
google_maps_url: "https://maps.google.com/?cid=biz-1",
|
||||
emails: ["Herr.Bewerber@beispiel-kanzlei.de", "Info@Beispiel-Kanzlei.de"],
|
||||
},
|
||||
],
|
||||
},
|
||||
1717480000000,
|
||||
);
|
||||
|
||||
assert.equal(candidates.length, 1);
|
||||
assert.equal(candidates[0]?.sourceProvider, "local_business_data");
|
||||
assert.equal(candidates[0]?.sourceBusinessId, "biz-1");
|
||||
assert.equal(candidates[0]?.placeId, "place-1");
|
||||
assert.equal(candidates[0]?.businessName, "Kanzlei Beispiel");
|
||||
assert.equal(candidates[0]?.websiteDomain, "beispiel-kanzlei.de");
|
||||
assert.equal(candidates[0]?.contactEmails?.length, 2);
|
||||
assert.equal(candidates[0]?.contactEmails?.[1]?.email, "info@beispiel-kanzlei.de");
|
||||
assert.equal(candidates[0]?.contactEmails?.[1]?.emailSource, "local_business_data");
|
||||
});
|
||||
|
||||
test("Local Business Data response reads extracted emails from emails_and_contacts", () => {
|
||||
const candidates = normalizeLocalBusinessSearchResponse(
|
||||
{
|
||||
status: "OK",
|
||||
request_id: "req-nested-email",
|
||||
data: [
|
||||
{
|
||||
business_id: "biz-nested",
|
||||
name: "PORZIG Immobilien GmbH",
|
||||
full_address: "Silberstrasse 18, 08451 Crimmitschau",
|
||||
website: "https://porzig.info",
|
||||
phone_number: "+49 3762 759775",
|
||||
emails_and_contacts: {
|
||||
emails: [
|
||||
"info@porzig.info",
|
||||
"Info@Porzig.Info",
|
||||
"makler@porzig.info",
|
||||
],
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
1717480000003,
|
||||
);
|
||||
|
||||
assert.equal(candidates.length, 1);
|
||||
assert.equal(candidates[0]?.contactEmails?.length, 2);
|
||||
assert.equal(candidates[0]?.email, "info@porzig.info");
|
||||
assert.equal(candidates[0]?.emailSource, "local_business_data");
|
||||
assert.deepEqual(
|
||||
candidates[0]?.contactEmails?.map((entry) => entry.email),
|
||||
["info@porzig.info", "makler@porzig.info"],
|
||||
);
|
||||
});
|
||||
|
||||
test("Local Business Data response accepts object-wrapped business arrays", () => {
|
||||
const candidates = normalizeLocalBusinessSearchResponse(
|
||||
{
|
||||
status: "OK",
|
||||
request_id: "req-456",
|
||||
data: {
|
||||
businesses: [
|
||||
{
|
||||
business_id: "biz-2",
|
||||
name: "Malerbetrieb Beispiel",
|
||||
address: "Hauptstrasse 2, 79098 Freiburg",
|
||||
site: "https://maler.example",
|
||||
phone: "+49 761 123",
|
||||
email: "kontakt@maler.example",
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
1717480000001,
|
||||
);
|
||||
|
||||
assert.equal(candidates.length, 1);
|
||||
assert.equal(candidates[0]?.placeId, "biz-2");
|
||||
assert.equal(candidates[0]?.email, "kontakt@maler.example");
|
||||
});
|
||||
|
||||
test("Local Business Data response throws provider error messages", () => {
|
||||
assert.throws(
|
||||
() =>
|
||||
normalizeLocalBusinessSearchResponse(
|
||||
{
|
||||
status: "ERROR",
|
||||
request_id: "req-error",
|
||||
error: { message: "Missing query", code: 400 },
|
||||
},
|
||||
1717480000002,
|
||||
),
|
||||
/Local Business Data API error 400: Missing query/,
|
||||
);
|
||||
});
|
||||
Reference in New Issue
Block a user