Merge pull request #41709 from nextcloud/fix/files-copy-move-action

fix(files): Reverse logic to prevent copy to itself
pull/41782/head
Eduardo Morales 2023-11-27 13:15:50 +07:00 committed by GitHub
commit f6059064f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 129 additions and 7 deletions

@ -80,7 +80,13 @@ export const handleCopyMoveNodeTo = async (node: Node, destination: Folder, meth
throw new Error(t('files', 'This file/folder is already in that directory'))
}
if (node.path.startsWith(destination.path)) {
/**
* Example:
* node: /foo/bar/file.txt -> path = /foo/bar
* destination: /foo
* Allow move of /foo does not start with /foo/bar so allow
*/
if (destination.path.startsWith(node.path)) {
throw new Error(t('files', 'You cannot move a file/folder onto itself or into a subfolder of itself'))
}

@ -0,0 +1,116 @@
/**
* @copyright Copyright (c) 2023 Ferdinand Thiessen <opensource@fthiessen.de>
*
* @author Ferdinand Thiessen <opensource@fthiessen.de>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
const getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${filename}"]`)
const getActionsForFile = (filename: string) => getRowForFile(filename).find('[data-cy-files-list-row-actions]')
const getActionButtonForFile = (filename: string) => getActionsForFile(filename).find('button[aria-label="Actions"]')
const triggerActionForFile = (filename: string, actionId: string) => {
getActionButtonForFile(filename).click()
cy.get(`[data-cy-files-list-row-action="${actionId}"] > button`).should('exist').click()
}
describe('Files: Move or copy files', { testIsolation: true }, () => {
let currentUser
beforeEach(() => {
cy.createRandomUser().then((user) => {
currentUser = user
cy.login(user)
})
})
afterEach(() => {
// nice to have cleanup
cy.deleteUser(currentUser)
})
it('Can copy a file to new folder', () => {
cy.uploadContent(currentUser, new Blob(), 'text/plain', '/original.txt')
.mkdir(currentUser, '/new-folder')
cy.login(currentUser)
cy.visit('/apps/files')
getRowForFile('original.txt').should('be.visible')
triggerActionForFile('original.txt', 'move-copy')
// select new folder
cy.get('.file-picker [data-filename="new-folder"]').should('be.visible').click()
// click copy
cy.get('.file-picker').contains('button', 'Copy to new-folder').should('be.visible').click()
getRowForFile('new-folder').find('[data-cy-files-list-row-name-link]').click()
cy.url().should('contain', 'dir=/new-folder')
getRowForFile('original.txt').should('be.visible')
getRowForFile('new-folder').should('not.exist')
})
it('Can move a file to new folder', () => {
cy.uploadContent(currentUser, new Blob(), 'text/plain', '/original.txt')
.mkdir(currentUser, '/new-folder')
cy.login(currentUser)
cy.visit('/apps/files')
getRowForFile('original.txt').should('be.visible')
triggerActionForFile('original.txt', 'move-copy')
// select new folder
cy.get('.file-picker [data-filename="new-folder"]').should('be.visible').click()
// click copy
cy.get('.file-picker').contains('button', 'Move to new-folder').should('be.visible').click()
// wait until visible again
getRowForFile('new-folder').should('be.visible')
// original should be moved -> not exist anymore
getRowForFile('original.txt').should('not.exist')
getRowForFile('new-folder').should('be.visible').find('[data-cy-files-list-row-name-link]').click()
cy.url().should('contain', 'dir=/new-folder')
getRowForFile('original.txt').should('be.visible')
getRowForFile('new-folder').should('not.exist')
})
it('Can move a file to its parent folder', () => {
cy.mkdir(currentUser, '/new-folder')
cy.uploadContent(currentUser, new Blob(), 'text/plain', '/new-folder/original.txt')
cy.login(currentUser)
cy.visit('/apps/files')
getRowForFile('new-folder').should('be.visible').find('[data-cy-files-list-row-name-link]').click()
cy.url().should('contain', 'dir=/new-folder')
getRowForFile('original.txt').should('be.visible')
triggerActionForFile('original.txt', 'move-copy')
// select new folder
cy.get('.file-picker a[title="Home"]').should('be.visible').click()
// click move
cy.get('.file-picker').contains('button', 'Move').should('be.visible').click()
// wait until visible again
cy.get('main').contains('No files in here').should('be.visible')
// original should be moved -> not exist anymore
getRowForFile('original.txt').should('not.exist')
cy.visit('/apps/files')
getRowForFile('new-folder').should('be.visible')
getRowForFile('original.txt').should('be.visible')
})
})

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long