99 lines
3.6 KiB
JavaScript
99 lines
3.6 KiB
JavaScript
|
|
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" }]);
|
||
|
|
});
|