fix: complete Xiaohongshu read-only flow

This commit is contained in:
2026-09-14 23:19:31 +08:00
parent 4c37d0c9bf
commit 5867aac20f
17 changed files with 857 additions and 147 deletions
+12 -6
View File
@@ -110,13 +110,19 @@ export function CreatorCompetitorsPage() {
const parseHomepage = () => {
try {
const parsed = new URL(form.homepage_url);
const allowed =
form.platform === "douyin"
? parsed.hostname === "www.douyin.com"
: parsed.hostname === "www.xiaohongshu.com" ||
parsed.hostname === "xiaohongshu.com";
const parts = parsed.pathname.split("/").filter(Boolean);
const candidate = parts.at(-1) || "";
const isXiaohongshu = form.platform === "xiaohongshu";
const allowed = isXiaohongshu
? parsed.protocol === "https:" &&
parsed.hostname === "www.xiaohongshu.com"
: parsed.hostname === "www.douyin.com";
let candidate = parts.at(-1) || "";
if (
isXiaohongshu &&
!(parts.length === 3 && parts[0] === "user" && parts[1] === "profile")
) {
candidate = "";
}
if (
!allowed ||
!candidate ||
+30
View File
@@ -203,6 +203,36 @@ describe("creator pages", () => {
);
});
it("parses and confirms a Xiaohongshu profile URL", async () => {
const dataProvider = provider();
renderPage(<CreatorCompetitorsPage />, dataProvider);
fireEvent.click(screen.getAllByRole("combobox")[0]);
fireEvent.click(screen.getByRole("option", { name: "小红书" }));
fireEvent.change(screen.getByLabelText("主页 URL", { exact: false }), {
target: {
value: "https://www.xiaohongshu.com/user/profile/xhs-b",
},
});
fireEvent.click(screen.getByRole("button", { name: "解析链接预览" }));
await waitFor(() =>
expect(
screen.getAllByText("xhs-b", { exact: false }).length,
).toBeGreaterThan(0),
);
fireEvent.click(screen.getByRole("button", { name: "确认预览内容" }));
fireEvent.click(screen.getByRole("button", { name: "加入监测" }));
await waitFor(() => expect(dataProvider.create).toHaveBeenCalled());
expect(dataProvider.create).toHaveBeenCalledWith(
expect.objectContaining({
resource: "creator-competitors",
variables: expect.objectContaining({
platform: "xiaohongshu",
platform_account_key: "xhs-b",
}),
}),
);
});
it("keeps account password out of the returned profile and exposes big-account action", async () => {
const dataProvider = provider();
renderPage(<CreatorAccountsPage />, dataProvider);