fix: recover favorites controller refresh

This commit is contained in:
wxs
2026-07-17 15:32:51 +08:00
parent 8ebb50524c
commit 01efa9f847
2 changed files with 69 additions and 5 deletions
+60 -3
View File
@@ -4872,7 +4872,7 @@ describe("market-content-entry", () => {
expect(document.querySelector('[data-plugin-batch-submit="button"]')).not.toBeNull();
});
test("clears stale favorite pickers when a later repository refresh fails", async () => {
test("recovers favorite pickers after a later refresh failure and page replacement", async () => {
document.body.innerHTML = buildRealMarketFixture([
{ authorId: "111", authorName: "达人 A", price21To60s: "¥11,000" }
]);
@@ -4881,12 +4881,13 @@ describe("market-content-entry", () => {
await repository.setCreatorFolderIds({ authorId: "111", authorName: "达人 A" }, [folder.id]);
const originalRead = repository.read.bind(repository);
let shouldRejectRead = false;
repository.read = async () => {
const read = vi.fn(async () => {
if (shouldRejectRead) {
throw new Error("storage unavailable");
}
return originalRead();
};
});
repository.read = read;
const observer = createMutationObserverFactory();
const { createMarketController } = await import("../src/content/market/index");
@@ -4916,6 +4917,62 @@ describe("market-content-entry", () => {
expect(document.querySelector('[data-sces-favorite-row-action="button"]')).toBeNull();
expect(document.querySelector('[data-plugin-export="button"]')).not.toBeNull();
shouldRejectRead = false;
document.documentElement.setAttribute("data-test-page-index", "2");
document.querySelector('[data-testid="action-cell-111"]')!.replaceChildren(
document.createTextNode("下单")
);
observer.trigger();
await waitForCondition(
() =>
document.querySelector('[data-sces-favorite-row-action="button"]')?.dataset
.scesFavoriteState === "saved"
);
expect(read).toHaveBeenCalledTimes(3);
expect(document.querySelector('[data-sces-favorites-drawer="error"]')).toBeNull();
});
test("settles the initial observer resync 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();
let shouldScheduleInitialResync = true;
repository.read = async () => {
if (shouldScheduleInitialResync) {
shouldScheduleInitialResync = false;
document.querySelector('[data-plugin-toolbar="root"]')?.remove();
observer.trigger();
}
return originalRead();
};
const buildCsv = vi.fn(() => "csv-output");
const { createMarketController } = await import("../src/content/market/index");
const controller = trackController(createMarketController({
buildCsv,
document,
favoritesRepository: repository,
loadAuthorMetrics: async () => ({ success: false, reason: "request-failed" }),
mutationObserverFactory: observer.factory,
onCsvReady: vi.fn(),
window
}));
await controller.ready;
expect(document.querySelector('[data-plugin-toolbar="root"]')).not.toBeNull();
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);
});
test("keeps the friendly drawer error when a direct folder mutation has no message", async () => {