diff --git a/tests/e2e/cucumber/features/shares/link.feature b/tests/e2e/cucumber/features/shares/link.feature index b724ea8daf..9606a74579 100644 --- a/tests/e2e/cucumber/features/shares/link.feature +++ b/tests/e2e/cucumber/features/shares/link.feature @@ -341,3 +341,24 @@ Feature: link | resource | | lorem.txt | And "Alice" logs out + + + Scenario: password is triggered when changing public link to writable role + Given "Admin" assigns following roles to the users using API + | id | role | + | Alice | Admin | + When "Alice" logs in + And "Alice" creates the following folders in personal space using API + | name | + | folderPublic | + And "Alice" opens the "files" app + And "Alice" creates a public link of following resource using the sidebar panel + | resource | role | password | + | folderPublic | Can view | %public% | + + # @issue-2048 + # Admin feature: ensure password is required for writable public links + # in case when OC_SHARING_PUBLIC_WRITEABLE_SHARE_MUST_HAVE_PASSWORD=true and OC_SHARING_PUBLIC_SHARE_MUST_HAVE_PASSWORD=false + And "Alice" deletes a password of the public link named "Unnamed link" of resource "folderPublic" + And "Alice" edits the public link named "Unnamed link" of resource "folderPublic" changing role to "Secret File Drop" and setting a password + And "Alice" logs out diff --git a/tests/e2e/cucumber/steps/ui/links.ts b/tests/e2e/cucumber/steps/ui/links.ts index ffc6f95199..e006a900ee 100644 --- a/tests/e2e/cucumber/steps/ui/links.ts +++ b/tests/e2e/cucumber/steps/ui/links.ts @@ -202,6 +202,27 @@ When( } ) +When( + '{string} edits the public link named {string} of resource {string} changing role to {string} and setting a password', + async function ( + this: World, + stepUser: string, + linkName: any, + resource: string, + role: string + ): Promise { + const { page } = this.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + const roleText = await linkObject.changeRole({ + linkName, + resource, + role, + requirePassword: true + }) + expect(roleText.toLowerCase()).toBe(role.toLowerCase()) + } +) + When( '{string} copies the link {string} of resource {string}', async function ( @@ -216,3 +237,12 @@ When( expect(clipboard).toBe(this.linksEnvironment.getLink({ name: linkName }).url) } ) + +When( + '{string} deletes a password of the public link named {string} of resource {string}', + async function (this: World, stepUser: string, name: string, resource: string): Promise { + const { page } = this.actorsEnvironment.getActor({ key: stepUser }) + const linkObject = new objects.applicationFiles.Link({ page }) + await linkObject.deletePassword({ resource, name }) + } +) diff --git a/tests/e2e/support/objects/app-files/link/actions.ts b/tests/e2e/support/objects/app-files/link/actions.ts index 330fc554cf..d6fc50b95c 100644 --- a/tests/e2e/support/objects/app-files/link/actions.ts +++ b/tests/e2e/support/objects/app-files/link/actions.ts @@ -50,6 +50,7 @@ export type changeRoleArgs = { linkName: string role: string space?: boolean + requirePassword?: boolean } export type deleteLinkArgs = { @@ -102,6 +103,8 @@ const copyLinkButton = '//span[contains(@class, "files-links-name") and text()="%s"]//ancestor::li//button[contains(@class, "oc-files-public-link-copy-url")]' const linkRoleDropdown = '.link-role-dropdown' const createLinkModal = '.oc-modal-body' +const removePublicLinkPasswordButton = + '//div[contains(@id,"edit-public-link-dropdown")]//button/span[text()="Remove password"]' const getRecentLinkUrl = async (page: Page, name: string): Promise => { const linkElement = page.locator(util.format(copyLinkButton, name)) @@ -173,7 +176,7 @@ export const createLink = async (args: createLinkArgs): Promise => { } export const changeRole = async (args: changeRoleArgs): Promise => { - const { page, resource, linkName, role, space } = args + const { page, resource, linkName, role, space, requirePassword = false } = args // clear all popups await clearAllPopups(page) @@ -199,7 +202,14 @@ export const changeRole = async (args: changeRoleArgs): Promise => { res.request().method() === 'PATCH' && res.status() === 200 ), - page.locator(util.format(publicLinkSetRoleButton, role)).click() + (async () => { + await page.locator(util.format(publicLinkSetRoleButton, role)).click() + + if (requirePassword) { + await generatePassword(page) + await setPassword(page) + } + })() ]) const message = await page.locator(linkUpdateDialog).textContent() @@ -374,3 +384,23 @@ export const copyLinkToClipboard = async (args: copyLinkArgs): Promise = await page.getByLabel('Copy link to clipboard').click() return await page.evaluate('navigator.clipboard.readText()') } + +export const deletePassword = async (args: createLinkArgs): Promise => { + const { page, resource, name } = args + + // clear all popups + await clearAllPopups(page) + + const resourcePaths = resource.split('/') + const resourceName = resourcePaths.pop() + if (resourcePaths.length) { + await clickResource({ page: page, path: resourcePaths.join('/') }) + } + await sidebar.open({ page: page, resource: resourceName }) + await sidebar.openPanel({ page: page, name: 'sharing' }) + await page.locator(util.format(editPublicLinkButton, name)).click() + + const passwordIndication = page.locator('.oc-files-file-link-has-password') + await page.locator(removePublicLinkPasswordButton).click() + await expect(passwordIndication).not.toBeVisible() +} diff --git a/tests/e2e/support/objects/app-files/link/index.ts b/tests/e2e/support/objects/app-files/link/index.ts index 40c4b992e1..b735dba142 100644 --- a/tests/e2e/support/objects/app-files/link/index.ts +++ b/tests/e2e/support/objects/app-files/link/index.ts @@ -96,4 +96,8 @@ export class Link { copyLinkToClipboard(args: Omit): Promise { return po.copyLinkToClipboard({ ...args, page: this.#page }) } + + async deletePassword(args: Omit): Promise { + await po.deletePassword({ page: this.#page, ...args }) + } }