fix(files_trashbin): disable bulk download for trashbin

The backend does not allow bulk download within the trashbin,
so we need to disable this also on the frontend.

Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
pull/51210/head
Ferdinand Thiessen 2025-02-28 18:13:24 +07:00
parent 00eb733d2c
commit 9458225989
No known key found for this signature in database
GPG Key ID: 45FAE7268762B400
3 changed files with 97 additions and 4 deletions

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

@ -4,7 +4,7 @@
*/
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 getRowForFile = (filename: string) => cy.get(`[data-cy-files-list-row-name="${CSS.escape(filename)}"]`)
@ -15,9 +15,22 @@ export const getActionsForFile = (filename: string) => getRowForFile(filename).f
export const getActionButtonForFileId = (fileid: number) => getActionsForFileId(fileid).findByRole('button', { name: 'Actions' })
export const getActionButtonForFile = (filename: string) => getActionsForFile(filename).findByRole('button', { name: 'Actions' })
export const searchForActionInRow = (row: JQuery<HTMLElement>, actionId: string): Cypress.Chainable<JQuery<HTMLElement>> => {
const action = row.find(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
if (action.length > 0) {
cy.log('Found action in row')
return cy.wrap(action)
}
// Else look in the action menu
const menuButtonId = row.find('button[aria-controls]').attr('aria-controls')
return cy.get(`#${menuButtonId} [data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
}
export const getActionEntryForFileId = (fileid: number, actionId: string) => {
return cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
}
export const getActionEntryForFile = (filename: string, actionId: string) => {
return cy.get(`[data-cy-files-list-row-action="${CSS.escape(actionId)}"]`)
}
@ -213,7 +226,11 @@ export const deleteFileWithRequest = (user: User, path: string) => {
const requestToken = body.token
cy.request({
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: {
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')
})
})