Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[stable30] fix(files): Correctly check for already used names when creating new folder #47547

Merged
merged 2 commits into from
Aug 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion apps/files/src/views/FilesList.vue
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ export default defineComponent({
// as the path is allowed to be undefined we need to normalize the path ('//' to '/')
const normalizedPath = normalize(`${this.currentFolder?.path ?? ''}/${path ?? ''}`)
// Try cache first
const nodes = this.filesStore.getNodesByPath(view.id, path)
const nodes = this.filesStore.getNodesByPath(view.id, normalizedPath)
if (nodes.length > 0) {
return nodes
}
Expand Down
16 changes: 16 additions & 0 deletions cypress/e2e/files/FilesUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,3 +136,19 @@ export const createFolder = (folderName: string) => {

getRowForFile(folderName).should('be.visible')
}

/**
* Check validity of an input element
* @param validity The expected validity message (empty string means it is valid)
* @example
* ```js
* cy.findByRole('textbox')
* .should(haveValidity(/must not be empty/i))
* ```
*/
export const haveValidity = (validity: string | RegExp) => {
if (typeof validity === 'string') {
return (el: JQuery<HTMLElement>) => expect((el.get(0) as HTMLInputElement).validationMessage).to.equal(validity)
}
return (el: JQuery<HTMLElement>) => expect((el.get(0) as HTMLInputElement).validationMessage).to.match(validity)
}
9 changes: 1 addition & 8 deletions cypress/e2e/files/files-renaming.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,7 @@
*/

import type { User } from '@nextcloud/cypress'
import { getRowForFile, triggerActionForFile } from './FilesUtils'

const haveValidity = (validity: string | RegExp) => {
if (typeof validity === 'string') {
return (el: JQuery<HTMLElement>) => expect((el.get(0) as HTMLInputElement).validationMessage).to.equal(validity)
}
return (el: JQuery<HTMLElement>) => expect((el.get(0) as HTMLInputElement).validationMessage).to.match(validity)
}
import { getRowForFile, haveValidity, triggerActionForFile } from './FilesUtils'

describe('files: Rename nodes', { testIsolation: true }, () => {
let user: User
Expand Down
123 changes: 123 additions & 0 deletions cypress/e2e/files/new-menu.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
/**
* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/

import { createFolder, getRowForFile, haveValidity, navigateToFolder } from './FilesUtils'

describe('"New"-menu', { testIsolation: true }, () => {

beforeEach(() => {
cy.createRandomUser().then(($user) => {
cy.login($user)
cy.visit('/apps/files')
})
})

it('Create new folder', () => {
// Click the "new" button
cy.get('[data-cy-upload-picker]')
.findByRole('button', { name: 'New' })
.should('be.visible')
.click()
// Click the "new folder" menu entry
cy.findByRole('menuitem', { name: 'New folder' })
.should('be.visible')
.click()
// Create a folder
cy.intercept('MKCOL', '**/remote.php/dav/files/**').as('mkdir')
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.type('A new folder{enter}')
cy.wait('@mkdir')
// See the folder is visible
getRowForFile('A new folder')
.should('be.visible')
})

it('Does not allow creating forbidden folder names', () => {
// Click the "new" button
cy.get('[data-cy-upload-picker]')
.findByRole('button', { name: 'New' })
.should('be.visible')
.click()
// Click the "new folder" menu entry
cy.findByRole('menuitem', { name: 'New folder' })
.should('be.visible')
.click()
// enter folder name
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.type('.htaccess')
// See that input has invalid state set
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.should(haveValidity(/reserved name/i))
// See that it can not create
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('button', { name: 'Create' })
.should('be.disabled')
})

it('Does not allow creating folders with already existing names', () => {
createFolder('already exists')
// Click the "new" button
cy.get('[data-cy-upload-picker]')
.findByRole('button', { name: 'New' })
.should('be.visible')
.click()
// Click the "new folder" menu entry
cy.findByRole('menuitem', { name: 'New folder' })
.should('be.visible')
.click()
// enter folder name
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.type('already exists')
// See that input has invalid state set
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.should(haveValidity(/already in use/i))
// See that it can not create
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('button', { name: 'Create' })
.should('be.disabled')
})

/**
* Regression test of https://github.com/nextcloud/server/issues/47530
*/
it('Create same folder in child folder', () => {
// setup other folders
createFolder('folder')
createFolder('other folder')
navigateToFolder('folder')

// Click the "new" button
cy.get('[data-cy-upload-picker]')
.findByRole('button', { name: 'New' })
.should('be.visible')
.click()
// Click the "new folder" menu entry
cy.findByRole('menuitem', { name: 'New folder' })
.should('be.visible')
.click()
// enter folder name
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.type('other folder')
// See that creating is allowed
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('textbox', { name: 'Folder name' })
.should(haveValidity(''))
// can create
cy.intercept('MKCOL', '**/remote.php/dav/files/**').as('mkdir')
cy.findByRole('dialog', { name: /create new folder/i })
.findByRole('button', { name: 'Create' })
.click()
cy.wait('@mkdir')
// see it is created
getRowForFile('other folder')
.should('be.visible')
})
})
4 changes: 2 additions & 2 deletions dist/files-main.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/files-main.js.map

Large diffs are not rendered by default.

Loading