153 lines
4.9 KiB
TypeScript
153 lines
4.9 KiB
TypeScript
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/,
|
|
);
|
|
});
|