From e7a49dc5a1591fdb3150c6bde2e69e8bcdf32ba8 Mon Sep 17 00:00:00 2001 From: Ferdinand Thiessen Date: Wed, 15 Jan 2025 15:47:33 +0100 Subject: [PATCH] test: Add end-to-end test for share expiration date Signed-off-by: Ferdinand Thiessen --- cypress/e2e/files_sharing/expiry-date.cy.ts | 128 ++++++++++++++++++ .../e2e/files_sharing/filesSharingUtils.ts | 27 +++- 2 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 cypress/e2e/files_sharing/expiry-date.cy.ts diff --git a/cypress/e2e/files_sharing/expiry-date.cy.ts b/cypress/e2e/files_sharing/expiry-date.cy.ts new file mode 100644 index 0000000000000..f39a47309e21c --- /dev/null +++ b/cypress/e2e/files_sharing/expiry-date.cy.ts @@ -0,0 +1,128 @@ +/*! + * SPDX-FileCopyrightText: 2025 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +import { User } from '@nextcloud/cypress' +import { closeSidebar } from '../files/FilesUtils.ts' +import { createShare, openSharingDetails, openSharingPanel, updateShare } from './FilesSharingUtils.ts' + +describe('files_sharing: Expiry date', () => { + const expectedDefaultDate = new Date(Date.now() + 2 * 24 * 60 * 60 * 1000) + const expectedDefaultDateString = `${expectedDefaultDate.getFullYear()}-${String(expectedDefaultDate.getMonth() + 1).padStart(2, '0')}-${String(expectedDefaultDate.getDate()).padStart(2, '0')}` + const fortnight = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000) + const fortnightString = `${fortnight.getFullYear()}-${String(fortnight.getMonth() + 1).padStart(2, '0')}-${String(fortnight.getDate()).padStart(2, '0')}` + + let alice: User + let bob: User + + before(() => { + // Ensure we have the admin setting setup for default dates with 2 days in the future + cy.runOccCommand('config:app:set --value yes core shareapi_default_internal_expire_date') + cy.runOccCommand('config:app:set --value 2 core shareapi_internal_expire_after_n_days') + + cy.createRandomUser().then((user) => { + alice = user + cy.login(alice) + }) + cy.createRandomUser().then((user) => { + bob = user + }) + }) + + after(() => { + cy.runOccCommand('config:app:delete core shareapi_default_internal_expire_date') + cy.runOccCommand('config:app:delete core shareapi_enforce_internal_expire_date') + cy.runOccCommand('config:app:delete core shareapi_internal_expire_after_n_days') + }) + + beforeEach(() => { + cy.runOccCommand('config:app:delete core shareapi_enforce_internal_expire_date') + }) + + it('See default expiry date is set and enforced', () => { + // Enforce the date + cy.runOccCommand('config:app:set --value yes core shareapi_enforce_internal_expire_date') + const dir = 'defaultExpiryDateEnforced' + prepareDirectory(dir) + + validateExpiryDate(dir, expectedDefaultDateString) + cy.findByRole('checkbox', { name: /expiration date/i }) + .should('be.checked') + .and('be.disabled') + }) + + it('See default expiry date is set also if not enforced', () => { + const dir = 'defaultExpiryDate' + prepareDirectory(dir) + + validateExpiryDate(dir, expectedDefaultDateString) + cy.findByRole('checkbox', { name: /expiration date/i }) + .should('be.checked') + .and('not.be.disabled') + .check({ force: true, scrollBehavior: 'nearest' }) + }) + + it('Can set custom expiry date', () => { + const dir = 'customExpiryDate' + prepareDirectory(dir) + updateShare(dir, 0, { expiryDate: fortnight }) + validateExpiryDate(dir, fortnightString) + }) + + it('Custom expiry date survives reload', () => { + const dir = 'customExpiryDateReload' + prepareDirectory(dir) + updateShare(dir, 0, { expiryDate: fortnight }) + validateExpiryDate(dir, fortnightString) + + cy.visit('/apps/files') + validateExpiryDate(dir, fortnightString) + }) + + /** + * Regression test for https://github.com/nextcloud/server/pull/50192 + * Ensure that admin default settings do not always override the user set value. + */ + it('Custom expiry date survives unrelated update', () => { + const dir = 'customExpiryUnrelatedChanges' + prepareDirectory(dir) + updateShare(dir, 0, { expiryDate: fortnight }) + validateExpiryDate(dir, fortnightString) + + closeSidebar() + updateShare(dir, 0, { note: 'Only note changed' }) + validateExpiryDate(dir, fortnightString) + + cy.visit('/apps/files') + validateExpiryDate(dir, fortnightString) + }) + + /** + * Prepare directory, login and share to bob + * + * @param name The directory name + */ + function prepareDirectory(name: string) { + cy.mkdir(alice, `/${name}`) + cy.login(alice) + cy.visit('/apps/files') + createShare(name, bob.userId) + } + + /** + * Validate expiry date on a share + * + * @param filename The filename to validate + * @param expectedDate The expected date in YYYY-MM-dd + */ + function validateExpiryDate(filename: string, expectedDate: string) { + openSharingPanel(filename) + openSharingDetails(0) + + cy.get('#share-date-picker') + .should('exist') + .and('have.value', expectedDate) + } + +}) diff --git a/cypress/e2e/files_sharing/filesSharingUtils.ts b/cypress/e2e/files_sharing/filesSharingUtils.ts index cb4071533805e..5e5a71fd46d1a 100644 --- a/cypress/e2e/files_sharing/filesSharingUtils.ts +++ b/cypress/e2e/files_sharing/filesSharingUtils.ts @@ -29,6 +29,8 @@ export interface ShareSetting { delete: boolean share: boolean download: boolean + note: string + expiryDate: Date } export function createShare(fileName: string, username: string, shareSettings: Partial = {}) { @@ -48,13 +50,18 @@ export function createShare(fileName: string, username: string, shareSettings: P updateShare(fileName, 0, shareSettings) } -export function updateShare(fileName: string, index: number, shareSettings: Partial = {}) { - openSharingPanel(fileName) - +export function openSharingDetails(index: number) { cy.get('#app-sidebar-vue').within(() => { cy.get('[data-cy-files-sharing-share-actions]').eq(index).click() cy.get('[data-cy-files-sharing-share-permissions-bundle="custom"]').click() + }) +} +export function updateShare(fileName: string, index: number, shareSettings: Partial = {}) { + openSharingPanel(fileName) + openSharingDetails(index) + + cy.get('#app-sidebar-vue').within(() => { if (shareSettings.download !== undefined) { cy.get('[data-cy-files-sharing-share-permissions-checkbox="download"]').find('input').as('downloadCheckbox') if (shareSettings.download) { @@ -99,8 +106,22 @@ export function updateShare(fileName: string, index: number, shareSettings: Part } } + if (shareSettings.note !== undefined) { + cy.findByRole('checkbox', { name: /note to recipient/i }).check({ force: true, scrollBehavior: 'nearest' }) + cy.findByRole('textbox', { name: /note to recipient/i }).type(shareSettings.note) + } + + if (shareSettings.expiryDate !== undefined) { + cy.findByRole('checkbox', { name: /expiration date/i }) + .check({ force: true, scrollBehavior: 'nearest' }) + cy.get('#share-date-picker') + .type(`${shareSettings.expiryDate.getFullYear()}-${String(shareSettings.expiryDate.getMonth() + 1).padStart(2, '0')}-${String(shareSettings.expiryDate.getDate()).padStart(2, '0')}`) + } + cy.get('[data-cy-files-sharing-share-editor-action="save"]').click({ scrollBehavior: 'nearest' }) }) + // close all toasts + cy.get('.toast-success').findAllByRole('button').click({ force: true, multiple: true }) } export function openSharingPanel(fileName: string) {