Skip to content

Commit ac9e926

Browse files
authored
feat: Add in CachedBundlesQueryOpts (#3644)
1 parent 9cd4b84 commit ac9e926

File tree

2 files changed

+463
-0
lines changed

2 files changed

+463
-0
lines changed
Lines changed: 290 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,290 @@
1+
import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
2+
import {
3+
QueryClientProvider as QueryClientProviderV5,
4+
QueryClient as QueryClientV5,
5+
useQuery as useQueryV5,
6+
useSuspenseQuery as useSuspenseQueryV5,
7+
} from '@tanstack/react-queryV5'
8+
import { renderHook, waitFor } from '@testing-library/react'
9+
import { graphql, HttpResponse } from 'msw'
10+
import { setupServer } from 'msw/node'
11+
import { Suspense } from 'react'
12+
import { MockInstance } from 'vitest'
13+
14+
import { CachedBundlesQueryOpts } from './CachedBundlesQueryOpts'
15+
16+
const mockBranchBundles = {
17+
owner: {
18+
repository: {
19+
__typename: 'Repository',
20+
branch: {
21+
head: {
22+
bundleAnalysis: {
23+
bundleAnalysisReport: {
24+
__typename: 'BundleAnalysisReport',
25+
bundles: [{ name: 'bundle1', isCached: true }],
26+
},
27+
},
28+
},
29+
},
30+
},
31+
},
32+
}
33+
34+
const mockUnsuccessfulParseError = {}
35+
36+
const mockNullOwner = { owner: null }
37+
38+
const mockRepoNotFound = {
39+
owner: {
40+
repository: {
41+
__typename: 'NotFoundError',
42+
message: 'Repository not found',
43+
},
44+
},
45+
}
46+
47+
const mockOwnerNotActivated = {
48+
owner: {
49+
repository: {
50+
__typename: 'OwnerNotActivatedError',
51+
message: 'Owner not activated',
52+
},
53+
},
54+
}
55+
56+
const server = setupServer()
57+
const queryClient = new QueryClient({
58+
defaultOptions: { queries: { retry: false, suspense: true } },
59+
})
60+
const queryClientV5 = new QueryClientV5({
61+
defaultOptions: { queries: { retry: false } },
62+
})
63+
64+
const wrapper: React.FC<React.PropsWithChildren> = ({ children }) => (
65+
<QueryClientProviderV5 client={queryClientV5}>
66+
<QueryClientProvider client={queryClient}>
67+
<Suspense fallback={<p>loading</p>}>{children}</Suspense>
68+
</QueryClientProvider>
69+
</QueryClientProviderV5>
70+
)
71+
72+
beforeAll(() => {
73+
server.listen()
74+
})
75+
76+
afterEach(() => {
77+
vi.clearAllMocks()
78+
queryClient.clear()
79+
queryClientV5.clear()
80+
server.resetHandlers()
81+
})
82+
83+
afterAll(() => {
84+
server.close()
85+
})
86+
87+
interface SetupArgs {
88+
isNotFoundError?: boolean
89+
isOwnerNotActivatedError?: boolean
90+
isUnsuccessfulParseError?: boolean
91+
isNullOwner?: boolean
92+
}
93+
94+
describe('CachedBundlesQueryOpts', () => {
95+
function setup({
96+
isNotFoundError = false,
97+
isOwnerNotActivatedError = false,
98+
isUnsuccessfulParseError = false,
99+
isNullOwner = false,
100+
}: SetupArgs) {
101+
const passedBranch = vi.fn()
102+
103+
server.use(
104+
graphql.query('CachedBundleList', (info) => {
105+
if (info.variables?.branch) {
106+
passedBranch(info.variables?.branch)
107+
}
108+
109+
if (isNotFoundError) {
110+
return HttpResponse.json({ data: mockRepoNotFound })
111+
} else if (isOwnerNotActivatedError) {
112+
return HttpResponse.json({ data: mockOwnerNotActivated })
113+
} else if (isUnsuccessfulParseError) {
114+
return HttpResponse.json({ data: mockUnsuccessfulParseError })
115+
} else if (isNullOwner) {
116+
return HttpResponse.json({ data: mockNullOwner })
117+
}
118+
119+
return HttpResponse.json({ data: mockBranchBundles })
120+
})
121+
)
122+
123+
return { passedBranch }
124+
}
125+
126+
describe('returns repository typename of repository', () => {
127+
describe('there is valid data', () => {
128+
it('returns the bundle summary', async () => {
129+
setup({})
130+
const { result } = renderHook(
131+
() =>
132+
useSuspenseQueryV5(
133+
CachedBundlesQueryOpts({
134+
provider: 'gh',
135+
owner: 'codecov',
136+
repo: 'codecov',
137+
branch: 'cool-branch',
138+
})
139+
),
140+
{ wrapper }
141+
)
142+
143+
const expectedResponse = {
144+
bundles: [{ bundleName: 'bundle1', isCached: true }],
145+
}
146+
147+
await waitFor(() =>
148+
expect(result.current.data).toStrictEqual(expectedResponse)
149+
)
150+
})
151+
})
152+
153+
describe('there is invalid data', () => {
154+
it('returns a null value', async () => {
155+
setup({ isNullOwner: true })
156+
const { result } = renderHook(
157+
() =>
158+
useSuspenseQueryV5(
159+
CachedBundlesQueryOpts({
160+
provider: 'gh',
161+
owner: 'codecov',
162+
repo: 'codecov',
163+
branch: 'cool-branch',
164+
})
165+
),
166+
{ wrapper }
167+
)
168+
169+
const expectedResponse = {
170+
bundles: [],
171+
}
172+
173+
await waitFor(() =>
174+
expect(result.current.data).toStrictEqual(expectedResponse)
175+
)
176+
})
177+
})
178+
})
179+
180+
describe('returns NotFoundError __typename', () => {
181+
let consoleSpy: MockInstance
182+
183+
beforeEach(() => {
184+
consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => null)
185+
})
186+
187+
afterEach(() => {
188+
consoleSpy.mockRestore()
189+
})
190+
191+
it('throws a 404', async () => {
192+
setup({ isNotFoundError: true })
193+
const { result } = renderHook(
194+
() =>
195+
useQueryV5(
196+
CachedBundlesQueryOpts({
197+
provider: 'gh',
198+
owner: 'codecov',
199+
repo: 'codecov',
200+
branch: 'main',
201+
})
202+
),
203+
{ wrapper }
204+
)
205+
206+
await waitFor(() => expect(result.current.isError).toBeTruthy())
207+
await waitFor(() =>
208+
expect(result.current.error).toEqual(
209+
expect.objectContaining({
210+
status: 404,
211+
})
212+
)
213+
)
214+
})
215+
})
216+
217+
describe('returns OwnerNotActivatedError __typename', () => {
218+
let consoleSpy: MockInstance
219+
220+
beforeEach(() => {
221+
consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => null)
222+
})
223+
224+
afterEach(() => {
225+
consoleSpy.mockRestore()
226+
})
227+
228+
it('throws a 403', async () => {
229+
setup({ isOwnerNotActivatedError: true })
230+
const { result } = renderHook(
231+
() =>
232+
useQueryV5(
233+
CachedBundlesQueryOpts({
234+
provider: 'gh',
235+
owner: 'codecov',
236+
repo: 'codecov',
237+
branch: 'main',
238+
})
239+
),
240+
{ wrapper }
241+
)
242+
243+
await waitFor(() => expect(result.current.isError).toBeTruthy())
244+
await waitFor(() =>
245+
expect(result.current.error).toEqual(
246+
expect.objectContaining({
247+
status: 403,
248+
})
249+
)
250+
)
251+
})
252+
})
253+
254+
describe('unsuccessful parse of zod schema', () => {
255+
let consoleSpy: MockInstance
256+
257+
beforeEach(() => {
258+
consoleSpy = vi.spyOn(console, 'error').mockImplementation(() => null)
259+
})
260+
261+
afterEach(() => {
262+
consoleSpy.mockRestore()
263+
})
264+
265+
it('throws a 404', async () => {
266+
setup({ isUnsuccessfulParseError: true })
267+
const { result } = renderHook(
268+
() =>
269+
useQueryV5(
270+
CachedBundlesQueryOpts({
271+
provider: 'gh',
272+
owner: 'codecov',
273+
repo: 'codecov',
274+
branch: 'main',
275+
})
276+
),
277+
{ wrapper }
278+
)
279+
280+
await waitFor(() => expect(result.current.isError).toBeTruthy())
281+
await waitFor(() =>
282+
expect(result.current.error).toEqual(
283+
expect.objectContaining({
284+
status: 404,
285+
})
286+
)
287+
)
288+
})
289+
})
290+
})

0 commit comments

Comments
 (0)