refactor!: simplify query and session ownership
Use Query cancellation and native mutation results instead of HTTP registries, access epochs and copied scope state. Keep local auth ordering and mutation identity fences. Allow staged generated files to remain excluded from ESLint. Backend contract: WealthLedger/backend@d698ed9 BREAKING CHANGE: drop investment stateVersion/progress/resources from the client contract and use data/metadata readiness instead of rewritten query status. Cross-tab auth may require re-login.
This commit is contained in:
@@ -21,7 +21,7 @@ function auth() {
|
||||
}
|
||||
|
||||
describe("page-owned screen synchronization", () => {
|
||||
it("ignores a late sync acceptance after the account scope changes", async () => {
|
||||
it("keeps the current scope when an older sync acceptance arrives last", async () => {
|
||||
auth();
|
||||
|
||||
const { promise: blocked, resolve: release }
|
||||
@@ -37,7 +37,7 @@ describe("page-owned screen synchronization", () => {
|
||||
};
|
||||
|
||||
posted.push(scope.accountId);
|
||||
await blocked;
|
||||
if (scope.accountId === "old") await blocked;
|
||||
|
||||
return HttpResponse.json(
|
||||
{ id: scope.accountId, now: "2026-09-25T00:00:00Z", scope },
|
||||
@@ -49,7 +49,6 @@ describe("page-owned screen synchronization", () => {
|
||||
|
||||
return HttpResponse.json({
|
||||
id: params.id,
|
||||
resources: [],
|
||||
state: "succeeded",
|
||||
});
|
||||
}),
|
||||
@@ -69,12 +68,13 @@ describe("page-owned screen synchronization", () => {
|
||||
});
|
||||
await waitFor(() => expect(posted).toEqual(["old"]));
|
||||
rerender({ accountId: "new" });
|
||||
await act(() => result.current.refresh());
|
||||
await waitFor(() => expect(polled).toEqual(["new"]));
|
||||
await act(async () => {
|
||||
release();
|
||||
await pending;
|
||||
});
|
||||
await act(() => result.current.refresh());
|
||||
await waitFor(() => expect(polled).toEqual(["new"]));
|
||||
expect(polled).toEqual(["new"]);
|
||||
expect(posted).toEqual(["old", "new"]);
|
||||
});
|
||||
it.each([false, true])(
|
||||
@@ -91,7 +91,7 @@ describe("page-owned screen synchronization", () => {
|
||||
return isUnavailable
|
||||
? HttpResponse.json({ code: "UNAVAILABLE" }, { status: 503 })
|
||||
: HttpResponse.json(
|
||||
resource([], { stateVersion: String(modes.length) }),
|
||||
resource([], { dataRevision: String(modes.length) }),
|
||||
);
|
||||
}),
|
||||
http.post("*/api/v1/tbank-sync", () => {
|
||||
@@ -129,7 +129,7 @@ describe("page-owned screen synchronization", () => {
|
||||
isUnavailable = false;
|
||||
await act(() => result.current.sync.retry());
|
||||
await waitFor(() => expect(result.current.accounts.isSuccess).toBe(true));
|
||||
expect(result.current.accounts.meta?.stateVersion).toBe(
|
||||
expect(result.current.accounts.meta?.dataRevision).toBe(
|
||||
cached ? "3" : "2",
|
||||
);
|
||||
expect(modes).toEqual(
|
||||
@@ -169,15 +169,15 @@ describe("page-owned screen synchronization", () => {
|
||||
server.use(
|
||||
http.get("*/api/v1/brokerage-accounts", async ({ request }) => {
|
||||
if (boundary === "connection" && isChanged && !request.signal.aborted)
|
||||
return HttpResponse.json(resource([], { stateVersion: "current" }));
|
||||
return HttpResponse.json(resource([], { dataRevision: "current" }));
|
||||
if (!new URL(request.url).searchParams.has("sync"))
|
||||
return isChanged
|
||||
? HttpResponse.json(resource([], { stateVersion: "current" }))
|
||||
? HttpResponse.json(resource([], { dataRevision: "current" }))
|
||||
: HttpResponse.json({ code: "UNAVAILABLE" }, { status: 503 });
|
||||
isRecovering = true;
|
||||
await blocked;
|
||||
|
||||
return HttpResponse.json(resource([], { stateVersion: "old" }));
|
||||
return HttpResponse.json(resource([], { dataRevision: "old" }));
|
||||
}),
|
||||
);
|
||||
const { queryClient, wrapper } = createQueryWrapper();
|
||||
@@ -247,11 +247,11 @@ describe("page-owned screen synchronization", () => {
|
||||
if (boundary === "connection")
|
||||
await waitFor(() =>
|
||||
// eslint-disable-next-line vitest/no-conditional-expect -- The fixed table case selects the expected outcome; every case asserts its own branch.
|
||||
expect(result.current.accounts.meta?.stateVersion).toBe("current"),
|
||||
expect(result.current.accounts.meta?.dataRevision).toBe("current"),
|
||||
);
|
||||
expect(published).not.toContainEqual(
|
||||
expect.objectContaining({
|
||||
meta: expect.objectContaining({ stateVersion: "old" }) as unknown,
|
||||
meta: expect.objectContaining({ dataRevision: "old" }) as unknown,
|
||||
}),
|
||||
);
|
||||
unsubscribe();
|
||||
@@ -281,7 +281,6 @@ describe("page-owned screen synchronization", () => {
|
||||
? HttpResponse.json({ code: "UNAVAILABLE" }, { status: 503 })
|
||||
: HttpResponse.json({
|
||||
id: "recover",
|
||||
resources: [resource([]).meta],
|
||||
state: "succeeded",
|
||||
});
|
||||
}),
|
||||
@@ -316,7 +315,8 @@ describe("page-owned screen synchronization", () => {
|
||||
await waitFor(() => expect(result.current.accounts.isSuccess).toBe(true));
|
||||
expect(result.current.accounts.data).toEqual([]);
|
||||
|
||||
expect(modes).toEqual([null, "observe"]);
|
||||
expect(modes[0]).toBeNull();
|
||||
expect(modes.slice(1).every(mode => mode === "observe")).toBe(true);
|
||||
expect(
|
||||
queryClient
|
||||
.getQueryCache()
|
||||
@@ -332,7 +332,7 @@ describe("page-owned screen synchronization", () => {
|
||||
let polls = 0;
|
||||
|
||||
const meta = () =>
|
||||
resource([], { stateVersion: isCompleted ? "2" : "1" }).meta;
|
||||
resource([], { dataRevision: isCompleted ? "2" : "1" }).meta;
|
||||
|
||||
server.use(
|
||||
http.get("*/api/v1/brokerage-accounts", ({ request }) => {
|
||||
@@ -361,8 +361,6 @@ describe("page-owned screen synchronization", () => {
|
||||
errorCode: null,
|
||||
id: "screen",
|
||||
now: "2026-09-25T00:00:00Z",
|
||||
progress: { completed: 1, discovering: false, total: 1 },
|
||||
resources: [meta()],
|
||||
scope: { screen: "accounts" },
|
||||
state: "succeeded",
|
||||
},
|
||||
@@ -390,7 +388,7 @@ describe("page-owned screen synchronization", () => {
|
||||
]);
|
||||
});
|
||||
await waitFor(() =>
|
||||
expect(result.current.accounts.meta?.stateVersion).toBe("2"),
|
||||
expect(result.current.accounts.meta?.dataRevision).toBe("2"),
|
||||
);
|
||||
expect(bodies).toEqual([{ screen: "accounts" }]);
|
||||
|
||||
@@ -427,7 +425,7 @@ describe("page-owned screen synchronization", () => {
|
||||
? []
|
||||
: null,
|
||||
{
|
||||
stateVersion: isCompleted ? "covered" : "initial",
|
||||
dataRevision: isCompleted ? "covered" : "initial",
|
||||
sync: { errorCode: null, id: "history", state: "running" },
|
||||
},
|
||||
);
|
||||
@@ -446,12 +444,6 @@ describe("page-owned screen synchronization", () => {
|
||||
errorCode: null,
|
||||
id: "history",
|
||||
now: "2026-09-25T00:00:00Z",
|
||||
progress: {
|
||||
completed: isCompleted ? 1 : 0,
|
||||
discovering: true,
|
||||
total: 2,
|
||||
},
|
||||
resources: [snapshot().meta],
|
||||
scope: null,
|
||||
state: "running",
|
||||
},
|
||||
@@ -487,7 +479,8 @@ describe("page-owned screen synchronization", () => {
|
||||
await new Promise(resolve => setTimeout(resolve, 1100));
|
||||
});
|
||||
|
||||
expect(modes).toEqual([null, "observe"]);
|
||||
expect(modes[0]).toBeNull();
|
||||
expect(modes.slice(1).every(mode => mode === "observe")).toBe(true);
|
||||
if (boundary === "leave") unmount();
|
||||
else act(() => configureAuthClient());
|
||||
const stopped = polls;
|
||||
@@ -545,8 +538,8 @@ describe("page-owned screen synchronization", () => {
|
||||
|
||||
[],
|
||||
{
|
||||
dataRevision: isObserved ? "covered" : "initial",
|
||||
resourceKey: "operations",
|
||||
stateVersion: isObserved ? "covered" : "initial",
|
||||
sync: {
|
||||
errorCode: null,
|
||||
id: "dependency",
|
||||
@@ -570,7 +563,7 @@ describe("page-owned screen synchronization", () => {
|
||||
dependencies: [
|
||||
{
|
||||
...dependency,
|
||||
stateVersion: isObserved ? "covered" : "initial",
|
||||
dataRevision: isObserved ? "covered" : "initial",
|
||||
},
|
||||
],
|
||||
resourceKey: "projection",
|
||||
@@ -585,8 +578,6 @@ describe("page-owned screen synchronization", () => {
|
||||
errorCode: null,
|
||||
id: "dependency",
|
||||
now: "2026-09-25T00:00:00Z",
|
||||
progress: { completed: 1, discovering: false, total: 1 },
|
||||
resources: [{ ...dependency, stateVersion: "covered" }],
|
||||
scope: null,
|
||||
state: "succeeded",
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user