From 13dd7ac194787fb7f9a7732757d6ce605a13cf61 Mon Sep 17 00:00:00 2001 From: Jannik Stehle Date: Fri, 8 Dec 2023 09:23:02 +0100 Subject: [PATCH] fix: selection after space duplication Spaces are listed as regular resources on the projects page, hence we need to make sure to insert duplicated spaces as such. --- .../unreleased/enhancement-duplicate-space | 1 + .../spaces/useSpaceActionsDuplicate.ts | 9 ++++ .../spaces/useSpaceActionsDuplicate.spec.ts | 46 +++++++++++++------ 3 files changed, 42 insertions(+), 14 deletions(-) diff --git a/changelog/unreleased/enhancement-duplicate-space b/changelog/unreleased/enhancement-duplicate-space index d8d1da53e9f..3428fbf9ea2 100644 --- a/changelog/unreleased/enhancement-duplicate-space +++ b/changelog/unreleased/enhancement-duplicate-space @@ -5,4 +5,5 @@ This includes copying the contents, the space name, subtitle, description, and i like tags or members. https://github.com/owncloud/web/pull/10024 +https://github.com/owncloud/web/pull/10132 https://github.com/owncloud/web/issues/10016 diff --git a/packages/web-pkg/src/composables/actions/spaces/useSpaceActionsDuplicate.ts b/packages/web-pkg/src/composables/actions/spaces/useSpaceActionsDuplicate.ts index 5a92755c405..c30fed1c751 100644 --- a/packages/web-pkg/src/composables/actions/spaces/useSpaceActionsDuplicate.ts +++ b/packages/web-pkg/src/composables/actions/spaces/useSpaceActionsDuplicate.ts @@ -11,6 +11,8 @@ import { buildSpace, isProjectSpaceResource } from '@ownclouders/web-client/src/ import { Drive } from '@ownclouders/web-client/src/generated' import { resolveFileNameDuplicate } from '../../../helpers' import PQueue from 'p-queue' +import { useRouter } from '../../router' +import { isLocationSpacesActive } from '../../../router' export const useSpaceActionsDuplicate = ({ store @@ -18,11 +20,14 @@ export const useSpaceActionsDuplicate = ({ store?: Store } = {}) => { store = store || useStore() + const router = useRouter() const { $gettext } = useGettext() const ability = useAbility() const clientService = useClientService() const loadingService = useLoadingService() + const isProjectsLocation = isLocationSpacesActive(router, 'files-spaces-projects') + const duplicateSpace = async (existingSpace: SpaceResource) => { const projectSpaces: SpaceResource[] = store.getters['runtime/spaces/spaces'].filter( (space: SpaceResource) => isProjectSpaceResource(space) @@ -96,6 +101,10 @@ export const useSpaceActionsDuplicate = ({ } store.commit('runtime/spaces/UPSERT_SPACE', duplicatedSpace) + if (isProjectsLocation) { + store.commit('Files/UPSERT_RESOURCE', duplicatedSpace) + } + store.dispatch('showMessage', { title: $gettext('Space "%{space}" was duplicated successfully', { space: existingSpace.name diff --git a/packages/web-pkg/tests/unit/composables/actions/spaces/useSpaceActionsDuplicate.spec.ts b/packages/web-pkg/tests/unit/composables/actions/spaces/useSpaceActionsDuplicate.spec.ts index 8169047d709..1580d91b74b 100644 --- a/packages/web-pkg/tests/unit/composables/actions/spaces/useSpaceActionsDuplicate.spec.ts +++ b/packages/web-pkg/tests/unit/composables/actions/spaces/useSpaceActionsDuplicate.spec.ts @@ -1,5 +1,5 @@ import { useSpaceActionsDuplicate } from '../../../../../src/composables/actions' -import { SpaceResource } from '@ownclouders/web-client/src/helpers' +import { AbilityRule, SpaceResource } from '@ownclouders/web-client/src/helpers' import { mock } from 'jest-mock-extended' import { createStore, @@ -24,14 +24,14 @@ const spaces = [ describe('restore', () => { describe('isEnabled property', () => { it('should be false when no resource given', () => { - const { wrapper } = getWrapper({ + getWrapper({ setup: ({ actions }, { storeOptions }) => { expect(unref(actions)[0].isEnabled({ resources: [] })).toBe(false) } }) }) it('should be false when the space is disabled', () => { - const { wrapper } = getWrapper({ + getWrapper({ setup: ({ actions }, { storeOptions }) => { expect( unref(actions)[0].isEnabled({ @@ -47,7 +47,7 @@ describe('restore', () => { }) }) it('should be false when the space is no project space', () => { - const { wrapper } = getWrapper({ + getWrapper({ setup: ({ actions }, { storeOptions }) => { expect( unref(actions)[0].isEnabled({ @@ -63,7 +63,7 @@ describe('restore', () => { }) }) it('should be false when the current user can not create spaces', () => { - const { wrapper } = getWrapper({ + getWrapper({ abilities: [], setup: ({ actions }, { storeOptions }) => { expect( @@ -75,7 +75,7 @@ describe('restore', () => { }) }) it('should be true when the current user can create spaces', () => { - const { wrapper } = getWrapper({ + getWrapper({ setup: ({ actions }, { storeOptions }) => { expect( unref(actions)[0].isEnabled({ @@ -90,9 +90,9 @@ describe('restore', () => { }) }) describe('method "duplicateSpace"', () => { - it('should show error message on error', async () => { + it('should show error message on error', () => { jest.spyOn(console, 'error').mockImplementation(() => undefined) - const { wrapper } = getWrapper({ + getWrapper({ setup: async ({ duplicateSpace }, { storeOptions, clientService }) => { clientService.graphAuthenticated.drives.createDrive.mockRejectedValue(new Error()) await duplicateSpace(spaces[0]) @@ -100,9 +100,8 @@ describe('restore', () => { } }) }) - it('should show message on success', async () => { - jest.spyOn(console, 'error').mockImplementation(() => undefined) - const { wrapper } = getWrapper({ + it('should show message on success', () => { + getWrapper({ setup: async ({ duplicateSpace }, { storeOptions, clientService }) => { clientService.graphAuthenticated.drives.createDrive.mockResolvedValue( mockAxiosResolve({ @@ -127,12 +126,30 @@ describe('restore', () => { } }) }) + it('should upsert a space as resource on the projects page', () => { + getWrapper({ + currentRouteName: 'files-spaces-projects', + setup: async ({ duplicateSpace }, { storeOptions, clientService }) => { + clientService.graphAuthenticated.drives.createDrive.mockResolvedValue( + mockAxiosResolve({ + id: '1', + name: 'Moon (1)', + special: [] + }) + ) + clientService.webdav.listFiles.mockResolvedValue({ children: [] } as ListFilesResult) + await duplicateSpace(spaces[0]) + expect(storeOptions.modules.Files.mutations.UPSERT_RESOURCE).toHaveBeenCalled() + } + }) + }) }) }) function getWrapper({ setup, - abilities = [{ action: 'create-all', subject: 'Drive' }] + abilities = [{ action: 'create-all', subject: 'Drive' }], + currentRouteName = 'files-spaces-generic' }: { setup: ( instance: ReturnType, @@ -144,7 +161,8 @@ function getWrapper({ clientService: ReturnType['$clientService'] } ) => void - abilities? + abilities?: AbilityRule[] + currentRouteName?: string }) { const storeOptions = { ...defaultStoreMockOptions @@ -152,7 +170,7 @@ function getWrapper({ storeOptions.modules.runtime.modules.spaces.getters.spaces = jest.fn(() => spaces) const store = createStore(storeOptions) const mocks = defaultComponentMocks({ - currentRoute: mock({ name: 'files-spaces-projects' }) + currentRoute: mock({ name: currentRouteName }) }) return { mocks,