Skip to content

Commit 19017c5

Browse files
committed
feat: upload limit test
1 parent 577e79c commit 19017c5

File tree

7 files changed

+109
-105
lines changed

7 files changed

+109
-105
lines changed

src/sections/shared/file-uploader/FileUploader.tsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { File as FileModel } from '@/files/domain/models/File'
22
import { FileRepository } from '@/files/domain/repositories/FileRepository'
3+
import { DatasetUploadLimits } from '@/dataset/domain/models/DatasetUploadLimits'
34
import { ReplaceFileReferrer } from '@/sections/replace-file/ReplaceFile'
45
import { FileUploaderProvider } from './context/FileUploaderContext'
56
import { useGetFixityAlgorithm } from './useGetFixityAlgorithm'
@@ -15,6 +16,7 @@ type FileUploaderProps =
1516
operationType: OperationType.REPLACE_FILE
1617
originalFile: FileModel
1718
referrer?: ReplaceFileReferrer
19+
fetchUploadLimits?: (datasetId: string) => Promise<DatasetUploadLimits>
1820
}
1921
| {
2022
fileRepository: FileRepository
@@ -23,6 +25,7 @@ type FileUploaderProps =
2325
operationType: OperationType.ADD_FILES_TO_DATASET
2426
originalFile?: never
2527
referrer?: never
28+
fetchUploadLimits?: (datasetId: string) => Promise<DatasetUploadLimits>
2629
}
2730

2831
export type StorageType = 'S3'
@@ -41,7 +44,8 @@ export const FileUploader = ({
4144
storageType,
4245
operationType,
4346
originalFile,
44-
referrer
47+
referrer,
48+
fetchUploadLimits
4549
}: FileUploaderProps) => {
4650
const { fixityAlgorithm, isLoadingFixityAlgorithm } = useGetFixityAlgorithm(fileRepository)
4751

@@ -68,6 +72,7 @@ export const FileUploader = ({
6872
<FileUploaderPanel
6973
fileRepository={fileRepository}
7074
datasetPersistentId={datasetPersistentId}
75+
fetchUploadLimits={fetchUploadLimits}
7176
referrer={referrer}
7277
/>
7378
</FileUploaderProvider>

src/sections/shared/file-uploader/FileUploaderPanel.tsx

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,17 +12,20 @@ import { useFileUploaderContext } from './context/FileUploaderContext'
1212
import FileUploadInput from './file-upload-input/FileUploadInput'
1313
import { UploadedFilesList } from './uploaded-files-list/UploadedFilesList'
1414
import { ConfirmLeaveModal } from './confirm-leave-modal/ConfirmLeaveModal'
15+
import { DatasetUploadLimits } from '@/dataset/domain/models/DatasetUploadLimits'
1516

1617
interface FileUploaderPanelProps {
1718
fileRepository: FileRepository
1819
datasetPersistentId: string
1920
referrer?: ReplaceFileReferrer
21+
fetchUploadLimits?: (datasetId: string) => Promise<DatasetUploadLimits>
2022
}
2123

2224
const FileUploaderPanel = ({
2325
fileRepository,
2426
datasetPersistentId,
25-
referrer
27+
referrer,
28+
fetchUploadLimits
2629
}: FileUploaderPanelProps) => {
2730
const { t } = useTranslation('shared')
2831
const navigate = useNavigate()
@@ -101,7 +104,11 @@ const FileUploaderPanel = ({
101104

102105
return (
103106
<Stack gap={4}>
104-
<FileUploadInput fileRepository={fileRepository} datasetPersistentId={datasetPersistentId} />
107+
<FileUploadInput
108+
fileRepository={fileRepository}
109+
datasetPersistentId={datasetPersistentId}
110+
fetchUploadLimits={fetchUploadLimits}
111+
/>
105112

106113
{uploadedFiles.length > 0 && (
107114
<UploadedFilesList

src/sections/shared/file-uploader/file-upload-input/FileUploadInput.tsx

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import cn from 'classnames'
88
import { FileRepository } from '@/files/domain/repositories/FileRepository'
99
import MimeTypeDisplay from '@/files/domain/models/FileTypeToFriendlyTypeMap'
1010
import { uploadFile } from '@/files/domain/useCases/uploadFile'
11+
import { DatasetUploadLimits } from '@/dataset/domain/models/DatasetUploadLimits'
1112
import { useFileUploaderContext } from '../context/FileUploaderContext'
1213
import { FileUploadState, FileUploadStatus } from '../context/fileUploaderReducer'
1314
import { OperationType } from '../FileUploader'
@@ -19,14 +20,19 @@ import { useUploadLimit } from './useUploadLimit'
1920
type FileUploadInputProps = {
2021
fileRepository: FileRepository
2122
datasetPersistentId: string
23+
fetchUploadLimits?: (datasetId: string) => Promise<DatasetUploadLimits>
2224
}
2325

2426
const limit = 6
2527
const semaphore = new Semaphore(limit)
2628

2729
const maxFilesPerUpload = 1000
2830

29-
const FileUploadInput = ({ fileRepository, datasetPersistentId }: FileUploadInputProps) => {
31+
const FileUploadInput = ({
32+
fileRepository,
33+
datasetPersistentId,
34+
fetchUploadLimits
35+
}: FileUploadInputProps) => {
3036
const {
3137
fileUploaderState,
3238
addFile,
@@ -47,7 +53,7 @@ const FileUploadInput = ({ fileRepository, datasetPersistentId }: FileUploadInpu
4753
const inputRef = useRef<HTMLInputElement>(null)
4854

4955
const [isDragging, setIsDragging] = useState(false)
50-
const { uploadLimit } = useUploadLimit(datasetPersistentId)
56+
const { uploadLimit } = useUploadLimit(datasetPersistentId, fetchUploadLimits)
5157

5258
const totalFiles = Object.keys(fileUploaderState.files).length
5359

src/sections/shared/file-uploader/file-upload-input/useUploadLimit.ts

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,28 @@ import { useCallback, useEffect, useState } from 'react'
22
import { ReadError } from '@iqss/dataverse-client-javascript'
33
import { FileSize, FileSizeUnit } from '@/files/domain/models/FileMetadata'
44
import { getDatasetUploadLimits } from '@/dataset/domain/useCases/getDatasetUploadLimits'
5+
import { DatasetUploadLimits } from '@/dataset/domain/models/DatasetUploadLimits'
56
import { JSDataverseReadErrorHandler } from '@/shared/helpers/JSDataverseReadErrorHandler'
67

78
interface UploadLimit {
89
maxFilesAvailableToUploadFormatted?: string
910
storageQuotaRemainingFormatted?: string
1011
}
1112

12-
export function useUploadLimit(datasetPersistentId: string) {
13+
export function useUploadLimit(
14+
datasetPersistentId: string,
15+
fetchUploadLimits: (datasetId: string) => Promise<DatasetUploadLimits> = getDatasetUploadLimits
16+
) {
1317
const [uploadLimit, setUploadLimit] = useState<UploadLimit>({})
1418
const [isLoadingUploadLimits, setIsLoadingUploadLimits] = useState<boolean>(true)
1519
const [errorUploadLimits, setErrorUploadLimits] = useState<string | null>(null)
1620

17-
const fetchUploadLimits = useCallback(async () => {
21+
const fetchUploadLimitsCallback = useCallback(async () => {
1822
setIsLoadingUploadLimits(true)
1923
setErrorUploadLimits(null)
2024

2125
try {
22-
const limits = await getDatasetUploadLimits(datasetPersistentId)
26+
const limits = await fetchUploadLimits(datasetPersistentId)
2327

2428
if (Object.keys(limits).length === 0) {
2529
setUploadLimit({})
@@ -50,16 +54,16 @@ export function useUploadLimit(datasetPersistentId: string) {
5054
} finally {
5155
setIsLoadingUploadLimits(false)
5256
}
53-
}, [datasetPersistentId])
57+
}, [datasetPersistentId, fetchUploadLimits])
5458

5559
useEffect(() => {
56-
void fetchUploadLimits()
57-
}, [fetchUploadLimits])
60+
void fetchUploadLimitsCallback()
61+
}, [fetchUploadLimitsCallback])
5862

5963
return {
6064
uploadLimit,
6165
isLoadingUploadLimits,
6266
errorUploadLimits,
63-
fetchUploadLimits
67+
fetchUploadLimits: fetchUploadLimitsCallback
6468
}
6569
}

tests/component/sections/shared/file-uploader/FileUploadInputUploadLimits.spec.tsx

Lines changed: 0 additions & 73 deletions
This file was deleted.

tests/component/sections/shared/file-uploader/FileUploader.spec.tsx

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1007,4 +1007,62 @@ describe('FileUploader', () => {
10071007
})
10081008
})
10091009
})
1010+
1011+
describe.only('upload limits UI', () => {
1012+
it('shows both upload limit messages when both limits are present', () => {
1013+
const fetchUploadLimits = cy.stub().resolves({
1014+
numberOfFilesRemaining: 20,
1015+
storageQuotaRemaining: 1048576
1016+
})
1017+
1018+
cy.customMount(
1019+
<FileUploader
1020+
fileRepository={fileMockRepository}
1021+
datasetPersistentId=":latest"
1022+
storageType="S3"
1023+
operationType={OperationType.ADD_FILES_TO_DATASET}
1024+
fetchUploadLimits={fetchUploadLimits}
1025+
/>
1026+
)
1027+
1028+
cy.findByText(/Maximum of 20 files available to upload./i).should('exist')
1029+
cy.findByText(/Storage quota: 1 MB remaining./i).should('exist')
1030+
})
1031+
1032+
it('shows only the available limit message when one limit is missing', () => {
1033+
const fetchUploadLimits = cy.stub().resolves({
1034+
numberOfFilesRemaining: 5
1035+
})
1036+
1037+
cy.customMount(
1038+
<FileUploader
1039+
fileRepository={fileMockRepository}
1040+
datasetPersistentId=":latest"
1041+
storageType="S3"
1042+
operationType={OperationType.ADD_FILES_TO_DATASET}
1043+
fetchUploadLimits={fetchUploadLimits}
1044+
/>
1045+
)
1046+
1047+
cy.findByText(/Maximum of 5 files available to upload./i).should('exist')
1048+
cy.findByText(/Storage quota:/i).should('not.exist')
1049+
})
1050+
1051+
it('does not show limits message when limits are not present', () => {
1052+
const fetchUploadLimits = cy.stub().resolves({})
1053+
1054+
cy.customMount(
1055+
<FileUploader
1056+
fileRepository={fileMockRepository}
1057+
datasetPersistentId=":latest"
1058+
storageType="S3"
1059+
operationType={OperationType.ADD_FILES_TO_DATASET}
1060+
fetchUploadLimits={fetchUploadLimits}
1061+
/>
1062+
)
1063+
1064+
cy.findByText(/Maximum of \d+ files available to upload./i).should('not.exist')
1065+
cy.findByText(/Storage quota:/i).should('not.exist')
1066+
})
1067+
})
10101068
})

tests/component/sections/shared/file-uploader/useUploadLimit.spec.tsx

Lines changed: 17 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,36 @@
1-
import { renderHook, waitFor } from '@testing-library/react'
1+
import { act, renderHook, waitFor } from '@testing-library/react'
22
import { useUploadLimit } from '@/sections/shared/file-uploader/file-upload-input/useUploadLimit'
3-
import * as uploadLimitsUseCase from '@/dataset/domain/useCases/getDatasetUploadLimits'
43

54
const DATASET_PERSISTENT_ID = 'doi:10.5072/FK2/8YOKQI'
65

76
describe('useUploadLimit', () => {
8-
let getDatasetUploadLimitsStub: sinon.SinonStub
9-
10-
beforeEach(() => {
11-
getDatasetUploadLimitsStub = cy.stub(uploadLimitsUseCase, 'getDatasetUploadLimits')
12-
})
13-
14-
afterEach(() => {
15-
getDatasetUploadLimitsStub.restore()
16-
})
17-
187
it('formats upload limit values when limits are present', async () => {
19-
getDatasetUploadLimitsStub.resolves({
8+
const fetchUploadLimits = cy.stub().resolves({
209
numberOfFilesRemaining: 1200,
2110
storageQuotaRemaining: 1048576
2211
})
2312

24-
const { result } = renderHook(() => useUploadLimit(DATASET_PERSISTENT_ID))
13+
const { result } = renderHook(() => useUploadLimit(DATASET_PERSISTENT_ID, fetchUploadLimits))
2514

26-
await waitFor(() => {
27-
expect(result.current.isLoadingUploadLimits).to.equal(false)
28-
expect(result.current.uploadLimit.maxFilesAvailableToUploadFormatted).to.equal('1,200')
29-
expect(result.current.uploadLimit.storageQuotaRemainingFormatted).to.equal('1 MB')
15+
await act(() => {
16+
expect(result.current.isLoadingUploadLimits).to.deep.equal(true)
17+
return expect(result.current.uploadLimit).to.deep.equal({})
18+
})
19+
20+
await act(() => {
21+
expect(result.current.isLoadingUploadLimits).to.deep.equal(false)
22+
23+
return expect(result.current.uploadLimit).to.deep.equal({
24+
maxFilesAvailableToUploadFormatted: '1,200',
25+
storageQuotaRemainingFormatted: '1 MB'
26+
})
3027
})
3128
})
3229

3330
it('returns empty uploadLimit when no limits are present', async () => {
34-
getDatasetUploadLimitsStub.resolves({})
31+
const fetchUploadLimits = cy.stub().resolves({})
3532

36-
const { result } = renderHook(() => useUploadLimit(DATASET_PERSISTENT_ID))
33+
const { result } = renderHook(() => useUploadLimit(DATASET_PERSISTENT_ID, fetchUploadLimits))
3734

3835
await waitFor(() => {
3936
expect(result.current.isLoadingUploadLimits).to.equal(false)

0 commit comments

Comments
 (0)