aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFerdinand Thiessen <opensource@fthiessen.de>2025-01-15 15:47:33 +0100
committerbackportbot[bot] <backportbot[bot]@users.noreply.github.com>2025-01-15 17:01:19 +0000
commitf5828fa9600abb750603f5e30aeb8c30a70fe739 (patch)
treedd6092faf377189a3da3a030c9b1591693992954
parentd9338277fad16060ddedc4b0c6e90e10eed72a9a (diff)
downloadnextcloud-server-backport/50192/stable28.tar.gz
nextcloud-server-backport/50192/stable28.zip
test: Add end-to-end test for share expiration datebackport/50192/stable28
Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de> [skip ci]
-rw-r--r--cypress/e2e/files_sharing/FilesSharingUtils.ts21
-rw-r--r--cypress/e2e/files_sharing/expiry-date.cy.ts128
2 files changed, 146 insertions, 3 deletions
diff --git a/cypress/e2e/files_sharing/FilesSharingUtils.ts b/cypress/e2e/files_sharing/FilesSharingUtils.ts
index ef8cf462a06..7c91b9e7ac7 100644
--- a/cypress/e2e/files_sharing/FilesSharingUtils.ts
+++ b/cypress/e2e/files_sharing/FilesSharingUtils.ts
@@ -12,6 +12,7 @@ export interface ShareSetting {
share: boolean
download: boolean
note: string
+ expiryDate: Date
}
export function createShare(fileName: string, username: string, shareSettings: Partial<ShareSetting> = {}) {
@@ -31,15 +32,20 @@ export function createShare(fileName: string, username: string, shareSettings: P
updateShare(fileName, 0, shareSettings)
}
+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<ShareSetting> = {}) {
openSharingPanel(fileName)
+ openSharingDetails(index)
cy.intercept({ times: 1, method: 'PUT', url: '**/apps/files_sharing/api/v1/shares/*' }).as('updateShare')
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()
-
if (shareSettings.download !== undefined) {
cy.get('[data-cy-files-sharing-share-permissions-checkbox="download"]').find('input').as('downloadCheckbox')
if (shareSettings.download) {
@@ -89,10 +95,19 @@ export function updateShare(fileName: string, index: number, shareSettings: Part
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' })
cy.wait('@updateShare')
})
+ // close all toasts
+ cy.get('.toast-success').findAllByRole('button').click({ force: true, multiple: true })
}
export function openSharingPanel(fileName: string) {
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 00000000000..f39a47309e2
--- /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)
+ }
+
+})