{
describe('FileViewer', () => {
function setup(data) {
+ useUploadPresignedUrl.mockReturnValue({
+ data: '/archive/v4/raw/2022-06-23/..',
+ })
useCommit.mockReturnValue(data)
useFileWithMainCoverage.mockReturnValue({
data: fileData,
@@ -235,9 +250,7 @@ describe('CommitPage', () => {
it('the impacted file', () => {
expect(screen.getByTestId('spinner')).toBeInTheDocument()
- waitFor(() => {
- expect(screen.getByText(/index.js/)).toBeInTheDocument()
- })
+ waitFor(()=> expect(screen.getByText(/index.js/)).toBeInTheDocument())
})
})
diff --git a/src/pages/CommitPage/UploadsCard/Upload.js b/src/pages/CommitPage/UploadsCard/Upload.js
index 690ece3e57..7b81e793f1 100644
--- a/src/pages/CommitPage/UploadsCard/Upload.js
+++ b/src/pages/CommitPage/UploadsCard/Upload.js
@@ -1,7 +1,6 @@
import PropTypes from 'prop-types'
-import config from 'config'
-
+import { useUploadPresignedUrl } from 'services/uploadPresignedUrl'
import {
ErrorCodeEnum,
UploadStateEnum,
@@ -24,6 +23,8 @@ const Upload = ({
state,
}) => {
const isCarriedForward = uploadType === UploadTypeEnum.CARRIED_FORWARD
+ const { data } = useUploadPresignedUrl({ path :downloadUrl })
+ const presignedGetUrl = data?.presignedUrl
return (
@@ -56,13 +57,8 @@ const Upload = ({
carry-forward
)}
- {downloadUrl && (
-
+ {presignedGetUrl && (
+
Download
)}
diff --git a/src/pages/CommitPage/UploadsCard/Upload.spec.js b/src/pages/CommitPage/UploadsCard/Upload.spec.js
index c4f37e3311..e350682597 100644
--- a/src/pages/CommitPage/UploadsCard/Upload.spec.js
+++ b/src/pages/CommitPage/UploadsCard/Upload.spec.js
@@ -1,22 +1,45 @@
import { render, screen } from '@testing-library/react'
+import { QueryClient, QueryClientProvider } from 'react-query'
+import { MemoryRouter, Route } from 'react-router-dom'
+import { useUploadPresignedUrl } from 'services/uploadPresignedUrl'
import { formatTimeToNow } from 'shared/utils/dates'
import Upload from './Upload'
+jest.mock('services/uploadPresignedUrl')
+
+const queryClient = new QueryClient()
+const mockedPresignedUrl = {
+ presignedUrl:
+ 'http://minio:9000/archive/v4/raw/2022-06-23/942173DE95CBF167C5683F40B7DB34C0/ee3ecad424e67419d6c4531540f1ef5df045ff12/919ccc6d-7972-4895-b289-f2d569683a17.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=codecov-default-key%2F20220705%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220705T101702Z&X-Amz-Expires=10&X-Amz-SignedHeaders=host&X-Amz-Signature=8846492d85f62187493cbff3631ec7f0ccf2d355f768eecf294f0572cf758e4c',
+}
+
describe('UploadsCard', () => {
- function setup(props) {
- render()
+ function setup({ props, data = mockedPresignedUrl }) {
+ useUploadPresignedUrl.mockReturnValue({ data })
+
+ render(
+
+
+
+
+
+
+
+ )
}
describe('renders', () => {
beforeEach(() => {
setup({
- ciUrl: 'ciUrl.com',
- createdAt: '2020-08-25T16:36:19.559474+00:00',
- downloadUrl: 'download.com',
- buildCode: '1234',
- uploadType: 'CARRIEDFORWARD',
+ props: {
+ ciUrl: 'ciUrl.com',
+ createdAt: '2020-08-25T16:36:19.559474+00:00',
+ downloadUrl: 'download.com',
+ buildCode: '1234',
+ uploadType: 'CARRIEDFORWARD',
+ },
})
})
@@ -35,10 +58,9 @@ describe('UploadsCard', () => {
expect(screen.getByText(createDate)).toBeInTheDocument()
})
it('renders a download link', () => {
- expect(screen.getByRole('link', { name: /Download/ })).toHaveAttribute(
- 'href',
- 'download.com'
- )
+ expect(
+ screen.getByRole('link', { name: /1234 external-link.svg/ })
+ ).toHaveAttribute('href')
})
it('renders carry-forward text', () => {
@@ -48,7 +70,7 @@ describe('UploadsCard', () => {
describe('build without build link', () => {
beforeEach(() => {
- setup({ buildCode: '1234' })
+ setup({ props: { buildCode: '1234' } })
})
it('renders a the build code', () => {
expect(screen.getByText(/1234/)).toBeInTheDocument()
@@ -61,7 +83,7 @@ describe('UploadsCard', () => {
})
describe('missinng data renders', () => {
beforeEach(() => {
- setup({})
+ setup({ props: {}, data: null })
})
it('renders a default build code if no code was provided', () => {
@@ -81,13 +103,17 @@ describe('UploadsCard', () => {
describe('rendering flags', () => {
it('one flag', () => {
setup({
- flags: ['flag1'],
+ props: {
+ flags: ['flag1'],
+ },
})
expect(screen.getByText(/flag1/)).toBeInTheDocument()
})
it('multiple flags', () => {
setup({
- flags: ['flag1', 'flag2', 'flag3', 'flag4'],
+ props: {
+ flags: ['flag1', 'flag2', 'flag3', 'flag4'],
+ },
})
expect(screen.getByText(/flag1/)).toBeInTheDocument()
expect(screen.getByText(/flag2/)).toBeInTheDocument()
@@ -103,30 +129,38 @@ describe('UploadsCard', () => {
it('fileNotFoundInStorage error', () => {
setup({
- errors: [{ errorCode: 'FILE_NOT_IN_STORAGE' }],
+ props: {
+ errors: [{ errorCode: 'FILE_NOT_IN_STORAGE' }],
+ },
})
expect(screen.getByText(/processing failed/)).toBeInTheDocument()
})
it('reportExpired error', () => {
setup({
- errors: [{ errorCode: 'REPORT_EXPIRED' }],
+ props: {
+ errors: [{ errorCode: 'REPORT_EXPIRED' }],
+ },
})
expect(screen.getByText(/upload expired/)).toBeInTheDocument()
})
it('reportEmpty error', () => {
setup({
- errors: [{ errorCode: 'REPORT_EMPTY' }],
+ props: {
+ errors: [{ errorCode: 'REPORT_EMPTY' }],
+ },
})
expect(screen.getByText(/upload is empty/)).toBeInTheDocument()
})
it('all errors', () => {
setup({
- errors: [
- { errorCode: 'FILE_NOT_IN_STORAGE' },
- { errorCode: 'REPORT_EXPIRED' },
- { errorCode: 'REPORT_EMPTY' },
- { errorCode: 'SOME_NEW_ERROR' },
- ],
+ props: {
+ errors: [
+ { errorCode: 'FILE_NOT_IN_STORAGE' },
+ { errorCode: 'REPORT_EXPIRED' },
+ { errorCode: 'REPORT_EMPTY' },
+ { errorCode: 'SOME_NEW_ERROR' },
+ ],
+ },
})
expect(screen.getByText(/processing failed/)).toBeInTheDocument()
expect(screen.getByText(/upload expired/)).toBeInTheDocument()
@@ -134,39 +168,49 @@ describe('UploadsCard', () => {
})
it('handles new errors the front end doesnt know how to handle', () => {
setup({
- errors: [{ errorCode: 'SOME_NEW_ERROR' }],
+ props: {
+ errors: [{ errorCode: 'SOME_NEW_ERROR' }],
+ },
})
expect(screen.getByText(/unknown error/)).toBeInTheDocument()
})
it('handles an unexpected error type', () => {
setup({
- errors: [{ errorCode: { error: 'bad config or something' } }],
+ props: {
+ errors: [{ errorCode: { error: 'bad config or something' } }],
+ },
})
expect(screen.getByText(/unknown error/)).toBeInTheDocument()
})
it('handles upload state error but no error code resolved as an known error', () => {
setup({
- state: 'ERROR',
+ props: {
+ state: 'ERROR',
+ },
})
expect(screen.getByText(/unknown error/)).toBeInTheDocument()
})
it('handles upload state error but no errors returned', () => {
setup({
- state: 'ERROR',
- errors: [],
+ props: {
+ state: 'ERROR',
+ errors: [],
+ },
})
expect(screen.getByText(/unknown error/)).toBeInTheDocument()
})
it('If no state is provided and no errors received do not show an error', () => {
setup({
- error: [],
+ props: {
+ error: [],
+ },
})
expect(screen.queryByText(/unknown error/)).not.toBeInTheDocument()
})
})
describe('rendering uploaded type of uploads', () => {
- setup({ uploadType: 'UPLOADED' })
+ setup({ props: { uploadType: 'UPLOADED' } })
it('does not render carry-forward text', () => {
expect(screen.queryByText('carry-forward')).not.toBeInTheDocument()
})
diff --git a/src/pages/CommitPage/UploadsCard/UploadsCard.spec.js b/src/pages/CommitPage/UploadsCard/UploadsCard.spec.js
index b4a8fa53e2..54921f6def 100644
--- a/src/pages/CommitPage/UploadsCard/UploadsCard.spec.js
+++ b/src/pages/CommitPage/UploadsCard/UploadsCard.spec.js
@@ -1,14 +1,26 @@
import { fireEvent, render, screen } from 'custom-testing-library'
+import { QueryClient, QueryClientProvider } from 'react-query'
+import { MemoryRouter, Route } from 'react-router-dom'
+
import { useUploads } from './hooks'
import UploadsCard from './UploadsCard'
+const queryClient = new QueryClient()
jest.mock('./hooks')
describe('UploadsCard', () => {
function setup(mockUploads) {
useUploads.mockReturnValue(mockUploads)
- render()
+ render(
+
+
+
+
+
+
+
+ )
}
describe('renders', () => {
diff --git a/src/services/uploadPresignedUrl/hooks.js b/src/services/uploadPresignedUrl/hooks.js
new file mode 100644
index 0000000000..6b7104a002
--- /dev/null
+++ b/src/services/uploadPresignedUrl/hooks.js
@@ -0,0 +1,15 @@
+import { useQuery } from 'react-query'
+import { useParams } from 'react-router-dom'
+
+import Api from 'shared/api'
+
+function fetchUploadPresignedUrl({ provider, path }) {
+ return Api.get({ path, provider, isUploadPath: true })
+}
+
+export function useUploadPresignedUrl({ path }) {
+ const { provider } = useParams()
+ return useQuery(['uploadPresignedUrl', provider], () => {
+ return fetchUploadPresignedUrl({ provider, path })
+ })
+}
diff --git a/src/services/uploadPresignedUrl/hooks.spec.js b/src/services/uploadPresignedUrl/hooks.spec.js
new file mode 100644
index 0000000000..eb29785b7e
--- /dev/null
+++ b/src/services/uploadPresignedUrl/hooks.spec.js
@@ -0,0 +1,68 @@
+import { renderHook } from '@testing-library/react-hooks'
+import { rest } from 'msw'
+import { setupServer } from 'msw/node'
+import { QueryClient, QueryClientProvider } from 'react-query'
+import { MemoryRouter, Route } from 'react-router-dom'
+
+import { useUploadPresignedUrl } from './hooks'
+
+const downloadUrl =
+ 'v4/raw/2022-06-23/storage_hash/repo_hash/commit_id/file_name.txt'
+
+const mockedPresignedUrl = {presignedUrl: "http://minio:9000/archive/v4/raw/2022-06-23/942173DE95CBF167C5683F40B7DB34C0/ee3ecad424e67419d6c4531540f1ef5df045ff12/919ccc6d-7972-4895-b289-f2d569683a17.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=codecov-default-key%2F20220705%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220705T101702Z&X-Amz-Expires=10&X-Amz-SignedHeaders=host&X-Amz-Signature=8846492d85f62187493cbff3631ec7f0ccf2d355f768eecf294f0572cf758e4c"}
+
+const queryClient = new QueryClient()
+const wrapper = ({ children }) => (
+
+
+ {children}
+
+
+)
+
+const server = setupServer()
+
+beforeAll(() => server.listen())
+beforeEach(() => {
+ server.resetHandlers()
+ queryClient.clear()
+})
+afterAll(() => server.close())
+
+describe('useUploadPresignedUrl', () => {
+ let hookData
+
+ function setup() {
+ server.use(
+ rest.get(downloadUrl, (req, res, ctx) => {
+ return res(ctx.status(200), ctx.json(mockedPresignedUrl))
+ })
+ )
+ hookData = renderHook(
+ () => useUploadPresignedUrl({ path: downloadUrl }),
+ {
+ wrapper,
+ }
+ )
+ }
+
+ describe('when called', () => {
+ beforeEach(() => {
+ setup()
+ })
+
+ it('renders isLoading true', () => {
+ expect(hookData.result.current.isLoading).toBeTruthy()
+ })
+
+ describe('when data is loaded', () => {
+ beforeEach(() => {
+ return hookData.waitFor(() => hookData.result.current.isSuccess)
+ })
+
+ it('returns the data', () => {
+ expect(hookData.result.current.data).toEqual(mockedPresignedUrl)
+ })
+ })
+ })
+})
diff --git a/src/services/uploadPresignedUrl/index.js b/src/services/uploadPresignedUrl/index.js
new file mode 100644
index 0000000000..fc78d35129
--- /dev/null
+++ b/src/services/uploadPresignedUrl/index.js
@@ -0,0 +1 @@
+export * from './hooks'
diff --git a/src/shared/api/api.js b/src/shared/api/api.js
index d20cbfe1a0..28fa56f07b 100644
--- a/src/shared/api/api.js
+++ b/src/shared/api/api.js
@@ -13,8 +13,9 @@ function _fetch({
body,
provider = 'gh',
extraHeaders = {},
+ isUploadPath,
}) {
- const uri = generatePath({ path, query })
+ const uri = generatePath({ path, query, isUploadPath })
const headers = {
Accept: 'application/json',
'Content-Type': 'application/json; charset=utf-8',
diff --git a/src/shared/api/api.test.js b/src/shared/api/api.test.js
index f7cfd90ce2..7f7dc09ba4 100644
--- a/src/shared/api/api.test.js
+++ b/src/shared/api/api.test.js
@@ -26,11 +26,19 @@ const userData = {
],
}
+const mockedPresignedUrl = {
+ presignedUrl:
+ 'http://minio:9000/archive/v4/raw/2022-06-23/942173DE95CBF167C5683F40B7DB34C0/ee3ecad424e67419d6c4531540f1ef5df045ff12/919ccc6d-7972-4895-b289-f2d569683a17.txt?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=codecov-default-key%2F20220705%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Date=20220705T101702Z&X-Amz-Expires=10&X-Amz-SignedHeaders=host&X-Amz-Signature=8846492d85f62187493cbff3631ec7f0ccf2d355f768eecf294f0572cf758e4c',
+}
+
const server = setupServer(
rest.get('/internal/test', (req, res, ctx) => {
const hasTokenType = Boolean(req.headers.get('token-type'))
return res(ctx.status(hasTokenType ? 200 : 401), ctx.json(rawUserData))
}),
+ rest.get('/upload', (req, res, ctx) => {
+ return res(ctx.status(200), ctx.json(mockedPresignedUrl))
+ }),
rest.post('/internal/test', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(req.body))
}),
@@ -123,25 +131,19 @@ describe('when calling an endpoint with a token', () => {
})
})
-describe('when using a post request', () => {
- const body = {
- test: 'foo',
- camel_case: 'snakeCase',
- }
+describe('when using a get request with upload path', () => {
beforeEach(() => {
- return Api.post({
- path: '/test',
- body,
+ return Api.get({
+ path: '/upload',
+ provider: 'gh',
+ isUploadPath: true,
}).then((data) => {
result = data
})
})
- it('returns the data, and transform to camelCase', () => {
- expect(result).toEqual({
- test: 'foo',
- camelCase: 'snakeCase',
- })
+ it('returns data as text', () => {
+ expect(result).toEqual(mockedPresignedUrl)
})
})
diff --git a/src/shared/api/helpers.js b/src/shared/api/helpers.js
index 3fbe089b36..f68aa9bd6a 100644
--- a/src/shared/api/helpers.js
+++ b/src/shared/api/helpers.js
@@ -13,8 +13,8 @@ export const ProviderCookieKeyMapping = {
bitbucket: 'bitbucket-token',
}
-export function generatePath({ path, query }) {
- const baseUrl = `${config.API_URL}/internal`
+export function generatePath({ path, query, isUploadPath = false }) {
+ const baseUrl = isUploadPath ? config.API_URL : config.INTERNAL_API
const queryString = qs.stringify(snakeifyKeys(query), {
arrayFormat: 'repeat',
})
diff --git a/src/shared/api/helpers.spec.js b/src/shared/api/helpers.spec.js
index d1ab637690..52fab1562c 100644
--- a/src/shared/api/helpers.spec.js
+++ b/src/shared/api/helpers.spec.js
@@ -19,6 +19,12 @@ describe('generatePath', () => {
generatePath({ path: '/epic', query: { rocket: 'league', fort: 'nite' } })
).toStrictEqual(`${config.API_URL}/internal/epic?rocket=league&fort=nite`)
})
+
+ it('generates a upload report path when use isUploadPath', () => {
+ expect(generatePath({ path: '/upload', isUploadPath: true })).toStrictEqual(
+ `${config.API_URL}/upload`
+ )
+ })
})
describe('getHeaders', () => {