Skip to content

Commit d2a63eb

Browse files
ref: Convert file entry stuff to ts (#2698)
Part of codecov/engineering-team#588
1 parent c59b171 commit d2a63eb

17 files changed

+602
-271
lines changed

src/services/file/useCoverageWithFilters.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ export function useCoverageWithFilters({
8282
flags,
8383
components,
8484
},
85-
}).then(extractCoverageFromResponse)
85+
}).then((res) => extractCoverageFromResponse(res.data.owner.repository))
8686
},
8787
...(!!opts && opts),
8888
})

src/services/file/useCoverageWithFilters.spec.js

+14-13
Original file line numberDiff line numberDiff line change
@@ -46,36 +46,38 @@ describe('useCoverageWithFilters', () => {
4646
commit: {
4747
commitid: 'f00162848a3cebc0728d915763c2fd9e92132408',
4848
flagNames: ['a', 'b'],
49-
componentNames: ['c'],
5049
coverageFile: {
5150
content:
5251
'import pytest\nfrom path1 import index\n\ndef test_uncovered_if():\n assert index.uncovered_if() == False\n\ndef test_fully_covered():\n assert index.fully_covered() == True\n\n\n\n\n',
5352
coverage: [
5453
{
5554
line: 1,
56-
coverage: 1,
55+
coverage: 'H',
5756
},
5857
{
5958
line: 2,
60-
coverage: 1,
59+
coverage: 'P',
6160
},
6261
{
63-
line: 4,
64-
coverage: 1,
62+
line: 3,
63+
coverage: 'H',
6564
},
6665
{
67-
line: 5,
68-
coverage: 1,
66+
line: 4,
67+
coverage: 'M',
6968
},
7069
{
71-
line: 7,
72-
coverage: 1,
70+
line: 5,
71+
coverage: 'H',
7372
},
7473
{
75-
line: 8,
76-
coverage: 1,
74+
line: 6,
75+
coverage: 'H',
7776
},
7877
],
78+
totals: {
79+
coverage: 66.67,
80+
},
7981
},
8082
},
8183
branch: null,
@@ -99,9 +101,8 @@ describe('useCoverageWithFilters', () => {
99101
await waitFor(() =>
100102
expect(result.current.data).toEqual({
101103
...data.owner.repository.commit.coverageFile,
102-
totals: 0,
104+
totals: 66.67,
103105
flagNames: ['a', 'b'],
104-
componentNames: ['c'],
105106
coverage: _.chain(data.owner.repository.commit.coverageFile.coverage)
106107
.keyBy('line')
107108
.mapValues('coverage')

src/services/file/utils.js src/services/file/utils.ts

+12-5
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import keyBy from 'lodash/keyBy'
22
import mapValues from 'lodash/mapValues'
33

4-
export function extractCoverageFromResponse(res) {
5-
const commit = res?.data?.owner?.repository?.commit
6-
const branch = res?.data?.owner?.repository?.branch?.head
4+
import { PathContentsRepositorySchema } from 'services/pathContents/constants'
5+
6+
export function extractCoverageFromResponse(
7+
repository: PathContentsRepositorySchema | undefined | null
8+
) {
9+
if (!repository) return null
10+
const commit = repository?.commit
11+
const branch = repository?.branch?.head
712
const coverageSource = commit || branch
813
const coverageFile = coverageSource?.coverageFile
914
if (!coverageFile) return null
@@ -15,9 +20,11 @@ export function extractCoverageFromResponse(res) {
1520
return {
1621
content: coverageFile?.content,
1722
coverage: fileCoverage,
18-
totals: isNaN(coverageTotal) ? 0 : coverageTotal,
23+
totals:
24+
typeof coverageTotal !== 'number' || isNaN(coverageTotal)
25+
? 0
26+
: coverageTotal,
1927
flagNames: coverageSource?.flagNames ?? [],
20-
componentNames: coverageSource?.componentNames ?? [],
2128
isCriticalFile: !!coverageFile?.isCriticalFile,
2229
...(hashedPath && { hashedPath }),
2330
}

src/services/pathContents/branch/file/usePrefetchBranchFileEntry.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,9 @@ export function usePrefetchBranchFileEntry({
4040
path,
4141
flags,
4242
},
43-
}).then(extractCoverageFromResponse),
43+
}).then((res) =>
44+
extractCoverageFromResponse(res.data.owner.repository)
45+
),
4446
staleTime: 10000,
4547
})
4648

src/services/pathContents/commit/file/usePrefetchCommitFileEntry.spec.tsx

+18-14
Original file line numberDiff line numberDiff line change
@@ -28,22 +28,25 @@ const mockData = {
2828
coverage: 'P',
2929
},
3030
{
31-
line: 4,
31+
line: 3,
3232
coverage: 'H',
3333
},
3434
{
35-
line: 5,
35+
line: 4,
3636
coverage: 'M',
3737
},
3838
{
39-
line: 7,
39+
line: 5,
4040
coverage: 'H',
4141
},
4242
{
43-
line: 8,
43+
line: 6,
4444
coverage: 'H',
4545
},
4646
],
47+
totals: {
48+
coverage: 66.67,
49+
},
4750
},
4851
},
4952
branch: null,
@@ -53,7 +56,6 @@ const mockData = {
5356

5457
const mockNotFoundError = {
5558
owner: {
56-
isCurrentUserPartOfOrg: true,
5759
repository: {
5860
__typename: 'NotFoundError',
5961
message: 'commit not found',
@@ -63,7 +65,6 @@ const mockNotFoundError = {
6365

6466
const mockOwnerNotActivatedError = {
6567
owner: {
66-
isCurrentUserPartOfOrg: true,
6768
repository: {
6869
__typename: 'OwnerNotActivatedError',
6970
message: 'owner not activated',
@@ -191,16 +192,15 @@ describe('usePrefetchCommitFileEntry', () => {
191192
coverage: {
192193
'1': 'H',
193194
'2': 'P',
194-
'4': 'H',
195-
'5': 'M',
196-
'7': 'H',
197-
'8': 'H',
195+
'3': 'H',
196+
'4': 'M',
197+
'5': 'H',
198+
'6': 'H',
198199
},
199200
flagNames: ['a', 'b'],
200-
componentNames: [],
201201
hashedPath: 'hashed-path',
202202
isCriticalFile: true,
203-
totals: 0,
203+
totals: 66.67,
204204
}
205205

206206
await waitFor(() =>
@@ -211,7 +211,7 @@ describe('usePrefetchCommitFileEntry', () => {
211211
})
212212

213213
describe('there is a null owner', () => {
214-
it('returns a null value', async () => {
214+
it('returns a 404', async () => {
215215
setup({ isNullOwner: true })
216216
const { result } = renderHook(
217217
() =>
@@ -230,7 +230,11 @@ describe('usePrefetchCommitFileEntry', () => {
230230
?.at(0) as Array<any>
231231

232232
await waitFor(() =>
233-
expect(queryClient?.getQueryState(queryKey)?.data).toBe(null)
233+
expect(queryClient?.getQueryState(queryKey)?.error).toEqual(
234+
expect.objectContaining({
235+
status: 404,
236+
})
237+
)
234238
)
235239
})
236240
})

src/services/pathContents/commit/file/usePrefetchCommitFileEntry.tsx

+23-8
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,13 @@ import { useParams } from 'react-router-dom'
33

44
import { extractCoverageFromResponse } from 'services/file/utils'
55
import Api from 'shared/api'
6+
import { NetworkErrorObject } from 'shared/api/helpers'
67
import A from 'ui/A'
78

8-
import { queryForCommitFile as query, RequestSchema } from '../../constants'
9+
import {
10+
PathContentsRequestSchema,
11+
queryForCommitFile as query,
12+
} from '../../constants'
913

1014
interface URLParams {
1115
provider: string
@@ -58,13 +62,14 @@ export function usePrefetchCommitFileEntry({
5862
components,
5963
},
6064
}).then((res) => {
61-
const parsedRes = RequestSchema.safeParse(res?.data)
65+
const parsedRes = PathContentsRequestSchema.safeParse(res?.data)
6266

6367
if (!parsedRes.success) {
6468
return Promise.reject({
6569
status: 404,
66-
data: null,
67-
})
70+
data: {},
71+
dev: 'usePrefetchCommitFileEntry - 404 schema parsing failed',
72+
} satisfies NetworkErrorObject)
6873
}
6974

7075
const data = parsedRes.data
@@ -73,7 +78,8 @@ export function usePrefetchCommitFileEntry({
7378
return Promise.reject({
7479
status: 404,
7580
data: {},
76-
})
81+
dev: 'usePrefetchCommitFileEntry - 404 NotFoundError',
82+
} satisfies NetworkErrorObject)
7783
}
7884

7985
if (
@@ -91,12 +97,21 @@ export function usePrefetchCommitFileEntry({
9197
</p>
9298
),
9399
},
94-
})
100+
dev: 'usePrefetchCommitFileEntry - 403 OwnerNotActivatedError',
101+
} satisfies NetworkErrorObject)
95102
}
96103

97-
const extractedResults = extractCoverageFromResponse({ data })
104+
const coverage = extractCoverageFromResponse(data?.owner?.repository)
105+
106+
if (!coverage) {
107+
return Promise.reject({
108+
status: 404,
109+
data: {},
110+
dev: 'usePrefetchCommitFileEntry - 404 failed to find coverage file',
111+
} satisfies NetworkErrorObject)
112+
}
98113

99-
return extractedResults
114+
return coverage
100115
})
101116
},
102117
staleTime: 10000,

src/services/pathContents/constants.ts

+32-6
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,33 @@
1+
import { ParsedQs } from 'qs'
12
import { z } from 'zod'
23

34
import {
45
RepoNotFoundErrorSchema,
56
RepoOwnerNotActivatedErrorSchema,
67
} from 'services/repo'
8+
import { DisplayType } from 'shared/ContentsTable/constants'
9+
10+
const pathContentsFiltersParam = [
11+
'NAME',
12+
'COVERAGE',
13+
'HITS',
14+
'MISSES',
15+
'PARTIALS',
16+
'LINES',
17+
] as const
18+
19+
type PathContentsFiltersParam = (typeof pathContentsFiltersParam)[number]
20+
21+
export type PathContentsFilters = {
22+
searchValue?: string
23+
displayType?: DisplayType
24+
ordering?: {
25+
direction: 'ASC' | 'DESC'
26+
parameter: PathContentsFiltersParam
27+
}
28+
flags?: string[] | ParsedQs[]
29+
components?: string[] | ParsedQs[]
30+
}
731

832
const CoverageSchema = z.array(
933
z
@@ -34,7 +58,7 @@ const CoverageForFileSchema = z.object({
3458
.nullish(),
3559
})
3660

37-
const RepositorySchema = z.object({
61+
export const RepositorySchema = z.object({
3862
__typename: z.literal('Repository'),
3963
commit: CoverageForFileSchema.nullish(),
4064
branch: z
@@ -45,14 +69,16 @@ const RepositorySchema = z.object({
4569
.nullish(),
4670
})
4771

48-
export const RequestSchema = z.object({
72+
export type PathContentsRepositorySchema = z.infer<typeof RepositorySchema>
73+
74+
export const PathContentsRequestSchema = z.object({
4975
owner: z
5076
.object({
5177
repository: z
52-
.union([
53-
RepositorySchema.partial(),
54-
RepoNotFoundErrorSchema.partial(),
55-
RepoOwnerNotActivatedErrorSchema.partial(),
78+
.discriminatedUnion('__typename', [
79+
RepositorySchema,
80+
RepoNotFoundErrorSchema,
81+
RepoOwnerNotActivatedErrorSchema,
5682
])
5783
.nullish(),
5884
})

src/services/pathContents/pull/file/usePrefetchPullFileEntry.js

-42
This file was deleted.

0 commit comments

Comments
 (0)