Skip to content

Commit 88ce4ed

Browse files
committed
chore: bump deps and improve test harness
1 parent 92aeeeb commit 88ce4ed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1251
-1118
lines changed

bun.lock

Lines changed: 75 additions & 663 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

bunfig.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,4 @@ linkWorkspacePackages = true
77
[test]
88
# Exclude test repositories from test execution to prevent timeouts
99
exclude = ["evals/test-repos/**"]
10-
preload = ["./sdk/test/setup-env.ts"]
10+
preload = ["./sdk/test/setup-env.ts", "./test/setup-bigquery-mocks.ts"]

cli/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,13 @@
3333
"@codebuff/sdk": "workspace:*",
3434
"@opentui/core": "^0.1.63",
3535
"@opentui/react": "^0.1.63",
36-
"@tanstack/react-query": "^5.62.8",
36+
"@tanstack/react-query": "^5.90.12",
3737
"commander": "^14.0.1",
3838
"immer": "^10.1.3",
3939
"jimp": "^1.6.0",
4040
"open": "^10.1.0",
4141
"pino": "9.4.0",
42-
"posthog-node": "4.17.2",
42+
"posthog-node": "^5.8.0",
4343
"react": "^19.0.0",
4444
"react-reconciler": "^0.32.0",
4545
"remark-breaks": "^4.0.0",
@@ -50,7 +50,7 @@
5050
"ts-pattern": "^5.9.0",
5151
"unified": "^11.0.0",
5252
"yoga-layout": "^3.2.1",
53-
"zod": "^4.0.0",
53+
"zod": "^4.2.1",
5454
"zustand": "^5.0.8"
5555
},
5656
"devDependencies": {

cli/src/__tests__/test-utils.ts

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,12 +37,68 @@ export const sleep = (ms: number) =>
3737

3838
let cachedEnv: Record<string, string> | null = null
3939

40+
const TEST_CLIENT_ENV_DEFAULTS: Record<string, string> = {
41+
NEXT_PUBLIC_CB_ENVIRONMENT: 'test',
42+
NEXT_PUBLIC_CODEBUFF_APP_URL: 'http://localhost:3000',
43+
NEXT_PUBLIC_SUPPORT_EMAIL: 'support@codebuff.com',
44+
NEXT_PUBLIC_POSTHOG_API_KEY: 'test-posthog-key',
45+
NEXT_PUBLIC_POSTHOG_HOST_URL: 'https://us.i.posthog.com',
46+
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY: 'pk_test_placeholder',
47+
NEXT_PUBLIC_STRIPE_CUSTOMER_PORTAL:
48+
'https://billing.stripe.com/p/login/test_placeholder',
49+
NEXT_PUBLIC_GOOGLE_SITE_VERIFICATION_ID: 'test-verification',
50+
NEXT_PUBLIC_WEB_PORT: '3000',
51+
}
52+
const TEST_SERVER_ENV_DEFAULTS: Record<string, string> = {
53+
OPEN_ROUTER_API_KEY: 'test',
54+
OPENAI_API_KEY: 'test',
55+
LINKUP_API_KEY: 'test',
56+
PORT: '4242',
57+
DATABASE_URL: 'postgres://user:pass@localhost:5432/db',
58+
CODEBUFF_GITHUB_ID: 'test-id',
59+
CODEBUFF_GITHUB_SECRET: 'test-secret',
60+
NEXTAUTH_SECRET: 'test-secret',
61+
STRIPE_SECRET_KEY: 'sk_test_dummy',
62+
STRIPE_WEBHOOK_SECRET_KEY: 'whsec_dummy',
63+
STRIPE_USAGE_PRICE_ID: 'price_test',
64+
STRIPE_TEAM_FEE_PRICE_ID: 'price_test',
65+
LOOPS_API_KEY: 'test',
66+
DISCORD_PUBLIC_KEY: 'test',
67+
DISCORD_BOT_TOKEN: 'test',
68+
DISCORD_APPLICATION_ID: 'test',
69+
}
70+
71+
function ensureCliEnvDefaults(): void {
72+
if (!process.env.NODE_ENV) {
73+
process.env.NODE_ENV = 'test'
74+
}
75+
if (!process.env.BUN_ENV) {
76+
process.env.BUN_ENV = 'test'
77+
}
78+
if (process.env.CI !== 'true' && process.env.CI !== '1') {
79+
process.env.CI = 'true'
80+
}
81+
82+
for (const [key, value] of Object.entries(TEST_CLIENT_ENV_DEFAULTS)) {
83+
if (!process.env[key]) {
84+
process.env[key] = value
85+
}
86+
}
87+
88+
for (const [key, value] of Object.entries(TEST_SERVER_ENV_DEFAULTS)) {
89+
if (!process.env[key]) {
90+
process.env[key] = value
91+
}
92+
}
93+
}
94+
4095
function loadCliEnv(): Record<string, string> {
4196
if (cachedEnv) {
4297
return cachedEnv
4398
}
4499

45100
try {
101+
ensureCliEnvDefaults()
46102
// NOTE: Inline require() is used for lazy loading - the env module depends on
47103
// Infisical secrets which may not be available at module load time in test environments
48104
const { env } = require('../../../packages/internal/src/env') as {

cli/src/__tests__/utils/env.test.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, test, expect, afterEach } from 'bun:test'
22

3-
import { getCliEnv, createTestCliEnv } from '../../utils/env'
3+
import { getCliEnv } from '../../utils/env'
4+
import { createTestCliEnv } from '../../testing/env'
45

56
describe('cli/utils/env', () => {
67
describe('getCliEnv', () => {

cli/src/hooks/__tests__/use-timeout.test.ts

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,33 @@
1+
import React from 'react'
12
import { describe, test, expect, beforeEach, afterEach, mock } from 'bun:test'
23

34
import { useTimeout } from '../use-timeout'
45

56
/**
67
* Tests for useTimeout hook
78
*
8-
* NOTE: These tests are currently skipped due to React 19 + Bun compatibility issues.
9-
* The renderHook utility from React Testing Library returns null results in this environment.
10-
* See cli/knowledge.md "React Testing Library + React 19 + Bun Incompatibility" section.
11-
*
12-
* The hook implementation follows the spec exactly and will be tested through integration
13-
* tests when used in actual components (e.g., in Part 5 when used for reconnection messages).
9+
* NOTE: Tests install a minimal React dispatcher so hooks can run without a renderer.
1410
*/
1511

1612
describe('useTimeout', () => {
13+
const reactInternals = (React as any)
14+
.__CLIENT_INTERNALS_DO_NOT_USE_OR_WARN_USERS_THEY_CANNOT_UPGRADE
1715
let originalSetTimeout: typeof setTimeout
1816
let originalClearTimeout: typeof clearTimeout
1917
let timers: { id: number; ms: number; fn: Function; cleared: boolean }[]
2018
let nextId: number
19+
let originalDispatcher: any
2120

2221
beforeEach(() => {
22+
originalDispatcher = reactInternals.H
23+
reactInternals.H = {
24+
useRef: (value: any) => ({ current: value }),
25+
useCallback: (callback: any) => callback,
26+
useEffect: (effect: any) => {
27+
effect()
28+
},
29+
}
30+
2331
timers = []
2432
nextId = 1
2533
originalSetTimeout = globalThis.setTimeout
@@ -40,11 +48,12 @@ describe('useTimeout', () => {
4048
})
4149

4250
afterEach(() => {
51+
reactInternals.H = originalDispatcher
4352
globalThis.setTimeout = originalSetTimeout
4453
globalThis.clearTimeout = originalClearTimeout
4554
})
4655

47-
test.skip('setTimeout schedules a timeout with correct delay', () => {
56+
test('setTimeout schedules a timeout with correct delay', () => {
4857
const { setTimeout } = useTimeout()
4958
const callback = mock(() => {})
5059

@@ -55,7 +64,7 @@ describe('useTimeout', () => {
5564
expect(timers[0].cleared).toBe(false)
5665
})
5766

58-
test.skip('timeout callback executes when invoked', () => {
67+
test('timeout callback executes when invoked', () => {
5968
const { setTimeout } = useTimeout()
6069
const callback = mock(() => {})
6170

@@ -69,7 +78,7 @@ describe('useTimeout', () => {
6978
expect(callback).toHaveBeenCalledTimes(1)
7079
})
7180

72-
test.skip('clearTimeout marks the timeout as cleared', () => {
81+
test('clearTimeout marks the timeout as cleared', () => {
7382
const { setTimeout, clearTimeout } = useTimeout()
7483
const callback = mock(() => {})
7584

@@ -80,7 +89,7 @@ describe('useTimeout', () => {
8089
expect(timers[0].cleared).toBe(true)
8190
})
8291

83-
test.skip('clearTimeout prevents callback from being used', () => {
92+
test('clearTimeout prevents callback from being used', () => {
8493
const { setTimeout, clearTimeout } = useTimeout()
8594
const callback = mock(() => {})
8695

@@ -92,7 +101,7 @@ describe('useTimeout', () => {
92101
expect(timers[0].cleared).toBe(true)
93102
})
94103

95-
test.skip('replacing timeout with same key clears the previous one', () => {
104+
test('replacing timeout with same key clears the previous one', () => {
96105
const { setTimeout } = useTimeout()
97106
const callback1 = mock(() => {})
98107
const callback2 = mock(() => {})
@@ -108,7 +117,7 @@ describe('useTimeout', () => {
108117
expect(timers[1].ms).toBe(2000)
109118
})
110119

111-
test.skip('clearTimeout when no timeout is active does nothing', () => {
120+
test('clearTimeout when no timeout is active does nothing', () => {
112121
const { clearTimeout } = useTimeout()
113122

114123
// Should not throw
@@ -117,7 +126,7 @@ describe('useTimeout', () => {
117126
expect(timers.length).toBe(0)
118127
})
119128

120-
test.skip('multiple setTimeout calls with different keys work independently', () => {
129+
test('multiple setTimeout calls with different keys work independently', () => {
121130
const { setTimeout } = useTimeout()
122131
const callbacks = [mock(() => {}), mock(() => {}), mock(() => {})]
123132

@@ -131,7 +140,7 @@ describe('useTimeout', () => {
131140
expect(timers[2].cleared).toBe(false)
132141
})
133142

134-
test.skip('setTimeout after clearTimeout works correctly', () => {
143+
test('setTimeout after clearTimeout works correctly', () => {
135144
const { setTimeout, clearTimeout } = useTimeout()
136145
const callback1 = mock(() => {})
137146
const callback2 = mock(() => {})
@@ -145,7 +154,7 @@ describe('useTimeout', () => {
145154
expect(timers[1].cleared).toBe(false)
146155
})
147156

148-
test.skip('hook returns stable setTimeout and clearTimeout functions', () => {
157+
test('hook returns distinct setTimeout and clearTimeout functions', () => {
149158
const result1 = useTimeout()
150159
const result2 = useTimeout()
151160

@@ -154,7 +163,7 @@ describe('useTimeout', () => {
154163
expect(result1.clearTimeout).not.toBe(result2.clearTimeout)
155164
})
156165

157-
test.skip('clearTimeout without key clears all timeouts', () => {
166+
test('clearTimeout without key clears all timeouts', () => {
158167
const { setTimeout, clearTimeout } = useTimeout()
159168
const callbacks = [mock(() => {}), mock(() => {}), mock(() => {})]
160169

@@ -174,7 +183,7 @@ describe('useTimeout', () => {
174183
expect(timers[2].cleared).toBe(true)
175184
})
176185

177-
test.skip('clearTimeout with specific key only clears that timeout', () => {
186+
test('clearTimeout with specific key only clears that timeout', () => {
178187
const { setTimeout, clearTimeout } = useTimeout()
179188
const callbacks = [mock(() => {}), mock(() => {}), mock(() => {})]
180189

@@ -189,7 +198,7 @@ describe('useTimeout', () => {
189198
expect(timers[2].cleared).toBe(false)
190199
})
191200

192-
test.skip('timeout auto-cleans up after execution', () => {
201+
test('timeout auto-cleans up after execution', () => {
193202
const { setTimeout } = useTimeout()
194203
const callback = mock(() => {})
195204

@@ -203,7 +212,7 @@ describe('useTimeout', () => {
203212
// but the implementation removes the key from the Map after execution
204213
})
205214

206-
test.skip('can reuse same key after timeout executes', () => {
215+
test('can reuse same key after timeout executes', () => {
207216
const { setTimeout } = useTimeout()
208217
const callback1 = mock(() => {})
209218
const callback2 = mock(() => {})
@@ -222,7 +231,7 @@ describe('useTimeout', () => {
222231
expect(timers[1].cleared).toBe(false)
223232
})
224233

225-
test.skip('multiple timeouts can execute independently', () => {
234+
test('multiple timeouts can execute independently', () => {
226235
const { setTimeout } = useTimeout()
227236
const callback1 = mock(() => {})
228237
const callback2 = mock(() => {})
@@ -242,7 +251,7 @@ describe('useTimeout', () => {
242251
expect(callback3).toHaveBeenCalledTimes(1)
243252
})
244253

245-
test.skip('replacing timeout before execution prevents old callback', () => {
254+
test('replacing timeout before execution prevents old callback', () => {
246255
const { setTimeout } = useTimeout()
247256
const oldCallback = mock(() => {})
248257
const newCallback = mock(() => {})
@@ -261,7 +270,7 @@ describe('useTimeout', () => {
261270
expect(newCallback).toHaveBeenCalledTimes(1)
262271
})
263272

264-
test.skip('clearTimeout on executed timeout does nothing', () => {
273+
test('clearTimeout on executed timeout does nothing', () => {
265274
const { setTimeout, clearTimeout } = useTimeout()
266275
const callback = mock(() => {})
267276

@@ -276,7 +285,7 @@ describe('useTimeout', () => {
276285
expect(timers.length).toBe(1)
277286
})
278287

279-
test.skip('mixing set and clear operations maintains correct state', () => {
288+
test('mixing set and clear operations maintains correct state', () => {
280289
const { setTimeout, clearTimeout } = useTimeout()
281290

282291
setTimeout(

0 commit comments

Comments
 (0)