Skip to content

Commit 5ccf63f

Browse files
d-csclaude
andcommitted
test(run-ops): stop RunPresenter read-seam test freezing on the first testcontainer
The RunStore singleton is built once at import and its error-normalizing wrapper memoizes each Prisma model delegate on first access. The test's delegating proxy returned current.taskRun directly, so the store cached the first test's container-bound delegate and later tests (fresh containers) failed with "Database test_0 does not exist". Object-valued delegates now return a stable per-key sub-proxy the store can safely cache, re-delegating to the live current client on each access. Production code is unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 82e91a4 commit 5ccf63f

1 file changed

Lines changed: 39 additions & 2 deletions

File tree

apps/webapp/test/runPresenterReadRoute.test.ts

Lines changed: 39 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,54 @@ import { describe, expect, vi } from "vitest";
1111

1212
vi.setConfig({ testTimeout: 60_000 });
1313

14-
// Hoisted alongside the vi.mock factory. `setCurrentPrisma` is called at the start
15-
// of each test to point the delegating Proxy at the real testcontainer client.
14+
// Hoisted alongside the vi.mock factory. `setCurrentPrisma` points the delegating
15+
// Proxy at each test's container. The RunStore singleton is built ONCE at import and
16+
// its error-normalizing wrapper memoizes each Prisma model delegate on first access;
17+
// returning `current.taskRun` directly would freeze the store onto the first test's
18+
// container ("Database test_0 does not exist" on later tests). So object-valued
19+
// delegates return a STABLE per-key sub-proxy the store can safely cache, which
20+
// re-delegates to the live `current[key]` on every access; functions/scalars pass
21+
// through to the live client.
1622
const { delegating, setCurrentPrisma } = vi.hoisted(() => {
1723
let current: any = undefined;
24+
const subProxyCache = new Map<string, unknown>();
25+
26+
const getSubProxy = (prop: string) => {
27+
const cached = subProxyCache.get(prop);
28+
if (cached) {
29+
return cached;
30+
}
31+
const subProxy = new Proxy(
32+
{},
33+
{
34+
get(_st, key) {
35+
if (!current) {
36+
throw new Error("currentPrisma not set");
37+
}
38+
const delegate = current[prop];
39+
const value = delegate?.[key];
40+
return typeof value === "function" ? value.bind(delegate) : value;
41+
},
42+
}
43+
);
44+
subProxyCache.set(prop, subProxy);
45+
return subProxy;
46+
};
47+
1848
const proxy = new Proxy(
1949
{},
2050
{
2151
get(_t, prop) {
2252
if (!current) {
2353
throw new Error("currentPrisma not set");
2454
}
55+
if (typeof prop === "string") {
56+
const value = current[prop];
57+
if (value != null && typeof value === "object") {
58+
return getSubProxy(prop);
59+
}
60+
return value;
61+
}
2562
return current[prop];
2663
},
2764
}

0 commit comments

Comments
 (0)