Files
koc-loop/tests/account-id-refresh.test.mjs

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" }]);
});