Merge pull request #51146 from nextcloud/fix/files-trash-download

fix(files_trashbin): disable bulk download for trashbin
pull/51211/head
Kate 2025-03-03 16:50:34 +07:00 committed by GitHub
commit 2582a55300
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 88 additions and 8 deletions

@ -2,7 +2,8 @@
* SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors * SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later * SPDX-License-Identifier: AGPL-3.0-or-later
*/ */
import { FileAction, Node, FileType, DefaultType } from '@nextcloud/files' import type { Node, View } from '@nextcloud/files'
import { FileAction, FileType, DefaultType } from '@nextcloud/files'
import { t } from '@nextcloud/l10n' import { t } from '@nextcloud/l10n'
import { isDownloadable } from '../utils/permissions' import { isDownloadable } from '../utils/permissions'
@ -75,7 +76,7 @@ export const action = new FileAction({
displayName: () => t('files', 'Download'), displayName: () => t('files', 'Download'),
iconSvgInline: () => ArrowDownSvg, iconSvgInline: () => ArrowDownSvg,
enabled(nodes: Node[]) { enabled(nodes: Node[], view: View) {
if (nodes.length === 0) { if (nodes.length === 0) {
return false return false
} }
@ -85,6 +86,11 @@ export const action = new FileAction({
return false return false
} }
// Trashbin does not allow batch download
if (nodes.length > 1 && view.id === 'trashbin') {
return false
}
return nodes.every(isDownloadable) return nodes.every(isDownloadable)
}, },

@ -4,7 +4,7 @@
*/ */
import type { User } from '@nextcloud/cypress' import type { User } from '@nextcloud/cypress'
import { ACTION_COPY_MOVE } from "../../../apps/files/src/actions/moveOrCopyAction" import { ACTION_COPY_MOVE } from '../../../apps/files/src/actions/moveOrCopyAction.ts'
export const getRowForFileId = (fileid: number) => cy.get(`[data-cy-files-list-row-fileid="${fileid}"]`) export const getRowForFileId = (fileid: number) => cy.get(`[data-cy-files-list-row-fileid="${fileid}"]`)
export const getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${CSS.escape(filename)}"]`) export const getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${CSS.escape(filename)}"]`)
@ -15,7 +15,7 @@ export const getActionsForFile = (filename: string) => getRowForFile(filename).f
export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' }) export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' })
export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' }) export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' })
const searchForActionInRow = (row: JQuery<HTMLElement>, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => { const searchForActionInRow = (row: JQuery<HTMLElement>, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => {
const action = row.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`) const action = row.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
if (action.length > 0) { if (action.length > 0) {
cy.log('Found action in row') cy.log('Found action in row')
@ -229,7 +229,11 @@ export const deleteFileWithRequest = (user: User, path: string) => {
const requestToken = body.token const requestToken = body.token
cy.request({ cy.request({
method: 'DELETE', method: 'DELETE',
url: `${Cypress.env('baseUrl')}/remote.php/dav/files/${user.userId}` + path, url: `${Cypress.env('baseUrl')}/remote.php/dav/files/${user.userId}${path}`,
auth: {
user: user.userId,
password: user.password,
},
headers: { headers: {
requestToken, requestToken,
}, },

@ -0,0 +1,70 @@
/*!
* SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors
* SPDX-License-Identifier: AGPL-3.0-or-later
*/
import type { User } from '@nextcloud/cypress'
// @ts-expect-error package has wrong typings
import { deleteDownloadsFolderBeforeEach } from 'cypress-delete-downloads-folder'
import { deleteFileWithRequest, getRowForFileId, selectAllFiles, triggerActionForFileId } from '../files/FilesUtils.ts'
describe('files_trashbin: download files', { testIsolation: true }, () => {
let user: User
const fileids: number[] = []
deleteDownloadsFolderBeforeEach()
before(() => {
cy.createRandomUser().then(($user) => {
user = $user
cy.uploadContent(user, new Blob(['<content>']), 'text/plain', '/file.txt')
.then(({ headers }) => fileids.push(Number.parseInt(headers['oc-fileid'])))
.then(() => deleteFileWithRequest(user, '/file.txt'))
cy.uploadContent(user, new Blob(['<content>']), 'text/plain', '/other-file.txt')
.then(({ headers }) => fileids.push(Number.parseInt(headers['oc-fileid'])))
.then(() => deleteFileWithRequest(user, '/other-file.txt'))
})
})
beforeEach(() => {
cy.login(user)
cy.visit('/apps/files/trashbin')
})
it('can download file', () => {
getRowForFileId(fileids[0]).should('be.visible')
getRowForFileId(fileids[1]).should('be.visible')
triggerActionForFileId(fileids[0], 'download')
const downloadsFolder = Cypress.config('downloadsFolder')
cy.readFile(`${downloadsFolder}/file.txt`, { timeout: 15000 })
.should('exist')
.and('have.length.gt', 8)
.and('equal', '<content>')
})
it('can download a file using default action', () => {
getRowForFileId(fileids[0])
.should('be.visible')
.findByRole('button', { name: 'Download' })
.click({ force: true })
const downloadsFolder = Cypress.config('downloadsFolder')
cy.readFile(`${downloadsFolder}/file.txt`, { timeout: 15000 })
.should('exist')
.and('have.length.gt', 8)
.and('equal', '<content>')
})
// TODO: Fix this as this dependens on the webdav zip folder plugin not working for trashbin (and never worked with old NC legacy download ajax as well)
it('does not offer bulk download', () => {
cy.get('[data-cy-files-list-row-checkbox]').should('have.length', 2)
selectAllFiles()
cy.get('.files-list__selected').should('have.text', '2 selected')
cy.get('[data-cy-files-list-selection-action="restore"]').should('be.visible')
cy.get('[data-cy-files-list-selection-action="download"]').should('not.exist')
})
})

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long