Skip to content

Commit f7ebc77

Browse files
committed
Remove unsafe casts in tests
1 parent c3f8ee0 commit f7ebc77

File tree

17 files changed

+426
-342
lines changed

17 files changed

+426
-342
lines changed

cli/src/__tests__/integration/api-integration.test.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { wrapMockAsFetch } from '@codebuff/common/testing/fixtures'
1+
import { wrapMockAsFetch, type FetchCallFn } from '@codebuff/common/testing/fixtures'
22
import {
33
AuthenticationError,
44
NetworkError,
@@ -42,9 +42,9 @@ describe('API Integration', () => {
4242
}) as LoggerMocks
4343

4444
const setFetchMock = (
45-
impl: Parameters<typeof mock>[0],
46-
): ReturnType<typeof mock> => {
47-
const fetchMock = mock(impl)
45+
impl: FetchCallFn,
46+
): ReturnType<typeof mock<FetchCallFn>> => {
47+
const fetchMock = mock<FetchCallFn>(impl)
4848
globalThis.fetch = wrapMockAsFetch(fetchMock)
4949
return fetchMock
5050
}

cli/src/__tests__/integration/usage-refresh-on-completion.test.ts

Lines changed: 10 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { wrapMockAsFetch } from '@codebuff/common/testing/fixtures'
1+
import { wrapMockAsFetch, type FetchCallFn } from '@codebuff/common/testing/fixtures'
22
import { QueryClient } from '@tanstack/react-query'
33
import { describe, test, expect, beforeEach, afterEach, mock, spyOn } from 'bun:test'
44

@@ -44,7 +44,7 @@ describe('Usage Refresh on SDK Completion', () => {
4444

4545
// Mock successful API response
4646
globalThis.fetch = wrapMockAsFetch(
47-
mock(async () =>
47+
mock<FetchCallFn>(async () =>
4848
new Response(
4949
JSON.stringify({
5050
type: 'usage-response',
@@ -72,8 +72,7 @@ describe('Usage Refresh on SDK Completion', () => {
7272
expect(useChatStore.getState().inputMode).toBe('usage')
7373

7474
// Spy on invalidateQueries
75-
const invalidateSpy = mock(queryClient.invalidateQueries.bind(queryClient))
76-
queryClient.invalidateQueries = invalidateSpy as any
75+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
7776

7877
// Simulate SDK run completion triggering invalidation
7978
const isUsageMode = useChatStore.getState().inputMode === 'usage'
@@ -91,8 +90,7 @@ describe('Usage Refresh on SDK Completion', () => {
9190
test('should invalidate multiple times for sequential runs', () => {
9291
useChatStore.getState().setInputMode('usage')
9392

94-
const invalidateSpy = mock(queryClient.invalidateQueries.bind(queryClient))
95-
queryClient.invalidateQueries = invalidateSpy as any
93+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
9694

9795
// Simulate three sequential SDK runs
9896
for (let i = 0; i < 3; i++) {
@@ -111,8 +109,7 @@ describe('Usage Refresh on SDK Completion', () => {
111109
useChatStore.getState().setInputMode('default')
112110
expect(useChatStore.getState().inputMode).toBe('default')
113111

114-
const invalidateSpy = mock(queryClient.invalidateQueries.bind(queryClient))
115-
queryClient.invalidateQueries = invalidateSpy as any
112+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
116113

117114
// Simulate SDK run completion check
118115
const isUsageMode = useChatStore.getState().inputMode === 'usage'
@@ -131,8 +128,7 @@ describe('Usage Refresh on SDK Completion', () => {
131128
// User closes banner before run completes
132129
useChatStore.getState().setInputMode('default')
133130

134-
const invalidateSpy = mock(queryClient.invalidateQueries.bind(queryClient))
135-
queryClient.invalidateQueries = invalidateSpy as any
131+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
136132

137133
// Simulate run completion
138134
const isUsageMode = useChatStore.getState().inputMode === 'usage'
@@ -149,8 +145,8 @@ describe('Usage Refresh on SDK Completion', () => {
149145
// Even if banner is visible in store, query won't run if enabled=false
150146
useChatStore.getState().setInputMode('usage')
151147

152-
const fetchMock = mock(globalThis.fetch)
153-
globalThis.fetch = fetchMock as any
148+
const fetchMock = mock<FetchCallFn>(async () => new Response(''))
149+
globalThis.fetch = wrapMockAsFetch(fetchMock)
154150

155151
// Query with enabled=false won't execute
156152
// (This would be the behavior when useUsageQuery({ enabled: false }) is called)
@@ -164,8 +160,8 @@ describe('Usage Refresh on SDK Completion', () => {
164160
getAuthTokenSpy.mockReturnValue(undefined)
165161
useChatStore.getState().setInputMode('usage')
166162

167-
const fetchMock = mock(globalThis.fetch)
168-
globalThis.fetch = fetchMock as any
163+
const fetchMock = mock<FetchCallFn>(async () => new Response(''))
164+
globalThis.fetch = wrapMockAsFetch(fetchMock)
169165

170166
// Query won't execute without auth token
171167
expect(fetchMock).not.toHaveBeenCalled()

cli/src/hooks/__tests__/use-usage-query.test.ts

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { wrapMockAsFetch } from '@codebuff/common/testing/fixtures'
1+
import { wrapMockAsFetch, type FetchCallFn } from '@codebuff/common/testing/fixtures'
22
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
33
import { renderHook, waitFor } from '@testing-library/react'
44
import {
@@ -12,7 +12,7 @@ import {
1212
} from 'bun:test'
1313
import React from 'react'
1414

15-
import type { ClientEnv } from '@codebuff/common/types/contracts/env'
15+
import type { Logger } from '@codebuff/common/types/contracts/logger'
1616

1717
import { useChatStore } from '../../state/chat-store'
1818
import * as authModule from '../../utils/auth'
@@ -46,7 +46,7 @@ describe('fetchUsageData', () => {
4646
}
4747

4848
globalThis.fetch = wrapMockAsFetch(
49-
mock(
49+
mock<FetchCallFn>(
5050
async () =>
5151
new Response(JSON.stringify(mockResponse), {
5252
status: 200,
@@ -61,10 +61,19 @@ describe('fetchUsageData', () => {
6161
})
6262

6363
test('should throw error on failed request', async () => {
64-
globalThis.fetch = wrapMockAsFetch(mock(async () => new Response('Error', { status: 500 })))
65-
const mockLogger = { error: mock(() => {}), warn: mock(() => {}), info: mock(() => {}), debug: mock(() => {}) }
64+
globalThis.fetch = wrapMockAsFetch(
65+
mock<FetchCallFn>(async () => new Response('Error', { status: 500 })),
66+
)
67+
const mockLogger: Logger = {
68+
error: mock<Logger['error']>(() => {}),
69+
warn: mock<Logger['warn']>(() => {}),
70+
info: mock<Logger['info']>(() => {}),
71+
debug: mock<Logger['debug']>(() => {}),
72+
}
6673

67-
await expect(fetchUsageData({ authToken: 'test-token', logger: mockLogger as any })).rejects.toThrow(
74+
await expect(
75+
fetchUsageData({ authToken: 'test-token', logger: mockLogger }),
76+
).rejects.toThrow(
6877
'Failed to fetch usage: 500',
6978
)
7079
})
@@ -73,7 +82,7 @@ describe('fetchUsageData', () => {
7382
await expect(
7483
fetchUsageData({
7584
authToken: 'test-token',
76-
clientEnv: { NEXT_PUBLIC_CODEBUFF_APP_URL: undefined } as unknown as ClientEnv,
85+
clientEnv: { NEXT_PUBLIC_CODEBUFF_APP_URL: undefined },
7786
}),
7887
).rejects.toThrow('NEXT_PUBLIC_CODEBUFF_APP_URL is not set')
7988
})
@@ -122,7 +131,7 @@ describe('useUsageQuery', () => {
122131
}
123132

124133
globalThis.fetch = wrapMockAsFetch(
125-
mock(
134+
mock<FetchCallFn>(
126135
async () =>
127136
new Response(JSON.stringify(mockResponse), {
128137
status: 200,
@@ -144,7 +153,7 @@ describe('useUsageQuery', () => {
144153
getAuthTokenSpy = spyOn(authModule, 'getAuthToken').mockReturnValue(
145154
'test-token',
146155
)
147-
const fetchMock = mock(async () => new Response('{}'))
156+
const fetchMock = mock<FetchCallFn>(async () => new Response('{}'))
148157
globalThis.fetch = wrapMockAsFetch(fetchMock)
149158

150159
const { result } = renderHook(() => useUsageQuery({ enabled: false }), {
@@ -161,7 +170,7 @@ describe('useUsageQuery', () => {
161170
getAuthTokenSpy = spyOn(authModule, 'getAuthToken').mockReturnValue(
162171
undefined,
163172
)
164-
const fetchMock = mock(async () => new Response('{}'))
173+
const fetchMock = mock<FetchCallFn>(async () => new Response('{}'))
165174
globalThis.fetch = wrapMockAsFetch(fetchMock)
166175

167176
renderHook(() => useUsageQuery(), {
@@ -191,8 +200,7 @@ describe('useRefreshUsage', () => {
191200
})
192201

193202
test.skip('should invalidate usage queries', async () => {
194-
const invalidateSpy = mock(queryClient.invalidateQueries.bind(queryClient))
195-
queryClient.invalidateQueries = invalidateSpy as any
203+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
196204

197205
const { result } = renderHook(() => useRefreshUsage(), {
198206
wrapper: createWrapper(),

cli/src/hooks/use-usage-query.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ interface UsageResponse {
2828
interface FetchUsageParams {
2929
authToken: string
3030
logger?: Logger
31-
clientEnv?: ClientEnv
31+
clientEnv?: Partial<Pick<ClientEnv, 'NEXT_PUBLIC_CODEBUFF_APP_URL'>>
3232
}
3333

3434
/**

0 commit comments

Comments
 (0)