diff --git a/.storybook/preview.tsx b/.storybook/preview.tsx index 9c9223e68..5b68e2be5 100644 --- a/.storybook/preview.tsx +++ b/.storybook/preview.tsx @@ -5,6 +5,7 @@ import { createBrowserRouter, RouteObject, RouterProvider } from 'react-router-d import { FakerHelper } from '../tests/component/shared/FakerHelper' import { ExternalToolsProvider } from '../src/shared/contexts/external-tools/ExternalToolsProvider' import { ExternalToolsEmptyMockRepository } from '../src/stories/shared-mock-repositories/externalTools/ExternalToolsMockRepository' +import { RepositoriesStoryProvider } from '../src/stories/WithRepositories' import 'react-loading-skeleton/dist/skeleton.css' import '../src/assets/global.scss' import '../src/assets/swal-custom.scss' @@ -40,9 +41,12 @@ const preview: Preview = { return ( - - - + + + + + ) } diff --git a/CHANGELOG.md b/CHANGELOG.md index ab6954c57..b6e660e06 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -12,6 +12,8 @@ This changelog follows the principles of [Keep a Changelog](https://keepachangel ### Changed +- Avoided prop-drilling for file, guestbook, user and external tool repository, so used context to share epository instances. + ### Fixed ### Removed diff --git a/src/App.tsx b/src/App.tsx index 07ef2e934..11c402b4f 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -8,6 +8,9 @@ import { ExternalToolsJSDataverseRepository } from './externalTools/infrastructu import { RepositoriesProvider } from './shared/contexts/repositories/RepositoriesProvider' import { CollectionJSDataverseRepository } from './collection/infrastructure/repositories/CollectionJSDataverseRepository' import { DatasetJSDataverseRepository } from './dataset/infrastructure/repositories/DatasetJSDataverseRepository' +import { FileJSDataverseRepository } from './files/infrastructure/FileJSDataverseRepository' +import { GuestbookJSDataverseRepository } from './guestbooks/infrastructure/repositories/GuestbookJSDataverseRepository' +import { UserJSDataverseRepository } from './users/infrastructure/repositories/UserJSDataverseRepository' import 'react-loading-skeleton/dist/skeleton.css' import './assets/global.scss' import './assets/react-toastify-custom.scss' @@ -16,6 +19,9 @@ import './assets/swal-custom.scss' const externalToolsRepository = new ExternalToolsJSDataverseRepository() const collectionRepository = new CollectionJSDataverseRepository() const datasetRepository = new DatasetJSDataverseRepository() +const fileRepository = new FileJSDataverseRepository() +const guestbookRepository = new GuestbookJSDataverseRepository() +const userRepository = new UserJSDataverseRepository() function App() { const appConfig = requireAppConfig() @@ -38,13 +44,17 @@ function App() { return ( <> - - + + - - + + diff --git a/src/router/routes.tsx b/src/router/routes.tsx index c664b40fa..976ca5e97 100644 --- a/src/router/routes.tsx +++ b/src/router/routes.tsx @@ -1,6 +1,5 @@ import { lazy, Suspense } from 'react' import { Navigate, RouteObject } from 'react-router-dom' -import { UserJSDataverseRepository } from '@/users/infrastructure/repositories/UserJSDataverseRepository' import { Route } from '@/sections/Route.enum' import { Layout } from '@/sections/layout/Layout' import { ErrorPage } from '@/sections/error-page/ErrorPage' @@ -9,8 +8,6 @@ import { AuthCallback } from '@/sections/auth-callback/AuthCallback' import { SessionProvider } from '@/sections/session/SessionProvider' import { ProtectedRoute } from './ProtectedRoute' -const userRepository = new UserJSDataverseRepository() - const Homepage = lazy(() => import('../sections/homepage/HomepageFactory').then(({ HomepageFactory }) => ({ default: () => HomepageFactory.create() @@ -155,7 +152,7 @@ const AdvancedSearchPage = lazy(() => export const routes: RouteObject[] = [ { - element: , + element: , children: [ { path: '/', diff --git a/src/sections/account/Account.tsx b/src/sections/account/Account.tsx index bd29f9185..a53bbd1d9 100644 --- a/src/sections/account/Account.tsx +++ b/src/sections/account/Account.tsx @@ -3,7 +3,6 @@ import { useTranslation } from 'react-i18next' import { useSearchParams } from 'react-router-dom' import { Tabs } from '@iqss/dataverse-design-system' import { AccountHelper, AccountPanelTabKey } from './AccountHelper' -import { UserJSDataverseRepository } from '@/users/infrastructure/repositories/UserJSDataverseRepository' import { NotificationRepository } from '@/notifications/domain/repositories/NotificationRepository' import { ApiTokenSection } from './api-token-section/ApiTokenSection' import { AccountInfoSection } from './account-info-section/AccountInfoSection' @@ -17,14 +16,12 @@ const tabsKeys = AccountHelper.ACCOUNT_PANEL_TABS_KEYS interface AccountProps { defaultActiveTabKey: AccountPanelTabKey - userRepository: UserJSDataverseRepository roleRepository: RoleJSDataverseRepository notificationRepository: NotificationRepository } export const Account = ({ defaultActiveTabKey, - userRepository, roleRepository, notificationRepository }: AccountProps) => { @@ -66,7 +63,7 @@ export const Account = ({
- +
diff --git a/src/sections/account/AccountFactory.tsx b/src/sections/account/AccountFactory.tsx index a0fa99c97..a127ec977 100644 --- a/src/sections/account/AccountFactory.tsx +++ b/src/sections/account/AccountFactory.tsx @@ -2,11 +2,9 @@ import { ReactElement } from 'react' import { useSearchParams } from 'react-router-dom' import { AccountHelper } from './AccountHelper' import { Account } from './Account' -import { UserJSDataverseRepository } from '@/users/infrastructure/repositories/UserJSDataverseRepository' import { RoleJSDataverseRepository } from '@/roles/infrastructure/repositories/RoleJSDataverseRepository' import { NotificationJSDataverseRepository } from '@/notifications/infrastructure/repositories/NotificationJSDataverseRepository' -const userRepository = new UserJSDataverseRepository() const roleRepository = new RoleJSDataverseRepository() const notificationRepository = new NotificationJSDataverseRepository() @@ -23,7 +21,6 @@ function AccountWithSearchParams() { return ( diff --git a/src/sections/account/api-token-section/ApiTokenSection.tsx b/src/sections/account/api-token-section/ApiTokenSection.tsx index a9efd7374..212d7eea7 100644 --- a/src/sections/account/api-token-section/ApiTokenSection.tsx +++ b/src/sections/account/api-token-section/ApiTokenSection.tsx @@ -7,21 +7,18 @@ import { useRevokeApiToken } from './useRevokeApiToken' import { ApiTokenSectionSkeleton } from './ApiTokenSectionSkeleton' import { TokenInfo } from '@/users/domain/models/TokenInfo' import { DateHelper } from '@/shared/helpers/DateHelper' -import { UserRepository } from '@/users/domain/repositories/UserRepository' import { Button } from '@iqss/dataverse-design-system' import { Alert } from '@iqss/dataverse-design-system' +import { useUserRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import accountStyles from '../Account.module.scss' import styles from './ApiTokenSection.module.scss' -interface ApiTokenSectionProps { - repository: UserRepository -} - -export const ApiTokenSection = ({ repository }: ApiTokenSectionProps) => { +export const ApiTokenSection = () => { + const { userRepository } = useUserRepositories() const { t } = useTranslation('account', { keyPrefix: 'apiToken' }) const [currentApiTokenInfo, setCurrentApiTokenInfo] = useState() - const { error: getError, apiTokenInfo, isLoading } = useGetApiToken(repository) + const { error: getError, apiTokenInfo, isLoading } = useGetApiToken(userRepository) useEffect(() => { setCurrentApiTokenInfo(apiTokenInfo) @@ -32,7 +29,7 @@ export const ApiTokenSection = ({ repository }: ApiTokenSectionProps) => { isRecreating, error: recreatingError, apiTokenInfo: updatedTokenInfo - } = useRecreateApiToken(repository) + } = useRecreateApiToken(userRepository) useEffect(() => { if (updatedTokenInfo) { @@ -44,7 +41,7 @@ export const ApiTokenSection = ({ repository }: ApiTokenSectionProps) => { void recreateToken() } - const { revokeToken, isRevoking, error: revokingError } = useRevokeApiToken(repository) + const { revokeToken, isRevoking, error: revokingError } = useRevokeApiToken(userRepository) const handleRevokeToken = async () => { await revokeToken() diff --git a/src/sections/collection/Collection.tsx b/src/sections/collection/Collection.tsx index 212eafcbc..bc3fdb137 100644 --- a/src/sections/collection/Collection.tsx +++ b/src/sections/collection/Collection.tsx @@ -22,7 +22,7 @@ import { ContactRepository } from '@/contact/domain/repositories/ContactReposito import { NotFoundPage } from '../not-found-page/NotFoundPage' import { LinkCollectionDropdown } from './link-collection-dropdown/LinkCollectionDropdown' import { useSession } from '../session/SessionContext' -import { useCollectionRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' +import { useRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import styles from './Collection.module.scss' interface CollectionProps { @@ -41,7 +41,7 @@ export function Collection({ contactRepository, accountCreated }: CollectionProps) { - const { collectionRepository } = useCollectionRepositories() + const { collectionRepository } = useRepositories() useScrollTop() const { previousPath } = useHistoryTracker() const previousPathIsHomepage = previousPath === Route.HOME diff --git a/src/sections/dataset/Dataset.tsx b/src/sections/dataset/Dataset.tsx index 51b30b691..658ec2afd 100644 --- a/src/sections/dataset/Dataset.tsx +++ b/src/sections/dataset/Dataset.tsx @@ -11,7 +11,6 @@ import { DatasetMetadata } from './dataset-metadata/DatasetMetadata' import { DatasetSummary } from './dataset-summary/DatasetSummary' import { DatasetCitation } from './dataset-citation/DatasetCitation' import { DatasetFiles } from './dataset-files/DatasetFiles' -import { FileRepository } from '../../files/domain/repositories/FileRepository' import { DatasetActionButtons } from './dataset-action-buttons/DatasetActionButtons' import { useDataset } from './DatasetContext' import { useNotImplementedModal } from '../not-implemented/NotImplementedModalContext' @@ -34,7 +33,6 @@ import { useAnonymized } from './anonymized/AnonymizedContext' import { useDatasetRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface DatasetProps { - fileRepository: FileRepository metadataBlockInfoRepository: MetadataBlockInfoRepository contactRepository: ContactRepository dataverseInfoRepository: DataverseInfoRepository @@ -44,7 +42,6 @@ interface DatasetProps { } export function Dataset({ - fileRepository, metadataBlockInfoRepository, contactRepository, dataverseInfoRepository, @@ -173,7 +170,6 @@ export function Dataset({
{filesTabInfiniteScrollEnabled ? ( ) : ( @@ -205,7 +200,6 @@ export function Dataset({ - - - - - - - - - - - - - - + + + + + + + + + + + + + ) } } @@ -82,7 +77,6 @@ function DatasetWithSearchParams() { searchParams={{ privateUrlToken: privateUrlToken }} isPublishing={publishInProgress}> { const { t } = useTranslation('shared') - const { datasetExploreTools, datasetConfigureTools, externalToolsRepository } = useExternalTools() + const { datasetExploreTools, datasetConfigureTools } = useExternalTools() const tools = kind === 'explore' ? datasetExploreTools : datasetConfigureTools if (!tools || tools.length === 0) return null @@ -35,7 +35,6 @@ const DatasetToolOptions = ({ persistentId, kind }: DatasetToolOptionsProps) => @@ -48,15 +47,10 @@ interface ToolOptionProps { toolId: number toolDisplayName: string persistentId: string - externalToolsRepository: ExternalToolsRepository } -const ToolOption = ({ - toolId, - toolDisplayName, - persistentId, - externalToolsRepository -}: ToolOptionProps) => { +const ToolOption = ({ toolId, toolDisplayName, persistentId }: ToolOptionProps) => { + const { externalToolsRepository } = useExternalToolsRepositories() const [isOpening, setIsOpening] = useState(false) const { t, i18n } = useTranslation('shared') const openingRef = useRef(false) diff --git a/src/sections/dataset/dataset-files/DatasetFiles.tsx b/src/sections/dataset/dataset-files/DatasetFiles.tsx index df6a4820f..d321e6298 100644 --- a/src/sections/dataset/dataset-files/DatasetFiles.tsx +++ b/src/sections/dataset/dataset-files/DatasetFiles.tsx @@ -1,4 +1,3 @@ -import { FileRepository } from '../../../files/domain/repositories/FileRepository' import { useState } from 'react' import { FilesTable } from './files-table/FilesTable' import { FileCriteriaForm } from './file-criteria-form/FileCriteriaForm' @@ -7,22 +6,19 @@ import { useFiles } from './useFiles' import { PaginationControls } from '../../shared/pagination/PaginationControls' import { DatasetVersion } from '../../../dataset/domain/models/Dataset' import { FilePaginationInfo } from '../../../files/domain/models/FilePaginationInfo' +import { useDatasetRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface DatasetFilesProps { - filesRepository: FileRepository datasetPersistentId: string datasetVersion: DatasetVersion } -export function DatasetFiles({ - filesRepository, - datasetPersistentId, - datasetVersion -}: DatasetFilesProps) { +export function DatasetFiles({ datasetPersistentId, datasetVersion }: DatasetFilesProps) { + const { fileRepository } = useDatasetRepositories() const [paginationInfo, setPaginationInfo] = useState(new FilePaginationInfo()) const [criteria, setCriteria] = useState(new FileCriteria()) const { files, isLoading, filesCountInfo, filesTotalDownloadSize } = useFiles( - filesRepository, + fileRepository, datasetPersistentId, datasetVersion, setPaginationInfo, @@ -39,7 +35,6 @@ export function DatasetFiles({ /> (null) const criteriaContainerRef = useRef(null) const criteriaContainerSize = useObserveElementSize(criteriaContainerRef) @@ -44,7 +43,7 @@ export function DatasetFilesScrollable({ isLoading: _isLoadingFilesCountInfo, error: errorFilesCountInfo } = useGetFilesCountInfo({ - filesRepository, + filesRepository: fileRepository, datasetPersistentId, datasetVersion, criteria, @@ -56,7 +55,7 @@ export function DatasetFilesScrollable({ isLoading: _isLoadingFilesTotalDownloadSize, error: errorFilesTotalDownloadSize } = useGetFilesTotalDownloadSize({ - filesRepository, + filesRepository: fileRepository, datasetPersistentId, datasetVersion, criteria, @@ -75,7 +74,7 @@ export function DatasetFilesScrollable({ isEmptyFiles, refreshFiles } = useGetAccumulatedFiles({ - filesRepository, + filesRepository: fileRepository, datasetPersistentId, datasetVersion }) @@ -183,7 +182,6 @@ export function DatasetFilesScrollable({ showSentryRef={showSentryRef} isEmptyFiles={isEmptyFiles} accumulatedCount={accumulatedCount} - fileRepository={filesRepository} />
diff --git a/src/sections/dataset/dataset-files/files-table/FilesTable.tsx b/src/sections/dataset/dataset-files/files-table/FilesTable.tsx index 319bd4ada..75afed124 100644 --- a/src/sections/dataset/dataset-files/files-table/FilesTable.tsx +++ b/src/sections/dataset/dataset-files/files-table/FilesTable.tsx @@ -10,12 +10,9 @@ import { useEffect, useState } from 'react' import { FileSelection } from './row-selection/useFileSelection' import { FileCriteria } from '../../../../files/domain/models/FileCriteria' import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' -import { FileRepository } from '@/files/domain/repositories/FileRepository' -import { useDatasetRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface FilesTableProps { files: FilePreview[] - fileRepository: FileRepository isLoading: boolean paginationInfo: FilePaginationInfo filesTotalDownloadSize: number @@ -27,15 +24,11 @@ export function FilesTable({ isLoading, paginationInfo, filesTotalDownloadSize, - fileRepository, criteria }: FilesTableProps) { - const { datasetRepository } = useDatasetRepositories() const { table, fileSelection, selectAllFiles, clearFileSelection } = useFilesTable( files, - paginationInfo, - fileRepository, - datasetRepository + paginationInfo ) const [visitedPagination, setVisitedPagination] = useState(paginationInfo) diff --git a/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx b/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx index 66c8d8083..3cfba53f8 100644 --- a/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx +++ b/src/sections/dataset/dataset-files/files-table/FilesTableColumnsDefinition.tsx @@ -7,14 +7,10 @@ import { FileActionsCell } from './file-actions/file-actions-cell/FileActionsCel import { FileSelection } from './row-selection/useFileSelection' import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' import { RowSelectionCheckbox } from '@/sections/shared/form/row-selection-checkbox/RowSelectionCheckbox' -import { FileRepository } from '@/files/domain/repositories/FileRepository' -import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' export const createColumnsDefinition = ( paginationInfo: FilePaginationInfo, fileSelection: FileSelection, - fileRepository: FileRepository, - datasetRepository: DatasetRepository, accumulatedFilesCount?: number ): ColumnDef[] => [ { @@ -56,10 +52,9 @@ export const createColumnsDefinition = ( row.original)} fileSelection={fileSelection} - fileRepository={fileRepository} /> ), accessorKey: 'status', - cell: (props) => + cell: (props) => } ] diff --git a/src/sections/dataset/dataset-files/files-table/FilesTableScrollable.tsx b/src/sections/dataset/dataset-files/files-table/FilesTableScrollable.tsx index 72e9739bf..878aa45f9 100644 --- a/src/sections/dataset/dataset-files/files-table/FilesTableScrollable.tsx +++ b/src/sections/dataset/dataset-files/files-table/FilesTableScrollable.tsx @@ -11,8 +11,6 @@ import { ZipDownloadLimitMessage } from './zip-download-limit-message/ZipDownloa import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' import { type SentryRef } from '../DatasetFilesScrollable' import styles from './FilesTable.module.scss' -import { FileRepository } from '@/files/domain/repositories/FileRepository' -import { useDatasetRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface FilesTableScrollableProps { files: FilePreview[] @@ -23,7 +21,6 @@ interface FilesTableScrollableProps { sentryRef: SentryRef showSentryRef: boolean isEmptyFiles: boolean - fileRepository: FileRepository accumulatedCount: number } @@ -36,18 +33,10 @@ export const FilesTableScrollable = ({ sentryRef, showSentryRef, isEmptyFiles, - fileRepository, accumulatedCount }: FilesTableScrollableProps) => { - const { datasetRepository } = useDatasetRepositories() const { table, fileSelection, selectAllPossibleRows, clearRowsSelection } = - useFilesTableScrollable( - files, - paginationInfo, - accumulatedCount, - fileRepository, - datasetRepository - ) + useFilesTableScrollable(files, paginationInfo, accumulatedCount) const [previousCriteria, setPreviousCriteria] = useState(criteria) diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.tsx index e7eac554b..2162ae7e7 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/FileActionsHeader.tsx @@ -4,23 +4,17 @@ import styles from './FileActionsHeader.module.scss' import { useTranslation } from 'react-i18next' import { DownloadFilesButton } from './download-files/DownloadFilesButton' import { FileSelection } from '../row-selection/useFileSelection' -import { FileRepository } from '@/files/domain/repositories/FileRepository' interface FileActionsHeaderProps { files: FilePreview[] fileSelection: FileSelection - fileRepository: FileRepository } -export function FileActionsHeader({ - files, - fileSelection, - fileRepository -}: FileActionsHeaderProps) { +export function FileActionsHeader({ files, fileSelection }: FileActionsHeaderProps) { const { t } = useTranslation('files') return (
- +
) diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetDeleteFileButton.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetDeleteFileButton.tsx index 7359f5f4e..e324b7e1a 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetDeleteFileButton.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetDeleteFileButton.tsx @@ -3,25 +3,21 @@ import { useTranslation } from 'react-i18next' import { useNavigate, useSearchParams } from 'react-router-dom' import { toast } from 'react-toastify' import { DropdownButtonItem } from '@iqss/dataverse-design-system' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { QueryParamKey, Route } from '@/sections/Route.enum' import { DatasetNonNumericVersionSearchParam } from '@/dataset/domain/models/Dataset' import { ConfirmDeleteFileModal } from '@/sections/file/file-action-buttons/edit-file-menu/delete-file-button/confirm-delete-file-modal/ConfirmDeleteFileModal' import { useDeleteFile } from '@/sections/file/file-action-buttons/edit-file-menu/delete-file-button/useDeleteFile' import { useFilesContext } from '@/sections/file/FilesContext' import { EditFilesMenuDatasetInfo } from './EditFilesOptions' +import { useFileRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface DatasetDeleteFileButtonProps { fileId: number - fileRepository: FileRepository datasetInfo: EditFilesMenuDatasetInfo } -export const DatasetDeleteFileButton = ({ - fileId, - fileRepository, - datasetInfo -}: DatasetDeleteFileButtonProps) => { +export const DatasetDeleteFileButton = ({ fileId, datasetInfo }: DatasetDeleteFileButtonProps) => { + const { fileRepository } = useFileRepositories() const [showConfirmationModal, setShowConfirmationModal] = useState(false) const navigate = useNavigate() const { t } = useTranslation('file') diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetEditFileTagsButton.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetEditFileTagsButton.tsx index 27a308276..3e03f4cd8 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetEditFileTagsButton.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetEditFileTagsButton.tsx @@ -4,17 +4,16 @@ import { DropdownButtonItem } from '@iqss/dataverse-design-system' import { EditFileTagsModal } from '@/sections/file/file-action-buttons/edit-file-menu/edit-file-tags/edit-file-tags-modal/EditFileTagsModal' import { useUpdateFileCategories } from '@/sections/file/file-action-buttons/edit-file-menu/edit-file-tags/useUpdateFileCategories' import { useUpdateFileTabularTags } from '@/sections/file/file-action-buttons/edit-file-menu/edit-file-tags/useUpdateFileTabularTags' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { toast } from 'react-toastify' import { FileLabel } from '@/files/domain/models/FileMetadata' import { useFilesContext } from '@/sections/file/FilesContext' import { QueryParamKey, Route } from '@/sections/Route.enum' import { useNavigate, useSearchParams } from 'react-router-dom' import { DatasetNonNumericVersionSearchParam } from '@/dataset/domain/models/Dataset' +import { useFileRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface EditFileTagsButtonProps { fileId: number - fileRepository: FileRepository existingLabels?: FileLabel[] datasetPersistentId: string isTabularFile: boolean @@ -22,11 +21,11 @@ interface EditFileTagsButtonProps { export const DatasetEditFileTagsButton = ({ fileId, - fileRepository, existingLabels, datasetPersistentId, isTabularFile }: EditFileTagsButtonProps) => { + const { fileRepository } = useFileRepositories() const [isModalOpen, setIsModalOpen] = useState(false) const { t } = useTranslation('file') const { refreshFiles } = useFilesContext() diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetRestrictFileButton.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetRestrictFileButton.tsx index 9b91daaba..5716e4659 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetRestrictFileButton.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetRestrictFileButton.tsx @@ -3,27 +3,26 @@ import { useTranslation } from 'react-i18next' import { useNavigate, useSearchParams } from 'react-router-dom' import { toast } from 'react-toastify' import { DropdownButtonItem } from '@iqss/dataverse-design-system' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { QueryParamKey, Route } from '@/sections/Route.enum' import { DatasetNonNumericVersionSearchParam } from '@/dataset/domain/models/Dataset' import { ConfirmRestrictFileModal } from '@/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/confirm-restrict-file-modal/ConfirmRestrictFileModal' import { useRestrictFile } from '@/sections/file/file-action-buttons/edit-file-menu/restrict-file-button/useRestrictFile' import { useFilesContext } from '@/sections/file/FilesContext' import { EditFilesMenuDatasetInfo } from './EditFilesOptions' +import { useFileRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface DatasetRestrictFileButtonProps { fileId: number isRestricted: boolean - fileRepository: FileRepository datasetInfo: EditFilesMenuDatasetInfo } export const DatasetRestrictFileButton = ({ fileId, isRestricted, - fileRepository, datasetInfo }: DatasetRestrictFileButtonProps) => { + const { fileRepository } = useFileRepositories() const [showConfirmationModal, setShowConfirmationModal] = useState(false) const navigate = useNavigate() const { t } = useTranslation('file') diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.tsx index df49cb577..e03335c43 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.tsx @@ -7,16 +7,14 @@ import { useTranslation } from 'react-i18next' import { useDataset } from '../../../../DatasetContext' import { FileSelection } from '../../row-selection/useFileSelection' import { useMediaQuery } from '../../../../../../shared/hooks/useMediaQuery' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import styles from './EditFilesMenu.module.scss' interface EditFilesMenuProps { files: FilePreview[] fileSelection: FileSelection - fileRepository: FileRepository } const MINIMUM_FILES_COUNT_TO_SHOW_EDIT_FILES_BUTTON = 1 -export function EditFilesMenu({ files, fileSelection, fileRepository }: EditFilesMenuProps) { +export function EditFilesMenu({ files, fileSelection }: EditFilesMenuProps) { const { t } = useTranslation('files') const { user } = useSession() const { dataset } = useDataset() @@ -40,12 +38,7 @@ export function EditFilesMenu({ files, fileSelection, fileRepository }: EditFile disabled={ dataset.checkIsLockedFromEdits(user.persistentId) || !dataset.hasValidTermsOfAccess }> - + ) } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.tsx index 62b46755b..7c9d6bcb0 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.tsx @@ -6,7 +6,6 @@ import { useState } from 'react' import { FileSelection } from '../../row-selection/useFileSelection' import { NoSelectedFilesModal } from '../no-selected-files-modal/NoSelectedFilesModal' import { useNotImplementedModal } from '../../../../../not-implemented/NotImplementedModalContext' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { DatasetRestrictFileButton } from '@/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetRestrictFileButton' import { DatasetDeleteFileButton } from '@/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/DatasetDeleteFileButton' import { RouteWithParams } from '@/sections/Route.enum' @@ -21,7 +20,6 @@ type EditFilesOptionsProps = files: FilePreview[] file?: never fileSelection: FileSelection - fileRepository: FileRepository datasetInfo?: never isHeader: true } @@ -29,7 +27,6 @@ type EditFilesOptionsProps = files?: never file: FilePreview fileSelection?: never - fileRepository: FileRepository datasetInfo: EditFilesMenuDatasetInfo isHeader: false } @@ -47,7 +44,6 @@ export function EditFilesOptions({ file, files, fileSelection, - fileRepository, datasetInfo, isHeader }: EditFilesOptionsProps) { @@ -78,7 +74,6 @@ export function EditFilesOptions({ {/* TODO: remove this when we can handle non-S3 files */} @@ -97,17 +92,12 @@ export function EditFilesOptions({ - + ) } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/FileActionsCell.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/FileActionsCell.tsx index 525cb407b..111ca468f 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/FileActionsCell.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/FileActionsCell.tsx @@ -1,4 +1,3 @@ -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { FilePreview } from '../../../../../../files/domain/models/FilePreview' import { FileActionButtons } from './file-action-buttons/FileActionButtons' import { FileInfoMessages } from './file-info-messages/FileInfoMessages' @@ -6,13 +5,12 @@ import styles from './FileActionsCell.module.scss' interface FileActionsCellProps { file: FilePreview - fileRepository: FileRepository } -export function FileActionsCell({ file, fileRepository }: FileActionsCellProps) { +export function FileActionsCell({ file }: FileActionsCellProps) { return (
- +
) } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx index 8f1c891f6..5b2bcd055 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileActionButtons.tsx @@ -1,6 +1,5 @@ import { useTranslation } from 'react-i18next' import { ButtonGroup } from '@iqss/dataverse-design-system' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { FilePreview } from '@/files/domain/models/FilePreview' import { DatasetPublishingStatus } from '@/dataset/domain/models/Dataset' import { AccessFileMenu } from '@/sections/file/file-action-buttons/access-file-menu/AccessFileMenu' @@ -10,9 +9,8 @@ import { FileTools } from './FileTools' interface FileActionButtonsProps { file: FilePreview - fileRepository: FileRepository } -export function FileActionButtons({ file, fileRepository }: FileActionButtonsProps) { +export function FileActionButtons({ file }: FileActionButtonsProps) { const { t } = useTranslation('files') const isBelow768px = useMediaQuery('(max-width: 768px)') @@ -30,7 +28,7 @@ export function FileActionButtons({ file, fileRepository }: FileActionButtonsPro ingestInProgress={file.ingest.isInProgress} asIcon /> - + ) } diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/DownloadWithTermsAndGuestbookModal.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/DownloadWithTermsAndGuestbookModal.tsx index 1e873c074..7edb8b112 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/DownloadWithTermsAndGuestbookModal.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/DownloadWithTermsAndGuestbookModal.tsx @@ -12,7 +12,7 @@ import { Guestbook, GuestbookCustomQuestion } from '@/guestbooks/domain/models/G import { useGuestbookCollectSubmission } from './useGuestbookCollectSubmission' import { CustomTerms as CustomTermsModel, DatasetLicense } from '@/dataset/domain/models/Dataset' import { useAccessRepository } from '@/sections/access/AccessRepositoryContext' -import { useGuestbookRepository } from '@/sections/guestbooks/GuestbookRepositoryContext' +import { useGuestbookRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import { GuestbookAnswerDTO, GuestbookResponseDTO @@ -50,7 +50,7 @@ export function DownloadWithTermsAndGuestbookModal({ const { t: tDataset } = useTranslation('dataset') const { user } = useSession() const accessRepository = useAccessRepository() - const guestbookRepository = useGuestbookRepository() + const { guestbookRepository } = useGuestbookRepositories() const hasGuestbook = guestbookId !== undefined const [formValues, setFormValues] = useState({}) diff --git a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx index 325e3adaa..1cf941f25 100644 --- a/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx +++ b/src/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/file-options-menu/FileOptionsMenu.tsx @@ -7,16 +7,14 @@ import { useTranslation } from 'react-i18next' import { useState } from 'react' import { FileAlreadyDeletedModal } from './FileAlreadyDeletedModal' import { useDataset } from '../../../../../../DatasetContext' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { EditFilesMenuDatasetInfo } from '../../../edit-files-menu/EditFilesOptions' import { FileConfigureToolsOptions } from '@/sections/file/file-action-buttons/access-file-menu/FileToolOptions' interface FileOptionsMenuProps { file: FilePreview - fileRepository: FileRepository } -export function FileOptionsMenu({ file, fileRepository }: FileOptionsMenuProps) { +export function FileOptionsMenu({ file }: FileOptionsMenuProps) { const { t } = useTranslation('files') const { user } = useSession() const { dataset } = useDataset() @@ -71,12 +69,7 @@ export function FileOptionsMenu({ file, fileRepository }: FileOptionsMenuProps) {t('actions.optionsMenu.headers.editOptions')} - + diff --git a/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx b/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx index 09202cda5..02e7be148 100644 --- a/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx +++ b/src/sections/dataset/dataset-files/files-table/useFilesTable.tsx @@ -4,19 +4,12 @@ import { getCoreRowModel, Row, useReactTable } from '@tanstack/react-table' import { createColumnsDefinition } from './FilesTableColumnsDefinition' import { useFileSelection } from './row-selection/useFileSelection' import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' -import { FileRepository } from '@/files/domain/repositories/FileRepository' -import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' export type RowSelection = { [key: string]: boolean } -export function useFilesTable( - files: FilePreview[], - paginationInfo: FilePaginationInfo, - fileRepository: FileRepository, - datasetRepository: DatasetRepository -) { +export function useFilesTable(files: FilePreview[], paginationInfo: FilePaginationInfo) { const [currentPageRowSelection, setCurrentPageRowSelection] = useState({}) const [currentPageSelectedRowModel, setCurrentPageSelectedRowModel] = useState< Record> @@ -28,12 +21,7 @@ export function useFilesTable( ) const table = useReactTable({ data: files, - columns: createColumnsDefinition( - paginationInfo, - fileSelection, - fileRepository, - datasetRepository - ), + columns: createColumnsDefinition(paginationInfo, fileSelection), state: { rowSelection: currentPageRowSelection }, diff --git a/src/sections/dataset/dataset-files/files-table/useFilesTableScrollable.tsx b/src/sections/dataset/dataset-files/files-table/useFilesTableScrollable.tsx index 7eefb8dac..3210028f1 100644 --- a/src/sections/dataset/dataset-files/files-table/useFilesTableScrollable.tsx +++ b/src/sections/dataset/dataset-files/files-table/useFilesTableScrollable.tsx @@ -4,8 +4,6 @@ import { FilePreview } from '../../../../files/domain/models/FilePreview' import { getCoreRowModel, Row, useReactTable } from '@tanstack/react-table' import { createColumnsDefinition } from './FilesTableColumnsDefinition' import { FilePaginationInfo } from '../../../../files/domain/models/FilePaginationInfo' -import { FileRepository } from '@/files/domain/repositories/FileRepository' -import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' export type RowSelection = { [key: string]: boolean @@ -18,9 +16,7 @@ export type FileSelection = { export function useFilesTableScrollable( files: FilePreview[], paginationInfo: FilePaginationInfo, - accumulatedFilesCount: number, - fileRepository: FileRepository, - datasetRepository: DatasetRepository + accumulatedFilesCount: number ) { const [rowSelection, setRowSelection] = useState({}) const [selectedRowsModels, setSelectedRowsModels] = useState>>({}) @@ -42,13 +38,7 @@ export function useFilesTableScrollable( const table = useReactTable({ data: files, - columns: createColumnsDefinition( - paginationInfo, - fileSelection, - fileRepository, - datasetRepository, - accumulatedFilesCount - ), + columns: createColumnsDefinition(paginationInfo, fileSelection, accumulatedFilesCount), state: { rowSelection: rowSelection }, diff --git a/src/sections/dataset/dataset-guestbook/DatasetGuestbook.tsx b/src/sections/dataset/dataset-guestbook/DatasetGuestbook.tsx index 338d37c18..1b4da518a 100644 --- a/src/sections/dataset/dataset-guestbook/DatasetGuestbook.tsx +++ b/src/sections/dataset/dataset-guestbook/DatasetGuestbook.tsx @@ -4,13 +4,13 @@ import { Button, Col, QuestionMarkTooltip, Row, Spinner } from '@iqss/dataverse- import { useGetGuestbookById } from './useGetGuestbookById' import { PreviewGuestbookModal } from '@/sections/guestbooks/preview-modal/PreviewGuestbookModal' import { useDataset } from '@/sections/dataset/DatasetContext' -import { useGuestbookRepository } from '@/sections/guestbooks/GuestbookRepositoryContext' +import { useGuestbookRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import styles from '@/sections/dataset/dataset-terms/DatasetTerms.module.scss' export const DatasetGuestbook = () => { const { t } = useTranslation('dataset') const { dataset } = useDataset() - const guestbookRepository = useGuestbookRepository() + const { guestbookRepository } = useGuestbookRepositories() const [showPreview, setShowPreview] = useState(false) const { guestbook, isLoadingGuestbook } = useGetGuestbookById({ guestbookRepository, diff --git a/src/sections/dataset/dataset-terms/DatasetTerms.tsx b/src/sections/dataset/dataset-terms/DatasetTerms.tsx index f5d823130..bbb957d5d 100644 --- a/src/sections/dataset/dataset-terms/DatasetTerms.tsx +++ b/src/sections/dataset/dataset-terms/DatasetTerms.tsx @@ -7,7 +7,6 @@ import { import { EditDatasetTermsButton } from '@/sections/dataset/dataset-terms/EditDatasetTermsButton' import { useTranslation } from 'react-i18next' import { useGetFilesCountInfo } from '@/sections/dataset/dataset-files/useGetFilesCountInfo' -import { FileRepository } from '@/files/domain/repositories/FileRepository' import { FileAccessCount } from '@/files/domain/models/FilesCountInfo' import { FileAccessOption } from '@/files/domain/models/FileCriteria' import { SpinnerSymbol } from '@/sections/dataset/dataset-files/files-table/spinner-symbol/SpinnerSymbol' @@ -16,11 +15,11 @@ import { TermsOfAccess } from '@/sections/dataset/dataset-terms/TermsOfAccess' import { License } from '@/sections/dataset/dataset-terms/License' import { DatasetGuestbook } from '@/sections/dataset/dataset-guestbook/DatasetGuestbook' import { useSearchParams } from 'react-router-dom' +import { useDatasetRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' interface DatasetTermsProps { license: DatasetLicense | undefined termsOfUse: DatasetTermsOfUse - filesRepository: FileRepository datasetPersistentId: string datasetVersion: DatasetVersion canUpdateDataset?: boolean @@ -29,15 +28,15 @@ interface DatasetTermsProps { export function DatasetTerms({ license, termsOfUse, - filesRepository, datasetPersistentId, datasetVersion, canUpdateDataset }: DatasetTermsProps) { + const { fileRepository } = useDatasetRepositories() const { t } = useTranslation('dataset') const [searchParams] = useSearchParams() const { filesCountInfo, isLoading } = useGetFilesCountInfo({ - filesRepository, + filesRepository: fileRepository, datasetPersistentId, datasetVersion, includeDeaccessioned: canUpdateDataset diff --git a/src/sections/edit-dataset-terms/EditDatasetTerms.tsx b/src/sections/edit-dataset-terms/EditDatasetTerms.tsx index 55c39a851..65597bbbf 100644 --- a/src/sections/edit-dataset-terms/EditDatasetTerms.tsx +++ b/src/sections/edit-dataset-terms/EditDatasetTerms.tsx @@ -7,7 +7,6 @@ import { EditLicenseAndTerms } from './edit-license-and-terms/EditLicenseAndTerm import { EditTermsOfAccess } from './edit-terms-of-access/EditTermsOfAccess' import { LicenseRepository } from '../../licenses/domain/repositories/LicenseRepository' import { EditGuestbook } from './edit-guestbook/EditGuestbook' -import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' import { useDataset } from '../dataset/DatasetContext' import { BreadcrumbsGenerator } from '../shared/hierarchy/BreadcrumbsGenerator' import { NotFoundPage } from '../not-found-page/NotFoundPage' @@ -21,13 +20,11 @@ const tabsKeys = EditDatasetTermsHelper.EDIT_DATASET_TERMS_TABS_KEYS interface EditDatasetTermsProps { defaultActiveTabKey: EditDatasetTermsTabKey licenseRepository: LicenseRepository - guestbookRepository: GuestbookRepository } export const EditDatasetTerms = ({ defaultActiveTabKey, - licenseRepository, - guestbookRepository + licenseRepository }: EditDatasetTermsProps) => { const { t } = useTranslation('dataset') const [activeKey, setActiveKey] = useState(defaultActiveTabKey) @@ -131,10 +128,7 @@ export const EditDatasetTerms = ({ {t('editTerms.tabs.guestbook')}
- +
@@ -160,10 +154,7 @@ export const EditDatasetTerms = ({
- +
diff --git a/src/sections/edit-dataset-terms/EditDatasetTermsFactory.tsx b/src/sections/edit-dataset-terms/EditDatasetTermsFactory.tsx index 4ce635b97..8b7197ce6 100644 --- a/src/sections/edit-dataset-terms/EditDatasetTermsFactory.tsx +++ b/src/sections/edit-dataset-terms/EditDatasetTermsFactory.tsx @@ -6,11 +6,9 @@ import { DatasetJSDataverseRepository } from '@/dataset/infrastructure/repositor import { DatasetProvider } from '../dataset/DatasetProvider' import { ReactElement } from 'react' import { DatasetNonNumericVersion } from '@/dataset/domain/models/Dataset' -import { GuestbookJSDataverseRepository } from '@/guestbooks/infrastructure/repositories/GuestbookJSDataverseRepository' const licenseRepository = new LicenseJSDataverseRepository() const datasetRepository = new DatasetJSDataverseRepository() -const guestbookRepository = new GuestbookJSDataverseRepository() export class EditDatasetTermsFactory { static create(): ReactElement { @@ -32,7 +30,6 @@ function EditDatasetTermsWithSearchParams() { ) diff --git a/src/sections/edit-dataset-terms/edit-guestbook/EditGuestbook.tsx b/src/sections/edit-dataset-terms/edit-guestbook/EditGuestbook.tsx index d91e7185b..8f87175c5 100644 --- a/src/sections/edit-dataset-terms/edit-guestbook/EditGuestbook.tsx +++ b/src/sections/edit-dataset-terms/edit-guestbook/EditGuestbook.tsx @@ -4,7 +4,6 @@ import { Trans, useTranslation } from 'react-i18next' import { useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' import { Guestbook } from '@/guestbooks/domain/models/Guestbook' -import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' import { DatasetNonNumericVersionSearchParam, DatasetPublishingStatus @@ -15,19 +14,16 @@ import { useAssignDatasetGuestbook } from './useAssignDatasetGuestbook' import { useRemoveDatasetGuestbook } from './useRemoveDatasetGuestbook' import { useDataset } from '../../dataset/DatasetContext' import { PreviewGuestbookModal } from '@/sections/guestbooks/preview-modal/PreviewGuestbookModal' +import { useGuestbookRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import styles from './EditGuestbook.module.scss' interface EditGuestbookProps { - guestbookRepository: GuestbookRepository onPreview?: () => void onFormStateChange?: (isDirty: boolean) => void } -export function EditGuestbook({ - guestbookRepository, - onPreview, - onFormStateChange -}: EditGuestbookProps) { +export function EditGuestbook({ onPreview, onFormStateChange }: EditGuestbookProps) { + const { guestbookRepository } = useGuestbookRepositories() const { t } = useTranslation('dataset') const { t: tShared } = useTranslation('shared') const [selectedGuestbookId, setSelectedGuestbookId] = useState(undefined) diff --git a/src/sections/file/File.tsx b/src/sections/file/File.tsx index a19dfcc80..74d8b954b 100644 --- a/src/sections/file/File.tsx +++ b/src/sections/file/File.tsx @@ -48,7 +48,7 @@ export function File({ const { setIsLoading } = useLoading() const { t } = useTranslation('file') const { file, isLoading } = useFile(repository, id, datasetVersionNumber) - const { externalTools, externalToolsRepository } = useExternalTools() + const { externalTools } = useExternalTools() const [activeTab, setActiveTab] = useState( toolTypeSelectedQueryParam && file?.permissions.canDownloadFile ? FilePageHelper.EXT_TOOL_TAB_KEY @@ -198,7 +198,6 @@ export function File({ applicableTools={fileApplicablePreviewOrQueryTools} toolTypeSelectedQueryParam={toolTypeSelectedQueryParam} isInView={activeTab === FilePageHelper.EXT_TOOL_TAB_KEY} - externalToolsRepository={externalToolsRepository} /> diff --git a/src/sections/file/FileFactory.tsx b/src/sections/file/FileFactory.tsx index ff960825c..f144fca2a 100644 --- a/src/sections/file/FileFactory.tsx +++ b/src/sections/file/FileFactory.tsx @@ -9,23 +9,18 @@ import { DataverseInfoJSDataverseRepository } from '@/info/infrastructure/reposi import { ContactJSDataverseRepository } from '@/contact/infrastructure/ContactJSDataverseRepository' import { AccessJSDataverseRepository } from '@/access/infrastructure/repositories/AccessJSDataverseRepository' import { AccessRepositoryProvider } from '../access/AccessRepositoryProvider' -import { GuestbookJSDataverseRepository } from '@/guestbooks/infrastructure/repositories/GuestbookJSDataverseRepository' -import { GuestbookRepositoryProvider } from '../guestbooks/GuestbookRepositoryProvider' const repository = new FileJSDataverseRepository() const dataverseInfoRepository = new DataverseInfoJSDataverseRepository() const contactRepository = new ContactJSDataverseRepository() const accessRepository = new AccessJSDataverseRepository() -const guestbookRepository = new GuestbookJSDataverseRepository() export class FileFactory { static create(): ReactElement { return ( - - - - - + + + ) } } diff --git a/src/sections/file/file-action-buttons/access-file-menu/FileToolOptions.tsx b/src/sections/file/file-action-buttons/access-file-menu/FileToolOptions.tsx index 1b3adf353..875021727 100644 --- a/src/sections/file/file-action-buttons/access-file-menu/FileToolOptions.tsx +++ b/src/sections/file/file-action-buttons/access-file-menu/FileToolOptions.tsx @@ -9,9 +9,9 @@ import { import { DropdownButtonItem, DropdownHeader } from '@iqss/dataverse-design-system' import { useExternalTools } from '@/shared/contexts/external-tools/ExternalToolsProvider' import { getFileExternalToolResolved } from '@/externalTools/domain/useCases/GetFileExternalToolResolved' -import { ExternalToolsRepository } from '@/externalTools/domain/repositories/ExternalToolsRepository' import { FilePageHelper } from '../../FilePageHelper' import { ExternalTool } from '@/externalTools/domain/models/ExternalTool' +import { useExternalToolsRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' type ToolKind = 'explore' | 'query' | 'configure' @@ -23,8 +23,7 @@ interface FileToolOptionsProps { const FileToolOptions = ({ fileId, fileType, kind }: FileToolOptionsProps) => { const { t } = useTranslation('shared') - const { fileExploreTools, fileQueryTools, fileConfigureTools, externalToolsRepository } = - useExternalTools() + const { fileExploreTools, fileQueryTools, fileConfigureTools } = useExternalTools() /** Per-kind config (single source of truth) */ const configByKind: Record< @@ -61,7 +60,6 @@ const FileToolOptions = ({ fileId, fileType, kind }: FileToolOptionsProps) => { toolId={tool.id} toolDisplayName={tool.displayName} fileId={fileId} - externalToolsRepository={externalToolsRepository} /> ))} @@ -72,15 +70,10 @@ interface ToolOptionProps { toolId: number toolDisplayName: string fileId: number - externalToolsRepository: ExternalToolsRepository } -const ToolOption = ({ - toolId, - toolDisplayName, - fileId, - externalToolsRepository -}: ToolOptionProps) => { +const ToolOption = ({ toolId, toolDisplayName, fileId }: ToolOptionProps) => { + const { externalToolsRepository } = useExternalToolsRepositories() const [isOpening, setIsOpening] = useState(false) const { t, i18n } = useTranslation('shared') const openingRef = useRef(false) diff --git a/src/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.tsx b/src/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.tsx index c9c384660..ddaced12f 100644 --- a/src/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.tsx +++ b/src/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.tsx @@ -5,12 +5,12 @@ import { WriteError } from '@iqss/dataverse-client-javascript' import { Alert, DropdownButton, DropdownButtonItem, Spinner } from '@iqss/dataverse-design-system' import { BoxArrowUpRight } from 'react-bootstrap-icons' import { ExternalTool } from '@/externalTools/domain/models/ExternalTool' -import { ExternalToolsRepository } from '@/externalTools/domain/repositories/ExternalToolsRepository' import { FileExternalToolResolved } from '@/externalTools/domain/models/FileExternalToolResolved' import { getFileExternalToolResolved } from '@/externalTools/domain/useCases/GetFileExternalToolResolved' import { JSDataverseWriteErrorHandler } from '@/shared/helpers/JSDataverseWriteErrorHandler' import { File } from '@/files/domain/models/File' import { FilePageHelper } from '../FilePageHelper' +import { useExternalToolsRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import styles from './FileEmbeddedExternalTool.module.scss' interface FileEmbeddedExternalToolProps { @@ -18,16 +18,15 @@ interface FileEmbeddedExternalToolProps { isInView: boolean applicableTools: ExternalTool[] toolTypeSelectedQueryParam: string | undefined - externalToolsRepository: ExternalToolsRepository } export const FileEmbeddedExternalTool = ({ file, isInView, applicableTools, - toolTypeSelectedQueryParam, - externalToolsRepository + toolTypeSelectedQueryParam }: FileEmbeddedExternalToolProps) => { + const { externalToolsRepository } = useExternalToolsRepositories() const { t, i18n } = useTranslation('file', { keyPrefix: 'previewTab' }) const [toolIdSelected, setToolIdSelected] = useState( FilePageHelper.getDefaultSelectedToolId(toolTypeSelectedQueryParam, applicableTools) diff --git a/src/sections/guestbooks/GuestbookRepositoryContext.ts b/src/sections/guestbooks/GuestbookRepositoryContext.ts deleted file mode 100644 index 09fae761f..000000000 --- a/src/sections/guestbooks/GuestbookRepositoryContext.ts +++ /dev/null @@ -1,9 +0,0 @@ -import { createContext, useContext } from 'react' -import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' -import { GuestbookJSDataverseRepository } from '@/guestbooks/infrastructure/repositories/GuestbookJSDataverseRepository' - -const guestbookRepository = new GuestbookJSDataverseRepository() - -export const GuestbookRepositoryContext = createContext(guestbookRepository) - -export const useGuestbookRepository = () => useContext(GuestbookRepositoryContext) diff --git a/src/sections/guestbooks/GuestbookRepositoryProvider.tsx b/src/sections/guestbooks/GuestbookRepositoryProvider.tsx deleted file mode 100644 index f4b026d5f..000000000 --- a/src/sections/guestbooks/GuestbookRepositoryProvider.tsx +++ /dev/null @@ -1,18 +0,0 @@ -import { PropsWithChildren } from 'react' -import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' -import { GuestbookRepositoryContext } from './GuestbookRepositoryContext' - -interface GuestbookRepositoryProviderProps { - repository: GuestbookRepository -} - -export function GuestbookRepositoryProvider({ - repository, - children -}: PropsWithChildren) { - return ( - - {children} - - ) -} diff --git a/src/sections/session/SessionProvider.tsx b/src/sections/session/SessionProvider.tsx index 8e14aef36..b1a776a9f 100644 --- a/src/sections/session/SessionProvider.tsx +++ b/src/sections/session/SessionProvider.tsx @@ -5,18 +5,15 @@ import { ReadError } from '@iqss/dataverse-client-javascript' import { User } from '../../users/domain/models/User' import { SessionContext, SessionError } from './SessionContext' import { getUser } from '../../users/domain/useCases/getUser' -import { UserRepository } from '../../users/domain/repositories/UserRepository' import { JSDataverseReadErrorHandler } from '@/shared/helpers/JSDataverseReadErrorHandler' import { QueryParamKey, Route } from '../Route.enum' +import { useUserRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' export const BEARER_TOKEN_IS_VALID_BUT_NOT_LINKED_MESSAGE = 'Bearer token is validated, but there is no linked user account.' -interface SessionProviderProps { - repository: UserRepository -} - -export function SessionProvider({ repository }: SessionProviderProps) { +export function SessionProvider() { + const { userRepository } = useUserRepositories() const navigate = useNavigate() const { token, loginInProgress } = useContext(AuthContext) const [user, setUser] = useState(null) @@ -63,14 +60,14 @@ export function SessionProvider({ repository }: SessionProviderProps) { setIsLoadingUser(true) try { - const user = await getUser(repository) + const user = await getUser(userRepository) setUser(user) } catch (err) { handleFetchError(err) } finally { setIsLoadingUser(false) } - }, [repository, handleFetchError]) + }, [userRepository, handleFetchError]) const refetchUserSession = async () => { await fetchUser() diff --git a/src/sections/shared/pagination/PaginationControls.tsx b/src/sections/shared/pagination/PaginationControls.tsx index 52a79e564..26ec6e83f 100644 --- a/src/sections/shared/pagination/PaginationControls.tsx +++ b/src/sections/shared/pagination/PaginationControls.tsx @@ -18,34 +18,30 @@ export function PaginationControls>({ }: PaginationProps) { const [paginationInfo, setPaginationInfo] = useState(initialPaginationInfo) const goToPage = (newPage: number) => { - setPaginationInfo(paginationInfo.goToPage(newPage)) + const updatedPaginationInfo = paginationInfo.goToPage(newPage) + setPaginationInfo(updatedPaginationInfo) + onPaginationInfoChange(updatedPaginationInfo) } const goToPreviousPage = () => { - setPaginationInfo(paginationInfo.goToPreviousPage()) + const updatedPaginationInfo = paginationInfo.goToPreviousPage() + setPaginationInfo(updatedPaginationInfo) + onPaginationInfoChange(updatedPaginationInfo) } const goToNextPage = () => { - setPaginationInfo(paginationInfo.goToNextPage()) + const updatedPaginationInfo = paginationInfo.goToNextPage() + setPaginationInfo(updatedPaginationInfo) + onPaginationInfoChange(updatedPaginationInfo) } const setPageSize = (newPageSize: number) => { - setPaginationInfo(paginationInfo.withPageSize(newPageSize)) + const updatedPaginationInfo = paginationInfo.withPageSize(newPageSize) + setPaginationInfo(updatedPaginationInfo) + onPaginationInfoChange(updatedPaginationInfo) } useEffect(() => { - onPaginationInfoChange(paginationInfo) - // TODO: Not a priority as not used for inifinite scroll is used but the eslint disable should be removed and the dependency should be added - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [paginationInfo.pageSize]) - - useEffect(() => { - onPaginationInfoChange(paginationInfo) - // TODO: Not a priority as not used for inifinite scroll is used but the eslint disable should be removed and the dependency should be added - // eslint-disable-next-line react-hooks/exhaustive-deps - }, [paginationInfo.page]) - - useEffect(() => { - setPaginationInfo(paginationInfo.withTotal(initialPaginationInfo.totalItems)) - // TODO: Not a priority as not used for inifinite scroll is used but the eslint disable should be removed and the dependency should be added - // eslint-disable-next-line react-hooks/exhaustive-deps + setPaginationInfo((currentPaginationInfo) => + currentPaginationInfo.withTotal(initialPaginationInfo.totalItems) + ) }, [initialPaginationInfo.totalItems]) if (paginationInfo.totalPages < MINIMUM_NUMBER_OF_PAGES_TO_DISPLAY_PAGINATION) { diff --git a/src/sections/sign-up/SignUp.tsx b/src/sections/sign-up/SignUp.tsx index 4d7e60f46..7ad02a282 100644 --- a/src/sections/sign-up/SignUp.tsx +++ b/src/sections/sign-up/SignUp.tsx @@ -1,20 +1,17 @@ import { useEffect } from 'react' import { useTranslation } from 'react-i18next' import { Alert, Tabs } from '@iqss/dataverse-design-system' -import { UserRepository } from '@/users/domain/repositories/UserRepository' import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { useLoading } from '../../shared/contexts/loading/LoadingContext' import { ValidTokenNotLinkedAccountForm } from './valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm' import styles from './SignUp.module.scss' interface SignUpProps { - userRepository: UserRepository dataverseInfoRepository: DataverseInfoRepository hasValidTokenButNotLinkedAccount: boolean } export const SignUp = ({ - userRepository, dataverseInfoRepository, hasValidTokenButNotLinkedAccount }: SignUpProps) => { @@ -64,10 +61,7 @@ export const SignUp = ({
{hasValidTokenButNotLinkedAccount && ( - + )}
diff --git a/src/sections/sign-up/SignUpFactory.tsx b/src/sections/sign-up/SignUpFactory.tsx index 9fa9879c3..3444d7fba 100644 --- a/src/sections/sign-up/SignUpFactory.tsx +++ b/src/sections/sign-up/SignUpFactory.tsx @@ -2,10 +2,8 @@ import { ReactElement } from 'react' import { useSearchParams } from 'react-router-dom' import { SignUp } from './SignUp' import { QueryParamKey } from '../Route.enum' -import { UserJSDataverseRepository } from '@/users/infrastructure/repositories/UserJSDataverseRepository' import { DataverseInfoJSDataverseRepository } from '@/info/infrastructure/repositories/DataverseInfoJSDataverseRepository' -const userRepository = new UserJSDataverseRepository() const dataverseInfoRepository = new DataverseInfoJSDataverseRepository() export class SignUpFactory { @@ -22,7 +20,6 @@ function SignUpWithSearchParams() { return ( diff --git a/src/sections/sign-up/valid-token-not-linked-account-form/FormFields.tsx b/src/sections/sign-up/valid-token-not-linked-account-form/FormFields.tsx index 84a3b22f7..53a00bf88 100644 --- a/src/sections/sign-up/valid-token-not-linked-account-form/FormFields.tsx +++ b/src/sections/sign-up/valid-token-not-linked-account-form/FormFields.tsx @@ -3,20 +3,20 @@ import { AuthContext } from 'react-oauth2-code-pkce' import { Controller, FormProvider, useForm } from 'react-hook-form' import { useTranslation } from 'react-i18next' import { Alert, Button, Col, Form, Stack } from '@iqss/dataverse-design-system' -import { UserRepository } from '@/users/domain/repositories/UserRepository' import { Validator } from '@/shared/helpers/Validator' import { type ValidTokenNotLinkedAccountFormData } from './types' import { TermsOfUse } from '@/info/domain/models/TermsOfUse' import { SubmissionStatus, useSubmitUser } from './useSubmitUser' +import { useUserRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' import styles from './FormFields.module.scss' interface FormFieldsProps { - userRepository: UserRepository formDefaultValues: ValidTokenNotLinkedAccountFormData termsOfUse: TermsOfUse } -export const FormFields = ({ userRepository, formDefaultValues, termsOfUse }: FormFieldsProps) => { +export const FormFields = ({ formDefaultValues, termsOfUse }: FormFieldsProps) => { + const { userRepository } = useUserRepositories() const { tokenData, logOut } = useContext(AuthContext) const { t } = useTranslation('signUp') const { t: tShared } = useTranslation('shared') diff --git a/src/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.tsx b/src/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.tsx index 960047ada..31dc27888 100644 --- a/src/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.tsx +++ b/src/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.tsx @@ -1,7 +1,6 @@ import { useContext } from 'react' import { AuthContext } from 'react-oauth2-code-pkce' import { Alert } from '@iqss/dataverse-design-system' -import { UserRepository } from '@/users/domain/repositories/UserRepository' import { DataverseInfoRepository } from '@/info/domain/repositories/DataverseInfoRepository' import { useGetTermsOfUse } from '@/shared/hooks/useGetTermsOfUse' import { OIDC_STANDARD_CLAIMS, type ValidTokenNotLinkedAccountFormData } from './types' @@ -10,12 +9,10 @@ import { FormFields } from './FormFields' import { FormFieldsSkeleton } from './FormFieldsSkeleton' interface ValidTokenNotLinkedAccountFormProps { - userRepository: UserRepository dataverseInfoRepository: DataverseInfoRepository } export const ValidTokenNotLinkedAccountForm = ({ - userRepository, dataverseInfoRepository }: ValidTokenNotLinkedAccountFormProps) => { const { tokenData } = useContext(AuthContext) @@ -72,11 +69,5 @@ export const ValidTokenNotLinkedAccountForm = ({ return {errorTermsOfUse} } - return ( - - ) + return } diff --git a/src/shared/contexts/external-tools/ExternalToolsProvider.tsx b/src/shared/contexts/external-tools/ExternalToolsProvider.tsx index 88ce8ccda..e3337a120 100644 --- a/src/shared/contexts/external-tools/ExternalToolsProvider.tsx +++ b/src/shared/contexts/external-tools/ExternalToolsProvider.tsx @@ -1,9 +1,9 @@ import React, { createContext, useCallback, useContext, useEffect, useMemo, useState } from 'react' import { ExternalTool, ToolScope, ToolType } from '@/externalTools/domain/models/ExternalTool' -import { ExternalToolsRepository } from '@/externalTools/domain/repositories/ExternalToolsRepository' import { getExternalTools } from '@/externalTools/domain/useCases/GetExternalTools' import { ReadError } from '@iqss/dataverse-client-javascript' import { JSDataverseReadErrorHandler } from '@/shared/helpers/JSDataverseReadErrorHandler' +import { useExternalToolsRepositories } from '@/shared/contexts/repositories/RepositoriesProvider' type ExternalToolsContextValue = { externalTools: ExternalTool[] @@ -16,20 +16,16 @@ type ExternalToolsContextValue = { filePreviewTools: ExternalTool[] fileQueryTools: ExternalTool[] fileConfigureTools: ExternalTool[] - externalToolsRepository: ExternalToolsRepository } const ExternalToolsContext = createContext(undefined) type ExternalToolsProviderProps = { - externalToolsRepository: ExternalToolsRepository children: React.ReactNode } -export function ExternalToolsProvider({ - externalToolsRepository, - children -}: ExternalToolsProviderProps) { +export function ExternalToolsProvider({ children }: ExternalToolsProviderProps) { + const { externalToolsRepository } = useExternalToolsRepositories() const [externalTools, setExternalTools] = useState([]) const [loading, setLoading] = useState(true) const [error, setError] = useState(null) @@ -111,8 +107,7 @@ export function ExternalToolsProvider({ filePreviewTools, fileQueryTools, fileConfigureTools, - refreshExternalTools: fetchExternalTools, - externalToolsRepository + refreshExternalTools: fetchExternalTools }), [ externalTools, @@ -124,8 +119,7 @@ export function ExternalToolsProvider({ filePreviewTools, fileQueryTools, fileConfigureTools, - fetchExternalTools, - externalToolsRepository + fetchExternalTools ] ) diff --git a/src/shared/contexts/repositories/RepositoriesProvider.tsx b/src/shared/contexts/repositories/RepositoriesProvider.tsx index 0141e274f..6b827e426 100644 --- a/src/shared/contexts/repositories/RepositoriesProvider.tsx +++ b/src/shared/contexts/repositories/RepositoriesProvider.tsx @@ -1,10 +1,18 @@ import React, { createContext, useContext, useMemo } from 'react' import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' +import { ExternalToolsRepository } from '@/externalTools/domain/repositories/ExternalToolsRepository' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' +import { UserRepository } from '@/users/domain/repositories/UserRepository' export interface RepositoriesContextValue { collectionRepository: CollectionRepository datasetRepository: DatasetRepository + externalToolsRepository: ExternalToolsRepository + fileRepository: FileRepository + guestbookRepository: GuestbookRepository + userRepository: UserRepository } const RepositoriesContext = createContext(undefined) @@ -16,14 +24,29 @@ interface RepositoriesProviderProps extends RepositoriesContextValue { export function RepositoriesProvider({ children, collectionRepository, - datasetRepository + datasetRepository, + externalToolsRepository, + fileRepository, + guestbookRepository, + userRepository }: RepositoriesProviderProps) { const value = useMemo( () => ({ collectionRepository, - datasetRepository + datasetRepository, + externalToolsRepository, + fileRepository, + guestbookRepository, + userRepository }), - [collectionRepository, datasetRepository] + [ + collectionRepository, + datasetRepository, + externalToolsRepository, + fileRepository, + guestbookRepository, + userRepository + ] ) return {children} @@ -46,7 +69,31 @@ export function useCollectionRepositories() { } export function useDatasetRepositories() { - const { datasetRepository } = useRepositories() + const { datasetRepository, fileRepository } = useRepositories() + + return { datasetRepository, fileRepository } +} + +export function useExternalToolsRepositories() { + const { externalToolsRepository } = useRepositories() + + return { externalToolsRepository } +} + +export function useFileRepositories() { + const { fileRepository } = useRepositories() + + return { fileRepository } +} + +export function useUserRepositories() { + const { userRepository } = useRepositories() + + return { userRepository } +} + +export function useGuestbookRepositories() { + const { guestbookRepository } = useRepositories() - return { datasetRepository } + return { guestbookRepository } } diff --git a/src/stories/WithRepositories.tsx b/src/stories/WithRepositories.tsx index a12ba61fa..bb08ac7a5 100644 --- a/src/stories/WithRepositories.tsx +++ b/src/stories/WithRepositories.tsx @@ -2,6 +2,10 @@ import { StoryFn } from '@storybook/react' import { ReactNode } from 'react' import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' +import { ExternalToolsRepository } from '@/externalTools/domain/repositories/ExternalToolsRepository' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' +import { UserRepository } from '@/users/domain/repositories/UserRepository' import { RepositoriesProvider } from '@/shared/contexts/repositories/RepositoriesProvider' function failFastRepository(name: string): T { @@ -21,17 +25,29 @@ function failFastRepository(name: string): T { interface WithRepositoriesProps { collectionRepository?: CollectionRepository datasetRepository?: DatasetRepository + externalToolsRepository?: ExternalToolsRepository + fileRepository?: FileRepository + guestbookRepository?: GuestbookRepository + userRepository?: UserRepository } export function WithRepositories({ collectionRepository = failFastRepository('CollectionRepository'), - datasetRepository = failFastRepository('DatasetRepository') + datasetRepository = failFastRepository('DatasetRepository'), + externalToolsRepository = failFastRepository('ExternalToolsRepository'), + fileRepository = failFastRepository('FileRepository'), + guestbookRepository = failFastRepository('GuestbookRepository'), + userRepository = failFastRepository('UserRepository') }: WithRepositoriesProps) { function WithRepositoriesDecorator(Story: StoryFn) { return ( + datasetRepository={datasetRepository} + externalToolsRepository={externalToolsRepository} + fileRepository={fileRepository} + guestbookRepository={guestbookRepository} + userRepository={userRepository}> ) @@ -49,12 +65,20 @@ interface RepositoriesStoryProviderProps extends WithRepositoriesProps { export function RepositoriesStoryProvider({ children, collectionRepository = failFastRepository('CollectionRepository'), - datasetRepository = failFastRepository('DatasetRepository') + datasetRepository = failFastRepository('DatasetRepository'), + externalToolsRepository = failFastRepository('ExternalToolsRepository'), + fileRepository = failFastRepository('FileRepository'), + guestbookRepository = failFastRepository('GuestbookRepository'), + userRepository = failFastRepository('UserRepository') }: RepositoriesStoryProviderProps) { return ( + datasetRepository={datasetRepository} + externalToolsRepository={externalToolsRepository} + fileRepository={fileRepository} + guestbookRepository={guestbookRepository} + userRepository={userRepository}> {children} ) diff --git a/src/stories/account/Account.stories.tsx b/src/stories/account/Account.stories.tsx index 566a0c416..0cfb3c4a0 100644 --- a/src/stories/account/Account.stories.tsx +++ b/src/stories/account/Account.stories.tsx @@ -25,10 +25,11 @@ type Story = StoryObj export const Default: Story = { render: () => ( - + diff --git a/src/stories/account/account-info-section/AccountInfoSection.stories.tsx b/src/stories/account/account-info-section/AccountInfoSection.stories.tsx index 3e3499c2f..79d071ce4 100644 --- a/src/stories/account/account-info-section/AccountInfoSection.stories.tsx +++ b/src/stories/account/account-info-section/AccountInfoSection.stories.tsx @@ -25,10 +25,11 @@ type Story = StoryObj export const Default: Story = { render: () => ( - + diff --git a/src/stories/account/api-token-section/ApiTokenSection.stories.tsx b/src/stories/account/api-token-section/ApiTokenSection.stories.tsx index 755710008..764e470d8 100644 --- a/src/stories/account/api-token-section/ApiTokenSection.stories.tsx +++ b/src/stories/account/api-token-section/ApiTokenSection.stories.tsx @@ -27,10 +27,11 @@ type Story = StoryObj export const Default: Story = { render: () => ( - + @@ -40,10 +41,11 @@ export const Default: Story = { export const Loading: Story = { render: () => ( - + @@ -53,10 +55,11 @@ export const Loading: Story = { export const Error: Story = { render: () => ( - + @@ -79,10 +82,11 @@ export const NoToken: Story = { } return ( - + diff --git a/src/stories/account/notification-section/NotificationSection.stories.tsx b/src/stories/account/notification-section/NotificationSection.stories.tsx index b0810be73..eeac2f82f 100644 --- a/src/stories/account/notification-section/NotificationSection.stories.tsx +++ b/src/stories/account/notification-section/NotificationSection.stories.tsx @@ -27,10 +27,11 @@ type Story = StoryObj export const Default: Story = { render: () => ( - + @@ -39,10 +40,11 @@ export const Default: Story = { } export const Error: Story = { render: () => ( - + diff --git a/src/stories/collection/collection-items-panel/CollectionCard.stories.tsx b/src/stories/collection/collection-items-panel/CollectionCard.stories.tsx index b39a6c1ab..fb0def6ee 100644 --- a/src/stories/collection/collection-items-panel/CollectionCard.stories.tsx +++ b/src/stories/collection/collection-items-panel/CollectionCard.stories.tsx @@ -2,7 +2,27 @@ import { Meta, StoryObj } from '@storybook/react' import { WithI18next } from '../../WithI18next' import { CollectionCard } from '@/sections/collection/collection-items-panel/items-list/collection-card/CollectionCard' import { CollectionItemTypePreviewMother } from '../../../../tests/component/collection/domain/models/CollectionItemTypePreviewMother' -import { FakerHelper } from '../../../../tests/component/shared/FakerHelper' + +const collectionPreview = CollectionItemTypePreviewMother.createRealistic() +const longDescriptionCollectionPreview = CollectionItemTypePreviewMother.create({ + ...collectionPreview, + description: 'Scientific research collection with a detailed public description. ' + .repeat(20) + .trim() +}) +const unpublishedCollectionPreview = CollectionItemTypePreviewMother.create({ + ...collectionPreview, + isReleased: false +}) +const thumbnailCollectionPreview = CollectionItemTypePreviewMother.create({ + ...collectionPreview, + thumbnail: + 'data:image/svg+xml,%3Csvg xmlns=%22http://www.w3.org/2000/svg%22 width=%2264%22 height=%2248%22 viewBox=%220 0 64 48%22%3E%3Crect width=%2264%22 height=%2248%22 fill=%22%23f1f5f9%22/%3E%3Cpath d=%22M10 34l12-12 9 9 8-8 15 15H10z%22 fill=%22%235b728a%22/%3E%3Ccircle cx=%2246%22 cy=%2214%22 r=%226%22 fill=%22%23f9c74f%22/%3E%3C/svg%3E' +}) +const linkedCollectionPreview = CollectionItemTypePreviewMother.create({ + ...collectionPreview, + isLinked: true +}) const meta: Meta = { title: 'Sections/Collection Page/CollectionCard', @@ -15,30 +35,24 @@ type Story = StoryObj export const Default: Story = { render: () => ( - + ) } export const WithLongDescription: Story = { - render: () => { - const collectionPreview = CollectionItemTypePreviewMother.create({ - name: 'Scientific Research Collection', - description: FakerHelper.paragraph(20) - }) - return ( - - ) - } + render: () => ( + + ) } export const Unpublished: Story = { render: () => ( ) } @@ -47,7 +61,7 @@ export const WithThumbnail: Story = { render: () => ( ) } @@ -56,7 +70,7 @@ export const Linked: Story = { render: () => ( ) } diff --git a/src/stories/dataset/Dataset.stories.tsx b/src/stories/dataset/Dataset.stories.tsx index 53e2df24f..f04f96635 100644 --- a/src/stories/dataset/Dataset.stories.tsx +++ b/src/stories/dataset/Dataset.stories.tsx @@ -22,7 +22,6 @@ import { CollectionMockRepository } from '@/stories/collection/CollectionMockRep import { ContactMockRepository } from '../shared-mock-repositories/contact/ContactMockRepository' import { DataverseInfoMockRepository } from '../shared-mock-repositories/info/DataverseInfoMockRepository' import { GuestbookMockRepository } from '../shared-mock-repositories/guestbook/GuestbookMockRepository' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' import { DatasetProvider } from '@/sections/dataset/DatasetProvider' import { RepositoriesStoryProvider } from '@/stories/WithRepositories' @@ -46,13 +45,11 @@ const WithDatasetGuestbook = (Story: () => JSX.Element) => { const datasetRepository = new DatasetWithGuestbookMockRepository() return ( - - - - - + + + ) } @@ -63,9 +60,10 @@ export const Default: Story = { render: () => ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()} + guestbookRepository={guestbookRepository}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockNoDataRepository()}> ( + datasetRepository={new DatasetMockRepository()} + fileRepository={new FileMockRepository()}> = { title: 'Sections/Dataset Page/DatasetActionButtons/AccessDatasetMenu', @@ -65,18 +66,20 @@ export const WithTabularFiles: Story = { export const WithExploreOptionsTools: Story = { render: () => ( - - - + + + + + ) } diff --git a/src/stories/dataset/dataset-files/DatasetFiles.stories.tsx b/src/stories/dataset/dataset-files/DatasetFiles.stories.tsx index be915cd6e..0b083b805 100644 --- a/src/stories/dataset/dataset-files/DatasetFiles.stories.tsx +++ b/src/stories/dataset/dataset-files/DatasetFiles.stories.tsx @@ -8,16 +8,12 @@ import { WithSettings } from '../../WithSettings' import { FileMockNoFiltersRepository } from '../../file/FileMockNoFiltersRepository' import { DatasetMother } from '../../../../tests/component/dataset/domain/models/DatasetMother' import { DatasetMockRepository } from '../../dataset/DatasetMockRepository' -import { WithRepositories } from '../../WithRepositories' +import { RepositoriesStoryProvider } from '../../WithRepositories' const meta: Meta = { title: 'Sections/Dataset Page/DatasetFiles', component: DatasetFiles, - decorators: [ - WithI18next, - WithSettings, - WithRepositories({ datasetRepository: new DatasetMockRepository() }) - ] + decorators: [WithI18next, WithSettings] } export default meta @@ -27,40 +23,52 @@ const testDataset = DatasetMother.createRealistic() export const Default: Story = { render: () => ( - + + + ) } export const Loading: Story = { render: () => ( - + + + ) } export const NoFiles: Story = { render: () => ( - + + + ) } export const NoFilters: Story = { render: () => ( - + + + ) } diff --git a/src/stories/dataset/dataset-files/DatasetFilesScrollable.stories.tsx b/src/stories/dataset/dataset-files/DatasetFilesScrollable.stories.tsx index 564277756..cad78c7f8 100644 --- a/src/stories/dataset/dataset-files/DatasetFilesScrollable.stories.tsx +++ b/src/stories/dataset/dataset-files/DatasetFilesScrollable.stories.tsx @@ -8,16 +8,12 @@ import { WithSettings } from '../../WithSettings' import { FileMockNoFiltersRepository } from '../../file/FileMockNoFiltersRepository' import { DatasetMother } from '../../../../tests/component/dataset/domain/models/DatasetMother' import { DatasetMockRepository } from '../../dataset/DatasetMockRepository' -import { WithRepositories } from '../../WithRepositories' +import { RepositoriesStoryProvider } from '../../WithRepositories' const meta: Meta = { title: 'Sections/Dataset Page/DatasetFilesScrollable', component: DatasetFilesScrollable, - decorators: [ - WithI18next, - WithSettings, - WithRepositories({ datasetRepository: new DatasetMockRepository() }) - ], + decorators: [WithI18next, WithSettings], parameters: { // Sets the delay for all stories. chromatic: { delay: 15000, pauseAnimationAtEnd: true } @@ -31,40 +27,52 @@ const testDataset = DatasetMother.createRealistic() export const Default: Story = { render: () => ( - + + + ) } export const Loading: Story = { render: () => ( - + + + ) } export const NoFiles: Story = { render: () => ( - + + + ) } export const NoFilters: Story = { render: () => ( - + + + ) } diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx index 27d8ad7e6..054a7783f 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesMenu.stories.tsx @@ -17,7 +17,10 @@ const meta: Meta = { WithSettings, WithLoggedInUser, WithDatasetAllPermissionsGranted, - WithRepositories({ datasetRepository: new DatasetMockRepository() }) + WithRepositories({ + datasetRepository: new DatasetMockRepository(), + fileRepository: new FileMockRepository() + }) ] } @@ -25,11 +28,5 @@ export default meta type Story = StoryObj export const Default: Story = { - render: () => ( - - ) + render: () => } diff --git a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx index 723ccef8b..7fcd85395 100644 --- a/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx +++ b/src/stories/dataset/dataset-files/files-table/file-actions/file-action-buttons/file-options-menu/FileOptionsMenu.stories.tsx @@ -12,7 +12,7 @@ import { ExternalToolsProvider } from '@/shared/contexts/external-tools/External import { ExternalToolsMockRepository } from '@/stories/shared-mock-repositories/externalTools/ExternalToolsMockRepository' import { FakerHelper } from '@tests/component/shared/FakerHelper' import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' -import { WithRepositories } from '@/stories/WithRepositories' +import { RepositoriesStoryProvider, WithRepositories } from '@/stories/WithRepositories' const meta: Meta = { title: @@ -22,7 +22,10 @@ const meta: Meta = { WithI18next, WithSettings, WithLoggedInUser, - WithRepositories({ datasetRepository: new DatasetMockRepository() }) + WithRepositories({ + datasetRepository: new DatasetMockRepository(), + fileRepository: new FileMockRepository() + }) ] } @@ -31,42 +34,22 @@ type Story = StoryObj export const DefaultWithLoggedInUser: Story = { decorators: [WithDatasetAllPermissionsGranted], - render: () => ( - - ) + render: () => } export const Restricted: Story = { decorators: [WithDatasetAllPermissionsGranted], - render: () => ( - - ) + render: () => } export const WithDatasetLocked: Story = { decorators: [WithDatasetLockedFromEdits], - render: () => ( - - ) + render: () => } export const WithFileAlreadyDeleted: Story = { decorators: [WithDatasetAllPermissionsGranted], - render: () => ( - - ) + render: () => } const externalToolsRepositoryWithFileConfigureTool = new ExternalToolsMockRepository() @@ -81,12 +64,12 @@ externalToolsRepositoryWithFileConfigureTool.getExternalTools = () => { export const WithConfigureTool: Story = { decorators: [WithDatasetAllPermissionsGranted], render: () => ( - - - + + + + + ) } diff --git a/src/stories/dataset/dataset-guestbook/DatasetGuestbook.stories.tsx b/src/stories/dataset/dataset-guestbook/DatasetGuestbook.stories.tsx index 560252471..be0f67f8a 100644 --- a/src/stories/dataset/dataset-guestbook/DatasetGuestbook.stories.tsx +++ b/src/stories/dataset/dataset-guestbook/DatasetGuestbook.stories.tsx @@ -3,11 +3,11 @@ import { DatasetGuestbook } from '@/sections/dataset/dataset-guestbook/DatasetGu import { WithI18next } from '@/stories/WithI18next' import { DatasetContext } from '@/sections/dataset/DatasetContext' import { DatasetMother } from '@tests/component/dataset/domain/models/DatasetMother' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' import { GuestbookMockRepository, storybookGuestbook } from '@/stories/shared-mock-repositories/guestbook/GuestbookMockRepository' +import { RepositoriesStoryProvider } from '@/stories/WithRepositories' const meta: Meta = { title: 'Sections/Dataset Page/DatasetTerms/DatasetGuestbook', @@ -22,7 +22,7 @@ const guestbookRepository = new GuestbookMockRepository() const withDatasetContext = (datasetWithGuestbook: boolean) => { const DatasetGuestbookStoryDecorator = (StoryComponent: () => JSX.Element) => ( - + { }}> - + ) DatasetGuestbookStoryDecorator.displayName = `DatasetGuestbookStoryDecorator-${String( diff --git a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx index 8cfa7409f..857ffe4cc 100644 --- a/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx +++ b/src/stories/dataset/dataset-terms/DatasetTerms.stories.tsx @@ -13,7 +13,8 @@ import { storybookGuestbook } from '@/stories/shared-mock-repositories/guestbook/GuestbookMockRepository' import { DatasetContext } from '@/sections/dataset/DatasetContext' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' +import { RepositoriesStoryProvider } from '@/stories/WithRepositories' +import { FileRepository } from '@/files/domain/repositories/FileRepository' const meta: Meta = { title: 'Sections/Dataset Page/DatasetTerms', @@ -35,29 +36,39 @@ const guestbookRepository = new GuestbookMockRepository() const withDatasetContext = (dataset = testDatasetWithGuestbook) => { const DatasetTermsStoryDecorator = (Story: () => JSX.Element) => ( - - {} - }}> - - - + {} + }}> + + ) DatasetTermsStoryDecorator.displayName = 'DatasetTermsStoryDecorator' return DatasetTermsStoryDecorator } +const withFileRepository = (fileRepository: FileRepository) => { + const DatasetTermsFileRepositoryStoryDecorator = (Story: () => JSX.Element) => ( + + + + ) + + DatasetTermsFileRepositoryStoryDecorator.displayName = 'DatasetTermsFileRepositoryStoryDecorator' + return DatasetTermsFileRepositoryStoryDecorator +} + export const Default: Story = { - decorators: [withDatasetContext()], + decorators: [withDatasetContext(), withFileRepository(new FileMockRepository())], render: () => ( @@ -65,11 +76,11 @@ export const Default: Story = { } export const Loading: Story = { + decorators: [withFileRepository(new FileMockLoadingRepository())], render: () => ( @@ -77,12 +88,11 @@ export const Loading: Story = { } export const RestrictedFiles: Story = { - decorators: [withDatasetContext()], + decorators: [withDatasetContext(), withFileRepository(new FileMockRestrictedFilesRepository())], render: () => ( @@ -90,24 +100,22 @@ export const RestrictedFiles: Story = { } export const NoRestrictedFiles: Story = { - decorators: [withDatasetContext()], + decorators: [withDatasetContext(), withFileRepository(new FileMockNoRestrictedFilesRepository())], render: () => ( ) } export const CustomTerms: Story = { - decorators: [withDatasetContext()], + decorators: [withDatasetContext(), withFileRepository(new FileMockNoRestrictedFilesRepository())], render: () => ( @@ -115,12 +123,14 @@ export const CustomTerms: Story = { } export const WithoutAssignedGuestbook: Story = { - decorators: [withDatasetContext(DatasetMother.createRealistic({ guestbookId: undefined }))], + decorators: [ + withDatasetContext(DatasetMother.createRealistic({ guestbookId: undefined })), + withFileRepository(new FileMockNoRestrictedFilesRepository()) + ], render: () => ( @@ -128,12 +138,14 @@ export const WithoutAssignedGuestbook: Story = { } export const GuestbookEmptyState: Story = { - decorators: [withDatasetContext(DatasetMother.createRealistic({ guestbookId: undefined }))], + decorators: [ + withDatasetContext(DatasetMother.createRealistic({ guestbookId: undefined })), + withFileRepository(new FileMockNoRestrictedFilesRepository()) + ], render: () => ( diff --git a/src/stories/edit-dataset-terms/EditDatasetTerms.stories.tsx b/src/stories/edit-dataset-terms/EditDatasetTerms.stories.tsx index 04ae10a96..4382b0468 100644 --- a/src/stories/edit-dataset-terms/EditDatasetTerms.stories.tsx +++ b/src/stories/edit-dataset-terms/EditDatasetTerms.stories.tsx @@ -20,7 +20,12 @@ const guestbookRepository: GuestbookRepository = const meta: Meta = { title: 'Pages/EditDatasetTerms', component: EditDatasetTerms, - decorators: [WithI18next, WithLayout, WithDataset, WithRepositories({ datasetRepository })], + decorators: [ + WithI18next, + WithLayout, + WithDataset, + WithRepositories({ datasetRepository, guestbookRepository }) + ], parameters: { chromatic: { delay: 15000, pauseAnimationAtEnd: true } } @@ -34,7 +39,6 @@ export const EditLicenseAndTermsTab: Story = { ) } @@ -44,7 +48,6 @@ export const EditTermsOfAccessTab: Story = { ) } @@ -54,7 +57,6 @@ export const EditGuestbookTab: Story = { ) } diff --git a/src/stories/file/File.stories.tsx b/src/stories/file/File.stories.tsx index 1d3b0eda0..0ef7514cf 100644 --- a/src/stories/file/File.stories.tsx +++ b/src/stories/file/File.stories.tsx @@ -13,7 +13,7 @@ import { FakerHelper } from '@tests/component/shared/FakerHelper' import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' import { DataverseInfoMockRepository } from '../shared-mock-repositories/info/DataverseInfoMockRepository' import { ContactMockRepository } from '../shared-mock-repositories/contact/ContactMockRepository' -import { WithRepositories } from '../WithRepositories' +import { RepositoriesStoryProvider, WithRepositories } from '../WithRepositories' const meta: Meta = { title: 'Pages/File', @@ -89,15 +89,17 @@ export const FileNotFound: Story = { export const WithMultipleExternalTools: Story = { render: () => ( - - - + + + + + ) } @@ -112,15 +114,17 @@ externalToolsRepositoryOnlyPreviewTool.getExternalTools = () => { export const WithOnlyOnePreviewExternalTool: Story = { render: () => ( - - - + + + + + ) } @@ -135,14 +139,16 @@ externalToolsRepositoryOnlyQueryTool.getExternalTools = () => { export const WithOnlyOneQueryExternalTool: Story = { render: () => ( - - - + + + + + ) } diff --git a/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx b/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx index f55904ea0..da98c451d 100644 --- a/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx +++ b/src/stories/file/file-action-buttons/access-file-menu/AccessFileMenu.stories.tsx @@ -6,6 +6,7 @@ import { FileAccessMother } from '../../../../../tests/component/files/domain/mo import { FileMetadataMother } from '../../../../../tests/component/files/domain/models/FileMetadataMother' import { ExternalToolsProvider } from '@/shared/contexts/external-tools/ExternalToolsProvider' import { ExternalToolsMockRepository } from '@/stories/shared-mock-repositories/externalTools/ExternalToolsMockRepository' +import { RepositoriesStoryProvider } from '@/stories/WithRepositories' const meta: Meta = { title: 'Sections/File Page/Action Buttons/AccessFileMenu', @@ -162,15 +163,17 @@ export const WithEmbargoAndRestrictedWithAccessGranted: Story = { export const WithExploreAndQueryOptionsTools: Story = { render: () => ( - - - + + + + + ) } diff --git a/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx b/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx index cd19ea437..f80878c5d 100644 --- a/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx +++ b/src/stories/file/file-action-buttons/edit-file-dropdown/EditFileDropdown.stories.tsx @@ -9,7 +9,7 @@ import { ExternalToolsProvider } from '@/shared/contexts/external-tools/External import { ExternalToolsMockRepository } from '@/stories/shared-mock-repositories/externalTools/ExternalToolsMockRepository' import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' import { FakerHelper } from '@tests/component/shared/FakerHelper' -import { WithRepositories } from '@/stories/WithRepositories' +import { RepositoriesStoryProvider, WithRepositories } from '@/stories/WithRepositories' const storyFile = FileMother.createRealistic() @@ -56,21 +56,24 @@ externalToolsRepositoryWithFileConfigureTool.getExternalTools = () => { export const WithConfigureToolOption: Story = { render: () => ( - - - + + + + + ) } diff --git a/src/stories/file/file-embedded-external-tool/FileEmbeddedExternalTool.stories.tsx b/src/stories/file/file-embedded-external-tool/FileEmbeddedExternalTool.stories.tsx index dcc339520..47bda11fd 100644 --- a/src/stories/file/file-embedded-external-tool/FileEmbeddedExternalTool.stories.tsx +++ b/src/stories/file/file-embedded-external-tool/FileEmbeddedExternalTool.stories.tsx @@ -4,6 +4,7 @@ import { FileEmbeddedExternalTool } from '@/sections/file/file-embedded-external import { FileMother } from '@tests/component/files/domain/models/FileMother' import { ExternalToolsMockRepository } from '@/stories/shared-mock-repositories/externalTools/ExternalToolsMockRepository' import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' +import { RepositoriesStoryProvider } from '@/stories/WithRepositories' const meta: Meta = { title: 'Sections/File Page/File External Tools Tab', @@ -19,27 +20,29 @@ const externalToolsRepository = new ExternalToolsMockRepository() export const WithOneToolOnly: Story = { render: () => ( - + + + ) } export const WithMoreThanOneTool: Story = { render: () => ( - + + + ) } diff --git a/src/stories/guestbooks/guestbook-applied-modal/DownloadWithTermsAndGuestbookModal.stories.tsx b/src/stories/guestbooks/guestbook-applied-modal/DownloadWithTermsAndGuestbookModal.stories.tsx index 1d1dfb810..c7bbf54cb 100644 --- a/src/stories/guestbooks/guestbook-applied-modal/DownloadWithTermsAndGuestbookModal.stories.tsx +++ b/src/stories/guestbooks/guestbook-applied-modal/DownloadWithTermsAndGuestbookModal.stories.tsx @@ -10,7 +10,7 @@ import { GuestbookResponseDTO } from '@/access/domain/repositories/AccessRepository' import { AccessRepositoryProvider } from '@/sections/access/AccessRepositoryProvider' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' +import { RepositoriesStoryProvider } from '@/stories/WithRepositories' const accessRepository: AccessRepository = { submitGuestbookForDatasetDownload: ( @@ -32,7 +32,7 @@ const meta: Meta = { WithI18next, WithLoggedInUser, (Story) => ( - + = { - + ) ] } diff --git a/src/stories/sign-up/SignUp.stories.tsx b/src/stories/sign-up/SignUp.stories.tsx index b81684631..fd2253efc 100644 --- a/src/stories/sign-up/SignUp.stories.tsx +++ b/src/stories/sign-up/SignUp.stories.tsx @@ -7,6 +7,7 @@ import { UserMockRepository } from '../shared-mock-repositories/user/UserMockRep import { DataverseInfoMockRepository } from '../shared-mock-repositories/info/DataverseInfoMockRepository' import { DataverseInfoMockLoadingRepository } from '../shared-mock-repositories/info/DataverseInfoMockLoadingkRepository' import { DataverseInfoMockErrorRepository } from '../shared-mock-repositories/info/DataverseInfoMockErrorRepository' +import { RepositoriesStoryProvider } from '@/stories/WithRepositories' const meta: Meta = { title: 'Pages/Sign Up', @@ -22,30 +23,33 @@ type Story = StoryObj export const ValidTokenWithNotLinkedAccount: Story = { render: () => ( - + + + ) } export const LoadingTermsOfUse: Story = { render: () => ( - + + + ) } export const FailedToFetchTermsOfUse: Story = { render: () => ( - + + + ) } diff --git a/tests/component/WithRepositories.tsx b/tests/component/WithRepositories.tsx index ceeb129c5..a8fa94e62 100644 --- a/tests/component/WithRepositories.tsx +++ b/tests/component/WithRepositories.tsx @@ -1,6 +1,10 @@ import { ReactNode } from 'react' import { CollectionRepository } from '@/collection/domain/repositories/CollectionRepository' import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' +import { ExternalToolsRepository } from '@/externalTools/domain/repositories/ExternalToolsRepository' +import { FileRepository } from '@/files/domain/repositories/FileRepository' +import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' +import { UserRepository } from '@/users/domain/repositories/UserRepository' import { RepositoriesProvider } from '@/shared/contexts/repositories/RepositoriesProvider' function failFastRepository(name: string): T { @@ -21,17 +25,29 @@ interface WithRepositoriesProps { children: ReactNode collectionRepository?: CollectionRepository datasetRepository?: DatasetRepository + externalToolsRepository?: ExternalToolsRepository + fileRepository?: FileRepository + guestbookRepository?: GuestbookRepository + userRepository?: UserRepository } export function WithRepositories({ children, collectionRepository = failFastRepository('CollectionRepository'), - datasetRepository = failFastRepository('DatasetRepository') + datasetRepository = failFastRepository('DatasetRepository'), + externalToolsRepository = failFastRepository('ExternalToolsRepository'), + fileRepository = failFastRepository('FileRepository'), + guestbookRepository = failFastRepository('GuestbookRepository'), + userRepository = failFastRepository('UserRepository') }: WithRepositoriesProps) { return ( + datasetRepository={datasetRepository} + externalToolsRepository={externalToolsRepository} + fileRepository={fileRepository} + guestbookRepository={guestbookRepository} + userRepository={userRepository}> {children} ) diff --git a/tests/component/sections/account/Account.spec.tsx b/tests/component/sections/account/Account.spec.tsx index 3661ca81a..03b104c36 100644 --- a/tests/component/sections/account/Account.spec.tsx +++ b/tests/component/sections/account/Account.spec.tsx @@ -1,6 +1,5 @@ import { Account } from '../../../../src/sections/account/Account' import { AccountHelper } from '../../../../src/sections/account/AccountHelper' -import { UserJSDataverseRepository } from '../../../../src/users/infrastructure/repositories/UserJSDataverseRepository' import { CollectionMockRepository } from '@/stories/collection/CollectionMockRepository' import { RoleMockRepository } from '@/stories/account/RoleMockRepository' import { NotificationType } from '@/notifications/domain/models/Notification' @@ -55,7 +54,6 @@ describe('Account', () => { @@ -74,7 +72,6 @@ describe('Account', () => { diff --git a/tests/component/sections/account/ApiTokenSection.spec.tsx b/tests/component/sections/account/ApiTokenSection.spec.tsx index e6c9418d0..c82923355 100644 --- a/tests/component/sections/account/ApiTokenSection.spec.tsx +++ b/tests/component/sections/account/ApiTokenSection.spec.tsx @@ -1,6 +1,7 @@ import { ApiTokenSection } from '../../../../src/sections/account/api-token-section/ApiTokenSection' import { DateHelper } from '@/shared/helpers/DateHelper' import { UserRepository } from '@/users/domain/repositories/UserRepository' +import { WithRepositories } from '@tests/component/WithRepositories' describe('ApiTokenSection', () => { const mockApiTokenInfo = { @@ -14,6 +15,12 @@ describe('ApiTokenSection', () => { let userRepository: UserRepository + const ApiTokenSectionWithRepositories = () => ( + + + + ) + beforeEach(() => { userRepository = { getCurrentApiToken: cy.stub().resolves(mockApiTokenInfo), @@ -23,7 +30,7 @@ describe('ApiTokenSection', () => { register: cy.stub().resolves() } - cy.mountAuthenticated() + cy.mountAuthenticated() }) it('should show the loading skeleton while fetching the token', () => { @@ -31,7 +38,7 @@ describe('ApiTokenSection', () => { return Cypress.Promise.delay(500).then(() => mockApiTokenInfo) }) - cy.mount() + cy.mount() cy.get('[data-testid="loadingSkeleton"]').should('exist') cy.wait(500) @@ -81,7 +88,7 @@ describe('ApiTokenSection', () => { it('should show error message when failing to fetch the current API token', () => { userRepository.getCurrentApiToken = cy.stub().rejects(new Error('Failed to fetch API token')) - cy.mountAuthenticated() + cy.mountAuthenticated() cy.findByText(/Failed to fetch API token/).should('exist') }) diff --git a/tests/component/sections/dataset/Dataset.spec.tsx b/tests/component/sections/dataset/Dataset.spec.tsx index 0cb871772..4eb9668d6 100644 --- a/tests/component/sections/dataset/Dataset.spec.tsx +++ b/tests/component/sections/dataset/Dataset.spec.tsx @@ -311,7 +311,8 @@ describe('Dataset', () => { + datasetRepository={datasetRepository} + fileRepository={fileRepository}> @@ -327,7 +328,6 @@ describe('Dataset', () => { it('renders skeleton while loading', () => { mountWithDataset( { mountWithDataset( { mountWithDataset( { it('renders the breadcrumbs', () => { mountWithDataset( { it('renders the Dataset page title and labels', () => { mountWithDataset( { it('renders the Dataset Metadata tab', () => { mountWithDataset( { it('renders the Dataset Terms tab', () => { mountWithDataset( { mountWithDataset( { it('renders the Dataset Files tab', () => { mountWithDataset( { mountWithDataset( { mountWithDataset( { mountWithDataset( { mountWithDataset( { it('renders the Dataset Action Buttons', () => { mountWithDataset( { it('renders the Dataset Files list table with infinite scrolling enabled', () => { mountWithDataset( { it('shows the toast when the information was sent to contact successfully', () => { mountWithDataset( { it('does not show the tooltip for contact owner button', () => { mountWithDataset( { mountWithDataset( { it('renders the dataset configure tools options if they are available', () => { cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') @@ -34,18 +37,22 @@ describe('DatasetToolOptions', () => { it('renders nothing if there are no dataset configure tools', () => { testExternalToolsRepository.getExternalTools = cy.stub().resolves([]) cy.customMount( - - - + + + + + ) cy.findByText('Configure Options').should('not.exist') }) it('renders the dataset explore tools options if they are available', () => { cy.customMount( - - - + + + + + ) cy.findByText('Configure Options').should('not.exist') @@ -56,9 +63,11 @@ describe('DatasetToolOptions', () => { it('renders nothing if there are no dataset explore tools', () => { testExternalToolsRepository.getExternalTools = cy.stub().resolves([]) cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') }) @@ -84,9 +93,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').should('exist').click() @@ -122,9 +133,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').click() @@ -157,9 +170,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').should('exist').click() @@ -192,9 +207,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').click() @@ -235,9 +252,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').should('exist').as('toolButton') @@ -260,9 +279,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').should('exist').click() @@ -288,9 +309,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').should('exist').click() @@ -316,9 +339,11 @@ describe('DatasetToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('Dataset Explore Tool').should('exist').click() diff --git a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx index 639811886..3d720e64d 100644 --- a/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx +++ b/tests/component/sections/dataset/dataset-action-buttons/access-dataset-menu/AccessDatasetMenu.spec.tsx @@ -5,12 +5,47 @@ import { DatasetVersionMother } from '../../../../dataset/domain/models/DatasetMother' import { FileSizeUnit } from '../../../../../../src/files/domain/models/FileMetadata' -import { getGuestbook, submitGuestbookForDatasetDownload } from '@iqss/dataverse-client-javascript' +import { submitGuestbookForDatasetDownload } from '@iqss/dataverse-client-javascript' import { ReactNode, Suspense } from 'react' import { useTranslation } from 'react-i18next' import { AccessRepository } from '@/access/domain/repositories/AccessRepository' import { DatasetPermissions } from '@/dataset/domain/models/Dataset' import { AccessRepositoryProvider } from '@/sections/access/AccessRepositoryProvider' +import { Guestbook } from '@/guestbooks/domain/models/Guestbook' +import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' +import { WithRepositories } from '@tests/component/WithRepositories' + +const guestbook: Guestbook = { + id: 10, + name: 'Guestbook Test', + enabled: true, + nameRequired: true, + emailRequired: true, + institutionRequired: false, + positionRequired: false, + customQuestions: [], + createTime: '2026-01-01T00:00:00.000Z', + dataverseId: 1 +} + +function createGuestbookRepository( + repositoryOverrides: Partial = {} +): GuestbookRepository { + return { + getGuestbook: cy.stub().resolves(guestbook), + getGuestbooksByCollectionId: cy.stub().resolves([]), + assignDatasetGuestbook: cy.stub().resolves(), + removeDatasetGuestbook: cy.stub().resolves(), + ...repositoryOverrides + } +} + +function withGuestbookRepository( + component: React.ReactNode, + guestbookRepository: GuestbookRepository +) { + return {component} +} function TranslationPreloader({ children }: { children: ReactNode }) { useTranslation('dataset') @@ -295,18 +330,7 @@ describe('AccessDatasetMenu', () => { const fileDownloadSizes = [ DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) ] - cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() const submitGuestbookForDatasetDownloadExecute = cy .stub(submitGuestbookForDatasetDownload, 'execute') .resolves('/api/v1/access/dataset/test-token') @@ -315,20 +339,23 @@ describe('AccessDatasetMenu', () => { }) cy.customMount( - - - - - + withGuestbookRepository( + + + + + , + guestbookRepository + ) ) cy.findByRole('button', { name: 'Access Dataset' }).click() @@ -351,42 +378,34 @@ describe('AccessDatasetMenu', () => { const fileDownloadSizes = [ DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) ] - const getGuestbookExecute = cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.customMount( - - - - - + withGuestbookRepository( + + + + + , + guestbookRepository + ) ) - cy.wrap(getGuestbookExecute).should('not.have.been.called') + cy.wrap(guestbookRepository.getGuestbook).should('not.have.been.called') cy.findByRole('button', { name: 'Access Dataset' }).click() cy.findByRole('button', { name: /Download ZIP/ }).click() - cy.wrap(getGuestbookExecute).should('have.been.calledOnceWith', 10) + cy.wrap(guestbookRepository.getGuestbook).should('have.been.calledOnceWith', 10) }) it('renders download option as a button and opens guestbook modal when guestbook exists', () => { @@ -397,34 +416,25 @@ describe('AccessDatasetMenu', () => { const fileDownloadSizes = [ DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) ] - - cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.customMount( - - - - - + withGuestbookRepository( + + + + + , + guestbookRepository + ) ) cy.findByRole('button', { name: 'Access Dataset' }).click() @@ -441,34 +451,25 @@ describe('AccessDatasetMenu', () => { const fileDownloadSizes = [ DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) ] - - cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.customMount( - - - - - + withGuestbookRepository( + + + + + , + guestbookRepository + ) ) cy.findByRole('button', { name: 'Access Dataset' }).click() @@ -486,34 +487,25 @@ describe('AccessDatasetMenu', () => { DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }), DatasetFileDownloadSizeMother.createArchival({ value: 4000, unit: FileSizeUnit.BYTES }) ] - - cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.customMount( - - - - - + withGuestbookRepository( + + + + + , + guestbookRepository + ) ) cy.findByRole('button', { name: 'Access Dataset' }).click() @@ -583,46 +575,38 @@ describe('AccessDatasetMenu', () => { const fileDownloadSizes = [ DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) ] - const getGuestbookExecute = cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.window().then((window) => { cy.stub(window.HTMLAnchorElement.prototype, 'click').as('anchorClick') }) cy.customMount( - withAccessRepository( - - - - - + withGuestbookRepository( + withAccessRepository( + + + + + + ), + guestbookRepository ) ) cy.findByRole('button', { name: 'Access Dataset' }).click() cy.findByRole('button', { name: /Download ZIP/ }).click() - cy.wrap(getGuestbookExecute).should('not.have.been.called') + cy.wrap(guestbookRepository.getGuestbook).should('not.have.been.called') cy.get('@anchorClick').should('have.been.calledOnce') cy.findByRole('dialog').should('not.exist') cy.findByText('Your download has started.').should('exist') @@ -637,46 +621,38 @@ describe('AccessDatasetMenu', () => { const fileDownloadSizes = [ DatasetFileDownloadSizeMother.createOriginal({ value: 2000, unit: FileSizeUnit.BYTES }) ] - const getGuestbookExecute = cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.window().then((window) => { cy.stub(window.HTMLAnchorElement.prototype, 'click').as('anchorClick') }) cy.customMount( - withAccessRepository( - - - - - + withGuestbookRepository( + withAccessRepository( + + + + + + ), + guestbookRepository ) ) cy.findByRole('button', { name: 'Access Dataset' }).click() cy.findByRole('button', { name: /Download ZIP/ }).click() - cy.wrap(getGuestbookExecute).should('not.have.been.called') + cy.wrap(guestbookRepository.getGuestbook).should('not.have.been.called') cy.get('@anchorClick').should('have.been.calledOnce') cy.findByRole('dialog').should('not.exist') cy.findByText('Your download has started.').should('exist') diff --git a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx index 42e943b75..6d35de84c 100644 --- a/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/DatasetFiles.spec.tsx @@ -72,12 +72,8 @@ describe('DatasetFiles', () => { it('renders the files table', () => { cy.customMount( - - + + ) @@ -88,12 +84,8 @@ describe('DatasetFiles', () => { describe('Pagination navigation', () => { it('renders the files table with the correct header on a page different than the first one ', () => { cy.customMount( - - + + ) @@ -104,12 +96,8 @@ describe('DatasetFiles', () => { it('renders the files table with the correct page selected after updating the pageSize', () => { cy.customMount( - - + + ) @@ -124,12 +112,8 @@ describe('DatasetFiles', () => { it('renders the files table with the correct header with a different page size ', () => { cy.customMount( - - + + ) @@ -148,12 +132,8 @@ describe('DatasetFiles', () => { fileRepository.getFilesTotalDownloadSizeByDatasetPersistentId = cy.stub().resolves(19900) cy.customMount( - - + + ) @@ -184,12 +164,8 @@ describe('DatasetFiles', () => { fileRepository.getFilesTotalDownloadSizeByDatasetPersistentId = cy.stub().resolves(19900) cy.customMount( - - + + ) @@ -217,12 +193,8 @@ describe('DatasetFiles', () => { it('maintains the selection when the page changes', () => { cy.customMount( - - + + ) cy.findByRole('columnheader', { name: '1 to 10 of 200 Files' }).should('exist') @@ -252,12 +224,8 @@ describe('DatasetFiles', () => { it('maintains the selection when the page size changes', () => { cy.customMount( - - + + ) cy.findByRole('columnheader', { name: '1 to 10 of 200 Files' }).should('exist') @@ -278,12 +246,8 @@ describe('DatasetFiles', () => { it('removes the selection when the filters change', () => { cy.customMount( - - + + ) cy.findByRole('columnheader', { name: '1 to 10 of 200 Files' }).should('exist') @@ -300,12 +264,8 @@ describe('DatasetFiles', () => { it('removes the selection when the Sort by changes', () => { cy.customMount( - - + + ) cy.findByRole('columnheader', { name: '1 to 10 of 200 Files' }).should('exist') @@ -322,12 +282,8 @@ describe('DatasetFiles', () => { it('removes the selection when the Search bar is used', () => { cy.customMount( - - + + ) cy.findByRole('columnheader', { name: '1 to 10 of 200 Files' }).should('exist') @@ -353,10 +309,9 @@ describe('DatasetFiles', () => { }) cy.customMount( - + @@ -381,10 +336,9 @@ describe('DatasetFiles', () => { it('renders the zip download limit message when selecting all rows', () => { cy.customMount( - + @@ -401,10 +355,9 @@ describe('DatasetFiles', () => { it('renders the zip download limit message when selecting all rows and then navigating to other page', () => { cy.customMount( - + @@ -424,12 +377,8 @@ describe('DatasetFiles', () => { describe('Calling use cases', () => { it('calls the useFiles hook with the correct parameters', () => { cy.customMount( - - + + ) @@ -448,12 +397,8 @@ describe('DatasetFiles', () => { it('calls the useFiles hook with the correct parameters when sortBy criteria changes', () => { cy.customMount( - - + + ) @@ -470,12 +415,8 @@ describe('DatasetFiles', () => { it('calls the useFiles hook with the correct parameters when filterByType criteria changes', () => { cy.customMount( - - + + ) @@ -492,12 +433,8 @@ describe('DatasetFiles', () => { it('calls the useFiles hook with the correct parameters when filterByAccess criteria changes', () => { cy.customMount( - - + + ) @@ -514,12 +451,8 @@ describe('DatasetFiles', () => { it('calls the useFiles hook with the correct parameters when filterByTag criteria changes', () => { cy.customMount( - - + + ) @@ -536,12 +469,8 @@ describe('DatasetFiles', () => { it('calls the useFiles hook with the correct parameters when searchText criteria changes', () => { cy.customMount( - - + + ) @@ -557,12 +486,8 @@ describe('DatasetFiles', () => { it('calls the useFiles hook with the correct parameters when paginationInfo changes', () => { cy.customMount( - - + + ) @@ -577,10 +502,9 @@ describe('DatasetFiles', () => { it('calls getFilesTotalDownloadSizeByDatasetPersistentId with the correct parameters when applying search file criteria', () => { cy.customMount( - + diff --git a/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx b/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx index 006189e31..80e265339 100644 --- a/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/DatasetFilesScrollable.spec.tsx @@ -93,9 +93,8 @@ describe('DatasetFilesScrollable', () => { it('renders the scrollable files table', () => { cy.customMount( - + @@ -109,9 +108,8 @@ describe('DatasetFilesScrollable', () => { it('check that the files sections are rendered even without edit permissions', () => { cy.customMount( - + { it('renders the first 10 files', () => { cy.customMount( - + @@ -165,9 +162,8 @@ describe('DatasetFilesScrollable', () => { totalFilesCount: 0 }) cy.customMount( - + @@ -182,9 +178,8 @@ describe('DatasetFilesScrollable', () => { fileRepository.getAllByDatasetPersistentIdWithCount = cy.stub().resolves(only4Files) cy.customMount( - + @@ -202,9 +197,8 @@ describe('DatasetFilesScrollable', () => { it('loads more files when scrolling to the bottom ', () => { cy.customMount( - + @@ -225,9 +219,8 @@ describe('DatasetFilesScrollable', () => { it('scrolls to the top when criteria changes', () => { cy.customMount( - + @@ -251,9 +244,8 @@ describe('DatasetFilesScrollable', () => { describe('Sticky elements', () => { it('should stick the header table when scrolling down', () => { cy.customMount( - + @@ -278,10 +270,9 @@ describe('DatasetFilesScrollable', () => { it('should stick the table top messages on top of the table header when scrolling down with selected files', () => { cy.customMount( - + @@ -313,10 +304,9 @@ describe('DatasetFilesScrollable', () => { it('table header should have css top value according to criteria container height', () => { cy.customMount( - + @@ -351,10 +341,9 @@ describe('DatasetFilesScrollable', () => { it('table header should have css top value according to criteria container height + top messages container height when selected files ,top messages container should have top value only according to criteria container height', () => { cy.customMount( - + @@ -419,9 +408,8 @@ describe('DatasetFilesScrollable', () => { describe('File selection', () => { it('selects first 10 files when clicking the top header checkbox', () => { cy.customMount( - + @@ -439,9 +427,8 @@ describe('DatasetFilesScrollable', () => { it('selects all files when clicking the select all button', () => { cy.customMount( - + @@ -463,9 +450,8 @@ describe('DatasetFilesScrollable', () => { it('selects all files when clicking the select all button and mantains selection when loading more on scroll to bottom', () => { cy.customMount( - + @@ -504,9 +490,8 @@ describe('DatasetFilesScrollable', () => { it('maintains the selection when scrolling to bottom and loading more files', () => { cy.customMount( - + @@ -550,9 +535,8 @@ describe('DatasetFilesScrollable', () => { it('removes the selection when the header checkbox is clicked again', () => { cy.customMount( - + @@ -574,9 +558,8 @@ describe('DatasetFilesScrollable', () => { it('selects all loaded by scroll files when clicking the header checkbox', () => { cy.customMount( - + @@ -603,9 +586,8 @@ describe('DatasetFilesScrollable', () => { it('all new loaded files should be checked if selecting all files when only displayed 10 and then scrolling to bottom to load 10 more files', () => { cy.customMount( - + @@ -640,9 +622,8 @@ describe('DatasetFilesScrollable', () => { it('removes the selection when the filters change', () => { cy.customMount( - + @@ -658,9 +639,8 @@ describe('DatasetFilesScrollable', () => { it('removes the selection when the Sort by changes', () => { cy.customMount( - + @@ -676,9 +656,8 @@ describe('DatasetFilesScrollable', () => { it('removes the selection when the Search bar is used', () => { cy.customMount( - + @@ -693,9 +672,8 @@ describe('DatasetFilesScrollable', () => { it('removes the selection when the clear all button is clicked', () => { cy.customMount( - + @@ -718,10 +696,9 @@ describe('DatasetFilesScrollable', () => { metadata: FileMetadataMother.create({ size: new FileSize(2, FileSizeUnit.BYTES) }) }) cy.customMount( - + @@ -745,10 +722,9 @@ describe('DatasetFilesScrollable', () => { it('renders the zip download limit message when selecting all rows', () => { cy.customMount( - + @@ -766,10 +742,9 @@ describe('DatasetFilesScrollable', () => { it('renders the zip download limit message when selecting all rows and then scrolling to bottom to load more files', () => { cy.customMount( - + @@ -795,9 +770,8 @@ describe('DatasetFilesScrollable', () => { describe('Calling use cases', () => { it('calls the useGetAccumulatedFiles hook with the correct parameters', () => { cy.customMount( - + @@ -816,9 +790,8 @@ describe('DatasetFilesScrollable', () => { }) it('calls the useGetAccumulatedFiles hook with the correct parameters when sortBy criteria changes', () => { cy.customMount( - + @@ -836,9 +809,8 @@ describe('DatasetFilesScrollable', () => { }) it('calls the useGetAccumulatedFiles hook with the correct parameters when filterByType criteria changes', () => { cy.customMount( - + @@ -856,9 +828,8 @@ describe('DatasetFilesScrollable', () => { }) it('calls the useGetAccumulatedFiles hook with the correct parameters when filterByAccess criteria changes', () => { cy.customMount( - + @@ -876,9 +847,8 @@ describe('DatasetFilesScrollable', () => { }) it('calls the useGetAccumulatedFiles hook with the correct parameters when filterByTag criteria changes', () => { cy.customMount( - + @@ -896,9 +866,8 @@ describe('DatasetFilesScrollable', () => { }) it('calls the useGetAccumulatedFiles hook with the correct parameters when searchText criteria changes', () => { cy.customMount( - + @@ -915,9 +884,8 @@ describe('DatasetFilesScrollable', () => { }) it('calls the useGetAccumulatedFiles hook with the correct parameters when scrolling to bottom', () => { cy.customMount( - + @@ -947,10 +915,9 @@ describe('DatasetFilesScrollable', () => { }) it('calls getFilesTotalDownloadSizeByDatasetPersistentId with the correct parameters when applying search file criteria', () => { cy.customMount( - + @@ -983,9 +950,8 @@ describe('DatasetFilesScrollable', () => { .rejects(new Error('Some error on getAllByDatasetPersistentIdWithCount')) cy.customMount( - + @@ -998,9 +964,8 @@ describe('DatasetFilesScrollable', () => { fileRepository.getAllByDatasetPersistentIdWithCount = cy.stub().rejects(new Error()) cy.customMount( - + @@ -1015,9 +980,8 @@ describe('DatasetFilesScrollable', () => { .rejects(new Error('Some error on getFilesTotalDownloadSizeByDatasetPersistentId')) cy.customMount( - + @@ -1030,9 +994,8 @@ describe('DatasetFilesScrollable', () => { fileRepository.getFilesTotalDownloadSizeByDatasetPersistentId = cy.stub().rejects(new Error()) cy.customMount( - + @@ -1047,9 +1010,8 @@ describe('DatasetFilesScrollable', () => { .rejects(new Error('Some error on getFilesCountInfoByDatasetPersistentId')) cy.customMount( - + @@ -1062,9 +1024,8 @@ describe('DatasetFilesScrollable', () => { fileRepository.getFilesCountInfoByDatasetPersistentId = cy.stub().rejects(new Error()) cy.customMount( - + diff --git a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx index eaf2b0529..ae3a9262e 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/FilesTable.spec.tsx @@ -25,14 +25,13 @@ const defaultCriteria = new FileCriteria() describe('FilesTable', () => { it('renders the files table', () => { cy.customMount( - + ) @@ -48,14 +47,13 @@ describe('FilesTable', () => { it('renders the spinner when the data isLoading', () => { cy.customMount( - + ) @@ -65,14 +63,13 @@ describe('FilesTable', () => { it('renders the no files message when there are no files', () => { cy.customMount( - + ) @@ -83,14 +80,13 @@ describe('FilesTable', () => { describe('Row selection', () => { it('selects all rows in the current page when the header checkbox is clicked', () => { cy.customMount( - + ) @@ -106,14 +102,13 @@ describe('FilesTable', () => { it('clears row selection for the current page when the header checkbox is clicked', () => { cy.customMount( - + ) @@ -133,14 +128,13 @@ describe('FilesTable', () => { it("selects all rows when the 'Select all' button is clicked", () => { cy.customMount( - + ) @@ -156,14 +150,13 @@ describe('FilesTable', () => { it('clears the selection when the clear selection button is clicked', () => { cy.customMount( - + ) @@ -181,14 +174,13 @@ describe('FilesTable', () => { it('highlights the selected rows', () => { cy.customMount( - + ) @@ -214,7 +206,7 @@ describe('FilesTable', () => { .resolves(SettingMother.createZipDownloadLimit(new ZipDownloadLimit(500, FileSizeUnit.BYTES))) cy.customMount( - + { isLoading={false} filesTotalDownloadSize={testFilesTotalDownloadSize} criteria={defaultCriteria} - fileRepository={fileRepository} /> @@ -241,14 +232,13 @@ describe('FilesTable', () => { it('renders the file actions column', () => { cy.customMount( - + ) 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 c443dd856..61085b02d 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 @@ -20,11 +20,11 @@ describe('FileActionsHeader', () => { datasetRepository.getByPersistentId = cy.stub().resolves(datasetWithUpdatePermissions) const files = FilePreviewMother.createMany(2) cy.mountAuthenticated( - + - + ) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx index 077c3ae3c..e177e71e4 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/download-files/DownloadFilesButton.spec.tsx @@ -1,6 +1,5 @@ import { ReactNode, Suspense } from 'react' import { - getGuestbook, submitGuestbookForDatasetDownload, submitGuestbookForDatafilesDownload } from '@iqss/dataverse-client-javascript' @@ -24,10 +23,26 @@ import { CustomTermsMother, TermsOfUseMother } from '../../../../../../dataset/domain/models/TermsOfUseMother' +import { Guestbook } from '@/guestbooks/domain/models/Guestbook' +import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' +import { WithRepositories } from '@tests/component/WithRepositories' const datasetRepository: DatasetRepository = {} as DatasetRepository const fileRepository = {} as FileRepository describe('DownloadFilesButton', () => { + const guestbook: Guestbook = { + id: 10, + name: 'Guestbook Test', + enabled: true, + nameRequired: true, + emailRequired: true, + institutionRequired: false, + positionRequired: false, + customQuestions: [], + createTime: '2026-01-01T00:00:00.000Z', + dataverseId: 1 + } + const TranslationPreloader = ({ children }: { children: ReactNode }) => { useTranslation('files') useTranslation('dataset') @@ -67,6 +82,21 @@ describe('DownloadFilesButton', () => { ) } + const createGuestbookRepository = ( + repositoryOverrides: Partial = {} + ): GuestbookRepository => ({ + getGuestbook: cy.stub().resolves(guestbook), + getGuestbooksByCollectionId: cy.stub().resolves([]), + assignDatasetGuestbook: cy.stub().resolves(), + removeDatasetGuestbook: cy.stub().resolves(), + ...repositoryOverrides + }) + + const withGuestbookRepository = ( + component: ReactNode, + guestbookRepository: GuestbookRepository + ) => {component} + beforeEach(() => { fileRepository.getMultipleFileDownloadUrl = cy .stub() @@ -463,32 +493,24 @@ describe('DownloadFilesButton', () => { const fileSelection = { 'some-file-id': files[0] } - const getGuestbookExecute = cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.mountAuthenticated( - withDataset( - , - datasetWithGuestbook + withGuestbookRepository( + withDataset( + , + datasetWithGuestbook + ), + guestbookRepository ) ) - cy.wrap(getGuestbookExecute).should('not.have.been.called') + cy.wrap(guestbookRepository.getGuestbook).should('not.have.been.called') cy.get('#download-files').click() cy.findByRole('button', { name: 'Original Format' }).click() - cy.wrap(getGuestbookExecute).should('have.been.calledOnceWith', 10) + cy.wrap(guestbookRepository.getGuestbook).should('have.been.calledOnceWith', 10) }) it('submits guestbook for the dataset when all files are selected and guestbook exists', () => { @@ -509,18 +531,7 @@ describe('DownloadFilesButton', () => { 'file-c': undefined } - cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() const submitDatasetStub = cy .stub(submitGuestbookForDatasetDownload, 'execute') .resolves('/api/v1/access/dataset/999?token=test') @@ -532,9 +543,12 @@ describe('DownloadFilesButton', () => { }) cy.mountAuthenticated( - withDataset( - , - datasetWithGuestbook + withGuestbookRepository( + withDataset( + , + datasetWithGuestbook + ), + guestbookRepository ) ) @@ -563,35 +577,27 @@ describe('DownloadFilesButton', () => { const fileSelection = { 'some-file-id': files[0] } - const getGuestbookExecute = cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.window().then((window) => { cy.stub(window.HTMLAnchorElement.prototype, 'click').as('anchorClick') }) cy.mountAuthenticated( - withAccessRepository( - withDataset( - , - datasetWithGuestbook - ) + withGuestbookRepository( + withAccessRepository( + withDataset( + , + datasetWithGuestbook + ) + ), + guestbookRepository ) ) cy.get('#download-files').click() - cy.wrap(getGuestbookExecute).should('not.have.been.called') + cy.wrap(guestbookRepository.getGuestbook).should('not.have.been.called') cy.get('@anchorClick').should('have.been.calledOnce') cy.findByRole('dialog').should('not.exist') cy.findByText('Your download has started.').should('exist') @@ -612,35 +618,27 @@ describe('DownloadFilesButton', () => { const fileSelection = { 'some-file-id': files[0] } - const getGuestbookExecute = cy.stub(getGuestbook, 'execute').resolves({ - id: 10, - name: 'Guestbook Test', - enabled: true, - nameRequired: true, - emailRequired: true, - institutionRequired: false, - positionRequired: false, - customQuestions: [], - createTime: '2026-01-01T00:00:00.000Z', - dataverseId: 1 - }) + const guestbookRepository = createGuestbookRepository() cy.window().then((window) => { cy.stub(window.HTMLAnchorElement.prototype, 'click').as('anchorClick') }) cy.mountAuthenticated( - withAccessRepository( - withDataset( - , - datasetWithGuestbook - ) + withGuestbookRepository( + withAccessRepository( + withDataset( + , + datasetWithGuestbook + ) + ), + guestbookRepository ) ) cy.get('#download-files').click() - cy.wrap(getGuestbookExecute).should('not.have.been.called') + cy.wrap(guestbookRepository.getGuestbook).should('not.have.been.called') cy.get('@anchorClick').should('have.been.calledOnce') cy.findByRole('dialog').should('not.exist') cy.findByText('Your download has started.').should('exist') 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 0200ace9b..ea0282851 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 @@ -25,7 +25,7 @@ describe('EditFilesMenu', () => { datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) return ( - + @@ -37,10 +37,7 @@ describe('EditFilesMenu', () => { it('renders the Edit Files menu', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.get('#edit-files-menu').should('exist') @@ -48,10 +45,7 @@ describe('EditFilesMenu', () => { it('does not render the Edit Files menu when the user is not authenticated', () => { cy.customMount( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.get('#edit-files-menu').should('not.exist') @@ -59,10 +53,7 @@ describe('EditFilesMenu', () => { it('does not render the Edit Files menu when there are no files in the dataset', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.get('#edit-files-menu').should('not.exist') @@ -70,10 +61,7 @@ describe('EditFilesMenu', () => { it('renders the Edit Files options', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.get('#edit-files-menu').click() @@ -87,7 +75,7 @@ describe('EditFilesMenu', () => { cy.mountAuthenticated( withDataset( - , + , datasetWithNoUpdatePermissions ) ) @@ -102,10 +90,7 @@ describe('EditFilesMenu', () => { }) cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.get('#edit-files-menu').should('be.disabled') @@ -118,10 +103,7 @@ describe('EditFilesMenu', () => { }) cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.get('#edit-files-menu').should('be.disabled') diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx index 05c60829f..aa86cb6b9 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/edit-files-menu/EditFilesOptions.spec.tsx @@ -21,13 +21,8 @@ const datasetInfo = { describe('EditFilesOptions', () => { it('renders the EditFilesOptions', () => { cy.customMount( - - + + ) @@ -41,13 +36,8 @@ describe('EditFilesOptions', () => { it('renders the restrict option if some file is unrestricted', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -59,13 +49,8 @@ describe('EditFilesOptions', () => { it('renders the unrestrict option if some file is restricted', () => { const fileRestricted = FilePreviewMother.createRestricted() cy.customMount( - - + + ) @@ -76,13 +61,8 @@ describe('EditFilesOptions', () => { it.skip('renders the embargo option if the embargo is allowed by settings', () => { cy.customMount( - - + + ) @@ -93,13 +73,8 @@ describe('EditFilesOptions', () => { it.skip('renders provenance option if provenance is enabled in config', () => { cy.customMount( - - + + ) @@ -110,13 +85,8 @@ describe('EditFilesOptions', () => { it('shows the No Selected Files message when no files are selected and one option is clicked', () => { cy.customMount( - - + + ) @@ -131,11 +101,10 @@ describe('EditFilesOptions', () => { it('does not show the No Selected Files message when files are selected and one option is clicked', () => { cy.customMount( - + @@ -153,13 +122,8 @@ describe('EditFilesOptions for a single file', () => { it('renders the EditFilesOptions', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -182,13 +146,8 @@ describe('EditFilesOptions for a single file', () => { it('renders the restrict option if some file is unrestricted', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -202,13 +161,8 @@ describe('EditFilesOptions for a single file', () => { it('renders the unrestrict option if file is restricted', () => { const fileRestricted = FilePreviewMother.createRestricted() cy.customMount( - - + + ) @@ -223,13 +177,8 @@ describe('EditFilesOptions for a single file', () => { it('renders delete modal', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -243,10 +192,9 @@ describe('EditFilesOptions for a single file', () => { it('should delete file if delete button clicked', () => { fileRepository.delete = cy.stub().resolves() cy.customMount( - + @@ -263,13 +211,8 @@ describe('EditFilesOptions for a single file', () => { it('should reset the modal if cancel is clicked in delete modal', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -292,13 +235,8 @@ describe('EditFilesOptions for a single file', () => { const fileToDelete = FilePreviewMother.createDefault() cy.customMount( - - + + , [ `${Route.DATASETS}?${QueryParamKey.PERSISTENT_ID}=${datasetInfo.persistentId}&${QueryParamKey.VERSION}=DRAFT` @@ -324,10 +262,9 @@ describe('EditFilesOptions for a single file', () => { it('should restrict file if restrict button clicked', () => { fileRepository.restrict = cy.stub().resolves() cy.customMount( - + @@ -346,13 +283,8 @@ describe('EditFilesOptions for a single file', () => { const fileRestricted = FilePreviewMother.createRestricted() cy.customMount( - - + + ) @@ -367,10 +299,9 @@ describe('EditFilesOptions for a single file', () => { it('should restrict file and call refreshFiles if restrict button clicked in draft version', () => { fileRepository.restrict = cy.stub().resolves() cy.customMount( - + @@ -390,13 +321,8 @@ describe('EditFilesOptions for a single file', () => { it('should reset the modal if cancel is clicked in restrict modal', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -413,13 +339,8 @@ describe('EditFilesOptions for a single file', () => { it('opens and closes the edit file tags modal', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -434,13 +355,8 @@ describe('EditFilesOptions for a single file', () => { const fileWithTags = FilePreviewMother.createWithLabels() cy.customMount( - - + + ) @@ -460,13 +376,8 @@ describe('EditFilesOptions for a single file', () => { const fileUnrestricted = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -482,13 +393,8 @@ describe('EditFilesOptions for a single file', () => { const fileRestricted = FilePreviewMother.createRestricted() cy.customMount( - - + + ) @@ -504,13 +410,8 @@ describe('EditFilesOptions for a single file', () => { const fileToDelete = FilePreviewMother.createDefault() cy.customMount( - - + + ) @@ -528,13 +429,8 @@ describe('EditFilesOptions for a single file', () => { fileRepository.updateCategories = cy.stub().resolves() cy.customMount( - - + + ) 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 9240bdfb8..5d0da5783 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 @@ -16,8 +16,8 @@ const datasetRepository: DatasetRepository = {} as DatasetRepository describe('FileActionButtons', () => { it('renders the file action buttons', () => { cy.customMount( - - + + ) @@ -35,11 +35,11 @@ describe('FileActionButtons', () => { datasetRepository.getByPrivateUrlToken = cy.stub().resolves(datasetWithUpdatePermissions) cy.mountAuthenticated( - + - + ) diff --git a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileTools.spec.tsx b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileTools.spec.tsx index 9ff86f86a..948aea5a6 100644 --- a/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileTools.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/files-table/file-actions/file-actions-cell/file-action-buttons/FileTools.spec.tsx @@ -5,6 +5,7 @@ import { ExternalToolsProvider } from '@/shared/contexts/external-tools/External import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' import { FileMetadataMother } from '@tests/component/files/domain/models/FileMetadataMother' import { FilePreviewMother } from '@tests/component/files/domain/models/FilePreviewMother' +import { WithRepositories } from '@tests/component/WithRepositories' const testFilePreview = FilePreviewMother.createDefault() // text/plain file const testExternalToolsRepository: ExternalToolsRepository = {} as ExternalToolsRepository @@ -21,9 +22,11 @@ describe('FileTools', () => { it('renders external tool buttons when user can download the file and there are applicable tools', () => { cy.customMount( - - - + + + + + ) cy.findByRole('link', { name: `Preview ${testFilePreview.name}` }) @@ -49,9 +52,11 @@ describe('FileTools', () => { it('does not render external tool buttons when user cannot download the file', () => { cy.customMount( - - - + + + + + ) }) @@ -63,9 +68,11 @@ describe('FileTools', () => { }) cy.customMount( - - - + + + + + ) }) }) 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 eab1da5a2..6ea05e687 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 @@ -25,7 +25,7 @@ describe('FileOptionsMenu', () => { datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) return ( - + @@ -37,20 +37,14 @@ describe('FileOptionsMenu', () => { it('renders the FileOptionsMenu', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.findByRole('button', { name: 'File Options' }).should('exist') }) it('renders the file options menu with tooltip', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.findByRole('button', { name: 'File Options' }).trigger('mouseover') @@ -59,10 +53,7 @@ describe('FileOptionsMenu', () => { it('renders the dropdown header', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.findByRole('button', { name: 'File Options' }).should('exist').click() @@ -70,12 +61,7 @@ describe('FileOptionsMenu', () => { }) it('does not render is the user is not authenticated', () => { - cy.customMount( - withDataset( - , - datasetWithUpdatePermissions - ) - ) + cy.customMount(withDataset(, datasetWithUpdatePermissions)) cy.findByRole('button', { name: 'File Options' }).should('not.exist') }) @@ -85,10 +71,7 @@ describe('FileOptionsMenu', () => { permissions: DatasetPermissionsMother.createWithUpdateDatasetNotAllowed() }) cy.mountAuthenticated( - withDataset( - , - datasetWithNoUpdatePermissions - ) + withDataset(, datasetWithNoUpdatePermissions) ) cy.findByRole('button', { name: 'File Options' }).should('not.exist') }) @@ -97,12 +80,7 @@ describe('FileOptionsMenu', () => { const datasetWithNoTermsOfAccess = DatasetMother.create({ hasValidTermsOfAccess: false }) - cy.mountAuthenticated( - withDataset( - , - datasetWithNoTermsOfAccess - ) - ) + cy.mountAuthenticated(withDataset(, datasetWithNoTermsOfAccess)) cy.findByRole('button', { name: 'File Options' }).should('not.exist') }) @@ -112,12 +90,7 @@ describe('FileOptionsMenu', () => { locks: [DatasetLockMother.createLockedInEditInProgress()], hasValidTermsOfAccess: true }) - cy.mountAuthenticated( - withDataset( - , - datasetLockedFromEdits - ) - ) + cy.mountAuthenticated(withDataset(, datasetLockedFromEdits)) cy.findByRole('button', { name: 'File Options' }).should('exist').should('be.disabled') }) @@ -126,10 +99,7 @@ describe('FileOptionsMenu', () => { const file = FilePreviewMother.createDeleted() cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.findByRole('button', { name: 'File Options' }).should('exist').click() @@ -143,10 +113,7 @@ describe('FileOptionsMenu', () => { it('renders the menu options', () => { cy.mountAuthenticated( - withDataset( - , - datasetWithUpdatePermissions - ) + withDataset(, datasetWithUpdatePermissions) ) cy.findByRole('button', { name: 'File Options' }).click() cy.findByRole('button', { name: 'Restrict' }).should('exist') diff --git a/tests/component/sections/dataset/dataset-files/guestbook/DownloadWithTermsAndGuestbookModal.spec.tsx b/tests/component/sections/dataset/dataset-files/guestbook/DownloadWithTermsAndGuestbookModal.spec.tsx index 66095d974..42c8e564c 100644 --- a/tests/component/sections/dataset/dataset-files/guestbook/DownloadWithTermsAndGuestbookModal.spec.tsx +++ b/tests/component/sections/dataset/dataset-files/guestbook/DownloadWithTermsAndGuestbookModal.spec.tsx @@ -9,9 +9,9 @@ import { GuestbookResponseDTO } from '@/access/domain/repositories/AccessRepository' import { AccessRepositoryProvider } from '@/sections/access/AccessRepositoryProvider' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' import { SessionContext } from '@/sections/session/SessionContext' import { DatasetMother } from '@tests/component/dataset/domain/models/DatasetMother' +import { WithRepositories } from '@tests/component/WithRepositories' const guestbook: Guestbook = { id: 10, @@ -113,11 +113,11 @@ describe('DownloadWithTermsAndGuestbookModal', () => { isLoading: false, refreshDataset: () => {} }}> - + {component} - + ) diff --git a/tests/component/sections/dataset/dataset-guestbook/DatasetGuestbook.spec.tsx b/tests/component/sections/dataset/dataset-guestbook/DatasetGuestbook.spec.tsx index 42df75645..926cc83da 100644 --- a/tests/component/sections/dataset/dataset-guestbook/DatasetGuestbook.spec.tsx +++ b/tests/component/sections/dataset/dataset-guestbook/DatasetGuestbook.spec.tsx @@ -1,10 +1,10 @@ import { DatasetGuestbook } from '@/sections/dataset/dataset-guestbook/DatasetGuestbook' import { DatasetContext } from '@/sections/dataset/DatasetContext' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' import { Guestbook } from '@/guestbooks/domain/models/Guestbook' import { Dataset as DatasetModel } from '@/dataset/domain/models/Dataset' import { DatasetMother } from '@tests/component/dataset/domain/models/DatasetMother' +import { WithRepositories } from '@tests/component/WithRepositories' const guestbook: Guestbook = { id: 10, @@ -35,7 +35,7 @@ describe('DatasetGuestbook', () => { dataset: DatasetModel = DatasetMother.create({ guestbookId: guestbook.id }) ) => cy.customMount( - + { }}> - + ) it('renders a spinner while the guestbook is loading', () => { diff --git a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx index 7bcb507c5..72ea785a3 100644 --- a/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx +++ b/tests/component/sections/dataset/dataset-terms/DatasetTerms.spec.tsx @@ -10,9 +10,9 @@ import { } from '../../../dataset/domain/models/TermsOfUseMother' import { DatasetContext } from '@/sections/dataset/DatasetContext' import { Dataset as DatasetModel } from '@/dataset/domain/models/Dataset' -import { ReactNode } from 'react' +import { ComponentProps, ReactNode } from 'react' import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' -import { GuestbookRepositoryProvider } from '@/sections/guestbooks/GuestbookRepositoryProvider' +import { WithRepositories } from '@tests/component/WithRepositories' const datasetPersistentId = 'test-dataset-persistent-id' const datasetVersion = DatasetMother.create().version @@ -54,17 +54,18 @@ const termsOfUseWithUndefinedValue = TermsOfUseMother.create({ }) const guestbookRepository: GuestbookRepository = {} as GuestbookRepository +const DatasetTermsWithRepositories = (props: ComponentProps) => ( + + + +) + describe('DatasetTerms', () => { const withDatasetContext = (component: ReactNode, dataset?: DatasetModel) => ( {} }}> {component} ) - const withGuestbookRepository = (component: ReactNode) => ( - - {component} - - ) beforeEach(() => { fileRepository.getFilesCountInfoByDatasetPersistentId = cy @@ -75,10 +76,9 @@ describe('DatasetTerms', () => { it('renders the license and terms of use sections', () => { cy.customMount( - @@ -91,10 +91,9 @@ describe('DatasetTerms', () => { it('shows no guestbook assigned message after expanding the guestbook accordion', () => { cy.customMount( withDatasetContext( - , @@ -127,17 +126,14 @@ describe('DatasetTerms', () => { }) cy.customMount( - withGuestbookRepository( - withDatasetContext( - , - DatasetMother.create({ guestbookId }) - ) + withDatasetContext( + , + DatasetMother.create({ guestbookId }) ) ) @@ -167,17 +163,14 @@ describe('DatasetTerms', () => { }) cy.customMount( - withGuestbookRepository( - withDatasetContext( - , - DatasetMother.create({ guestbookId }) - ) + withDatasetContext( + , + DatasetMother.create({ guestbookId }) ), ['/datasets?tab=terms&termsTab=guestbook'] ) @@ -188,10 +181,9 @@ describe('DatasetTerms', () => { it('check that the terms of use sections are rendered even without edit permissions', () => { cy.customMount( - { it('renders the correct number of restricted files', () => { cy.customMount( - @@ -225,10 +216,9 @@ describe('DatasetTerms', () => { }) it('does not render a row if the value is undefined', () => { cy.customMount( - @@ -242,10 +232,9 @@ describe('DatasetTerms', () => { .stub() .resolves(singleRestrictedFilesCountInfo) cy.customMount( - @@ -256,10 +245,9 @@ describe('DatasetTerms', () => { }) it('renders the custom terms', () => { cy.customMount( - @@ -273,10 +261,9 @@ describe('DatasetTerms', () => { it('renders the request access allowed message', () => { cy.customMount( - @@ -287,10 +274,9 @@ describe('DatasetTerms', () => { }) it('renders the request access not allowed message', () => { cy.customMount( - @@ -302,10 +288,9 @@ describe('DatasetTerms', () => { it('renders the data access place', () => { cy.customMount( - @@ -317,10 +302,9 @@ describe('DatasetTerms', () => { it('renders the original archive information', () => { cy.customMount( - @@ -332,10 +316,9 @@ describe('DatasetTerms', () => { it('renders the availability status', () => { cy.customMount( - @@ -347,10 +330,9 @@ describe('DatasetTerms', () => { it('renders the contact for access information', () => { cy.customMount( - @@ -362,10 +344,9 @@ describe('DatasetTerms', () => { it('renders the size of collection information', () => { cy.customMount( - @@ -377,10 +358,9 @@ describe('DatasetTerms', () => { it('renders the study completion information', () => { cy.customMount( - @@ -394,10 +374,9 @@ describe('DatasetTerms', () => { .stub() .resolves(noRestrictedFilesCountInfo) cy.customMount( - @@ -410,10 +389,9 @@ describe('DatasetTerms', () => { .stub() .resolves(singleRestrictedFilesCountInfo) cy.customMount( - @@ -426,10 +404,9 @@ describe('DatasetTerms', () => { .stub() .resolves(noRestrictedFilesCountInfo) cy.customMount( - diff --git a/tests/component/sections/edit-dataset-terms/EditDatasetTerms.spec.tsx b/tests/component/sections/edit-dataset-terms/EditDatasetTerms.spec.tsx index 0caf998fd..3fee56978 100644 --- a/tests/component/sections/edit-dataset-terms/EditDatasetTerms.spec.tsx +++ b/tests/component/sections/edit-dataset-terms/EditDatasetTerms.spec.tsx @@ -93,7 +93,9 @@ describe('EditDatasetTerms', () => { datasetRepository.getByPersistentId = cy.stub().resolves(dataset) datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) return ( - + @@ -151,7 +153,6 @@ describe('EditDatasetTerms', () => { ) @@ -171,7 +172,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -193,7 +193,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -226,7 +225,6 @@ describe('EditDatasetTerms', () => { EditDatasetTermsHelper.EDIT_DATASET_TERMS_TABS_KEYS.restrictedFilesTerms } licenseRepository={licenseRepository} - guestbookRepository={guestbookRepository} />, dataset ) @@ -251,7 +249,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -270,7 +267,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -309,7 +305,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -343,8 +338,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -367,7 +360,6 @@ describe('EditDatasetTerms', () => { // Force an invalid key to hit the default branch in getCurrentFormDirtyState defaultActiveTabKey={'unknown-tab' as unknown as EditDatasetTermsTabKey} licenseRepository={licenseRepository} - datasetRepository={datasetRepository} />, dataset ) @@ -389,7 +381,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -413,7 +404,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -434,7 +424,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -464,7 +453,6 @@ describe('EditDatasetTerms', () => { EditDatasetTermsHelper.EDIT_DATASET_TERMS_TABS_KEYS.restrictedFilesTerms } licenseRepository={licenseRepository} - guestbookRepository={guestbookRepository} />, dataset ) @@ -493,7 +481,6 @@ describe('EditDatasetTerms', () => { EditDatasetTermsHelper.EDIT_DATASET_TERMS_TABS_KEYS.restrictedFilesTerms } licenseRepository={licenseRepository} - guestbookRepository={guestbookRepository} />, dataset ) @@ -537,7 +524,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -561,7 +547,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -583,7 +568,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -607,7 +591,9 @@ describe('EditDatasetTerms', () => { datasetRepository.getByPersistentId = cy.stub().resolves(dataset) datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) return ( - + @@ -623,7 +609,6 @@ describe('EditDatasetTerms', () => { , undefined ) @@ -641,7 +626,6 @@ describe('EditDatasetTerms', () => { EditDatasetTermsHelper.EDIT_DATASET_TERMS_TABS_KEYS.restrictedFilesTerms } licenseRepository={licenseRepository} - guestbookRepository={guestbookRepository} />, dataset ) @@ -663,7 +647,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -681,7 +664,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -700,7 +682,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -722,7 +703,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -747,7 +727,6 @@ describe('EditDatasetTerms', () => { , dataset ) @@ -763,7 +742,9 @@ describe('EditDatasetTerms Mobile View', () => { datasetRepository.getByPersistentId = cy.stub().resolves(dataset) datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) return ( - + @@ -785,7 +766,6 @@ describe('EditDatasetTerms Mobile View', () => { , dataset ) diff --git a/tests/component/sections/edit-dataset-terms/EditGuestbook.spec.tsx b/tests/component/sections/edit-dataset-terms/EditGuestbook.spec.tsx index 3dff96744..ff3814cf3 100644 --- a/tests/component/sections/edit-dataset-terms/EditGuestbook.spec.tsx +++ b/tests/component/sections/edit-dataset-terms/EditGuestbook.spec.tsx @@ -12,6 +12,7 @@ import { import { Dataset } from '@/dataset/domain/models/Dataset' import { Guestbook } from '@/guestbooks/domain/models/Guestbook' import { GuestbookRepository } from '@/guestbooks/domain/repositories/GuestbookRepository' +import { WithRepositories } from '@tests/component/WithRepositories' const LocationDisplay = () => { const location = useLocation() @@ -62,23 +63,27 @@ describe('EditGuestbook', () => { datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) return ( - - {component} - + + + {component} + + ) } const withDatasetContext = (component: ReactNode, dataset: Dataset | undefined) => ( - {} - }}> - {component} - + + {} + }}> + {component} + + ) beforeEach(() => { @@ -93,9 +98,7 @@ describe('EditGuestbook', () => { it('renders guestbook options and keeps Save Changes disabled for current guestbook', () => { const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Data Request Guestbook').should('be.checked') cy.findByLabelText('Secondary Guestbook').should('not.be.checked') @@ -106,9 +109,7 @@ describe('EditGuestbook', () => { it('enables Save Changes when selecting a different guestbook', () => { const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Secondary Guestbook').click() cy.findByRole('button', { name: 'Save Changes' }).should('be.enabled') @@ -118,15 +119,7 @@ describe('EditGuestbook', () => { const onFormStateChange = cy.stub().as('onFormStateChange') const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders( - , - dataset - ) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Secondary Guestbook').click() @@ -136,9 +129,7 @@ describe('EditGuestbook', () => { it('keeps Save Changes disabled when dataset has no assigned guestbook and none is selected', () => { const dataset = DatasetMother.create({ guestbookId: undefined }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Data Request Guestbook').should('not.be.checked') cy.findByLabelText('Secondary Guestbook').should('not.be.checked') @@ -149,9 +140,7 @@ describe('EditGuestbook', () => { it('falls back to no preselection when dataset has no guestbook id', () => { const dataset = DatasetMother.create({ guestbookId: undefined }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Data Request Guestbook').should('not.be.checked') cy.findByLabelText('Secondary Guestbook').should('not.be.checked') @@ -162,9 +151,7 @@ describe('EditGuestbook', () => { it('clears the selected guestbook when clicking Clear Selection', () => { const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByRole('button', { name: 'Clear Selection' }).click() @@ -180,9 +167,7 @@ describe('EditGuestbook', () => { ) const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Data Request Guestbook').should('not.exist') cy.findByLabelText('Secondary Guestbook').should('not.exist') @@ -200,9 +185,7 @@ describe('EditGuestbook', () => { it('opens preview modal when clicking Preview Guestbook', () => { const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findAllByRole('button', { name: 'Preview Guestbook' }).should('have.length', 2) cy.findAllByRole('button', { name: 'Preview Guestbook' }).eq(1).click() @@ -226,9 +209,7 @@ describe('EditGuestbook', () => { it('closes preview modal when clicking Close', () => { const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findAllByRole('button', { name: 'Preview Guestbook' }).eq(0).click() cy.findByRole('dialog').should('be.visible') @@ -240,12 +221,7 @@ describe('EditGuestbook', () => { const onPreview = cy.stub().as('onPreview') const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders( - , - dataset - ) - ) + cy.customMount(withProviders(, dataset)) cy.findAllByRole('button', { name: 'Preview Guestbook' }).eq(0).click() cy.get('@onPreview').should('have.been.calledOnce') @@ -259,9 +235,7 @@ describe('EditGuestbook', () => { assignDatasetGuestbookStub.as('assignDatasetGuestbookExecute') const dataset = DatasetMother.create({ id: 999, guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Secondary Guestbook').click() cy.findByRole('button', { name: 'Save Changes' }).click() @@ -287,7 +261,7 @@ describe('EditGuestbook', () => { cy.customMount( withProviders( <> - + , releasedDataset @@ -316,7 +290,7 @@ describe('EditGuestbook', () => { cy.customMount( withProviders( <> - + , draftDataset @@ -345,7 +319,7 @@ describe('EditGuestbook', () => { cy.customMount( withProviders( <> - + , releasedDataset @@ -385,7 +359,7 @@ describe('EditGuestbook', () => { const [dataset, setDataset] = useState(createDataset(collectionA)) return ( <> - {withDatasetContext(, dataset)} + {withDatasetContext(, dataset)} @@ -427,7 +401,7 @@ describe('EditGuestbook', () => { const [dataset, setDataset] = useState(createDataset(collectionA)) return ( <> - {withDatasetContext(, dataset)} + {withDatasetContext(, dataset)} @@ -452,9 +426,7 @@ describe('EditGuestbook', () => { ) const dataset = DatasetMother.create({ id: 999, guestbookId: undefined }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.get('form').submit() cy.get('@assignDatasetGuestbookExecute').should('not.have.been.called') @@ -469,9 +441,7 @@ describe('EditGuestbook', () => { 'removeDatasetGuestbookExecute' ) - cy.customMount( - withDatasetContext(, undefined) - ) + cy.customMount(withDatasetContext(, undefined)) cy.get('form').submit() cy.get('@assignDatasetGuestbookExecute').should('not.have.been.called') @@ -485,9 +455,7 @@ describe('EditGuestbook', () => { removeDatasetGuestbookStub.as('removeDatasetGuestbookExecute') const dataset = DatasetMother.create({ id: 999, guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByRole('button', { name: 'Clear Selection' }).click() cy.findByRole('button', { name: 'Save Changes' }).click() @@ -502,9 +470,7 @@ describe('EditGuestbook', () => { ) const dataset = DatasetMother.create({ id: 999, guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByLabelText('Secondary Guestbook').click() cy.findByRole('button', { name: 'Save Changes' }).click() @@ -519,9 +485,7 @@ describe('EditGuestbook', () => { ) const dataset = DatasetMother.create({ id: 999, guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByRole('button', { name: 'Clear Selection' }).click() cy.findByRole('button', { name: 'Save Changes' }).click() @@ -536,9 +500,7 @@ describe('EditGuestbook', () => { ) const dataset = DatasetMother.create({ guestbookId: mockGuestbooks[0].id }) - cy.customMount( - withProviders(, dataset) - ) + cy.customMount(withProviders(, dataset)) cy.findByText( /Something went wrong getting guestbooks by collection id. Try again later./ diff --git a/tests/component/sections/edit-dataset-terms/EditTermsOfAccess.spec.tsx b/tests/component/sections/edit-dataset-terms/EditTermsOfAccess.spec.tsx index d5865d514..dae92cf97 100644 --- a/tests/component/sections/edit-dataset-terms/EditTermsOfAccess.spec.tsx +++ b/tests/component/sections/edit-dataset-terms/EditTermsOfAccess.spec.tsx @@ -38,6 +38,10 @@ const mockDataset = DatasetMother.create({ }) describe('EditTermsOfAccess', () => { + beforeEach(() => { + datasetRepository.updateTermsOfAccess = cy.stub().resolves() + }) + const withProviders = (component: ReactNode, dataset: Dataset) => { datasetRepository.getByPersistentId = cy.stub().resolves(dataset) datasetRepository.getByPrivateUrlToken = cy.stub().resolves(dataset) diff --git a/tests/component/sections/file/File.spec.tsx b/tests/component/sections/file/File.spec.tsx index 1f9cf81bd..c9d6a18ae 100644 --- a/tests/component/sections/file/File.spec.tsx +++ b/tests/component/sections/file/File.spec.tsx @@ -171,8 +171,10 @@ describe('File', () => { it('renders the External Tools tab with "Preview" title if only one tool applicable and is a preview tool', () => { cy.customMount( - - + + { .resolves([ExternalToolsMother.createFileQueryTool()]) cy.customMount( - - + + { ]) cy.customMount( - - + + { externalToolsRepository.getExternalTools = cy.stub().resolves([]) cy.customMount( - - + + { fileRepository.getById = cy.stub().resolves(testFile) cy.customMount( - - + + { const guestbook: Guestbook = { @@ -214,7 +214,7 @@ describe('AccessFileMenu', () => { cy.customMount( - + { datasetPersistentId="doi:10.5072/FK2/FILEPAGE" /> - + ) @@ -345,7 +345,7 @@ describe('AccessFileMenu', () => { cy.customMount( - + { }} /> - + ) diff --git a/tests/component/sections/file/file-action-buttons/access-file-menu/FileToolOptions.spec.tsx b/tests/component/sections/file/file-action-buttons/access-file-menu/FileToolOptions.spec.tsx index 3efcb91de..f3834d112 100644 --- a/tests/component/sections/file/file-action-buttons/access-file-menu/FileToolOptions.spec.tsx +++ b/tests/component/sections/file/file-action-buttons/access-file-menu/FileToolOptions.spec.tsx @@ -7,6 +7,7 @@ import { import { ExternalToolsProvider } from '@/shared/contexts/external-tools/ExternalToolsProvider' import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' import { FileExternalToolResolvedMother } from '@tests/component/externalTools/domain/models/FileExternalToolResolvedMother' +import { WithRepositories } from '@tests/component/WithRepositories' const testExternalToolsRepository: ExternalToolsRepository = {} as ExternalToolsRepository const testFileExploreTool = ExternalToolsMother.createFileExploreTool() @@ -23,9 +24,11 @@ describe('FileToolOptions', () => { describe('FileExploreToolsOptions', () => { it('renders the tool options if file explore tools are available and compatible with the type', () => { cy.customMount( - - - + + + + + ) cy.findByText('Query Options').should('not.exist') @@ -36,9 +39,11 @@ describe('FileToolOptions', () => { it('does not render the tool options if there are not applicable tools for the file type', () => { cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') @@ -49,9 +54,11 @@ describe('FileToolOptions', () => { describe('FileQueryToolsOptions', () => { it('renders the tool options if file query tools are available and compatible with the type', () => { cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') @@ -62,9 +69,11 @@ describe('FileToolOptions', () => { it('does not render the tool options if there are not applicable tools for the file type', () => { cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') @@ -75,9 +84,11 @@ describe('FileToolOptions', () => { describe('FileConfigureToolsOptions', () => { it('renders the tool options if file configure tools are available and compatible with the type', () => { cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') @@ -88,9 +99,11 @@ describe('FileToolOptions', () => { it('does not render the tool options if there are not applicable tools for the file type', () => { cy.customMount( - - - + + + + + ) cy.findByText('Explore Options').should('not.exist') @@ -119,9 +132,11 @@ describe('FileToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('File Explore Tool').should('exist').click() @@ -152,9 +167,11 @@ describe('FileToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('File Explore Tool').should('exist').click() @@ -199,9 +216,11 @@ describe('FileToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('File Explore Tool').should('exist').as('toolButton') @@ -224,9 +243,11 @@ describe('FileToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('File Explore Tool').should('exist').click() @@ -252,9 +273,11 @@ describe('FileToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('File Explore Tool').should('exist').click() @@ -280,9 +303,11 @@ describe('FileToolOptions', () => { }) cy.customMount( - - - + + + + + ) cy.findByText('File Explore Tool').should('exist').click() diff --git a/tests/component/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.spec.tsx b/tests/component/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.spec.tsx index 469c57039..f134bbdb0 100644 --- a/tests/component/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.spec.tsx +++ b/tests/component/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool.spec.tsx @@ -2,9 +2,11 @@ import { ExternalToolsRepository } from '@/externalTools/domain/repositories/Ext import { FileEmbeddedExternalTool } from '@/sections/file/file-embedded-external-tool/FileEmbeddedExternalTool' import { FilePageHelper } from '@/sections/file/FilePageHelper' import { WriteError } from '@iqss/dataverse-client-javascript' +import { ComponentProps } from 'react' import { ExternalToolsMother } from '@tests/component/externalTools/domain/models/ExternalToolsMother' import { FileExternalToolResolvedMother } from '@tests/component/externalTools/domain/models/FileExternalToolResolvedMother' import { FileMother } from '@tests/component/files/domain/models/FileMother' +import { WithRepositories } from '@tests/component/WithRepositories' const externalToolsRepository: ExternalToolsRepository = {} as ExternalToolsRepository // Used for fetching the tool resolved URL @@ -20,6 +22,14 @@ const fileQueryToolResolved = FileExternalToolResolvedMother.create({ toolUrlResolved: 'https://example.com/query-tool?fileId=1' }) +const FileEmbeddedExternalToolWithRepositories = ( + props: ComponentProps +) => ( + + + +) + describe('FileEmbeddedExternalTool', () => { it('renders a single preview tool', () => { externalToolsRepository.getFileExternalToolResolved = cy @@ -27,11 +37,10 @@ describe('FileEmbeddedExternalTool', () => { .resolves(filePreviewToolResolved) cy.customMount( - ) @@ -67,11 +76,10 @@ describe('FileEmbeddedExternalTool', () => { externalToolsRepository.getFileExternalToolResolved = getFileExternalToolResolvedStub cy.customMount( - ) @@ -119,11 +127,10 @@ describe('FileEmbeddedExternalTool', () => { .resolves(filePreviewToolResolved) cy.customMount( - ) @@ -136,11 +143,10 @@ describe('FileEmbeddedExternalTool', () => { .stub() .rejects(new WriteError('Some js dataverse processed error message.')) cy.customMount( - ) @@ -155,11 +161,10 @@ describe('FileEmbeddedExternalTool', () => { .rejects(new Error('Failed to fetch tool URL')) cy.customMount( - ) diff --git a/tests/component/sections/session/SessionProvider.spec.tsx b/tests/component/sections/session/SessionProvider.spec.tsx index cce06c8e7..b93217345 100644 --- a/tests/component/sections/session/SessionProvider.spec.tsx +++ b/tests/component/sections/session/SessionProvider.spec.tsx @@ -9,6 +9,7 @@ import { SessionProvider } from '@/sections/session/SessionProvider' import { useSession } from '@/sections/session/SessionContext' +import { WithRepositories } from '@tests/component/WithRepositories' const userRepository: UserRepository = {} as UserRepository const testUser = UserMother.create() @@ -54,12 +55,14 @@ describe('SessionProvider', () => { error: null, login: () => {} // 👈 deprecated }}> - - }> - } /> - Sign up} /> - - + + + }> + } /> + Sign up} /> + + + ) } diff --git a/tests/component/sections/shared/citation/CitationDownloadButton.spec.tsx b/tests/component/sections/shared/citation/CitationDownloadButton.spec.tsx index 2d143683e..48a3520fd 100644 --- a/tests/component/sections/shared/citation/CitationDownloadButton.spec.tsx +++ b/tests/component/sections/shared/citation/CitationDownloadButton.spec.tsx @@ -1,8 +1,9 @@ import { DatasetRepository } from '@/dataset/domain/repositories/DatasetRepository' import { CitationDownloadButton } from '../../../../../src/sections/shared/citation/citation-download/CitationDownloadButton' import { FormattedCitation } from '@/dataset/domain/models/DatasetCitation' -import { ViewStyledCitationModal } from '@/sections/shared/citation/citation-download/ViewStyledCitationModal' import { WithRepositories } from '@tests/component/WithRepositories' +import { ViewStyledCitationModal } from '@/sections/shared/citation/citation-download/ViewStyledCitationModal' +import i18next from '@/i18n' const datasetRepository: DatasetRepository = {} as DatasetRepository const mockCitation: FormattedCitation = { @@ -12,11 +13,16 @@ const mockCitation: FormattedCitation = { describe('CitationDownloadButton', () => { beforeEach(() => { - // Mock URL.createObjectURL and URL.revokeObjectURL + cy.wrap(i18next.loadNamespaces('files')) + cy.window().then((win) => { - cy.stub(win.URL, 'createObjectURL').returns('mock-url') - cy.stub(win.URL, 'revokeObjectURL') + cy.stub(win.URL, 'createObjectURL').as('createObjectURL').returns('mock-url') + cy.stub(win.URL, 'revokeObjectURL').as('revokeObjectURL') }) + + cy.customMount( + {}} citation={mockCitation} /> + ) }) it('renders the button', () => { @@ -47,10 +53,8 @@ describe('CitationDownloadButton', () => { 'EndNote' ) }) - cy.window().then((win) => { - expect(win.URL['createObjectURL']).to.have.been.called - expect(win.URL['revokeObjectURL']).to.have.been.called - }) + cy.get('@createObjectURL').should('have.been.called') + cy.get('@revokeObjectURL').should('have.been.called') }) it('downloads RIS citation and triggers file download', () => { @@ -72,9 +76,7 @@ describe('CitationDownloadButton', () => { 'RIS' ) }) - cy.window().then((win) => { - expect(win.URL['createObjectURL']).to.have.been.called - }) + cy.get('@createObjectURL').should('have.been.called') }) it('downloads BibTeX citation and creates download link', () => { @@ -97,10 +99,8 @@ describe('CitationDownloadButton', () => { ) }) - cy.window().then((win) => { - expect(win.URL['createObjectURL']).to.have.been.called - expect(win.URL['revokeObjectURL']).to.have.been.called - }) + cy.get('@createObjectURL').should('have.been.called') + cy.get('@revokeObjectURL').should('have.been.called') }) it('verifies correct filename is used for download', () => { @@ -157,15 +157,13 @@ describe('CitationDownloadButton', () => { ) - cy.customMount( - {}} citation={mockCitation} /> - ) + cy.findByRole('button', { name: 'Cite Dataset' }).click() + cy.findByText('View Styled Citation').click() - cy.findByText('Styled Citation').click() + cy.findByRole('dialog').should('exist') cy.findByText('Select a CSL Style').should('exist') cy.findByText(mockCitation.content).should('exist') cy.findByRole('button', { name: /Copy to clipboard icon/ }).should('exist') - cy.findByRole('dialog').should('exist') }) it('closes styled citation modal when close is triggered', () => { @@ -181,7 +179,8 @@ describe('CitationDownloadButton', () => { cy.findByText('View Styled Citation').click() cy.findByRole('dialog').should('exist') - cy.findByRole('button', { name: /close/i }).click() + cy.findByText(mockCitation.content).should('exist') + cy.findByRole('button', { name: 'Cancel' }).click() cy.findByRole('dialog').should('not.exist') }) diff --git a/tests/component/sections/sign-up/SignUp.spec.tsx b/tests/component/sections/sign-up/SignUp.spec.tsx index f359d17f8..2ea92f1dd 100644 --- a/tests/component/sections/sign-up/SignUp.spec.tsx +++ b/tests/component/sections/sign-up/SignUp.spec.tsx @@ -3,6 +3,7 @@ import { SignUp } from '@/sections/sign-up/SignUp' import { UserRepository } from '@/users/domain/repositories/UserRepository' import { AuthContextMother } from '@tests/component/auth/AuthContextMother' import { AuthContext } from 'react-oauth2-code-pkce' +import { WithRepositories } from '@tests/component/WithRepositories' const dataverseInfoRepository: DataverseInfoRepository = {} as DataverseInfoRepository const userRepository: UserRepository = {} as UserRepository @@ -14,24 +15,25 @@ describe('SignUp', () => { it('renders the valid token not linked account form and correct alerts when hasValidTokenButNotLinkedAccount prop is true', () => { cy.customMount( - {}, - logOut: () => {}, - loginInProgress: false, - tokenData: AuthContextMother.createTokenData(), - idTokenData: AuthContextMother.createTokenData(), - error: null, - login: () => {} // 👈 deprecated - }}> - - + + {}, + logOut: () => {}, + loginInProgress: false, + tokenData: AuthContextMother.createTokenData(), + idTokenData: AuthContextMother.createTokenData(), + error: null, + login: () => {} // 👈 deprecated + }}> + + + ) cy.findByTestId('valid-token-not-linked-account-alert-text').should('exist') @@ -44,24 +46,25 @@ describe('SignUp', () => { // For now we are only rendering the form for the case when theres is a valid token but is not linked to any account, but we prepare the test for other cases it('renders the default create account alert when hasValidTokenButNotLinkedAccount prop is false', () => { cy.customMount( - {}, - logOut: () => {}, - loginInProgress: false, - tokenData: AuthContextMother.createTokenData(), - idTokenData: AuthContextMother.createTokenData(), - error: null, - login: () => {} // 👈 deprecated - }}> - - + + {}, + logOut: () => {}, + loginInProgress: false, + tokenData: AuthContextMother.createTokenData(), + idTokenData: AuthContextMother.createTokenData(), + error: null, + login: () => {} // 👈 deprecated + }}> + + + ) cy.findByTestId('default-create-account-alert-text').should('exist') diff --git a/tests/component/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.spec.tsx b/tests/component/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.spec.tsx index 23c9ba527..5065cb08b 100644 --- a/tests/component/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.spec.tsx +++ b/tests/component/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm.spec.tsx @@ -7,6 +7,8 @@ import { JSTermsOfUseMapper } from '@/info/infrastructure/mappers/JSTermsOfUseMa import { ValidTokenNotLinkedAccountForm } from '@/sections/sign-up/valid-token-not-linked-account-form/ValidTokenNotLinkedAccountForm' import { AuthContextMother } from '@tests/component/auth/AuthContextMother' import { TermsOfUseMother } from '@tests/component/info/domain/models/TermsOfUseMother' +import { WithRepositories } from '@tests/component/WithRepositories' +import { ComponentProps } from 'react' const userRepository: UserRepository = {} as UserRepository const dataverseInfoRepository: DataverseInfoRepository = {} as DataverseInfoRepository @@ -19,6 +21,14 @@ const mockFirstName = 'mockFirstName' const mockLastName = 'mockLastName' const mockEmail = 'mockEmail@email.com' +const ValidTokenNotLinkedAccountFormWithRepositories = ( + props: ComponentProps +) => ( + + + +) + describe('ValidTokenNotLinkedAccountForm', () => { beforeEach(() => { cy.viewport(1280, 720) @@ -47,8 +57,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -75,8 +84,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -115,8 +123,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -156,8 +163,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -246,8 +252,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -274,8 +279,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -302,8 +306,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - @@ -341,8 +344,7 @@ describe('ValidTokenNotLinkedAccountForm', () => { error: null, login: () => {} // 👈 deprecated }}> - diff --git a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx index 1bba11036..dbee60144 100644 --- a/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx +++ b/tests/e2e-integration/e2e/sections/dataset/Dataset.spec.tsx @@ -961,7 +961,8 @@ describe('Dataset', () => { cy.wrap( DatasetHelper.createWithFiles(FileHelper.createMany(3)).then((dataset) => DatasetHelper.publish(dataset.persistentId) - ) + ), + { timeout: 30_000 } ) .its('persistentId') .then((persistentId: string) => { diff --git a/tests/e2e-integration/shared/TestsUtils.ts b/tests/e2e-integration/shared/TestsUtils.ts index aebbd36a4..73d246e7d 100644 --- a/tests/e2e-integration/shared/TestsUtils.ts +++ b/tests/e2e-integration/shared/TestsUtils.ts @@ -74,15 +74,17 @@ export class TestsUtils { } static finishSignUp() { - cy.get('body').then(($body) => { + cy.location('pathname', { timeout: 20_000 }).should('not.include', '/auth-callback') + + cy.get('body', { timeout: 20_000 }).then(($body) => { const isOnSignUpPage = $body.find('[data-testid="sign-up-page"]').length > 0 - const hasTermsCheckbox = $body.find('#termsAccepted').length > 0 - if (!isOnSignUpPage || !hasTermsCheckbox) { + if (!isOnSignUpPage) { return } - cy.get('#termsAccepted').check({ force: true }) + cy.findByTestId('valid-token-not-linked-account-form', { timeout: 20_000 }).should('exist') + cy.findByTestId('termsAcceptedCheckbox').check({ force: true }) cy.findByRole('button', { name: 'Create Account' }).click() }) } diff --git a/tests/support/commands.tsx b/tests/support/commands.tsx index 9b989c77d..29162a078 100644 --- a/tests/support/commands.tsx +++ b/tests/support/commands.tsx @@ -53,6 +53,7 @@ import { requireAppConfig } from '@/config' import { ToastContainer } from 'react-toastify' import { ExternalToolsProvider } from '@/shared/contexts/external-tools/ExternalToolsProvider' import { ExternalToolsMockRepository } from '@/stories/shared-mock-repositories/externalTools/ExternalToolsMockRepository' +import { WithRepositories } from '@tests/component/WithRepositories' // Define your custom mount function @@ -74,9 +75,11 @@ Cypress.Commands.add( return cy.mount( - - - + + + + + diff --git a/vite.config.ts b/vite.config.ts index 472516589..9b612ecd2 100644 --- a/vite.config.ts +++ b/vite.config.ts @@ -42,6 +42,9 @@ export default defineConfig({ } }) ], + optimizeDeps: { + include: ['react-dom/client'] + }, preview: { port: 5173 },