diff --git a/packages/ui/src/stores/detail.svelte.test.ts b/packages/ui/src/stores/detail.svelte.test.ts index cad1db0e7..05ab85721 100644 --- a/packages/ui/src/stores/detail.svelte.test.ts +++ b/packages/ui/src/stores/detail.svelte.test.ts @@ -1,4 +1,4 @@ -import { describe, expect, it, vi } from "vite-plus/test"; +import { afterEach, describe, expect, it, vi } from "vite-plus/test"; import type { PullDetail } from "../api/types.js"; import type { MiddlemanClient } from "../types.js"; @@ -40,6 +40,10 @@ function mockClient(overrides: Partial = {}): MiddlemanClient { } describe("createDetailStore", () => { + afterEach(() => { + vi.useRealTimers(); + }); + it("syncs detail and resolves after applying the refreshed head", async () => { const post = vi.fn().mockResolvedValue({ data: pullDetail("fresh-head"), @@ -62,4 +66,32 @@ describe("createDetailStore", () => { expect(store.getDetail()?.platform_head_sha).toBe("fresh-head"); expect(pulls.loadPulls).toHaveBeenCalledTimes(1); }); + + it("enqueues background sync when active detail polling fires", async () => { + vi.useFakeTimers(); + const post = vi.fn().mockResolvedValue({ error: undefined }); + const get = vi.fn().mockResolvedValue({ data: pullDetail("cached-head") }); + const store = createDetailStore({ + client: mockClient({ GET: get, POST: post }), + }); + + store.startDetailPolling("acme", "widget", 7, { + provider: "github", + platformHost: "github.com", + repoPath: "acme/widget", + }); + + await vi.advanceTimersByTimeAsync(60_000); + + expect(post).toHaveBeenCalledWith("/pulls/{provider}/{owner}/{name}/{number}/sync/async", { + params: { + path: { + provider: "github", + owner: "acme", + name: "widget", + number: 7, + }, + }, + }); + }); }); diff --git a/packages/ui/src/stores/detail.svelte.ts b/packages/ui/src/stores/detail.svelte.ts index 88f8f9d1d..286b1f287 100644 --- a/packages/ui/src/stores/detail.svelte.ts +++ b/packages/ui/src/stores/detail.svelte.ts @@ -908,7 +908,7 @@ export function createDetailStore(opts: DetailStoreOptions) { const ref = detailRequestRef(owner, name, number, identity); stopDetailPolling(); detailPollHandle = setInterval(() => { - void refreshDetail(owner, name, number, syncGeneration, ref); + void enqueueBackgroundDetailSync(owner, name, number, syncGeneration, detail?.detail_fetched_at, ref); }, 60_000); if (syncDep) { unsubSyncComplete = syncDep.subscribeSyncComplete(() => {