Skip to content

Commit 9ad460f

Browse files
committed
Remove unsafe casts in tests
1 parent e97ce74 commit 9ad460f

File tree

17 files changed

+421
-356
lines changed

17 files changed

+421
-356
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 & 22 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 {
44
describe,
@@ -54,7 +54,7 @@ describe('Usage Refresh on SDK Completion', () => {
5454

5555
// Mock successful API response
5656
globalThis.fetch = wrapMockAsFetch(
57-
mock(async () =>
57+
mock<FetchCallFn>(async () =>
5858
new Response(
5959
JSON.stringify({
6060
type: 'usage-response',
@@ -82,10 +82,7 @@ describe('Usage Refresh on SDK Completion', () => {
8282
expect(useChatStore.getState().inputMode).toBe('usage')
8383

8484
// Spy on invalidateQueries
85-
const invalidateSpy = mock(
86-
queryClient.invalidateQueries.bind(queryClient),
87-
)
88-
queryClient.invalidateQueries = invalidateSpy as any
85+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
8986

9087
// Simulate SDK run completion triggering invalidation
9188
const isUsageMode = useChatStore.getState().inputMode === 'usage'
@@ -103,10 +100,7 @@ describe('Usage Refresh on SDK Completion', () => {
103100
test('should invalidate multiple times for sequential runs', () => {
104101
useChatStore.getState().setInputMode('usage')
105102

106-
const invalidateSpy = mock(
107-
queryClient.invalidateQueries.bind(queryClient),
108-
)
109-
queryClient.invalidateQueries = invalidateSpy as any
103+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
110104

111105
// Simulate three sequential SDK runs
112106
for (let i = 0; i < 3; i++) {
@@ -125,10 +119,7 @@ describe('Usage Refresh on SDK Completion', () => {
125119
useChatStore.getState().setInputMode('default')
126120
expect(useChatStore.getState().inputMode).toBe('default')
127121

128-
const invalidateSpy = mock(
129-
queryClient.invalidateQueries.bind(queryClient),
130-
)
131-
queryClient.invalidateQueries = invalidateSpy as any
122+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
132123

133124
// Simulate SDK run completion check
134125
const isUsageMode = useChatStore.getState().inputMode === 'usage'
@@ -147,10 +138,7 @@ describe('Usage Refresh on SDK Completion', () => {
147138
// User closes banner before run completes
148139
useChatStore.getState().setInputMode('default')
149140

150-
const invalidateSpy = mock(
151-
queryClient.invalidateQueries.bind(queryClient),
152-
)
153-
queryClient.invalidateQueries = invalidateSpy as any
141+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
154142

155143
// Simulate run completion
156144
const isUsageMode = useChatStore.getState().inputMode === 'usage'
@@ -167,8 +155,8 @@ describe('Usage Refresh on SDK Completion', () => {
167155
// Even if banner is visible in store, query won't run if enabled=false
168156
useChatStore.getState().setInputMode('usage')
169157

170-
const fetchMock = mock(globalThis.fetch)
171-
globalThis.fetch = fetchMock as any
158+
const fetchMock = mock<FetchCallFn>(async () => new Response(''))
159+
globalThis.fetch = wrapMockAsFetch(fetchMock)
172160

173161
// Query with enabled=false won't execute
174162
// (This would be the behavior when useUsageQuery({ enabled: false }) is called)
@@ -182,8 +170,8 @@ describe('Usage Refresh on SDK Completion', () => {
182170
getAuthTokenSpy.mockReturnValue(undefined)
183171
useChatStore.getState().setInputMode('usage')
184172

185-
const fetchMock = mock(globalThis.fetch)
186-
globalThis.fetch = fetchMock as any
173+
const fetchMock = mock<FetchCallFn>(async () => new Response(''))
174+
globalThis.fetch = wrapMockAsFetch(fetchMock)
187175

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

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

Lines changed: 15 additions & 18 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,
@@ -62,27 +62,25 @@ describe('fetchUsageData', () => {
6262

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

7474
await expect(
75-
fetchUsageData({ authToken: 'test-token', logger: mockLogger as any }),
75+
fetchUsageData({ authToken: 'test-token', logger: mockLogger }),
7676
).rejects.toThrow('Failed to fetch usage: 500')
7777
})
7878

7979
test('should throw error when app URL is not set', async () => {
8080
await expect(
8181
fetchUsageData({
8282
authToken: 'test-token',
83-
clientEnv: {
84-
NEXT_PUBLIC_CODEBUFF_APP_URL: undefined,
85-
} as unknown as ClientEnv,
83+
clientEnv: { NEXT_PUBLIC_CODEBUFF_APP_URL: undefined },
8684
}),
8785
).rejects.toThrow('NEXT_PUBLIC_CODEBUFF_APP_URL is not set')
8886
})
@@ -131,7 +129,7 @@ describe('useUsageQuery', () => {
131129
}
132130

133131
globalThis.fetch = wrapMockAsFetch(
134-
mock(
132+
mock<FetchCallFn>(
135133
async () =>
136134
new Response(JSON.stringify(mockResponse), {
137135
status: 200,
@@ -153,7 +151,7 @@ describe('useUsageQuery', () => {
153151
getAuthTokenSpy = spyOn(authModule, 'getAuthToken').mockReturnValue(
154152
'test-token',
155153
)
156-
const fetchMock = mock(async () => new Response('{}'))
154+
const fetchMock = mock<FetchCallFn>(async () => new Response('{}'))
157155
globalThis.fetch = wrapMockAsFetch(fetchMock)
158156

159157
const { result } = renderHook(() => useUsageQuery({ enabled: false }), {
@@ -170,7 +168,7 @@ describe('useUsageQuery', () => {
170168
getAuthTokenSpy = spyOn(authModule, 'getAuthToken').mockReturnValue(
171169
undefined,
172170
)
173-
const fetchMock = mock(async () => new Response('{}'))
171+
const fetchMock = mock<FetchCallFn>(async () => new Response('{}'))
174172
globalThis.fetch = wrapMockAsFetch(fetchMock)
175173

176174
renderHook(() => useUsageQuery(), {
@@ -200,8 +198,7 @@ describe('useRefreshUsage', () => {
200198
})
201199

202200
test.skip('should invalidate usage queries', async () => {
203-
const invalidateSpy = mock(queryClient.invalidateQueries.bind(queryClient))
204-
queryClient.invalidateQueries = invalidateSpy as any
201+
const invalidateSpy = spyOn(queryClient, 'invalidateQueries')
205202

206203
const { result } = renderHook(() => useRefreshUsage(), {
207204
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)