diff --git a/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx b/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx index 6e9f05b98..e7a6e3df1 100644 --- a/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx +++ b/frontend/src/app/(editor)/@appBar/n/[noteId]/editor-app-bar.spec.tsx @@ -3,14 +3,14 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import * as UseApplicationStateModule from '../../../../../hooks/common/use-application-state' -import type { ApplicationState } from '../../../../../redux/application-state' import { mockI18n } from '../../../../../test-utils/mock-i18n' import { EditorAppBar } from './editor-app-bar' import type { NoteGroupPermissionEntry, NoteUserPermissionEntry } from '@hedgedoc/commons' import { render } from '@testing-library/react' import type { PropsWithChildren } from 'react' import React from 'react' +import { mockAppState } from '../../../../../test-utils/mock-app-state' +import type { LoginUserInfo } from '../../../../../api/me/types' jest.mock('../../../../../components/layout/app-bar/base-app-bar', () => ({ __esModule: true, @@ -40,7 +40,7 @@ const mockedCommonAppState = { }, user: { username: 'test' - } + } as LoginUserInfo } describe('app bar', () => { @@ -48,40 +48,34 @@ describe('app bar', () => { afterAll(() => jest.restoreAllMocks()) it('contains note title when editor is synced', () => { - jest.spyOn(UseApplicationStateModule, 'useApplicationState').mockImplementation((fn) => { - return fn({ - ...mockedCommonAppState, - realtimeStatus: { - isSynced: true - } - } as ApplicationState) + mockAppState({ + ...mockedCommonAppState, + realtimeStatus: { + isSynced: true + } }) const view = render() expect(view.container).toMatchSnapshot() }) it('contains alert when editor is not synced', () => { - jest.spyOn(UseApplicationStateModule, 'useApplicationState').mockImplementation((fn) => { - return fn({ - ...mockedCommonAppState, - realtimeStatus: { - isSynced: false - } - } as ApplicationState) + mockAppState({ + ...mockedCommonAppState, + realtimeStatus: { + isSynced: false + } }) const view = render() expect(view.container).toMatchSnapshot() }) it('contains note title and read-only marker when having only read permissions', () => { - jest.spyOn(UseApplicationStateModule, 'useApplicationState').mockImplementation((fn) => { - return fn({ - ...mockedCommonAppState, - realtimeStatus: { - isSynced: true - }, - user: null - } as ApplicationState) + mockAppState({ + ...mockedCommonAppState, + realtimeStatus: { + isSynced: true + }, + user: null }) const view = render() expect(view.container).toMatchSnapshot() diff --git a/frontend/src/components/common/modals/__snapshots__/deletion-moadal.spec.tsx.snap b/frontend/src/components/common/modals/__snapshots__/deletion-modal.spec.tsx.snap similarity index 100% rename from frontend/src/components/common/modals/__snapshots__/deletion-moadal.spec.tsx.snap rename to frontend/src/components/common/modals/__snapshots__/deletion-modal.spec.tsx.snap diff --git a/frontend/src/components/common/modals/deletion-moadal.spec.tsx b/frontend/src/components/common/modals/deletion-modal.spec.tsx similarity index 87% rename from frontend/src/components/common/modals/deletion-moadal.spec.tsx rename to frontend/src/components/common/modals/deletion-modal.spec.tsx index 38004077c..e6255f71c 100644 --- a/frontend/src/components/common/modals/deletion-moadal.spec.tsx +++ b/frontend/src/components/common/modals/deletion-modal.spec.tsx @@ -4,7 +4,7 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import { mockI18n } from '../../../test-utils/mock-i18n' -import { mockNoteOwnership } from '../../../test-utils/note-ownership' +import { mockNotePermissions } from '../../../test-utils/mock-note-permissions' import { DeletionModal } from './deletion-modal' import { render, screen } from '@testing-library/react' @@ -19,7 +19,7 @@ describe('DeletionModal', () => { }) it('renders correctly with deletionButtonI18nKey', async () => { - mockNoteOwnership('test', 'test') + mockNotePermissions('test', 'test') const onConfirm = jest.fn() render( @@ -31,7 +31,7 @@ describe('DeletionModal', () => { }) it('disables deletion when user is not owner', async () => { - mockNoteOwnership('test2', 'test') + mockNotePermissions('test2', 'test') const onConfirm = jest.fn() render( diff --git a/frontend/src/components/editor-page/editor-pane/hooks/use-disconnect-on-user-login-status-change.spec.tsx b/frontend/src/components/editor-page/editor-pane/hooks/use-disconnect-on-user-login-status-change.spec.tsx index 08b30d19e..9c5c50e52 100644 --- a/frontend/src/components/editor-page/editor-pane/hooks/use-disconnect-on-user-login-status-change.spec.tsx +++ b/frontend/src/components/editor-page/editor-pane/hooks/use-disconnect-on-user-login-status-change.spec.tsx @@ -4,13 +4,12 @@ * SPDX-License-Identifier: AGPL-3.0-only */ import type { LoginUserInfo } from '../../../../api/me/types' -import * as UseApplicationStateModule from '../../../../hooks/common/use-application-state' -import type { ApplicationState } from '../../../../redux/application-state' import { useDisconnectOnUserLoginStatusChange } from './use-disconnect-on-user-login-status-change' import type { MessageTransporter } from '@hedgedoc/commons' import { render } from '@testing-library/react' import React, { Fragment } from 'react' import { Mock } from 'ts-mockery' +import { mockAppState } from '../../../../test-utils/mock-app-state' jest.mock('../../../../hooks/common/use-application-state') @@ -21,11 +20,9 @@ describe('use logout on user change', () => { } const mockUseApplicationState = (userLoggedIn: boolean) => { - jest - .spyOn(UseApplicationStateModule, 'useApplicationState') - .mockImplementation((fn) => - fn(Mock.of({ user: userLoggedIn ? Mock.of({}) : null })) - ) + mockAppState({ + user: userLoggedIn ? Mock.of({}) : null + }) } let disconnectCallback: jest.Mock diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-add-form.spec.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-add-form.spec.tsx index f2df404ef..37b755d54 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-add-form.spec.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-add-form.spec.tsx @@ -7,12 +7,12 @@ import * as AliasModule from '../../../../../../api/alias' import * as NoteDetailsReduxModule from '../../../../../../redux/note-details/methods' import type { NoteDetails } from '../../../../../../redux/note-details/types/note-details' import { mockI18n } from '../../../../../../test-utils/mock-i18n' -import { mockNoteOwnership } from '../../../../../../test-utils/note-ownership' -import * as useUiNotificationsModule from '../../../../../notifications/ui-notification-boundary' +import { mockNotePermissions } from '../../../../../../test-utils/mock-note-permissions' import { AliasesAddForm } from './aliases-add-form' import { act, render, screen } from '@testing-library/react' import testEvent from '@testing-library/user-event' import React from 'react' +import { mockUiNotifications } from '../../../../../../test-utils/mock-ui-notifications' jest.mock('../../../../../../api/alias') jest.mock('../../../../../../redux/note-details/methods') @@ -24,14 +24,10 @@ const addPromise = Promise.resolve({ name: 'mock', primaryAlias: true, noteId: ' describe('AliasesAddForm', () => { beforeEach(async () => { await mockI18n() + mockUiNotifications() jest.spyOn(AliasModule, 'addAlias').mockImplementation(() => addPromise) jest.spyOn(NoteDetailsReduxModule, 'updateMetadata').mockImplementation(() => Promise.resolve()) - jest.spyOn(useUiNotificationsModule, 'useUiNotifications').mockReturnValue({ - showErrorNotification: jest.fn(), - dismissNotification: jest.fn(), - dispatchUiNotification: jest.fn() - }) - mockNoteOwnership('test', 'test', { noteDetails: { id: 'mock-note' } as NoteDetails }) + mockNotePermissions('test', 'test', undefined, { noteDetails: { id: 'mock-note' } as NoteDetails }) }) afterAll(() => { diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.spec.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.spec.tsx index 7c3377057..2cbe12789 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.spec.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list-entry.spec.tsx @@ -7,16 +7,15 @@ import * as AliasModule from '../../../../../../api/alias' import type { Alias } from '../../../../../../api/alias/types' import * as NoteDetailsReduxModule from '../../../../../../redux/note-details/methods' import { mockI18n } from '../../../../../../test-utils/mock-i18n' -import { mockNoteOwnership } from '../../../../../../test-utils/note-ownership' -import * as useUiNotificationsModule from '../../../../../notifications/ui-notification-boundary' +import { mockNotePermissions } from '../../../../../../test-utils/mock-note-permissions' import { AliasesListEntry } from './aliases-list-entry' import { act, render, screen } from '@testing-library/react' import React from 'react' +import { mockUiNotifications } from '../../../../../../test-utils/mock-ui-notifications' jest.mock('../../../../../../api/alias') jest.mock('../../../../../../redux/note-details/methods') jest.mock('../../../../../notifications/ui-notification-boundary') -// This needs to be mocked here in addition to note-ownership.ts, because jest doesn't work otherwise jest.mock('../../../../../../hooks/common/use-application-state') const deletePromise = Promise.resolve() @@ -25,14 +24,10 @@ const markAsPrimaryPromise = Promise.resolve({ name: 'mock', primaryAlias: true, describe('AliasesListEntry', () => { beforeEach(async () => { await mockI18n() + mockUiNotifications() jest.spyOn(AliasModule, 'deleteAlias').mockImplementation(() => deletePromise) jest.spyOn(AliasModule, 'markAliasAsPrimary').mockImplementation(() => markAsPrimaryPromise) jest.spyOn(NoteDetailsReduxModule, 'updateMetadata').mockImplementation(() => Promise.resolve()) - jest.spyOn(useUiNotificationsModule, 'useUiNotifications').mockReturnValue({ - showErrorNotification: jest.fn(), - dismissNotification: jest.fn(), - dispatchUiNotification: jest.fn() - }) }) afterEach(() => { @@ -41,7 +36,7 @@ describe('AliasesListEntry', () => { }) it('renders an AliasesListEntry that is primary', async () => { - mockNoteOwnership('test', 'test') + mockNotePermissions('test', 'test') const testAlias: Alias = { name: 'test-primary', primaryAlias: true, @@ -59,7 +54,7 @@ describe('AliasesListEntry', () => { }) it("disables button in AliasesListEntry if it's primary", () => { - mockNoteOwnership('test2', 'test') + mockNotePermissions('test2', 'test') const testAlias: Alias = { name: 'test-primary', primaryAlias: true, @@ -70,7 +65,7 @@ describe('AliasesListEntry', () => { }) it('renders an AliasesListEntry that is not primary', async () => { - mockNoteOwnership('test', 'test') + mockNotePermissions('test', 'test') const testAlias: Alias = { name: 'test-non-primary', primaryAlias: false, @@ -95,7 +90,7 @@ describe('AliasesListEntry', () => { }) it("disables button in AliasesListEntry if it's not primary", () => { - mockNoteOwnership('test2', 'test') + mockNotePermissions('test2', 'test') const testAlias: Alias = { name: 'test-primary', primaryAlias: false, diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list.spec.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list.spec.tsx index e3e902372..d4e106ed4 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list.spec.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-list.spec.tsx @@ -3,14 +3,13 @@ * * SPDX-License-Identifier: AGPL-3.0-only */ -import type { Alias } from '../../../../../../api/alias/types' -import * as useApplicationStateModule from '../../../../../../hooks/common/use-application-state' import { mockI18n } from '../../../../../../test-utils/mock-i18n' import { AliasesList } from './aliases-list' import type { AliasesListEntryProps } from './aliases-list-entry' import * as AliasesListEntryModule from './aliases-list-entry' import { render } from '@testing-library/react' import React from 'react' +import { mockAppState } from '../../../../../../test-utils/mock-app-state' jest.mock('../../../../../../hooks/common/use-application-state') jest.mock('./aliases-list-entry') @@ -18,23 +17,27 @@ jest.mock('./aliases-list-entry') describe('AliasesList', () => { beforeEach(async () => { await mockI18n() - jest.spyOn(useApplicationStateModule, 'useApplicationState').mockReturnValue([ - { - name: 'a-test', - noteId: 'note-id', - primaryAlias: false - }, - { - name: 'z-test', - noteId: 'note-id', - primaryAlias: false - }, - { - name: 'b-test', - noteId: 'note-id', - primaryAlias: true + mockAppState({ + noteDetails: { + aliases: [ + { + name: 'a-test', + noteId: 'note-id', + primaryAlias: false + }, + { + name: 'z-test', + noteId: 'note-id', + primaryAlias: false + }, + { + name: 'b-test', + noteId: 'note-id', + primaryAlias: true + } + ] } - ] as Alias[]) + }) jest.spyOn(AliasesListEntryModule, 'AliasesListEntry').mockImplementation((({ alias }) => { return ( diff --git a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-modal.spec.tsx b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-modal.spec.tsx index 0f256b33b..16c0b45bf 100644 --- a/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-modal.spec.tsx +++ b/frontend/src/components/editor-page/sidebar/specific-sidebar-entries/aliases-sidebar-entry/aliases-modal/aliases-modal.spec.tsx @@ -6,13 +6,13 @@ import { mockI18n } from '../../../../../../test-utils/mock-i18n' import type { CommonModalProps } from '../../../../../common/modals/common-modal' import * as CommonModalModule from '../../../../../common/modals/common-modal' -import * as useUiNotificationsModule from '../../../../../notifications/ui-notification-boundary' import * as AliasesAddFormModule from './aliases-add-form' import * as AliasesListModule from './aliases-list' import { AliasesModal } from './aliases-modal' import { render } from '@testing-library/react' import type { PropsWithChildren } from 'react' import React from 'react' +import { mockUiNotifications } from '../../../../../../test-utils/mock-ui-notifications' jest.mock('./aliases-list') jest.mock('./aliases-add-form') @@ -22,6 +22,7 @@ jest.mock('../../../../../notifications/ui-notification-boundary') describe('AliasesModal', () => { beforeEach(async () => { await mockI18n() + mockUiNotifications() jest.spyOn(CommonModalModule, 'CommonModal').mockImplementation((({ children }) => { return ( @@ -35,11 +36,6 @@ describe('AliasesModal', () => { jest.spyOn(AliasesAddFormModule, 'AliasesAddForm').mockImplementation((() => { return This is a mock for the AliasesAddForm that is tested separately. }) as React.FC) - jest.spyOn(useUiNotificationsModule, 'useUiNotifications').mockReturnValue({ - showErrorNotification: jest.fn(), - dismissNotification: jest.fn(), - dispatchUiNotification: jest.fn() - }) }) afterAll(() => { diff --git a/frontend/src/redux/dark-mode/reducers.ts b/frontend/src/redux/dark-mode/reducers.ts index 196ea5ac0..47afd8aed 100644 --- a/frontend/src/redux/dark-mode/reducers.ts +++ b/frontend/src/redux/dark-mode/reducers.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import type { DarkModeConfig, DarkModeConfigAction } from './types' import { DarkModeConfigActionType, DarkModePreference } from './types' import type { Reducer } from 'redux' -const initialState: DarkModeConfig = { +export const initialState: DarkModeConfig = { darkModePreference: DarkModePreference.AUTO } diff --git a/frontend/src/redux/editor/reducers.ts b/frontend/src/redux/editor/reducers.ts index dd5cb240a..e8bfa598f 100644 --- a/frontend/src/redux/editor/reducers.ts +++ b/frontend/src/redux/editor/reducers.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -10,7 +10,7 @@ import { Logger } from '../../utils/logger' const logger = new Logger('EditorConfig Local Storage') -const initialState: EditorConfig = { +export const initialState: EditorConfig = { ligatures: true, syncScroll: true, smartPaste: true, diff --git a/frontend/src/redux/realtime/reducers.ts b/frontend/src/redux/realtime/reducers.ts index c8becf160..90eedc7e1 100644 --- a/frontend/src/redux/realtime/reducers.ts +++ b/frontend/src/redux/realtime/reducers.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2022 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import type { RealtimeStatus, RealtimeStatusActions } from './types' import { RealtimeStatusActionType } from './types' import type { Reducer } from 'redux' -const initialState: RealtimeStatus = { +export const initialState: RealtimeStatus = { isSynced: false, isConnected: false, onlineUsers: [], diff --git a/frontend/src/redux/renderer-status/reducers.ts b/frontend/src/redux/renderer-status/reducers.ts index 0f73bbf20..8086d8746 100644 --- a/frontend/src/redux/renderer-status/reducers.ts +++ b/frontend/src/redux/renderer-status/reducers.ts @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2021 The HedgeDoc developers (see AUTHORS file) + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) * * SPDX-License-Identifier: AGPL-3.0-only */ @@ -7,7 +7,7 @@ import type { RendererStatus, RendererStatusActions } from './types' import { RendererStatusActionType } from './types' import type { Reducer } from 'redux' -const initialState: RendererStatus = { +export const initialState: RendererStatus = { rendererReady: false } diff --git a/frontend/src/test-utils/mock-app-state.ts b/frontend/src/test-utils/mock-app-state.ts new file mode 100644 index 000000000..38df25b51 --- /dev/null +++ b/frontend/src/test-utils/mock-app-state.ts @@ -0,0 +1,56 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import * as useApplicationStateModule from '../hooks/common/use-application-state' +import type { ApplicationState } from '../redux/application-state' +import type { DeepPartial } from 'redux' +import { initialState as initialStateDarkMode } from '../redux/dark-mode/reducers' +import { initialState as initialStateEditorConfig } from '../redux/editor/reducers' +import { initialState as initialStateNoteDetails } from '../redux/note-details/initial-state' +import { initialState as initialStateRealtimeStatus } from '../redux/realtime/reducers' +import { initialState as initialStateRendererStatus } from '../redux/renderer-status/reducers' +import type { NoteDetails } from '../redux/note-details/types/note-details' +import type { RealtimeStatus } from '../redux/realtime/types' +import type { HistoryEntryWithOrigin } from '../api/history/types' + +jest.mock('../redux/editor/methods', () => ({ + loadFromLocalStorage: jest.fn().mockReturnValue(undefined) +})) +jest.mock('../hooks/common/use-application-state') + +/** + * Mocks the {@link ApplicationState} for a test. + * When not overriden, it uses the initial state of the reducers. + * + * @param state Overrides for the mocked state + */ +export const mockAppState = (state?: DeepPartial) => { + jest.spyOn(useApplicationStateModule, 'useApplicationState').mockImplementation((fn) => { + return fn({ + darkMode: { + ...initialStateDarkMode, + ...state?.darkMode + }, + editorConfig: { + ...initialStateEditorConfig, + ...state?.editorConfig + }, + history: (state?.history ?? []) as HistoryEntryWithOrigin[], + noteDetails: { + ...initialStateNoteDetails, + ...state?.noteDetails + } as NoteDetails, + realtimeStatus: { + ...initialStateRealtimeStatus, + ...state?.realtimeStatus + } as RealtimeStatus, + rendererStatus: { + ...initialStateRendererStatus, + ...state?.rendererStatus + }, + user: state?.user ?? null + }) + }) +} diff --git a/frontend/src/test-utils/mock-note-permissions.ts b/frontend/src/test-utils/mock-note-permissions.ts new file mode 100644 index 000000000..df9be71de --- /dev/null +++ b/frontend/src/test-utils/mock-note-permissions.ts @@ -0,0 +1,43 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import type { ApplicationState } from '../redux/application-state' +import type { DeepPartial } from 'redux' +import { mockAppState } from './mock-app-state' +import type { LoginUserInfo } from '../api/me/types' +import type { NotePermissions } from '@hedgedoc/commons' + +/** + * Mocks the {@link NotePermissions} field of a note in the {@link ApplicationState }for a test. + * This test-util should not be used alongside {@link mockAppState} to avoid overwriting the mocked state. + * + * @param ownUsername The name of the own user to set in the state (for comparing note ownership) + * @param noteOwner The owner's username of the mocked note + * @param permissions Overrides for the mocked permissions + * @param additionalState Overrides for the overall mocked application state + */ +export const mockNotePermissions = ( + ownUsername: string, + noteOwner: string, + permissions?: DeepPartial, + additionalState?: DeepPartial +) => { + mockAppState({ + ...additionalState, + noteDetails: { + ...additionalState?.noteDetails, + permissions: { + sharedToGroups: [], + sharedToUsers: [], + ...permissions, + owner: noteOwner + } + }, + user: { + ...additionalState?.user, + username: ownUsername + } as LoginUserInfo + }) +} diff --git a/frontend/src/test-utils/mock-ui-notifications.ts b/frontend/src/test-utils/mock-ui-notifications.ts new file mode 100644 index 000000000..0247fd312 --- /dev/null +++ b/frontend/src/test-utils/mock-ui-notifications.ts @@ -0,0 +1,19 @@ +/* + * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) + * + * SPDX-License-Identifier: AGPL-3.0-only + */ +import * as useUiNotificationsModule from '../components/notifications/ui-notification-boundary' + +jest.mock('../components/notifications/ui-notification-boundary') + +/** + * Mocks the {@link useUiNotifications} hook with stub functions for tests. + */ +export const mockUiNotifications = () => { + jest.spyOn(useUiNotificationsModule, 'useUiNotifications').mockReturnValue({ + showErrorNotification: jest.fn(), + dismissNotification: jest.fn(), + dispatchUiNotification: jest.fn() + }) +} diff --git a/frontend/src/test-utils/note-ownership.ts b/frontend/src/test-utils/note-ownership.ts deleted file mode 100644 index 23276dad3..000000000 --- a/frontend/src/test-utils/note-ownership.ts +++ /dev/null @@ -1,30 +0,0 @@ -/* - * SPDX-FileCopyrightText: 2023 The HedgeDoc developers (see AUTHORS file) - * - * SPDX-License-Identifier: AGPL-3.0-only - */ -import * as useApplicationStateModule from '../hooks/common/use-application-state' -import type { ApplicationState } from '../redux/application-state' - -jest.mock('../hooks/common/use-application-state') -export const mockNoteOwnership = ( - ownUsername: string, - noteOwner: string, - additionalState?: Partial -) => { - jest.spyOn(useApplicationStateModule, 'useApplicationState').mockImplementation((fn) => { - return fn({ - ...additionalState, - noteDetails: { - ...additionalState?.noteDetails, - permissions: { - owner: noteOwner - } - }, - user: { - ...additionalState?.user, - username: ownUsername - } - } as ApplicationState) - }) -}