feat: filter market export by selected creators
This commit is contained in:
@@ -1242,6 +1242,84 @@ describe("market-content-entry", () => {
|
||||
).toContain("有效页数");
|
||||
});
|
||||
|
||||
test("selected export uses only creators selected in the current range", async () => {
|
||||
document.body.innerHTML = buildRealMarketFixture([
|
||||
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" },
|
||||
{ authorId: "222", authorName: "达人 B", price21To60s: "¥22,000" },
|
||||
{ authorId: "333", authorName: "达人 C", price21To60s: "¥33,000" }
|
||||
]);
|
||||
const buildCsv = vi.fn(() => "csv-output");
|
||||
|
||||
const { createMarketController } = await import("../src/content/market/index");
|
||||
const controller = trackController(createMarketController({
|
||||
buildCsv,
|
||||
document,
|
||||
loadAuthorMetrics: async () => ({
|
||||
success: false,
|
||||
reason: "request-failed"
|
||||
}),
|
||||
onCsvReady: vi.fn(),
|
||||
window
|
||||
}));
|
||||
|
||||
await controller.ready;
|
||||
clickSelectionCheckboxForAuthor("111");
|
||||
clickSelectionCheckboxForAuthor("333");
|
||||
setSelectValue('[data-plugin-export-range="select"]', "current");
|
||||
dispatchChange('[data-plugin-export-range="select"]');
|
||||
|
||||
click('[data-plugin-export="button"]');
|
||||
await waitForMockCall(buildCsv, 40, 50);
|
||||
|
||||
expect(buildCsv.mock.calls[0][0].map((record) => record.authorId)).toEqual([
|
||||
"111",
|
||||
"333"
|
||||
]);
|
||||
});
|
||||
|
||||
test("selected export falls back to all creators in the current range when no selection matches", async () => {
|
||||
const pages = [
|
||||
[
|
||||
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" },
|
||||
{ authorId: "222", authorName: "达人 B", price21To60s: "¥22,000" }
|
||||
],
|
||||
[
|
||||
{ authorId: "333", authorName: "达人 C", price21To60s: "¥33,000" },
|
||||
{ authorId: "444", authorName: "达人 D", price21To60s: "¥44,000" }
|
||||
]
|
||||
];
|
||||
document.body.innerHTML = buildRealMarketFixture(pages[0]);
|
||||
installAsyncPaginationHarness(pages);
|
||||
const buildCsv = vi.fn(() => "csv-output");
|
||||
|
||||
const { createMarketController } = await import("../src/content/market/index");
|
||||
const controller = trackController(createMarketController({
|
||||
buildCsv,
|
||||
document,
|
||||
loadAuthorMetrics: async () => ({
|
||||
success: false,
|
||||
reason: "request-failed"
|
||||
}),
|
||||
onCsvReady: vi.fn(),
|
||||
window
|
||||
}));
|
||||
|
||||
await controller.ready;
|
||||
clickSelectionCheckboxForAuthor("111");
|
||||
click('[data-testid="next-page"]');
|
||||
await flushWithTimers();
|
||||
setSelectValue('[data-plugin-export-range="select"]', "current");
|
||||
dispatchChange('[data-plugin-export-range="select"]');
|
||||
|
||||
click('[data-plugin-export="button"]');
|
||||
await waitForMockCall(buildCsv, 40, 50);
|
||||
|
||||
expect(buildCsv.mock.calls[0][0].map((record) => record.authorId)).toEqual([
|
||||
"333",
|
||||
"444"
|
||||
]);
|
||||
});
|
||||
|
||||
test("prompts for a batch name before submitting the current range", async () => {
|
||||
document.body.innerHTML = buildMarketFixture();
|
||||
const promptBatchName = vi.fn(() => "618达人筛选第一批");
|
||||
@@ -1281,6 +1359,100 @@ describe("market-content-entry", () => {
|
||||
);
|
||||
});
|
||||
|
||||
test("selected batch submit uses only creators selected in the current range", async () => {
|
||||
document.body.innerHTML = buildRealMarketFixture([
|
||||
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" },
|
||||
{ authorId: "222", authorName: "达人 B", price21To60s: "¥22,000" },
|
||||
{ authorId: "333", authorName: "达人 C", price21To60s: "¥33,000" }
|
||||
]);
|
||||
const promptBatchName = vi.fn(() => "自动选择批次");
|
||||
const submitBatch = vi.fn(async () => ({ ok: true }));
|
||||
|
||||
const { createMarketController } = await import("../src/content/market/index");
|
||||
const controller = trackController(createMarketController({
|
||||
document,
|
||||
getAuthState: async () => ({
|
||||
isAuthenticated: true,
|
||||
resource: "https://talent-search.intelligrow.cn",
|
||||
userInfo: { name: "王少卿", sub: "p7pdhhtde8kj" }
|
||||
}),
|
||||
loadAuthorMetrics: async () => ({
|
||||
success: false,
|
||||
reason: "request-failed"
|
||||
}),
|
||||
promptBatchName,
|
||||
submitBatch,
|
||||
window
|
||||
}));
|
||||
|
||||
await controller.ready;
|
||||
clickSelectionCheckboxForAuthor("222");
|
||||
setSelectValue('[data-plugin-export-range="select"]', "current");
|
||||
dispatchChange('[data-plugin-export-range="select"]');
|
||||
|
||||
click('[data-plugin-batch-submit="button"]');
|
||||
await waitForMockCall(submitBatch, 40, 50);
|
||||
|
||||
expect(submitBatch).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
authors: [{ authorId: "222", authorName: "达人 B" }]
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test("selected batch submit falls back to all creators in the current range when no selection matches", async () => {
|
||||
const pages = [
|
||||
[
|
||||
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" },
|
||||
{ authorId: "222", authorName: "达人 B", price21To60s: "¥22,000" }
|
||||
],
|
||||
[
|
||||
{ authorId: "333", authorName: "达人 C", price21To60s: "¥33,000" },
|
||||
{ authorId: "444", authorName: "达人 D", price21To60s: "¥44,000" }
|
||||
]
|
||||
];
|
||||
document.body.innerHTML = buildRealMarketFixture(pages[0]);
|
||||
installAsyncPaginationHarness(pages);
|
||||
const promptBatchName = vi.fn(() => "自动选择批次");
|
||||
const submitBatch = vi.fn(async () => ({ ok: true }));
|
||||
|
||||
const { createMarketController } = await import("../src/content/market/index");
|
||||
const controller = trackController(createMarketController({
|
||||
document,
|
||||
getAuthState: async () => ({
|
||||
isAuthenticated: true,
|
||||
resource: "https://talent-search.intelligrow.cn",
|
||||
userInfo: { name: "王少卿", sub: "p7pdhhtde8kj" }
|
||||
}),
|
||||
loadAuthorMetrics: async () => ({
|
||||
success: false,
|
||||
reason: "request-failed"
|
||||
}),
|
||||
promptBatchName,
|
||||
submitBatch,
|
||||
window
|
||||
}));
|
||||
|
||||
await controller.ready;
|
||||
clickSelectionCheckboxForAuthor("111");
|
||||
click('[data-testid="next-page"]');
|
||||
await flushWithTimers();
|
||||
setSelectValue('[data-plugin-export-range="select"]', "current");
|
||||
dispatchChange('[data-plugin-export-range="select"]');
|
||||
|
||||
click('[data-plugin-batch-submit="button"]');
|
||||
await waitForMockCall(submitBatch, 40, 50);
|
||||
|
||||
expect(submitBatch).toHaveBeenCalledWith(
|
||||
expect.objectContaining({
|
||||
authors: [
|
||||
{ authorId: "333", authorName: "达人 C" },
|
||||
{ authorId: "444", authorName: "达人 D" }
|
||||
]
|
||||
})
|
||||
);
|
||||
});
|
||||
|
||||
test("shows an error when the batch name is blank", async () => {
|
||||
document.body.innerHTML = buildMarketFixture();
|
||||
const promptBatchName = vi.fn(() => " ");
|
||||
|
||||
@@ -293,6 +293,20 @@ describe("market-dom-sync", () => {
|
||||
expect(readScrollHintText()).toBe("横向滚动可查看看后搜率、秒探指标");
|
||||
});
|
||||
|
||||
test("keeps reading native author rows after the selection column is injected", () => {
|
||||
document.body.innerHTML = buildRealMarketGridFixture();
|
||||
|
||||
expect(syncMarketTable(document)?.rows.map((row) => row.authorId)).toEqual([
|
||||
"111",
|
||||
"222"
|
||||
]);
|
||||
|
||||
const table = syncMarketTable(document);
|
||||
|
||||
expect(table?.rows.map((row) => row.authorId)).toEqual(["111", "222"]);
|
||||
expect(readAuthorNames()).toEqual(["达人 A", "达人 B"]);
|
||||
});
|
||||
|
||||
test("uses native-like alignment styles for plugin cells", () => {
|
||||
document.body.innerHTML = buildRealMarketGridFixtureWithScopedAttributes();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user