feat: KOC资源页新增一键爬取更新全部账号ID
This commit is contained in:
98
tests/account-id-refresh.test.mjs
Normal file
98
tests/account-id-refresh.test.mjs
Normal file
@@ -0,0 +1,98 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
import {
|
||||
runPublicAccountIdRefresh,
|
||||
} from "../lib/account-id-refresh-service.ts";
|
||||
|
||||
function fakeDb(accounts) {
|
||||
const updates = [];
|
||||
return {
|
||||
db: {
|
||||
prepare: (sql) => {
|
||||
if (sql.startsWith("SELECT")) {
|
||||
return {
|
||||
all: async () => ({
|
||||
results: accounts.map((account) => ({
|
||||
id: account.id,
|
||||
platform: account.platform,
|
||||
platform_uid: account.platform_uid,
|
||||
profile_url: account.profile_url,
|
||||
})),
|
||||
success: true,
|
||||
meta: { changes: 0, last_row_id: 0 },
|
||||
}),
|
||||
};
|
||||
}
|
||||
const match = sql.match(/WHERE id = \?$/);
|
||||
assert.ok(match, `unexpected sql: ${sql}`);
|
||||
assert.match(sql, /UPDATE accounts SET public_account_id = \?/);
|
||||
assert.doesNotMatch(sql, /followers|tags|nickname|bio|gender|ip_location/);
|
||||
return {
|
||||
bind: (value, id) => ({
|
||||
run: async () => {
|
||||
updates.push({ value, id });
|
||||
return { success: true, meta: { changes: 1, last_row_id: 0 } };
|
||||
},
|
||||
}),
|
||||
};
|
||||
},
|
||||
},
|
||||
updates,
|
||||
};
|
||||
}
|
||||
|
||||
test("updates only public_account_id for scrapeable accounts", async () => {
|
||||
const accounts = [
|
||||
{ id: "a1", platform: "小红书", platform_uid: "uid-1", profile_url: "https://www.xiaohongshu.com/user/profile/a1" },
|
||||
{ id: "a2", platform: "抖音", platform_uid: "uid-2", profile_url: "https://www.douyin.com/user/a2" },
|
||||
];
|
||||
const { db, updates } = fakeDb(accounts);
|
||||
const status = await runPublicAccountIdRefresh(db, async (url) => {
|
||||
if (url.endsWith("a1")) return { redId: "xhs-id-1" };
|
||||
if (url.endsWith("a2")) return { redId: " dy-id-2 " };
|
||||
return { redId: null };
|
||||
});
|
||||
|
||||
assert.equal(status.status, "done");
|
||||
assert.equal(status.total, 2);
|
||||
assert.equal(status.processed, 2);
|
||||
assert.equal(status.updated, 2);
|
||||
assert.equal(status.failed, 0);
|
||||
assert.deepEqual(updates, [
|
||||
{ value: "xhs-id-1", id: "a1" },
|
||||
{ value: "dy-id-2", id: "a2" },
|
||||
]);
|
||||
});
|
||||
|
||||
test("counts failures and skips empty redId without writing", async () => {
|
||||
const accounts = [
|
||||
{ id: "a1", platform: "小红书", platform_uid: "uid-1", profile_url: "https://www.xiaohongshu.com/user/profile/a1" },
|
||||
{ id: "a2", platform: "小红书", platform_uid: "uid-2", profile_url: "https://www.xiaohongshu.com/user/profile/a2" },
|
||||
{ id: "a3", platform: "小红书", platform_uid: "uid-3", profile_url: "https://www.xiaohongshu.com/user/profile/a3" },
|
||||
];
|
||||
const { db, updates } = fakeDb(accounts);
|
||||
const status = await runPublicAccountIdRefresh(db, async (url) => {
|
||||
if (url.endsWith("a1")) throw new Error("mcp down");
|
||||
if (url.endsWith("a2")) return { redId: " " };
|
||||
return { redId: "ok-3" };
|
||||
});
|
||||
|
||||
assert.equal(status.total, 3);
|
||||
assert.equal(status.updated, 1);
|
||||
assert.equal(status.failed, 1);
|
||||
assert.equal(status.skipped, 1);
|
||||
assert.deepEqual(updates, [{ value: "ok-3", id: "a3" }]);
|
||||
});
|
||||
|
||||
test("ignores demo accounts and accounts without profile_url at query level", async () => {
|
||||
const accounts = [
|
||||
{ id: "demo", platform: "小红书", platform_uid: "xhs-8af3", profile_url: "https://www.xiaohongshu.com/user/profile/demo" },
|
||||
{ id: "real", platform: "小红书", platform_uid: "uid-9", profile_url: "https://www.xiaohongshu.com/user/profile/real" },
|
||||
];
|
||||
const { db, updates } = fakeDb(accounts);
|
||||
const status = await runPublicAccountIdRefresh(db, async () => ({ redId: "id-9" }));
|
||||
|
||||
assert.equal(status.total, 1);
|
||||
assert.equal(status.updated, 1);
|
||||
assert.deepEqual(updates, [{ value: "id-9", id: "real" }]);
|
||||
});
|
||||
Reference in New Issue
Block a user