Skip to content

Commit e494d19

Browse files
committed
Merge remote-tracking branch 'origin/main' into brandon/mock-db
# Conflicts: # web/jest.config.cjs # web/playwright.config.ts # web/src/__tests__/e2e/store-ssr.e2e.ts
2 parents c05b299 + 8d33c52 commit e494d19

File tree

100 files changed

+4518
-839
lines changed

Some content is hidden

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

100 files changed

+4518
-839
lines changed

bun.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cli/src/__tests__/README.md

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ The `.bin/bun` wrapper automatically checks for tmux when running integration/E2
8484
- **Skips** tests gracefully if tmux unavailable
8585

8686
**Benefits:**
87+
8788
- ✅ Project-wide (works in any package)
8889
- ✅ No hardcoded paths
8990
- ✅ Clear test categorization
@@ -165,17 +166,19 @@ await sleep(1000)
165166
## tmux Testing
166167

167168
**See [`../../tmux.knowledge.md`](../../tmux.knowledge.md) for comprehensive tmux documentation**, including:
169+
168170
- Why standard `send-keys` doesn't work (must use bracketed paste mode)
169171
- Helper functions for Bash and TypeScript
170172
- Complete example scripts
171173
- Debugging and troubleshooting tips
172174

173175
**Quick reference:**
176+
174177
```typescript
175-
// ❌ Broken:
178+
// ❌ Broken:
176179
await tmux(['send-keys', '-t', session, 'hello'])
177180

178-
// ✅ Works:
181+
// ✅ Works:
179182
await tmux(['send-keys', '-t', session, '-l', '\x1b[200~hello\x1b[201~'])
180183
```
181184

cli/src/__tests__/bash-mode.test.ts

Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,8 @@ describe('bash-mode', () => {
8989
}
9090
const inputMode = 'bash' as InputMode
9191

92-
const userTypedBang = inputMode === ('default' as InputMode) && inputValue.text === '!'
92+
const userTypedBang =
93+
inputMode === ('default' as InputMode) && inputValue.text === '!'
9394

9495
if (userTypedBang) {
9596
setInputMode('bash')
@@ -231,15 +232,17 @@ describe('bash-mode', () => {
231232
const trimmedInput = 'ls -la' // The stored value WITHOUT '!'
232233

233234
// Router logic prepends '!' when in bash mode
234-
const commandWithBang = inputMode === 'bash' ? '!' + trimmedInput : trimmedInput
235+
const commandWithBang =
236+
inputMode === 'bash' ? '!' + trimmedInput : trimmedInput
235237

236238
expect(commandWithBang).toBe('!ls -la')
237239
})
238240

239241
test('submission displays "!" in user message', () => {
240242
const inputMode: InputMode = 'bash'
241243
const trimmedInput = 'pwd'
242-
const commandWithBang = inputMode === 'bash' ? '!' + trimmedInput : trimmedInput
244+
const commandWithBang =
245+
inputMode === 'bash' ? '!' + trimmedInput : trimmedInput
243246

244247
// The user message should show the command WITH '!'
245248
const userMessage = { content: commandWithBang }
@@ -291,8 +294,14 @@ describe('bash-mode', () => {
291294
describe('bash mode UI state', () => {
292295
test('input mode is stored separately from input value', () => {
293296
// The inputMode is independent of the input text
294-
const state1: { inputMode: InputMode; inputValue: string } = { inputMode: 'bash', inputValue: 'ls' }
295-
const state2: { inputMode: InputMode; inputValue: string } = { inputMode: 'default', inputValue: 'hello' }
297+
const state1: { inputMode: InputMode; inputValue: string } = {
298+
inputMode: 'bash',
299+
inputValue: 'ls',
300+
}
301+
const state2: { inputMode: InputMode; inputValue: string } = {
302+
inputMode: 'default',
303+
inputValue: 'hello',
304+
}
296305

297306
expect(state1.inputMode).toBe('bash')
298307
expect(state1.inputValue).not.toContain('!')
@@ -317,7 +326,9 @@ describe('bash-mode', () => {
317326
const inputModeValue = 'default' as InputMode
318327

319328
const adjustedInputWidth =
320-
inputModeValue === ('bash' as InputMode) ? baseInputWidth - 2 : baseInputWidth
329+
inputModeValue === ('bash' as InputMode)
330+
? baseInputWidth - 2
331+
: baseInputWidth
321332

322333
expect(adjustedInputWidth).toBe(100)
323334
})
@@ -339,7 +350,9 @@ describe('bash-mode', () => {
339350
const inputMode = 'default' as InputMode
340351

341352
const effectivePlaceholder =
342-
inputMode === ('bash' as InputMode) ? bashPlaceholder : normalPlaceholder
353+
inputMode === ('bash' as InputMode)
354+
? bashPlaceholder
355+
: normalPlaceholder
343356

344357
expect(effectivePlaceholder).toBe('Ask Buffy anything...')
345358
})

cli/src/__tests__/e2e-cli.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import path from 'path'
44
import { describe, test, expect } from 'bun:test'
55
import stripAnsi from 'strip-ansi'
66

7-
87
import { isSDKBuilt, ensureCliTestEnv } from './test-utils'
98

109
const CLI_PATH = path.join(__dirname, '../index.tsx')

cli/src/__tests__/e2e/logout-relogin-flow.test.ts

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,8 +19,8 @@ import {
1919
} from '../../utils/auth'
2020
import { setProjectRoot } from '../../project-files'
2121

22-
import type * as AuthModule from '../../utils/auth'
23-
import type * as CodebuffApiModule from '../../utils/codebuff-api'
22+
import * as AuthModule from '../../utils/auth'
23+
import * as CodebuffApiModule from '../../utils/codebuff-api'
2424

2525
type User = AuthModule.User
2626

@@ -57,16 +57,14 @@ describe('Logout and Re-login helpers', () => {
5757
})
5858

5959
const mockConfigPaths = () => {
60-
const authModule = require('../../utils/auth') as typeof AuthModule
61-
spyOn(authModule, 'getConfigDir').mockReturnValue(tempConfigDir)
62-
spyOn(authModule, 'getCredentialsPath').mockReturnValue(
60+
spyOn(AuthModule, 'getConfigDir').mockReturnValue(tempConfigDir)
61+
spyOn(AuthModule, 'getCredentialsPath').mockReturnValue(
6362
path.join(tempConfigDir, 'credentials.json'),
6463
)
6564
}
6665

6766
const mockLogoutApi = () => {
68-
const apiModule = require('../../utils/codebuff-api') as typeof CodebuffApiModule
69-
spyOn(apiModule, 'getApiClient').mockReturnValue({
67+
spyOn(CodebuffApiModule, 'getApiClient').mockReturnValue({
7068
logout: async () => ({ ok: true, status: 200 }),
7169
} as any)
7270
}

cli/src/__tests__/e2e/returning-user-auth.test.ts

Lines changed: 8 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,9 @@ import {
1313
spyOn,
1414
} from 'bun:test'
1515

16-
1716
import { validateApiKey } from '../../hooks/use-auth-query'
18-
import {
19-
getAuthTokenDetails,
20-
saveUserCredentials,
21-
} from '../../utils/auth'
22-
23-
import type * as AuthModule from '../../utils/auth'
17+
import * as AuthModule from '../../utils/auth'
18+
import { getAuthTokenDetails, saveUserCredentials } from '../../utils/auth'
2419
import type { GetUserInfoFromApiKeyFn } from '@codebuff/common/types/contracts/database'
2520
import type { Logger } from '@codebuff/common/types/contracts/logger'
2621

@@ -62,10 +57,8 @@ describe('Returning User Authentication helpers', () => {
6257
})
6358

6459
test('should load auth token from credentials file for returning user', () => {
65-
const authModule = require('../../utils/auth') as typeof AuthModule
66-
67-
spyOn(authModule, 'getConfigDir').mockReturnValue(tempConfigDir)
68-
spyOn(authModule, 'getCredentialsPath').mockReturnValue(
60+
spyOn(AuthModule, 'getConfigDir').mockReturnValue(tempConfigDir)
61+
spyOn(AuthModule, 'getCredentialsPath').mockReturnValue(
6962
path.join(tempConfigDir, 'credentials.json'),
7063
)
7164

@@ -77,10 +70,8 @@ describe('Returning User Authentication helpers', () => {
7770
})
7871

7972
test('should fall back to CODEBUFF_API_KEY when credentials are missing', () => {
80-
const authModule = require('../../utils/auth') as typeof AuthModule
81-
82-
spyOn(authModule, 'getConfigDir').mockReturnValue(tempConfigDir)
83-
spyOn(authModule, 'getCredentialsPath').mockReturnValue(
73+
spyOn(AuthModule, 'getConfigDir').mockReturnValue(tempConfigDir)
74+
spyOn(AuthModule, 'getCredentialsPath').mockReturnValue(
8475
path.join(tempConfigDir, 'credentials.json'),
8576
)
8677

@@ -92,10 +83,8 @@ describe('Returning User Authentication helpers', () => {
9283
})
9384

9485
test('should validate stored credentials without blocking the UI thread', async () => {
95-
const authModule = require('../../utils/auth') as typeof AuthModule
96-
97-
spyOn(authModule, 'getConfigDir').mockReturnValue(tempConfigDir)
98-
spyOn(authModule, 'getCredentialsPath').mockReturnValue(
86+
spyOn(AuthModule, 'getConfigDir').mockReturnValue(tempConfigDir)
87+
spyOn(AuthModule, 'getCredentialsPath').mockReturnValue(
9988
path.join(tempConfigDir, 'credentials.json'),
10089
)
10190

cli/src/__tests__/helpers/mock-api-client.ts

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,18 +37,28 @@ export const createMockApiClient = (
3737
overrides: MockApiClientOverrides = {},
3838
): CodebuffApiClient => ({
3939
get: (overrides.get ?? mock(defaultOkResponse)) as CodebuffApiClient['get'],
40-
post: (overrides.post ?? mock(defaultOkResponse)) as CodebuffApiClient['post'],
40+
post: (overrides.post ??
41+
mock(defaultOkResponse)) as CodebuffApiClient['post'],
4142
put: (overrides.put ?? mock(defaultOkResponse)) as CodebuffApiClient['put'],
42-
patch: (overrides.patch ?? mock(defaultOkResponse)) as CodebuffApiClient['patch'],
43-
delete: (overrides.delete ?? mock(defaultOkResponse)) as CodebuffApiClient['delete'],
44-
request: (overrides.request ?? mock(defaultOkResponse)) as CodebuffApiClient['request'],
43+
patch: (overrides.patch ??
44+
mock(defaultOkResponse)) as CodebuffApiClient['patch'],
45+
delete: (overrides.delete ??
46+
mock(defaultOkResponse)) as CodebuffApiClient['delete'],
47+
request: (overrides.request ??
48+
mock(defaultOkResponse)) as CodebuffApiClient['request'],
4549
me: (overrides.me ?? mock(defaultOkResponse)) as CodebuffApiClient['me'],
46-
usage: (overrides.usage ?? mock(defaultOkResponse)) as CodebuffApiClient['usage'],
47-
loginCode: (overrides.loginCode ?? mock(defaultOkResponse)) as CodebuffApiClient['loginCode'],
48-
loginStatus: (overrides.loginStatus ?? mock(defaultOkResponse)) as CodebuffApiClient['loginStatus'],
49-
referral: (overrides.referral ?? mock(defaultOkResponse)) as CodebuffApiClient['referral'],
50-
publish: (overrides.publish ?? mock(defaultOkResponse)) as CodebuffApiClient['publish'],
51-
logout: (overrides.logout ?? mock(defaultOkResponse)) as CodebuffApiClient['logout'],
50+
usage: (overrides.usage ??
51+
mock(defaultOkResponse)) as CodebuffApiClient['usage'],
52+
loginCode: (overrides.loginCode ??
53+
mock(defaultOkResponse)) as CodebuffApiClient['loginCode'],
54+
loginStatus: (overrides.loginStatus ??
55+
mock(defaultOkResponse)) as CodebuffApiClient['loginStatus'],
56+
referral: (overrides.referral ??
57+
mock(defaultOkResponse)) as CodebuffApiClient['referral'],
58+
publish: (overrides.publish ??
59+
mock(defaultOkResponse)) as CodebuffApiClient['publish'],
60+
logout: (overrides.logout ??
61+
mock(defaultOkResponse)) as CodebuffApiClient['logout'],
5262
baseUrl: overrides.baseUrl ?? 'https://test.codebuff.com',
5363
authToken: overrides.authToken,
5464
})

0 commit comments

Comments
 (0)