fix: match Xingtu profile endpoints

This commit is contained in:
2026-05-18 17:54:37 +08:00
parent c8287e8d8e
commit ca9ce02db5
4 changed files with 77 additions and 27 deletions
+29 -2
View File
@@ -1,6 +1,7 @@
import { describe, expect, test, vi } from "vitest";
import {
AUDIENCE_PROFILE_TARGETS,
createAudienceProfileClient,
mapAudienceProfileResponse
} from "../src/content/market/audience-profile-client";
@@ -21,10 +22,10 @@ describe("audience-profile-client", () => {
authorId: "7294473194298146854",
authorName: "奇奇de海洋",
status: "success"
}, 3);
}, AUDIENCE_PROFILE_TARGETS.audience);
expect(fetchImpl).toHaveBeenCalledWith(
"https://www.xingtu.cn/gw/api/data_sp/author_audience_distribution?o_author_id=7294473194298146854&platform_source=1&platform_channel=1&link_type=3",
"https://www.xingtu.cn/gw/api/data_sp/author_audience_distribution?o_author_id=7294473194298146854&platform_source=1&platform_channel=1&link_type=5",
expect.objectContaining({
credentials: "include",
method: "GET"
@@ -42,6 +43,32 @@ describe("audience-profile-client", () => {
);
});
test("loads fans and iron fan profiles from Xingtu fan distribution endpoint", async () => {
const fetchImpl = vi.fn(async () => ({
json: async () => buildAudiencePayload(),
ok: true
}));
const client = createAudienceProfileClient({
baseUrl: "https://www.xingtu.cn",
fetchImpl,
timeoutMs: 1000
});
await client.loadAudienceProfile({
authorId: "7294473194298146854",
authorName: "奇奇de海洋",
status: "success"
}, AUDIENCE_PROFILE_TARGETS.longtimeFans);
expect(fetchImpl).toHaveBeenCalledWith(
"https://www.xingtu.cn/gw/api/data_sp/get_author_fans_distribution?o_author_id=7294473194298146854&platform_source=1&author_type=5",
expect.objectContaining({
credentials: "include",
method: "GET"
})
);
});
test("maps Xingtu audience distribution payload into named profile sections", () => {
const result = mapAudienceProfileResponse(buildAudiencePayload());
+6 -6
View File
@@ -1624,8 +1624,8 @@ describe("market-content-entry", () => {
{ authorId: "222", authorName: "达人 B", price21To60s: "¥22,000" }
]);
const buildAudienceProfileCsv = vi.fn(() => "profile-csv");
const loadAudienceProfile = vi.fn(async (_record, linkType: number) => {
if (linkType === 4) {
const loadAudienceProfile = vi.fn(async (_record, target) => {
if (target.source === "fansDistribution" && target.authorType === 5) {
return {
age: [{ label: "31-40", value: "30%" }],
crowd: [{ label: "都市蓝领", value: "50%" }],
@@ -1666,10 +1666,10 @@ describe("market-content-entry", () => {
await waitForMockCall(buildAudienceProfileCsv, 40, 50);
expect(loadAudienceProfile).toHaveBeenCalledTimes(3);
expect(loadAudienceProfile.mock.calls.map(([, linkType]) => linkType)).toEqual([
3,
1,
4
expect(loadAudienceProfile.mock.calls.map(([, target]) => target)).toEqual([
{ linkType: 5, source: "audienceDistribution" },
{ authorType: 1, source: "fansDistribution" },
{ authorType: 5, source: "fansDistribution" }
]);
expect(buildAudienceProfileCsv).toHaveBeenCalledWith([
{