/*! * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors * SPDX-License-Identifier: AGPL-3.0-or-later */ import { getRowForFile } from '../../files/FilesUtils.ts' import { openSharingPanel } from '../FilesSharingUtils.ts' describe('files_sharing: Public share - File drop', { testIsolation: true }, () => { let shareUrl: string let user: string const shareName = 'shared' before(() => { cy.createRandomUser().then(($user) => { user = $user.userId cy.mkdir($user, `/${shareName}`) cy.uploadContent($user, new Blob(['content']), 'text/plain', `/${shareName}/foo.txt`) cy.login($user) // open the files app cy.visit('/apps/files') // open the sidebar openSharingPanel(shareName) // create the share cy.intercept('POST', '**/ocs/v2.php/apps/files_sharing/api/v1/shares').as('createShare') cy.findByRole('button', { name: 'Create a new share link' }) .click() // extract the link cy.wait('@createShare').should(({ response }) => { const { ocs } = response?.body ?? {} shareUrl = ocs?.data.url expect(shareUrl).to.match(/^http:\/\//) }) // Update the share to be a file drop cy.findByRole('list', { name: 'Link shares' }) .findAllByRole('listitem') .first() .findByRole('button', { name: /Actions/i }) .click() cy.findByRole('menuitem', { name: /Customize link/i }) .should('be.visible') .click() cy.get('[data-cy-files-sharing-share-permissions-bundle]') .should('be.visible') cy.get('[data-cy-files-sharing-share-permissions-bundle="file-drop"]') .click() // save the update cy.intercept('PUT', '**/ocs/v2.php/apps/files_sharing/api/v1/shares/*').as('updateShare') cy.findByRole('button', { name: 'Update share' }) .click() cy.wait('@updateShare') }) }) beforeEach(() => { cy.logout() cy.visit(shareUrl) }) it('Cannot see share content', () => { cy.contains(`Upload files to ${shareName}`) .should('be.visible') // foo exists cy.userFileExists(user, `${shareName}/foo.txt`).should('be.gt', 0) // but is not visible getRowForFile('foo.txt') .should('not.exist') }) it('Can only see upload files and upload folders menu entries', () => { cy.contains(`Upload files to ${shareName}`) .should('be.visible') cy.findByRole('button', { name: 'New' }) .should('be.visible') .click() // See upload actions cy.findByRole('menuitem', { name: 'Upload files' }) .should('be.visible') cy.findByRole('menuitem', { name: 'Upload folders' }) .should('be.visible') // But no other cy.findByRole('menu') .findAllByRole('menuitem') .should('have.length', 2) }) it('Can only see dedicated upload button', () => { cy.contains(`Upload files to ${shareName}`) .should('be.visible') cy.findByRole('button', { name: 'Upload' }) .should('be.visible') .click() // See upload actions cy.findByRole('menuitem', { name: 'Upload files' }) .should('be.visible') cy.findByRole('menuitem', { name: 'Upload folders' }) .should('be.visible') // But no other cy.findByRole('menu') .findAllByRole('menuitem') .should('have.length', 2) }) it('Can upload files', () => { cy.contains(`Upload files to ${shareName}`) .should('be.visible') const { promise, resolve } = Promise.withResolvers() cy.intercept('PUT', '**/public.php/dav/files/**', (request) => { if (request.url.includes('first.txt')) { // just continue the first one request.continue() } else { // We delay the second one until we checked that the progress bar is visible request.on('response', async () => { await promise }) } }).as('uploadFile') cy.get('[data-cy-files-sharing-file-drop] input[type="file"]') .should('exist') .selectFile([ { fileName: 'first.txt', contents: Buffer.from('8 bytes!') }, { fileName: 'second.md', contents: Buffer.from('x'.repeat(128)) }, ], { force: true }) cy.wait('@uploadFile') cy.findByRole('progressbar') .should('be.visible') .and((el) => { expect(Number.parseInt(el.attr('value') ?? '0')).be.gte(50) }) // continue second request .then(() => resolve(null)) cy.wait('@uploadFile') // Check files uploaded cy.userFileExists(user, `${shareName}/first.txt`).should('eql', 8) cy.userFileExists(user, `${shareName}/second.md`).should('eql', 128) }) describe('Terms of service', { testIsolation: true }, () => { before(() => cy.runOccCommand('config:app:set --value "TEST: Some disclaimer text" --type string core shareapi_public_link_disclaimertext')) beforeEach(() => cy.visit(shareUrl)) after(() => cy.runOccCommand('config:app:delete core shareapi_public_link_disclaimertext')) it('shows ToS on file-drop view', () => { cy.contains(`Upload files to ${shareName}`) .should('be.visible') .should('contain.text', 'agree to the terms of service') cy.findByRole('button', { name: /Terms of service/i }) .should('be.visible') .click() cy.findByRole('dialog', { name: 'Terms of service' }) .should('contain.text', 'TEST: Some disclaimer text') // close .findByRole('button', { name: 'Close' }) .click() cy.findByRole('dialog', { name: 'Terms of service' }) .should('not.exist') }) }) })