fix: await initial market synchronization
This commit is contained in:
@@ -4975,6 +4975,85 @@ describe("market-content-entry", () => {
|
||||
expect(buildCsv).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
test("awaits a scheduled initial hydration before ready enables an immediate export", async () => {
|
||||
document.body.innerHTML = buildRealMarketFixture([
|
||||
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" }
|
||||
]);
|
||||
const repository = createTestFavoritesRepository();
|
||||
const originalRead = repository.read.bind(repository);
|
||||
const observer = createMutationObserverFactory();
|
||||
const successfulMetrics = {
|
||||
rates: {
|
||||
personalVideoAfterSearchRate: "0.2%",
|
||||
singleVideoAfterSearchRate: "0.1%"
|
||||
},
|
||||
success: true as const
|
||||
};
|
||||
const deferredMetrics = createDeferred<typeof successfulMetrics>();
|
||||
let shouldReplaceInitialPage = true;
|
||||
let activeMetricLoads = 0;
|
||||
let maxActiveMetricLoads = 0;
|
||||
repository.read = async () => {
|
||||
const state = await originalRead();
|
||||
if (shouldReplaceInitialPage) {
|
||||
shouldReplaceInitialPage = false;
|
||||
document.body.innerHTML = buildRealMarketFixture([
|
||||
{ authorId: "222", authorName: "达人 B", price21To60s: "¥22,000" }
|
||||
]);
|
||||
observer.trigger();
|
||||
}
|
||||
return state;
|
||||
};
|
||||
const loadAuthorMetrics = vi.fn(async (authorId: string) => {
|
||||
activeMetricLoads += 1;
|
||||
maxActiveMetricLoads = Math.max(maxActiveMetricLoads, activeMetricLoads);
|
||||
try {
|
||||
if (authorId === "222") {
|
||||
return await deferredMetrics.promise;
|
||||
}
|
||||
return successfulMetrics;
|
||||
} finally {
|
||||
activeMetricLoads -= 1;
|
||||
}
|
||||
});
|
||||
const buildCsv = vi.fn(() => "csv-output");
|
||||
|
||||
const { createMarketController } = await import("../src/content/market/index");
|
||||
const controller = trackController(createMarketController({
|
||||
buildCsv,
|
||||
document,
|
||||
favoritesRepository: repository,
|
||||
loadAuthorMetrics,
|
||||
mutationObserverFactory: observer.factory,
|
||||
onCsvReady: vi.fn(),
|
||||
window
|
||||
}));
|
||||
let readySettled = false;
|
||||
void controller.ready.then(() => {
|
||||
readySettled = true;
|
||||
});
|
||||
|
||||
await waitForCondition(() =>
|
||||
loadAuthorMetrics.mock.calls.some(([authorId]) => authorId === "222")
|
||||
);
|
||||
await Promise.resolve();
|
||||
|
||||
expect(readySettled).toBe(false);
|
||||
|
||||
deferredMetrics.resolve(successfulMetrics);
|
||||
await controller.ready;
|
||||
|
||||
setSelectValue('[data-plugin-export-range="select"]', "current");
|
||||
dispatchChange('[data-plugin-export-range="select"]');
|
||||
removeDefaultSpreadMetricFilter();
|
||||
click('[data-plugin-export="button"]');
|
||||
await waitForMockCall(buildCsv, 40, 50);
|
||||
|
||||
expect(buildCsv).toHaveBeenCalledTimes(1);
|
||||
expect(loadAuthorMetrics.mock.calls.map(([authorId]) => authorId)).toEqual(["111", "222"]);
|
||||
expect(maxActiveMetricLoads).toBe(1);
|
||||
});
|
||||
|
||||
test("keeps the friendly drawer error when a direct folder mutation has no message", async () => {
|
||||
document.body.innerHTML = buildRealMarketFixture([
|
||||
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" }
|
||||
|
||||
Reference in New Issue
Block a user