diff --git a/package-lock.json b/package-lock.json index 58e56b9b5..531ccf176 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,7 +9,7 @@ "version": "0.1.0", "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr82.33671e5", + "@iqss/dataverse-client-javascript": "2.0.0-pr88.9d7ced6", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", @@ -3408,9 +3408,9 @@ }, "node_modules/@iqss/dataverse-client-javascript": { "name": "@IQSS/dataverse-client-javascript", - "version": "2.0.0-pr82.33671e5", - "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr82.33671e5/d792f7f07a03a14a0f29438ca360b31cac130c5f", - "integrity": "sha512-G91dlp6pnEC9LRFx60m6Sc/iFKfamm+O8dDpgG9ZL31+rXkdFfesy+jIDOA4ftU2m+/yy/v/VSXZ9TXHtzncaw==", + "version": "2.0.0-pr88.9d7ced6", + "resolved": "https://npm.pkg.github.com/download/@IQSS/dataverse-client-javascript/2.0.0-pr88.9d7ced6/829cd0eefdf14c3911cc5b02a7fca9eed303587c", + "integrity": "sha512-Wjut9iCGif6cKGPZkMAyFgvR3L8ssdRHab0owXw4IJQZU8Cm4+nNvQaCFlO2cxC95zbJh0GUEUc07oqb7AOlpA==", "license": "MIT", "dependencies": { "@types/node": "^18.15.11", diff --git a/package.json b/package.json index 9f05b8773..7ab6c2405 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,7 @@ }, "dependencies": { "@faker-js/faker": "7.6.0", - "@iqss/dataverse-client-javascript": "2.0.0-pr82.33671e5", + "@iqss/dataverse-client-javascript": "2.0.0-pr88.9d7ced6", "@iqss/dataverse-design-system": "*", "@istanbuljs/nyc-config-typescript": "1.0.2", "@tanstack/react-table": "8.9.2", diff --git a/src/files/domain/models/FileCriteria.ts b/src/files/domain/models/FileCriteria.ts index 2c13f6851..8de6c9dab 100644 --- a/src/files/domain/models/FileCriteria.ts +++ b/src/files/domain/models/FileCriteria.ts @@ -10,23 +10,47 @@ export class FileCriteria { ) {} withSortBy(sortBy: FileSortByOption): FileCriteria { - return new FileCriteria(sortBy, this.filterByType, this.filterByAccess, this.filterByTag) + return new FileCriteria( + sortBy, + this.filterByType, + this.filterByAccess, + this.filterByTag, + this.searchText + ) } withFilterByType(filterByType: string | undefined): FileCriteria { const newFilterByType = filterByType === undefined ? undefined : new FileType(filterByType) - return new FileCriteria(this.sortBy, newFilterByType, this.filterByAccess, this.filterByTag) + return new FileCriteria( + this.sortBy, + newFilterByType, + this.filterByAccess, + this.filterByTag, + this.searchText + ) } withFilterByAccess(filterByAccess: FileAccessOption | undefined): FileCriteria { - return new FileCriteria(this.sortBy, this.filterByType, filterByAccess, this.filterByTag) + return new FileCriteria( + this.sortBy, + this.filterByType, + filterByAccess, + this.filterByTag, + this.searchText + ) } withFilterByTag(filterByTag: string | undefined): FileCriteria { const newFilterByTag = filterByTag === undefined ? undefined : new FileTag(filterByTag) - return new FileCriteria(this.sortBy, this.filterByType, this.filterByAccess, newFilterByTag) + return new FileCriteria( + this.sortBy, + this.filterByType, + this.filterByAccess, + newFilterByTag, + this.searchText + ) } withSearchText(searchText: string | undefined): FileCriteria { diff --git a/src/files/domain/repositories/FileRepository.ts b/src/files/domain/repositories/FileRepository.ts index e34a01bea..158806a33 100644 --- a/src/files/domain/repositories/FileRepository.ts +++ b/src/files/domain/repositories/FileRepository.ts @@ -12,9 +12,9 @@ export interface FileRepository { paginationInfo?: FilePaginationInfo, criteria?: FileCriteria ) => Promise - getCountInfoByDatasetPersistentId: ( + getFilesCountInfoByDatasetPersistentId: ( datasetPersistentId: string, datasetVersion: DatasetVersion ) => Promise - getFileUserPermissionsById: (id: number) => Promise + getUserPermissionsById: (id: number) => Promise } diff --git a/src/files/domain/useCases/checkFileDownloadPermission.ts b/src/files/domain/useCases/checkFileDownloadPermission.ts index 9176c6a5b..974f0dd5b 100644 --- a/src/files/domain/useCases/checkFileDownloadPermission.ts +++ b/src/files/domain/useCases/checkFileDownloadPermission.ts @@ -6,7 +6,7 @@ export async function checkFileDownloadPermission( file: File ): Promise { if (file.version.publishingStatus === FilePublishingStatus.DEACCESSIONED) { - return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => { + return fileRepository.getUserPermissionsById(file.id).then((permissions) => { return permissions.canEditDataset }) } @@ -16,7 +16,7 @@ export async function checkFileDownloadPermission( return true } - return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => { + return fileRepository.getUserPermissionsById(file.id).then((permissions) => { return permissions.canDownloadFile }) } diff --git a/src/files/domain/useCases/checkFileEditDatasetPermission.ts b/src/files/domain/useCases/checkFileEditDatasetPermission.ts index d7ea9d5fd..a2a69206f 100644 --- a/src/files/domain/useCases/checkFileEditDatasetPermission.ts +++ b/src/files/domain/useCases/checkFileEditDatasetPermission.ts @@ -5,7 +5,7 @@ export async function checkFileEditDatasetPermission( fileRepository: FileRepository, file: File ): Promise { - return fileRepository.getFileUserPermissionsById(file.id).then((permissions) => { + return fileRepository.getUserPermissionsById(file.id).then((permissions) => { return permissions.canEditDataset }) } diff --git a/src/files/domain/useCases/getFilesCountInfoByDatasetPersistentId.ts b/src/files/domain/useCases/getFilesCountInfoByDatasetPersistentId.ts index 6305f588c..518897809 100644 --- a/src/files/domain/useCases/getFilesCountInfoByDatasetPersistentId.ts +++ b/src/files/domain/useCases/getFilesCountInfoByDatasetPersistentId.ts @@ -8,7 +8,7 @@ export async function getFilesCountInfoByDatasetPersistentId( datasetVersion: DatasetVersion ): Promise { return fileRepository - .getCountInfoByDatasetPersistentId(datasetPersistentId, datasetVersion) + .getFilesCountInfoByDatasetPersistentId(datasetPersistentId, datasetVersion) .catch((error: Error) => { throw new Error(error.message) }) diff --git a/src/files/infrastructure/FileJSDataverseRepository.ts b/src/files/infrastructure/FileJSDataverseRepository.ts index 529c60df8..dd221a16c 100644 --- a/src/files/infrastructure/FileJSDataverseRepository.ts +++ b/src/files/infrastructure/FileJSDataverseRepository.ts @@ -1,10 +1,10 @@ import { FileRepository } from '../domain/repositories/FileRepository' import { File, FilePublishingStatus } from '../domain/models/File' import { FilesCountInfo } from '../domain/models/FilesCountInfo' -import { FilesCountInfoMother } from '../../../tests/component/files/domain/models/FilesCountInfoMother' import { FilePaginationInfo } from '../domain/models/FilePaginationInfo' import { FileUserPermissions } from '../domain/models/FileUserPermissions' import { + getDatasetFileCounts, getDatasetFiles, getFileDownloadCount, getFileUserPermissions, @@ -62,21 +62,23 @@ export class FileJSDataverseRepository implements FileRepository { return Promise.resolve(0) } - getCountInfoByDatasetPersistentId( - // eslint-disable-next-line unused-imports/no-unused-vars + getFilesCountInfoByDatasetPersistentId( datasetPersistentId: string, - // eslint-disable-next-line unused-imports/no-unused-vars datasetVersion: DatasetVersion ): Promise { - // TODO - implement using js-dataverse - return new Promise((resolve) => { - setTimeout(() => { - resolve(FilesCountInfoMother.create()) - }, 1000) - }) + // TODO - Take into account the FileCriteria https://github.com/IQSS/dataverse-frontend/issues/172 + return getDatasetFileCounts + .execute(datasetPersistentId, datasetVersion.toString()) + .then((jsFilesCountInfo) => { + return JSFileMapper.toFilesCountInfo(jsFilesCountInfo) + }) + .catch((error: WriteError) => { + console.error('Error getting files count info from Dataverse', error) + throw new Error(error.message) + }) } - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return getFileUserPermissions .execute(id) .then((jsFileUserPermissions) => diff --git a/src/files/infrastructure/mappers/JSFileMapper.ts b/src/files/infrastructure/mappers/JSFileMapper.ts index d98dd31fb..201606a27 100644 --- a/src/files/infrastructure/mappers/JSFileMapper.ts +++ b/src/files/infrastructure/mappers/JSFileMapper.ts @@ -17,10 +17,22 @@ import { import { File as JSFile, FileEmbargo as JSFileEmbargo, - FileChecksum as JSFileChecksum + FileChecksum as JSFileChecksum, + FileCounts as JSFilesCountInfo, + FileContentTypeCount as JSFileContentTypeCount, + FileCategoryNameCount as JSFileCategoryNameCount, + FileAccessStatusCount as JSFileAccessStatusCount, + FileAccessStatus as JSFileAccessStatus } from '@iqss/dataverse-client-javascript' import { DatasetPublishingStatus, DatasetVersion } from '../../../dataset/domain/models/Dataset' import { FileUserPermissions } from '../../domain/models/FileUserPermissions' +import { + FileAccessCount, + FilesCountInfo, + FileTagCount, + FileTypeCount +} from '../../domain/models/FilesCountInfo' +import { FileAccessOption, FileTag } from '../../domain/models/FileCriteria' export class JSFileMapper { static toFile(jsFile: JSFile, datasetVersion: DatasetVersion): File { @@ -169,4 +181,53 @@ export class JSFileMapper { static toFileDescription(jsFileDescription?: string): string | undefined { return jsFileDescription } + + static toFilesCountInfo(jsFilesCountInfo: JSFilesCountInfo): FilesCountInfo { + return { + total: jsFilesCountInfo.total, + perFileType: jsFilesCountInfo.perContentType.map((jsFileContentTypeCount) => + JSFileMapper.toFileTypeCount(jsFileContentTypeCount) + ), + perFileTag: jsFilesCountInfo.perCategoryName.map((jsFileCategoryNameCount) => + JSFileMapper.toFileTagCount(jsFileCategoryNameCount) + ), + perAccess: jsFilesCountInfo.perAccessStatus.map((jsFileAccessStatusCount) => + JSFileMapper.toFileAccessCount(jsFileAccessStatusCount) + ) + } + } + + static toFileTypeCount(jsFileContentTypeCount: JSFileContentTypeCount): FileTypeCount { + return { + type: new FileType(jsFileContentTypeCount.contentType), + count: jsFileContentTypeCount.count + } + } + + static toFileTagCount(jsFileCategoryNameCount: JSFileCategoryNameCount): FileTagCount { + return { + tag: new FileTag(jsFileCategoryNameCount.categoryName), + count: jsFileCategoryNameCount.count + } + } + + static toFileAccessCount(jsFileAccessStatusCount: JSFileAccessStatusCount): FileAccessCount { + return { + access: JSFileMapper.toFileAccessOption(jsFileAccessStatusCount.accessStatus), + count: jsFileAccessStatusCount.count + } + } + + static toFileAccessOption(jsFileAccessStatus: JSFileAccessStatus): FileAccessOption { + switch (jsFileAccessStatus) { + case JSFileAccessStatus.RESTRICTED: + return FileAccessOption.RESTRICTED + case JSFileAccessStatus.PUBLIC: + return FileAccessOption.PUBLIC + case JSFileAccessStatus.EMBARGOED: + return FileAccessOption.EMBARGOED + case JSFileAccessStatus.EMBARGOED_RESTRICTED: + return FileAccessOption.EMBARGOED_RESTRICTED + } + } } diff --git a/src/sections/dataset/dataset-files/DatasetFiles.tsx b/src/sections/dataset/dataset-files/DatasetFiles.tsx index 2da1645f2..33d75a2a7 100644 --- a/src/sections/dataset/dataset-files/DatasetFiles.tsx +++ b/src/sections/dataset/dataset-files/DatasetFiles.tsx @@ -25,6 +25,7 @@ export function DatasetFiles({ filesRepository, datasetPersistentId, datasetVersion, + setPaginationInfo, paginationInfo, criteria ) @@ -40,7 +41,7 @@ export function DatasetFiles({ diff --git a/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.tsx b/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.tsx index 2ad347002..5096d4001 100644 --- a/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.tsx +++ b/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.tsx @@ -10,7 +10,7 @@ import { DatasetUploadFilesButton } from '../dataset-upload-files-button/Dataset interface FileCriteriaInputsProps { criteria: FileCriteria onCriteriaChange: (criteria: FileCriteria) => void - filesCountInfo: FilesCountInfo + filesCountInfo: FilesCountInfo | undefined } const MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS = 2 export function FileCriteriaForm({ @@ -18,7 +18,7 @@ export function FileCriteriaForm({ onCriteriaChange, filesCountInfo }: FileCriteriaInputsProps) { - if (filesCountInfo.total < MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS) { + if (!filesCountInfo || filesCountInfo.total < MINIMUM_FILES_TO_SHOW_CRITERIA_INPUTS) { return <> } return ( diff --git a/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaSearchText.tsx b/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaSearchText.tsx index a392d461b..00f409555 100644 --- a/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaSearchText.tsx +++ b/src/sections/dataset/dataset-files/file-criteria-form/FileCriteriaSearchText.tsx @@ -1,7 +1,7 @@ import { Button, Form } from '@iqss/dataverse-design-system' import { Search } from 'react-bootstrap-icons' import { FileCriteria } from '../../../../files/domain/models/FileCriteria' -import { ChangeEvent, useState, KeyboardEvent } from 'react' +import { ChangeEvent, useState, KeyboardEvent, MouseEvent } from 'react' import { useTranslation } from 'react-i18next' interface FileCriteriaSearchTextProps { @@ -18,8 +18,9 @@ export function FileCriteriaSearchText({ const updatedSearchText = event.target.value setSearchText(updatedSearchText) } - const handleSubmitSearch = () => { - onCriteriaChange(criteria.withSearchText(searchText)) + const handleButtonClick = (event: MouseEvent) => { + event.preventDefault() + handleSubmitSearch() } const handleKeyDown = (event: KeyboardEvent) => { if (event.key === 'Enter') { @@ -27,6 +28,9 @@ export function FileCriteriaSearchText({ handleSubmitSearch() } } + const handleSubmitSearch = () => { + onCriteriaChange(criteria.withSearchText(searchText)) + } return ( @@ -43,7 +47,7 @@ export function FileCriteriaSearchText({ variant="secondary" icon={} aria-label={t('criteria.searchText.submit')} - onClick={handleSubmitSearch} + onClick={handleButtonClick} /> diff --git a/src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx b/src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx index 13035b5a1..5220275a2 100644 --- a/src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx +++ b/src/sections/dataset/dataset-files/files-pagination/FilesPagination.tsx @@ -18,6 +18,7 @@ export function FilesPagination({ pageSize, total }: FilesPaginationProps) { + console.log('FilesPagination', page, pageSize, total) const [paginationInfo, setPaginationInfo] = useState( new FilePaginationInfo(page, pageSize, total) ) @@ -36,7 +37,7 @@ export function FilesPagination({ useEffect(() => { onPaginationInfoChange(paginationInfo) - }, [paginationInfo]) + }, [paginationInfo.pageSize, paginationInfo.page]) useEffect(() => { setPaginationInfo(paginationInfo.withTotal(total)) diff --git a/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx b/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx index 6397c7770..53f985f51 100644 --- a/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx +++ b/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx @@ -5,8 +5,9 @@ import { FileInfoCell } from './file-info/file-info-cell/FileInfoCell' import { FileInfoHeader } from './file-info/FileInfoHeader' import { FileActionsHeader } from './file-actions/FileActionsHeader' import { FileActionsCell } from './file-actions/file-actions-cell/FileActionsCell' +import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' -export const columns: ColumnDef[] = [ +export const createColumnsDefinition = (paginationInfo: FilePaginationInfo): ColumnDef[] => [ { id: 'select', header: ({ table }) => ( @@ -31,13 +32,7 @@ export const columns: ColumnDef[] = [ ) }, { - header: ({ table }) => ( - - ), + header: () => , accessorKey: 'info', cell: (props) => }, diff --git a/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx b/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx index 6120ce0b0..fd76cc997 100644 --- a/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader.tsx @@ -1,15 +1,14 @@ import styles from '../FilesTable.module.scss' +import { FilePaginationInfo } from '../../../../../files/domain/models/FilePaginationInfo' interface FileInfoHeaderProps { - pageCount: number - pageIndex: number - pageSize: number + paginationInfo: FilePaginationInfo } -export function FileInfoHeader({ pageCount, pageIndex, pageSize }: FileInfoHeaderProps) { - const startIndex = pageIndex * pageSize + 1 - const fileCount = pageCount * pageSize - const endIndex = Math.min(startIndex + pageSize - 1, fileCount) +export function FileInfoHeader({ paginationInfo }: FileInfoHeaderProps) { + const fileCount = paginationInfo.totalFiles + const startIndex = (paginationInfo.page - 1) * paginationInfo.pageSize + 1 + const endIndex = Math.min(startIndex + paginationInfo.pageSize - 1, fileCount) if (fileCount === 0) { return <> diff --git a/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx b/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx index 52cd528fb..a3e0d6d46 100644 --- a/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx +++ b/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx @@ -1,7 +1,7 @@ import { useEffect, useState } from 'react' import { File } from '../../../../files/domain/models/File' import { getCoreRowModel, Row, useReactTable } from '@tanstack/react-table' -import { columns } from './FilesTableColumnsDefinition' +import { createColumnsDefinition } from './FilesTableColumnsDefinition' import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' import { useFileSelection } from './row-selection/useFileSelection' @@ -21,7 +21,7 @@ export function useFilesTable(files: File[], paginationInfo: FilePaginationInfo) ) const table = useReactTable({ data: files, - columns: columns, + columns: createColumnsDefinition(paginationInfo), state: { rowSelection: currentPageRowSelection }, diff --git a/src/sections/dataset/dataset-files/useFiles.tsx b/src/sections/dataset/dataset-files/useFiles.tsx index 14259112c..5617803c0 100644 --- a/src/sections/dataset/dataset-files/useFiles.tsx +++ b/src/sections/dataset/dataset-files/useFiles.tsx @@ -14,23 +14,21 @@ export function useFiles( filesRepository: FileRepository, datasetPersistentId: string, datasetVersion: DatasetVersion, - paginationInfo?: FilePaginationInfo, + onPaginationInfoChange: (paginationInfo: FilePaginationInfo) => void, + paginationInfo: FilePaginationInfo, criteria?: FileCriteria ) { const { fetchFilesPermission } = useFilePermissions() const [files, setFiles] = useState([]) const [isLoading, setIsLoading] = useState(true) - const [filesCountInfo, setFilesCountInfo] = useState({ - total: 0, - perFileType: [], - perAccess: [], - perFileTag: [] - }) + const [filesCountInfo, setFilesCountInfo] = useState() useEffect(() => { getFilesCountInfoByDatasetPersistentId(filesRepository, datasetPersistentId, datasetVersion) .then((filesCountInfo: FilesCountInfo) => { setFilesCountInfo(filesCountInfo) + onPaginationInfoChange(paginationInfo.withTotal(filesCountInfo.total)) + console.log(paginationInfo) }) .catch((error) => { console.error('There was an error getting the files count info', error) @@ -40,25 +38,31 @@ export function useFiles( useEffect(() => { setIsLoading(true) - if (filesCountInfo.total !== 0 && paginationInfo?.totalFiles !== 0) { - getFilesByDatasetPersistentId( - filesRepository, - datasetPersistentId, - datasetVersion, - paginationInfo, - criteria - ) - .then((files: File[]) => { - setFiles(files) - return files - }) - .then((files: File[]) => - fetchFilesPermission(FilePermission.DOWNLOAD_FILE, files).then(() => setIsLoading(false)) + if (filesCountInfo) { + if (filesCountInfo.total === 0) { + setIsLoading(false) + } else { + getFilesByDatasetPersistentId( + filesRepository, + datasetPersistentId, + datasetVersion, + paginationInfo, + criteria ) - .catch((error) => { - console.error('There was an error getting the files', error) - setIsLoading(false) - }) + .then((files: File[]) => { + setFiles(files) + return files + }) + .then((files: File[]) => + fetchFilesPermission(FilePermission.DOWNLOAD_FILE, files).then(() => + setIsLoading(false) + ) + ) + .catch((error) => { + console.error('There was an error getting the files', error) + setIsLoading(false) + }) + } } }, [filesRepository, datasetPersistentId, datasetVersion, paginationInfo, criteria]) diff --git a/src/stories/files/FileMockLoadingRepository.ts b/src/stories/files/FileMockLoadingRepository.ts index 6177273f7..6c36865db 100644 --- a/src/stories/files/FileMockLoadingRepository.ts +++ b/src/stories/files/FileMockLoadingRepository.ts @@ -19,7 +19,7 @@ export class FileMockLoadingRepository implements FileRepository { }) } - getCountInfoByDatasetPersistentId( + getFilesCountInfoByDatasetPersistentId( // eslint-disable-next-line unused-imports/no-unused-vars datasetPersistentId: string, // eslint-disable-next-line unused-imports/no-unused-vars @@ -32,7 +32,7 @@ export class FileMockLoadingRepository implements FileRepository { }) } // eslint-disable-next-line unused-imports/no-unused-vars - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.create()) diff --git a/src/stories/files/FileMockNoDataRepository.ts b/src/stories/files/FileMockNoDataRepository.ts index b8412c213..9f8b77f50 100644 --- a/src/stories/files/FileMockNoDataRepository.ts +++ b/src/stories/files/FileMockNoDataRepository.ts @@ -20,7 +20,7 @@ export class FileMockNoDataRepository implements FileRepository { }) } - getCountInfoByDatasetPersistentId( + getFilesCountInfoByDatasetPersistentId( // eslint-disable-next-line unused-imports/no-unused-vars datasetPersistentId: string, // eslint-disable-next-line unused-imports/no-unused-vars @@ -33,7 +33,7 @@ export class FileMockNoDataRepository implements FileRepository { }) } // eslint-disable-next-line unused-imports/no-unused-vars - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.create()) diff --git a/src/stories/files/FileMockNoFiltersRepository.ts b/src/stories/files/FileMockNoFiltersRepository.ts index 60a496144..203366df9 100644 --- a/src/stories/files/FileMockNoFiltersRepository.ts +++ b/src/stories/files/FileMockNoFiltersRepository.ts @@ -21,7 +21,7 @@ export class FileMockNoFiltersRepository implements FileRepository { }) } - getCountInfoByDatasetPersistentId( + getFilesCountInfoByDatasetPersistentId( // eslint-disable-next-line unused-imports/no-unused-vars datasetPersistentId: string, // eslint-disable-next-line unused-imports/no-unused-vars @@ -34,7 +34,7 @@ export class FileMockNoFiltersRepository implements FileRepository { }) } // eslint-disable-next-line unused-imports/no-unused-vars - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.create()) diff --git a/src/stories/files/FileMockRepository.ts b/src/stories/files/FileMockRepository.ts index 53706bb0d..f9209ecb9 100644 --- a/src/stories/files/FileMockRepository.ts +++ b/src/stories/files/FileMockRepository.ts @@ -22,7 +22,7 @@ export class FileMockRepository implements FileRepository { }) } - getCountInfoByDatasetPersistentId( + getFilesCountInfoByDatasetPersistentId( // eslint-disable-next-line unused-imports/no-unused-vars datasetPersistentId: string, // eslint-disable-next-line unused-imports/no-unused-vars @@ -35,7 +35,7 @@ export class FileMockRepository implements FileRepository { }) } // eslint-disable-next-line unused-imports/no-unused-vars - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.create()) diff --git a/src/stories/files/FileWithDeniedPermissionsRepository.ts b/src/stories/files/FileWithDeniedPermissionsRepository.ts index 5c87a926d..4385df633 100644 --- a/src/stories/files/FileWithDeniedPermissionsRepository.ts +++ b/src/stories/files/FileWithDeniedPermissionsRepository.ts @@ -8,7 +8,7 @@ export class FileWithDeniedPermissionsRepository implements FileRepository { // eslint-disable-next-line unused-imports/no-unused-vars - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.createWithDeniedPermissions()) diff --git a/src/stories/files/FileWithGrantedPermissionsRepository.ts b/src/stories/files/FileWithGrantedPermissionsRepository.ts index 5eb6475f5..c3e66e911 100644 --- a/src/stories/files/FileWithGrantedPermissionsRepository.ts +++ b/src/stories/files/FileWithGrantedPermissionsRepository.ts @@ -8,7 +8,7 @@ export class FileWithGrantedPermissionsRepository implements FileRepository { // eslint-disable-next-line unused-imports/no-unused-vars - getFileUserPermissionsById(id: number): Promise { + getUserPermissionsById(id: number): Promise { return new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.createWithGrantedPermissions()) diff --git a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx index 25337b58d..867ee4b89 100644 --- a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx @@ -46,7 +46,7 @@ const filePaginationInfo = new FilePaginationInfo(1, 10, 200) describe('DatasetFiles', () => { beforeEach(() => { fileRepository.getAllByDatasetPersistentId = cy.stub().resolves(testFiles) - fileRepository.getCountInfoByDatasetPersistentId = cy.stub().resolves(testFilesCountInfo) + fileRepository.getFilesCountInfoByDatasetPersistentId = cy.stub().resolves(testFilesCountInfo) }) it('renders the files table', () => { @@ -215,7 +215,7 @@ describe('DatasetFiles', () => { datasetVersion ) - cy.wrap(fileRepository.getCountInfoByDatasetPersistentId).should( + cy.wrap(fileRepository.getFilesCountInfoByDatasetPersistentId).should( 'be.calledWith', datasetPersistentId, datasetVersion diff --git a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx index 04f856069..6cf8aa96a 100644 --- a/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/file-criteria-form/FileCriteriaForm.spec.tsx @@ -2,6 +2,7 @@ import { FileCriteriaForm } from '../../../../../../src/sections/dataset/dataset import { FileAccessOption, FileCriteria, + FileSortByOption, FileTag } from '../../../../../../src/files/domain/models/FileCriteria' import { FilesCountInfoMother } from '../../../../files/domain/models/FilesCountInfoMother' @@ -104,10 +105,12 @@ describe('FileCriteriaForm', () => { }) it('saves global criteria when the sort by option changes', () => { + const onCriteriaChange = cy.stub().as('onCriteriaChange') const criteria = new FileCriteria() .withFilterByTag('document') .withFilterByAccess(FileAccessOption.PUBLIC) .withFilterByType('image') + .withSearchText('search text') cy.customMount( { cy.findByRole('button', { name: /Sort/ }).click() cy.findByText('Oldest').click() + cy.wrap(onCriteriaChange).should('be.calledWith', criteria.withSortBy(FileSortByOption.OLDEST)) + cy.findByRole('button', { name: 'File Type: Image' }).should('exist') cy.findByRole('button', { name: 'Access: Public' }).should('exist') cy.findByRole('button', { name: 'File Tags: Document' }).should('exist') + cy.findByLabelText('Search').should('have.value', 'search text') }) it('saves global criteria when the filter by type option changes', () => { + const onCriteriaChange = cy.stub().as('onCriteriaChange') const criteria = new FileCriteria() .withFilterByTag('document') .withFilterByAccess(FileAccessOption.PUBLIC) .withFilterByType('image') + .withSearchText('search text') cy.customMount( { cy.findByRole('button', { name: 'File Type: Image' }).click() cy.findByText('Text (10)').click() + cy.wrap(onCriteriaChange).should('be.calledWith', criteria.withFilterByType('text')) + cy.findByRole('button', { name: 'File Type: Text' }).should('exist') cy.findByRole('button', { name: 'Access: Public' }).should('exist') cy.findByRole('button', { name: 'File Tags: Document' }).should('exist') + cy.findByLabelText('Search').should('have.value', 'search text') }) it('saves global criteria when the filter by access option changes', () => { + const onCriteriaChange = cy.stub().as('onCriteriaChange') const criteria = new FileCriteria() .withFilterByTag('document') .withFilterByAccess(FileAccessOption.PUBLIC) .withFilterByType('image') + .withSearchText('search text') cy.customMount( { cy.findByRole('button', { name: 'Access: Public' }).click() cy.findByText('Restricted (10)').click() + cy.wrap(onCriteriaChange).should( + 'be.calledWith', + criteria.withFilterByAccess(FileAccessOption.RESTRICTED) + ) + cy.findByRole('button', { name: 'File Type: Image' }).should('exist') cy.findByRole('button', { name: 'Access: Restricted' }).should('exist') cy.findByRole('button', { name: 'File Tags: Document' }).should('exist') + cy.findByLabelText('Search').should('have.value', 'search text') }) it('saves global criteria when the filter by tag option changes', () => { + const onCriteriaChange = cy.stub().as('onCriteriaChange') const criteria = new FileCriteria() .withFilterByTag('document') .withFilterByAccess(FileAccessOption.PUBLIC) .withFilterByType('image') + .withSearchText('search text') cy.customMount( { cy.findByRole('button', { name: 'File Tags: Document' }).click() cy.findByText('Data (10)').click() + cy.wrap(onCriteriaChange).should('be.calledWith', criteria.withFilterByTag('data')) + cy.findByRole('button', { name: 'File Type: Image' }).should('exist') cy.findByRole('button', { name: 'Access: Public' }).should('exist') cy.findByRole('button', { name: 'File Tags: Data' }).should('exist') + cy.findByLabelText('Search').should('have.value', 'search text') }) it('saves global criteria when the search input changes', () => { + const onCriteriaChange = cy.stub().as('onCriteriaChange') const criteria = new FileCriteria() .withFilterByTag('document') .withFilterByAccess(FileAccessOption.PUBLIC) .withFilterByType('image') - .withSearchText('search') + .withSearchText('search text') cy.customMount( { /> ) - cy.findByLabelText('Search').clear().type('new search') + cy.findByLabelText('Search').clear().type('new search{enter}') + + cy.wrap(onCriteriaChange).should('be.calledWith', criteria.withSearchText('new search')) cy.findByRole('button', { name: 'File Type: Image' }).should('exist') cy.findByRole('button', { name: 'Access: Public' }).should('exist') @@ -232,4 +259,27 @@ describe('FileCriteriaForm', () => { cy.findByRole('button', { name: 'Upload Files' }).should('exist') }) + + it('does not reload the page when the search button is clicked', () => { + const onCriteriaChange = cy.stub().as('onCriteriaChange') + const criteria = new FileCriteria() + .withFilterByTag('document') + .withFilterByAccess(FileAccessOption.PUBLIC) + .withFilterByType('image') + + cy.customMount( + + ) + + cy.findByLabelText('Search').type('test') + cy.findByRole('button', { name: 'Submit search' }).click() + + cy.wrap(onCriteriaChange).should('be.calledWith', criteria.withSearchText('test')) + + cy.findByLabelText('Search').should('have.value', 'test') + }) }) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx index 9d22c9601..335b16c43 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.spec.tsx @@ -15,7 +15,7 @@ describe('FileActionsHeader', () => { userRepository.removeAuthenticated = cy.stub().resolves() const files = FileMother.createMany(2) const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: files[0].id, canEditDataset: true diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx index dd7aac757..db841720a 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.spec.tsx @@ -15,7 +15,7 @@ describe('EditFilesMenu', () => { beforeEach(() => { userRepository.getAuthenticated = cy.stub().resolves(user) userRepository.removeAuthenticated = cy.stub().resolves() - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: files[0].id, canEditDataset: true @@ -74,7 +74,7 @@ describe('EditFilesMenu', () => { }) it.skip('does not render the Edit Files menu when the user does not have update dataset permissions', () => { - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: files[0].id, canEditDataset: false diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx index beef29fba..3451e1151 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.spec.tsx @@ -22,7 +22,7 @@ describe('FileActionButtons', () => { userRepository.getAuthenticated = cy.stub().resolves(user) userRepository.removeAuthenticated = cy.stub().resolves() const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx index 79e591067..c1ba17998 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/AccessStatus.spec.tsx @@ -25,7 +25,7 @@ describe('AccessStatus', () => { it('renders the access status restricted with access', () => { const fileRestrictedWithAccess = FileMother.createWithRestrictedAccessWithAccessGranted() const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: fileRestrictedWithAccess.id, canDownloadFile: true @@ -47,7 +47,7 @@ describe('AccessStatus', () => { it('renders the access status embargoed', () => { const fileRestrictedWithAccess = FileMother.createWithRestrictedAccessWithAccessGranted() const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: fileRestrictedWithAccess.id, canDownloadFile: true @@ -75,7 +75,7 @@ describe('AccessStatus', () => { it('renders the access status embargoed restricted with access', () => { const fileRestrictedWithAccess = FileMother.createWithRestrictedAccessWithAccessGranted() const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: fileRestrictedWithAccess.id, canDownloadFile: true diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx index dbeaec172..edf2eb32d 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/access-file-menu/RequestAccessOption.spec.tsx @@ -69,7 +69,7 @@ describe('RequestAccessOption', () => { it('does not render the request access button when the file status is public', () => { const filePublic = FileMother.createWithPublicAccess() const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: filePublic.id, canDownloadFile: true @@ -96,7 +96,7 @@ describe('RequestAccessOption', () => { it('does not render the request access button when the file status is restricted with access granted', () => { const fileRestrictedWithAccess = FileMother.createWithRestrictedAccessWithAccessGranted() const fileRepository: FileRepository = {} as FileRepository - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: fileRestrictedWithAccess.id, canDownloadFile: true diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx index 40fc93d59..efcac3355 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.spec.tsx @@ -15,7 +15,7 @@ describe('FileOptionsMenu', () => { beforeEach(() => { userRepository.getAuthenticated = cy.stub().resolves(user) userRepository.removeAuthenticated = cy.stub().resolves() - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true @@ -71,7 +71,7 @@ describe('FileOptionsMenu', () => { }) it('does not render is the user do not have permissions to update the dataset', () => { - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: false diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/FileInfoHeader.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/FileInfoHeader.spec.tsx index 77016f6e7..b36a49371 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/FileInfoHeader.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/FileInfoHeader.spec.tsx @@ -1,14 +1,25 @@ import { FileInfoHeader } from '../../../../../../../src/sections/dataset/dataset-files/files-table/file-info/FileInfoHeader' +import { FilePaginationInfo } from '../../../../../../../src/files/domain/models/FilePaginationInfo' describe('FileInfoHeader', () => { it('renders the file info header', () => { - cy.customMount() + const paginationInfo: FilePaginationInfo = new FilePaginationInfo(1, 100, 100) + cy.customMount() cy.findByText('1 to 100 of 100 Files').should('exist') }) + it('renders the file info header when the totalFiles does not complete a full pageSize', () => { + const paginationInfo: FilePaginationInfo = new FilePaginationInfo(2, 10, 15) + + cy.customMount() + + cy.findByText('11 to 15 of 15 Files').should('exist') + }) + it('does not render the file info header when there are no files', () => { - cy.customMount() + const paginationInfo: FilePaginationInfo = new FilePaginationInfo(1, 100, 0) + cy.customMount() cy.findByText('1 to 100 of 100 Files').should('not.exist') }) diff --git a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx index 3c8949ec2..29a269c67 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/files-info/file-info-cell/file-info-data/file-thumbnail/FileThumbnail.spec.tsx @@ -8,7 +8,7 @@ const fileRepository: FileRepository = {} as FileRepository describe('FileThumbnail', () => { it('renders FileThumbnailPreviewImage when thumbnail is provided and file can be downloaded', () => { const file = FileMother.createWithThumbnail() - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true @@ -40,7 +40,7 @@ describe('FileThumbnail', () => { it('renders FileThumbnailPreviewImage when thumbnail is provided with unlocked icon if restricted with access', () => { const file = FileMother.createWithThumbnailRestrictedWithAccessGranted() - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true @@ -101,7 +101,7 @@ describe('FileThumbnail', () => { it('renders FileThumbnailIcon when thumbnail is not provided with unlock icon when restricted with access', () => { const file = FileMother.createWithRestrictedAccessWithAccessGranted() - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true diff --git a/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx index 90284be51..4b072adb8 100644 --- a/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/useFiles.spec.tsx @@ -4,7 +4,7 @@ import { FileRepository } from '../../../../../src/files/domain/repositories/Fil import { useFiles } from '../../../../../src/sections/dataset/dataset-files/useFiles' import { FileUserPermissionsMother } from '../../../files/domain/models/FileUserPermissionsMother' import { FilePermissionsProvider } from '../../../../../src/sections/file/file-permissions/FilePermissionsProvider' -import { useEffect, useState } from 'react' +import { useState } from 'react' import { FilePaginationInfo } from '../../../../../src/files/domain/models/FilePaginationInfo' import { DatasetPublishingStatus, @@ -18,23 +18,20 @@ const datasetVersion = new DatasetVersion(1, DatasetPublishingStatus.RELEASED, 1 const FilesTableTestComponent = ({ datasetPersistentId }: { datasetPersistentId: string }) => { const [paginationInfo, setPaginationInfo] = useState(new FilePaginationInfo()) - const { isLoading, files, filesCountInfo } = useFiles( + const { isLoading, files } = useFiles( fileRepository, datasetPersistentId, datasetVersion, + setPaginationInfo, paginationInfo ) - useEffect(() => { - setPaginationInfo(paginationInfo.withTotal(filesCountInfo.total)) - }, [filesCountInfo]) - if (isLoading) { return Loading... } return ( <> -
Files count: {filesCountInfo.total}
+
Files count: {paginationInfo.totalFiles}
{files.map((file) => ( @@ -51,8 +48,8 @@ const FilesTableTestComponent = ({ datasetPersistentId }: { datasetPersistentId: describe('useFiles', () => { beforeEach(() => { fileRepository.getAllByDatasetPersistentId = cy.stub().resolves(files) - fileRepository.getCountInfoByDatasetPersistentId = cy.stub().resolves(filesCountInfo) - fileRepository.getFileUserPermissionsById = cy + fileRepository.getFilesCountInfoByDatasetPersistentId = cy.stub().resolves(filesCountInfo) + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: files[0].id })) }) @@ -80,7 +77,7 @@ describe('useFiles', () => { cy.customMount() cy.findByText('Loading...').should('exist') - cy.wrap(fileRepository.getCountInfoByDatasetPersistentId).should( + cy.wrap(fileRepository.getFilesCountInfoByDatasetPersistentId).should( 'be.calledOnceWith', 'persistentId' ) @@ -98,7 +95,7 @@ describe('useFiles', () => { it('calls the file repository to get the permissions before removing the loading', () => { const files = FileMother.createMany(5) fileRepository.getAllByDatasetPersistentId = cy.stub().resolves(files) - fileRepository.getFileUserPermissionsById = cy.stub().resolves( + fileRepository.getUserPermissionsById = cy.stub().resolves( new Promise((resolve) => { setTimeout(() => { resolve(FileUserPermissionsMother.create({ fileId: files[0].id })) @@ -116,14 +113,14 @@ describe('useFiles', () => { cy.wrap(fileRepository.getAllByDatasetPersistentId).should('be.calledOnceWith', 'persistentId') cy.findByText('Loading...').should('exist') - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', files[0].id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', files[0].id) cy.findByText('Loading...').should('exist') cy.findByText('Files count: 100').should('exist') }) it('calls the file repository to get the files only if files count info is greater than 0', () => { - fileRepository.getCountInfoByDatasetPersistentId = cy + fileRepository.getFilesCountInfoByDatasetPersistentId = cy .stub() .resolves(FilesCountInfoMother.create({ total: 0 })) diff --git a/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx b/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx index 90e465f6d..9492c88d3 100644 --- a/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx +++ b/tests/component/sections/file/file-permissions/useFileDownloadPermission.spec.tsx @@ -24,14 +24,14 @@ function TestComponent({ file }: { file: File }) { describe('useFileDownloadPermission', () => { beforeEach(() => { fileRepository.getAllByDatasetPersistentId = cy.stub().resolves([]) - fileRepository.getCountInfoByDatasetPersistentId = cy + fileRepository.getFilesCountInfoByDatasetPersistentId = cy .stub() .resolves(FilesCountInfoMother.create()) }) it('should return file download permission', () => { const file = FileMother.createDeaccessioned() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true })) @@ -41,13 +41,13 @@ describe('useFileDownloadPermission', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has download permission').should('exist') }) it('should return false for file download permission if there is an error', () => { const file = FileMother.createDeaccessioned() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .rejects(new Error('Error getting file user permissions')) @@ -57,7 +57,7 @@ describe('useFileDownloadPermission', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Does not have download permission').should('exist') }) }) diff --git a/tests/component/sections/file/file-permissions/useFileEditDatasetPermission.spec.tsx b/tests/component/sections/file/file-permissions/useFileEditDatasetPermission.spec.tsx index 870dc4ef1..cebdd7865 100644 --- a/tests/component/sections/file/file-permissions/useFileEditDatasetPermission.spec.tsx +++ b/tests/component/sections/file/file-permissions/useFileEditDatasetPermission.spec.tsx @@ -24,14 +24,14 @@ function TestComponent({ file }: { file: File }) { describe('useFileEditDatasetPermission', () => { beforeEach(() => { fileRepository.getAllByDatasetPersistentId = cy.stub().resolves([]) - fileRepository.getCountInfoByDatasetPersistentId = cy + fileRepository.getFilesCountInfoByDatasetPersistentId = cy .stub() .resolves(FilesCountInfoMother.create()) }) it('should return edit dataset permission', () => { const file = FileMother.createDefault() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true })) @@ -41,13 +41,13 @@ describe('useFileEditDatasetPermission', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has edit dataset permission').should('exist') }) it('should return false for edit dataset permission if there is an error', () => { const file = FileMother.createDefault() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .rejects(new Error('Error getting file user permissions')) @@ -57,7 +57,7 @@ describe('useFileEditDatasetPermission', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Does not have edit dataset permission').should('exist') }) }) diff --git a/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx b/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx index 7f2d2b9f1..127ae2f9b 100644 --- a/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx +++ b/tests/component/sections/file/file-permissions/useFilePermissions.spec.tsx @@ -79,7 +79,7 @@ function TestComponent({ file, permission }: { file: File; permission: FilePermi describe('useFilePermissions', () => { beforeEach(() => { fileRepository.getAllByDatasetPersistentId = cy.stub().resolves([]) - fileRepository.getCountInfoByDatasetPersistentId = cy + fileRepository.getFilesCountInfoByDatasetPersistentId = cy .stub() .resolves(FilesCountInfoMother.create()) }) @@ -87,7 +87,7 @@ describe('useFilePermissions', () => { describe('Download permission', () => { it('should not call getFileUserPermissionsById when the file is not deaccessioned nor restricted nor embargoed', () => { const file = FileMother.createDefault() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id })) @@ -96,13 +96,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('not.be.called') + cy.wrap(fileRepository.getUserPermissionsById).should('not.be.called') cy.findByText('Has file permission').should('exist') }) it('should call getFileUserPermissionsById when the file is deaccessioned', () => { const file = FileMother.createDeaccessioned() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true })) @@ -112,13 +112,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has file permission').should('exist') }) it('should call getFileUserPermissionsById when the file is restricted', () => { const file = FileMother.createWithRestrictedAccess() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true })) cy.mount( @@ -127,13 +127,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has file permission').should('exist') }) it('should call getFileUserPermissionsById when the file is public but latest version is restricted', () => { const file = FileMother.createWithPublicAccessButLatestVersionRestricted() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true })) cy.mount( @@ -142,13 +142,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has file permission').should('exist') }) it('should call getFileUserPermissionsById when the file is embargoed', () => { const file = FileMother.createWithEmbargo() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true })) cy.mount( @@ -157,13 +157,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has file permission').should('exist') }) it('should return false if there is an error in the use case request', () => { const file = FileMother.createWithEmbargo() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .rejects(new Error('There was an error getting the file user permissions')) cy.mount( @@ -172,13 +172,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Does not have file permission').should('exist') }) it('should use the saved state of the permission the second time the file is being consulted', () => { const file = FileMother.createWithRestrictedAccess() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: true })) cy.mount( @@ -189,12 +189,12 @@ describe('useFilePermissions', () => { cy.findAllByText('Has file permission').should('exist') cy.findAllByText('Has file permission again').should('exist') - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledOnce') + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledOnce') }) it('should always allow to download if the user is in anonymized view (privateUrl)', () => { const file = FileMother.createWithRestrictedAccess() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canDownloadFile: false })) @@ -208,7 +208,7 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('not.be.called') + cy.wrap(fileRepository.getUserPermissionsById).should('not.be.called') cy.findAllByText('Has file permission').should('exist') }) }) @@ -216,7 +216,7 @@ describe('useFilePermissions', () => { describe('Edit dataset permission', () => { it('should call getFileUserPermissionsById when asking for edit dataset permission', () => { const file = FileMother.createDefault() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true })) @@ -226,13 +226,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Has file permission').should('exist') }) it('should return false if there is an error in the use case request', () => { const file = FileMother.createDefault() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .rejects(new Error('There was an error getting the file user permissions')) cy.mount( @@ -241,13 +241,13 @@ describe('useFilePermissions', () => { ) - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledWith', file.id) + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledWith', file.id) cy.findByText('Does not have file permission').should('exist') }) it('should use the saved state of the edit dataset permission the second time the file is being consulted', () => { const file = FileMother.createDefault() - fileRepository.getFileUserPermissionsById = cy + fileRepository.getUserPermissionsById = cy .stub() .resolves(FileUserPermissionsMother.create({ fileId: file.id, canEditDataset: true })) cy.mount( @@ -258,7 +258,7 @@ describe('useFilePermissions', () => { cy.findAllByText('Has file permission').should('exist') cy.findAllByText('Has file permission again').should('exist') - cy.wrap(fileRepository.getFileUserPermissionsById).should('be.calledOnce') + cy.wrap(fileRepository.getUserPermissionsById).should('be.calledOnce') }) }) }) diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index a52676cec..1dadda464 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -132,7 +132,7 @@ describe('Dataset', () => { }) describe('Visualizing the Files Tab', () => { - it('successfully loads the files tab', () => { + it.only('successfully loads the files tab', () => { cy.wrap(DatasetHelper.create()) .its('persistentId') .then((persistentId: string) => { @@ -152,31 +152,39 @@ describe('Dataset', () => { cy.findByText('Files').should('exist') - // cy.findByText('1 to 3 of 3 Files').should('exist') // TODO - Connect files count implementation + cy.findByText('1 to 3 of 3 Files').should('exist') cy.findByText('blob').should('exist') cy.findByText('blob-1').should('exist') cy.findByText('blob-2').should('exist') }) }) - it.skip('navigates to the next page of files', () => { - // TODO - Connect files count implementation to the pagination - cy.wrap(DatasetHelper.createWithFiles(FileHelper.createMany(20)), { timeout: 10000 }) + it('navigates to the next page of files', () => { + cy.wrap(DatasetHelper.createWithFiles(FileHelper.createMany(30)), { timeout: 10000 }) .its('persistentId') .then((persistentId: string) => { cy.visit(`/spa/datasets?persistentId=${persistentId}`) cy.findByText('Files').should('exist') + cy.findByRole('button', { name: /Sort/ }).click({ force: true }) + cy.findByText('Name (A-Z)').should('exist').click({ force: true }) + cy.findByText('1 to 10 of 30 Files').should('exist') cy.findByText('blob').should('exist') - cy.findByText('blob-9').should('exist') + cy.findByText('blob-17').should('exist') - cy.findByText('Next').click() + cy.findByText('Next').click({ force: true }) cy.findByText('11 to 20 of 30 Files').should('exist') - cy.findByText('blob-10').should('exist') - cy.findByText('blob-19').should('exist') + cy.findByText('blob-18').should('exist') + cy.findByText('blob-26').should('exist') + + cy.findByText('Previous').click({ force: true }) + + cy.findByText('1 to 10 of 30 Files').should('exist') + cy.findByText('blob').should('exist') + cy.findByText('blob-17').should('exist') }) }) @@ -287,7 +295,7 @@ describe('Dataset', () => { }) it.skip('applies filters to the Files Table in the correct order', () => { - // TODO - Integrate fileCountInfo + // TODO - Restore this test once fileCountsInfo use case takes into account the filtered results https://github.com/IQSS/dataverse-frontend/issues/172 const files = [ FileHelper.create('csv', { description: 'Some description', @@ -330,6 +338,7 @@ describe('Dataset', () => { cy.findByText('Files').should('exist') + cy.findByText('1 to 6 of 6 Files').should('exist') cy.findByText('blob').should('exist') cy.findByText('blob-1').should('exist') cy.findByText('blob-2').should('exist') @@ -339,6 +348,7 @@ describe('Dataset', () => { cy.findByLabelText('Search').type('blob-{enter}', { force: true }) + cy.findByText('1 to 5 of 5 Files').should('exist') cy.findByText('blob').should('not.exist') cy.findByText('blob-1').should('exist') cy.findByText('blob-2').should('exist') @@ -347,8 +357,9 @@ describe('Dataset', () => { cy.findByText('blob-5').should('exist') cy.findByRole('button', { name: 'Filter Tag: All' }).click({ force: true }) - cy.findByText('category').should('exist').click({ force: true }) + cy.findByText('Category (4)').should('exist').click({ force: true }) + cy.findByText('1 to 4 of 4 Files').should('exist') cy.findByText('blob').should('not.exist') cy.findByText('blob-1').should('not.exist') cy.findByText('blob-2').should('exist') @@ -356,9 +367,10 @@ describe('Dataset', () => { cy.findByText('blob-4').should('exist') cy.findByText('blob-5').should('exist') - cy.findByRole('button', { name: 'Access: All' }).click() - cy.findByText('Restricted').should('exist').click() + cy.findByRole('button', { name: 'Access: All' }).click({ force: true }) + cy.findByText('Restricted (3)').should('exist').click({ force: true }) + cy.findByText('1 to 3 of 3 Files').should('exist') cy.findByText('blob').should('not.exist') cy.findByText('blob-1').should('not.exist') cy.findByText('blob-2').should('not.exist') @@ -366,9 +378,10 @@ describe('Dataset', () => { cy.findByText('blob-4').should('exist') cy.findByText('blob-5').should('exist') - cy.findByRole('button', { name: 'Filter Type: All' }).click() - cy.findByText('text/csv').should('exist').click() + cy.findByRole('button', { name: 'Filter Type: All' }).click({ force: true }) + cy.findByText('Text/csv (2)').should('exist').click({ force: true }) + cy.findByText('1 to 2 of 2 Files').should('exist') cy.findByText('blob').should('not.exist') cy.findByText('blob-1').should('not.exist') cy.findByText('blob-2').should('not.exist') @@ -376,8 +389,8 @@ describe('Dataset', () => { cy.findByText('blob-4').should('exist') cy.findByText('blob-5').should('exist') - cy.findByRole('button', { name: /Sort/ }).click() - cy.findByText('Name (Z-A)').should('exist').click() + cy.findByRole('button', { name: /Sort/ }).click({ force: true }) + cy.findByText('Name (Z-A)').should('exist').click({ force: true }) cy.findByText('blob').should('not.exist') cy.findByText('blob-1').should('not.exist') diff --git a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts index 1c3d2f17d..844b61ed1 100644 --- a/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts +++ b/tests/e2e-integration/integration/files/FileJSDataverseRepository.spec.ts @@ -22,10 +22,12 @@ import { FilePaginationInfo } from '../../../../src/files/domain/models/FilePagi import { FileAccessOption, FileCriteria, - FileSortByOption + FileSortByOption, + FileTag } from '../../../../src/files/domain/models/FileCriteria' import { DatasetHelper } from '../../shared/datasets/DatasetHelper' import { FileData, FileHelper } from '../../shared/files/FileHelper' +import { FilesCountInfo } from '../../../../src/files/domain/models/FilesCountInfo' chai.use(chaiAsPromised) const expect = chai.expect @@ -421,10 +423,92 @@ describe('File JSDataverse Repository', () => { } await fileRepository - .getFileUserPermissionsById(datasetResponse.files[0].id) + .getUserPermissionsById(datasetResponse.files[0].id) .then((fileUserPermissions) => { expect(fileUserPermissions).to.deep.equal(expectedFileUserPermissions) }) }) }) + + describe('Get FilesCountInfo by dataset persistentId', () => { + it('gets FilesCountInfo by dataset persistentId', async () => { + const files = [ + FileHelper.create('csv', { + description: 'Some description', + categories: ['category'], + restrict: 'true', + tabIngest: 'false' + }), + FileHelper.create('txt', { + description: 'Some description', + tabIngest: 'false' + }), + FileHelper.create('csv', { + description: 'Some description', + categories: ['category'], + tabIngest: 'false' + }), + FileHelper.create('txt', { + description: 'Some description', + categories: ['category_1'] + }), + FileHelper.create('csv', { + description: 'Some description', + categories: ['category_1'], + restrict: 'true', + tabIngest: 'false' + }), + FileHelper.create('txt', { + description: 'Some description', + categories: ['category'], + restrict: 'true', + tabIngest: 'false' + }) + ] + const dataset = await DatasetHelper.createWithFiles(files).then((datasetResponse) => + datasetRepository.getByPersistentId(datasetResponse.persistentId) + ) + if (!dataset) throw new Error('Dataset not found') + + const expectedFilesCountInfo: FilesCountInfo = { + total: 6, + perAccess: [ + { + access: FileAccessOption.PUBLIC, + count: 3 + }, + { + access: FileAccessOption.RESTRICTED, + count: 3 + } + ], + perFileType: [ + { + type: new FileType('text/csv'), + count: 3 + }, + { + type: new FileType('text/plain'), + count: 3 + } + ], + perFileTag: [ + { + tag: new FileTag('category_1'), + count: 2 + }, + { + tag: new FileTag('category'), + count: 3 + } + ] + } + + await fileRepository + .getFilesCountInfoByDatasetPersistentId(dataset.persistentId, dataset.version) + .then((filesCountInfo) => { + expect(filesCountInfo).to.deep.equal(expectedFilesCountInfo) + }) + }) + }) })