diff options
author | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-02-28 21:50:47 +0100 |
---|---|---|
committer | Ferdinand Thiessen <opensource@fthiessen.de> | 2025-03-05 08:31:25 +0100 |
commit | 4eb2c45c33d9ea03d994c283abcf8dc3f74b083d (patch) | |
tree | e9f9a90ee4d919edcece11138f93ba1a3a96ac41 /cypress | |
parent | a4760ef906ba897f19669898466bdb5c48703ec0 (diff) | |
download | nextcloud-server-4eb2c45c33d9ea03d994c283abcf8dc3f74b083d.tar.gz nextcloud-server-4eb2c45c33d9ea03d994c283abcf8dc3f74b083d.zip |
fix(files_sharing): ensure downloaded file has the correct filename
Single file shares use the share token as source name, so we need to use
the displayname. To do so we need to set the download attribute to the
displayname of the file to download.
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
Diffstat (limited to 'cypress')
-rw-r--r-- | cypress/e2e/files_sharing/public-share/download-files.cy.ts | 240 | ||||
-rw-r--r-- | cypress/e2e/files_sharing/public-share/setup-public-share.ts | 6 |
2 files changed, 142 insertions, 104 deletions
diff --git a/cypress/e2e/files_sharing/public-share/download-files.cy.ts b/cypress/e2e/files_sharing/public-share/download-files.cy.ts index a21361bd8b9..59542f080a8 100644 --- a/cypress/e2e/files_sharing/public-share/download-files.cy.ts +++ b/cypress/e2e/files_sharing/public-share/download-files.cy.ts @@ -4,136 +4,170 @@ */ // @ts-expect-error The package is currently broken - but works... import { deleteDownloadsFolderBeforeEach } from 'cypress-delete-downloads-folder' - +import { createShare, getShareUrl, setupPublicShare, type ShareContext } from './setup-public-share.ts' +import { getRowForFile, getRowForFileId, triggerActionForFile, triggerActionForFileId } from '../../files/FilesUtils.ts' import { zipFileContains } from '../../../support/utils/assertions.ts' -import { getRowForFile, triggerActionForFile } from '../../files/FilesUtils.ts' -import { getShareUrl, setupPublicShare } from './setup-public-share.ts' describe('files_sharing: Public share - downloading files', { testIsolation: true }, () => { - before(() => setupPublicShare()) - - deleteDownloadsFolderBeforeEach() - - beforeEach(() => { - cy.logout() - cy.visit(getShareUrl()) - }) - - it('Can download all files', () => { - getRowForFile('foo.txt').should('be.visible') - - cy.get('[data-cy-files-list]').within(() => { - cy.findByRole('checkbox', { name: /Toggle selection for all files/i }) - .should('exist') - .check({ force: true }) - - // see that two files are selected - cy.contains('2 selected').should('be.visible') + // in general there is no difference except downloading + // as file shares have the source of the share token but a different displayname + describe('file share', () => { + let fileId: number + + before(() => { + cy.createRandomUser().then((user) => { + const context: ShareContext = { user } + cy.uploadContent(user, new Blob(['<content>foo</content>']), 'text/plain', '/file.txt') + .then(({ headers }) => { fileId = Number.parseInt(headers['oc-fileid']) }) + cy.login(user) + createShare(context, 'file.txt') + .then(() => cy.logout()) + .then(() => cy.visit(context.url!)) + }) + }) - // click download - cy.findByRole('button', { name: 'Download (selected)' }) + it('can download the file', () => { + getRowForFileId(fileId) .should('be.visible') - .click() - - // check a file is downloaded + getRowForFileId(fileId) + .find('[data-cy-files-list-row-name]') + .should((el) => expect(el.text()).to.match(/file\s*\.txt/)) // extension is sparated so there might be a space between + triggerActionForFileId(fileId, 'download') + // check a file is downloaded with the correct name const downloadsFolder = Cypress.config('downloadsFolder') - cy.readFile(`${downloadsFolder}/download.zip`, null, { timeout: 15000 }) + cy.readFile(`${downloadsFolder}/file.txt`, 'utf-8', { timeout: 15000 }) .should('exist') - .and('have.length.gt', 30) - // Check all files are included - .and(zipFileContains([ - 'foo.txt', - 'subfolder/', - 'subfolder/bar.txt', - ])) + .and('have.length.gt', 5) + .and('contain', '<content>foo</content>') }) }) - it('Can download selected files', () => { - getRowForFile('subfolder') - .should('be.visible') + describe('folder share', () => { + before(() => setupPublicShare()) - cy.get('[data-cy-files-list]').within(() => { - getRowForFile('subfolder') - .findByRole('checkbox') - .check({ force: true }) + deleteDownloadsFolderBeforeEach() + + beforeEach(() => { + cy.logout() + cy.visit(getShareUrl()) + }) - // see that two files are selected - cy.contains('1 selected').should('be.visible') + it('Can download all files', () => { + getRowForFile('foo.txt').should('be.visible') + + cy.get('[data-cy-files-list]').within(() => { + cy.findByRole('checkbox', { name: /Toggle selection for all files/i }) + .should('exist') + .check({ force: true }) + + // see that two files are selected + cy.contains('2 selected').should('be.visible') + + // click download + cy.findByRole('button', { name: 'Download (selected)' }) + .should('be.visible') + .click() + + // check a file is downloaded + const downloadsFolder = Cypress.config('downloadsFolder') + cy.readFile(`${downloadsFolder}/download.zip`, null, { timeout: 15000 }) + .should('exist') + .and('have.length.gt', 30) + // Check all files are included + .and(zipFileContains([ + 'foo.txt', + 'subfolder/', + 'subfolder/bar.txt', + ])) + }) + }) - // click download - cy.findByRole('button', { name: 'Download (selected)' }) + it('Can download selected files', () => { + getRowForFile('subfolder') .should('be.visible') - .click() - // check a file is downloaded - const downloadsFolder = Cypress.config('downloadsFolder') - cy.readFile(`${downloadsFolder}/subfolder.zip`, null, { timeout: 15000 }) - .should('exist') - .and('have.length.gt', 30) - // Check all files are included - .and(zipFileContains([ - 'subfolder/', - 'subfolder/bar.txt', - ])) + cy.get('[data-cy-files-list]').within(() => { + getRowForFile('subfolder') + .findByRole('checkbox') + .check({ force: true }) + + // see that two files are selected + cy.contains('1 selected').should('be.visible') + + // click download + cy.findByRole('button', { name: 'Download (selected)' }) + .should('be.visible') + .click() + + // check a file is downloaded + const downloadsFolder = Cypress.config('downloadsFolder') + cy.readFile(`${downloadsFolder}/subfolder.zip`, null, { timeout: 15000 }) + .should('exist') + .and('have.length.gt', 30) + // Check all files are included + .and(zipFileContains([ + 'subfolder/', + 'subfolder/bar.txt', + ])) + }) }) - }) - it('Can download folder by action', () => { - getRowForFile('subfolder') - .should('be.visible') - - cy.get('[data-cy-files-list]').within(() => { - triggerActionForFile('subfolder', 'download') + it('Can download folder by action', () => { + getRowForFile('subfolder') + .should('be.visible') - // check a file is downloaded - const downloadsFolder = Cypress.config('downloadsFolder') - cy.readFile(`${downloadsFolder}/subfolder.zip`, null, { timeout: 15000 }) - .should('exist') - .and('have.length.gt', 30) - // Check all files are included - .and(zipFileContains([ - 'subfolder/', - 'subfolder/bar.txt', - ])) + cy.get('[data-cy-files-list]').within(() => { + triggerActionForFile('subfolder', 'download') + + // check a file is downloaded + const downloadsFolder = Cypress.config('downloadsFolder') + cy.readFile(`${downloadsFolder}/subfolder.zip`, null, { timeout: 15000 }) + .should('exist') + .and('have.length.gt', 30) + // Check all files are included + .and(zipFileContains([ + 'subfolder/', + 'subfolder/bar.txt', + ])) + }) }) - }) - it('Can download file by action', () => { - getRowForFile('foo.txt') - .should('be.visible') + it('Can download file by action', () => { + getRowForFile('foo.txt') + .should('be.visible') - cy.get('[data-cy-files-list]').within(() => { - triggerActionForFile('foo.txt', 'download') + cy.get('[data-cy-files-list]').within(() => { + triggerActionForFile('foo.txt', 'download') - // check a file is downloaded - const downloadsFolder = Cypress.config('downloadsFolder') - cy.readFile(`${downloadsFolder}/foo.txt`, 'utf-8', { timeout: 15000 }) - .should('exist') - .and('have.length.gt', 5) - .and('contain', '<content>foo</content>') + // check a file is downloaded + const downloadsFolder = Cypress.config('downloadsFolder') + cy.readFile(`${downloadsFolder}/foo.txt`, 'utf-8', { timeout: 15000 }) + .should('exist') + .and('have.length.gt', 5) + .and('contain', '<content>foo</content>') + }) }) - }) - it('Can download file by selection', () => { - getRowForFile('foo.txt') - .should('be.visible') - - cy.get('[data-cy-files-list]').within(() => { + it('Can download file by selection', () => { getRowForFile('foo.txt') - .findByRole('checkbox') - .check({ force: true }) - - cy.findByRole('button', { name: 'Download (selected)' }) - .click() + .should('be.visible') - // check a file is downloaded - const downloadsFolder = Cypress.config('downloadsFolder') - cy.readFile(`${downloadsFolder}/foo.txt`, 'utf-8', { timeout: 15000 }) - .should('exist') - .and('have.length.gt', 5) - .and('contain', '<content>foo</content>') + cy.get('[data-cy-files-list]').within(() => { + getRowForFile('foo.txt') + .findByRole('checkbox') + .check({ force: true }) + + cy.findByRole('button', { name: 'Download (selected)' }) + .click() + + // check a file is downloaded + const downloadsFolder = Cypress.config('downloadsFolder') + cy.readFile(`${downloadsFolder}/foo.txt`, 'utf-8', { timeout: 15000 }) + .should('exist') + .and('have.length.gt', 5) + .and('contain', '<content>foo</content>') + }) }) }) }) diff --git a/cypress/e2e/files_sharing/public-share/setup-public-share.ts b/cypress/e2e/files_sharing/public-share/setup-public-share.ts index ac40d318592..42dedc77183 100644 --- a/cypress/e2e/files_sharing/public-share/setup-public-share.ts +++ b/cypress/e2e/files_sharing/public-share/setup-public-share.ts @@ -79,9 +79,13 @@ function checkExpirationDateState(enforced: boolean, hasDefault: boolean) { cy.get('input[data-cy-files-sharing-expiration-date-input]') .invoke('val') .then((val) => { + // eslint-disable-next-line no-unused-expressions + expect(val).to.not.be.undefined + + const inputDate = new Date(typeof val === 'number' ? val : String(val)) const expectedDate = new Date() expectedDate.setDate(expectedDate.getDate() + 2) - expect(new Date(val).toDateString()).to.eq(expectedDate.toDateString()) + expect(inputDate.toDateString()).to.eq(expectedDate.toDateString()) }) } |