From c8287e8d8ec78a045ee943e0342a018858179c76 Mon Sep 17 00:00:00 2001 From: admin123 Date: Mon, 18 May 2026 17:40:21 +0800 Subject: [PATCH] fix: fill missing audience profile buckets --- src/content/market/audience-profile-csv.ts | 2 +- tests/audience-profile-csv.test.ts | 55 ++++++++++++++++++++++ 2 files changed, 56 insertions(+), 1 deletion(-) diff --git a/src/content/market/audience-profile-csv.ts b/src/content/market/audience-profile-csv.ts index 7170782..b2bbb4c 100644 --- a/src/content/market/audience-profile-csv.ts +++ b/src/content/market/audience-profile-csv.ts @@ -122,7 +122,7 @@ function readDistributionValue( return ( readProfileDistributionItems(profile, key).find( (candidate) => candidate.label === label - )?.value ?? "" + )?.value ?? "0%" ); } diff --git a/tests/audience-profile-csv.test.ts b/tests/audience-profile-csv.test.ts index 3d286c1..8bda508 100644 --- a/tests/audience-profile-csv.test.ts +++ b/tests/audience-profile-csv.test.ts @@ -95,4 +95,59 @@ describe("audience-profile-csv", () => { expect(rowLine).not.toContain("request-failed"); expect(rowLine).not.toContain("timeout"); }); + + test("fills missing fixed distribution buckets with zero for successful profiles", () => { + const csv = buildAudienceProfileCsv([ + { + profiles: { + audience: { status: "success" }, + fans: { status: "success" }, + longtimeFans: { + age: [ + { label: "18-23", value: "11.1%" }, + { label: "24-30", value: "33.3%" }, + { label: "31-40", value: "55.6%" } + ], + cityTier: [ + { label: "一线城市", value: "10%" }, + { label: "二线城市", value: "20%" }, + { label: "三线城市", value: "40%" }, + { label: "四线城市", value: "30%" } + ], + crowd: [ + { label: "精致妈妈", value: "30%" }, + { label: "新锐白领", value: "20%" }, + { label: "资深中产", value: "10%" }, + { label: "都市蓝领", value: "20%" }, + { label: "小镇中老年", value: "10%" }, + { label: "小镇青年", value: "10%" } + ], + status: "success" + } + }, + record: { + authorId: "123", + authorName: "达人 A", + status: "success" + } + } satisfies AudienceProfileExportRow + ]); + + expect(readCsvValue(csv, "铁粉画像-41-50占比")).toBe("0%"); + expect(readCsvValue(csv, "铁粉画像-50+占比")).toBe("0%"); + expect(readCsvValue(csv, "铁粉画像-新一线城市占比")).toBe("0%"); + expect(readCsvValue(csv, "铁粉画像-五线城市占比")).toBe("0%"); + expect(readCsvValue(csv, "铁粉画像-都市银发占比")).toBe("0%"); + expect(readCsvValue(csv, "铁粉画像-Z世代占比")).toBe("0%"); + }); }); + +function readCsvValue(csv: string, header: string): string { + const [headerLine, rowLine] = csv.split("\n"); + const headers = headerLine.split(","); + const values = rowLine.split(","); + const index = headers.indexOf(header); + + expect(index).toBeGreaterThanOrEqual(0); + return values[index] ?? ""; +}