Skip to content

Commit

Permalink
Merge pull request owncloud#6461 from owncloud/unauthorizedUserOpenPu…
Browse files Browse the repository at this point in the history
…blicLink

[tests-only] Add e2e test for unauthorized user opening public link
  • Loading branch information
individual-it authored Mar 14, 2022
2 parents beb64b2 + 62bf306 commit e07230e
Show file tree
Hide file tree
Showing 7 changed files with 179 additions and 8 deletions.
10 changes: 10 additions & 0 deletions tests/e2e/cucumber/publicLinkToFolderJourney.feature
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,13 @@ Feature: Create public link to folder
| resource | name | role | dateOfExpiration | password |
| folderPublic | myPublicLink | uploader | +5 days | 12345 |
Then "Alice" should see 1 public link
When the public accesses the last created public link with password "12345"
Then the public should not see the following resource
| lorem.txt |
When the public uploads the following files on the files-drop page
| textfile.txt |
Then the public should see the following files on the files-drop page
| textfile.txt |
When the public reloads the public link pages
Then the public should not see the following files on the files-drop page
| textfile.txt |
55 changes: 47 additions & 8 deletions tests/e2e/cucumber/step_definitions/app.files.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import { DataTable, Given, Then, When } from '@cucumber/cucumber'
import { expect } from '@playwright/test'
import * as assert from 'assert'
import { World } from '../environment'
import { config } from '../../config'
import { FilesPage } from '../../support'
import { expect } from '@playwright/test'
import assert = require('assert')
import { PublicLinkPage } from '../../support/page/publicLinkPage'
import { filesCta } from '../../support/cta'

When(
'{string} navigates to the files page',
Expand Down Expand Up @@ -275,11 +277,7 @@ Then(
await allFilesPage.navigate()
const resourceExist = await allFilesPage.resourceExist({ name: resource })

if (actionType === 'see' && !resourceExist) {
throw new Error(`resource wasn't found: "${resource}"`)
} else if (actionType === 'not see' && resourceExist) {
throw new Error(`resource was found: "${resource}"`)
}
filesCta.resourceExistenceErrorMessage(actionType, resourceExist, resource)
}
await allFilesPage.navigate()
}
Expand All @@ -294,7 +292,7 @@ Then(

// skipped in Oc10, since the version number in Oc10 is no more than 1
if (config.ocis) {
await expect(await versionPage.numberOfVersions({ resource })).toEqual(countOfVersion)
expect(await versionPage.numberOfVersions({ resource })).toEqual(countOfVersion)
}
await allFilesPage.navigate()
}
Expand Down Expand Up @@ -394,3 +392,44 @@ When(
}
}
)

When(
'the public accesses the last created public link with password {string}',
async function (this: World, password: string): Promise<void> {
const publicLinkPage = await PublicLinkPage.setup()
await publicLinkPage.navigateToPublicLink()
await publicLinkPage.authenticatePassword(password)
}
)

Then(
/the public should( not | )see the following (resource|resources)$/,
async function (this: World, actionType: string, _: string, stepTable: DataTable): Promise<void> {
await filesCta.checkResourcesExistence({ actionType, stepTable })
}
)

When(
'the public uploads the following files on the files-drop page',
async function (this: World, stepTable: DataTable): Promise<void> {
const publicLinkPage = new PublicLinkPage()

const files = stepTable.raw().map((f) => f[0])
for (const file of files) {
const uploadInfo = this.filesEnvironment.getFile({ name: file })
await publicLinkPage.uploadFiles(uploadInfo.path)
}
}
)

Then(
/the public should( not | )see the following files on the files-drop page$/,
async function (this: World, actionType: string, stepTable: DataTable): Promise<void> {
await filesCta.checkResourcesExistence({ actionType, stepTable, pageType: 'upload' })
}
)

When('the public reloads the public link pages', async function (this: World): Promise<void> {
const publicLinkPage = new PublicLinkPage()
await publicLinkPage.reload()
})
1 change: 1 addition & 0 deletions tests/e2e/support/cta/files/index.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/* eslint-disable */
export * as sidebar from './sidebar'
export * from './misc'
export * from './publicLink'
12 changes: 12 additions & 0 deletions tests/e2e/support/cta/files/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,3 +53,15 @@ export const waitForResources = async ({
names.map((name) => page.waitForSelector(`[data-test-resource-name="${name}"]`))
)
}

export const resourceExistenceErrorMessage = (
actionType: string,
resourceExist: boolean,
resource: string
): void => {
if (actionType === '' && !resourceExist) {
throw new Error(`resource wasn't found: "${resource}"`)
} else if (actionType === 'not' && resourceExist) {
throw new Error(`resource was found: "${resource}"`)
}
}
25 changes: 25 additions & 0 deletions tests/e2e/support/cta/files/publicLink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
import { DataTable } from '@cucumber/cucumber'
import { PublicLinkPage } from '../../page/publicLinkPage'
import { filesCta } from '../../cta'

export const checkResourcesExistence = async ({
actionType,
stepTable,
pageType = 'public'
}: {
actionType: string
stepTable: DataTable
pageType?: string
}): Promise<void> => {
const publicLinkPage = new PublicLinkPage()
actionType = actionType.trim()

const files = stepTable.raw().map((f) => f[0])
for (const file of files) {
const resourceExist = await publicLinkPage.resourceExists({
pageType,
name: file
})
filesCta.resourceExistenceErrorMessage(actionType, resourceExist, file)
}
}
16 changes: 16 additions & 0 deletions tests/e2e/support/page/files/publicLink.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ export class PublicLink {
private readonly publicLinkListSelector: string
private readonly roleSelector: string
private readonly folderSelector: string
private publicLinkSelector: string
private static lastCreatedPublicLink: string

constructor({ actor }: { actor: Actor }) {
this.actor = actor
Expand All @@ -48,6 +50,7 @@ export class PublicLink {
this.publicLinkListSelector = `//ul[@class = 'oc-list oc-list-divider oc-overflow-hidden oc-m-rm']/li`
this.roleSelector = `//span[@id="files-role-%s"]`
this.folderSelector = `//*[@data-test-resource-name="%s"]/ancestor::tr//button[contains(@class, "files-quick-action-collaborators")]`
this.publicLinkSelector = `//ul/li//h5[contains(text(),'%s')]/following-sibling::div/a`
}

async getLinksCount(): Promise<number> {
Expand Down Expand Up @@ -117,5 +120,18 @@ export class PublicLink {
}

await this.createLinkButtonLocator.click()

const publicLinkUrl = await page
.locator(util.format(this.publicLinkSelector, name))
.textContent()
PublicLink.setLastCreatedPublicLink(publicLinkUrl)
}

public static setLastCreatedPublicLink(publicLinkUrl: string): void {
this.lastCreatedPublicLink = publicLinkUrl
}

public static getLastCreatedPublicLink(): string {
return this.lastCreatedPublicLink
}
}
68 changes: 68 additions & 0 deletions tests/e2e/support/page/publicLinkPage.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
import { errors, Page } from 'playwright'
import util from 'util'
import { state } from '../../cucumber/environment/shared'
import { PublicLink } from './files/publicLink'

export class PublicLinkPage {
private static page: Page
private readonly passwordInput: string
private readonly passwordSubmitButton: string
private readonly fileUploadInput: string
private publicResourceSelector: string
private uploadedResourceSelector: string

constructor() {
this.passwordInput = 'input[type="password"]'
this.passwordSubmitButton =
'//*[@id="password-submit"]|//*[@id="oc-textinput-3"]/ancestor::div[contains(@class, "oc-mb-s")]/following-sibling::button'
this.publicResourceSelector = `[data-test-resource-name="%s"]`
this.uploadedResourceSelector = `//tbody/tr/td[contains(@class, "oc-pl-rm") and contains(text(), "%s")]`
this.fileUploadInput = '//input[@id="file_upload_start" or @class="dz-hidden-input"]'
}

public static async setup(): Promise<PublicLinkPage> {
PublicLinkPage.page = await state.browser
.newContext({ ignoreHTTPSErrors: true })
.then((context) => context.newPage())
return new PublicLinkPage()
}

async navigateToPublicLink(): Promise<void> {
await PublicLinkPage.page.goto(PublicLink.getLastCreatedPublicLink())
}

async authenticatePassword(password: string): Promise<void> {
await PublicLinkPage.page.locator(this.passwordInput).fill(password)
await PublicLinkPage.page.locator(this.passwordSubmitButton).click()
}

async resourceExists({ pageType, name, timeout = 500 }): Promise<boolean> {
let exist = true
let resourceSelector
if (pageType === 'upload') {
resourceSelector = this.uploadedResourceSelector
} else {
resourceSelector = this.publicResourceSelector
}

await PublicLinkPage.page
.waitForSelector(util.format(resourceSelector, name), { timeout })
.catch((e) => {
if (!(e instanceof errors.TimeoutError)) {
throw e
}

exist = false
})

return exist
}

async uploadFiles(filePath: string): Promise<void> {
await PublicLinkPage.page.locator(this.fileUploadInput).setInputFiles(filePath)
}

async reload(): Promise<void> {
await PublicLinkPage.page.reload()
}
}

0 comments on commit e07230e

Please sign in to comment.