Skip to content

Commit

Permalink
refactor: Modularize setup-public-share.ts
Browse files Browse the repository at this point in the history
This update enhances the testing framework for public sharing by
improving the setup and management of share contexts.
It refactors the code to make the `createShare` function reusable externally,
ensuring better testability and flexibility.
Additionally, the update optimizes share permission adjustments and
improves state management, making public share setups more efficient and maintainable.

Signed-off-by: nfebe <[email protected]>
  • Loading branch information
nfebe committed Jan 20, 2025
1 parent 5ba9ece commit fe545ae
Showing 1 changed file with 77 additions and 64 deletions.
141 changes: 77 additions & 64 deletions cypress/e2e/files_sharing/public-share/setup-public-share.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,110 +5,123 @@
import type { User } from '@nextcloud/cypress'
import { openSharingPanel } from '../FilesSharingUtils.ts'

let user: User
let url: string
export interface ShareContext {
user: User
url?: string
}

const defaultShareContext: ShareContext = {
user: {} as User,
url: undefined,
}

/**
* URL of the share
* Retrieves the URL of the share.
* Throws an error if the share context is not initialized properly.
*
* @param context The current share context (defaults to `defaultShareContext` if not provided).
* @return The share URL.
* @throws Error if the share context has no URL.
*/
export function getShareUrl() {
if (url === undefined) {
throw new Error('You need to setup the share first!')
export function getShareUrl(context: ShareContext = defaultShareContext): string {
if (!context.url) {
throw new Error('Share context is not properly initialized with a URL.')
}
return url
return context.url
}

/**
* Setup the available data
* @param context The current share context
* @param shareName The name of the shared folder
*/
function setupData(shareName: string) {
cy.mkdir(user, `/${shareName}`)
cy.mkdir(user, `/${shareName}/subfolder`)
cy.uploadContent(user, new Blob(['<content>foo</content>']), 'text/plain', `/${shareName}/foo.txt`)
cy.uploadContent(user, new Blob(['<content>bar</content>']), 'text/plain', `/${shareName}/subfolder/bar.txt`)
export function setupData(context: ShareContext, shareName: string): void {
cy.mkdir(context.user, `/${shareName}`)
cy.mkdir(context.user, `/${shareName}/subfolder`)
cy.uploadContent(context.user, new Blob(['<content>foo</content>']), 'text/plain', `/${shareName}/foo.txt`)
cy.uploadContent(context.user, new Blob(['<content>bar</content>']), 'text/plain', `/${shareName}/subfolder/bar.txt`)
}

/**
* Create a public link share
* @param context The current share context
* @param shareName The name of the shared folder
*/
function createShare(shareName: string) {
cy.login(user)
// open the files app
cy.visit('/apps/files')
// open the sidebar
openSharingPanel(shareName)
// create the share
export function createShare(context: ShareContext, shareName: string) {
cy.login(context.user)
cy.visit('/apps/files') // Open the files app
openSharingPanel(shareName) // Open the sharing sidebar

cy.intercept('POST', '**/ocs/v2.php/apps/files_sharing/api/v1/shares').as('createShare')
cy.findByRole('button', { name: 'Create a new share link' })
.click()
cy.findByRole('button', { name: 'Create a new share link' }).click()

// extract the link
// Extract the share link
return cy.wait('@createShare')
.should(({ response }) => {
const { ocs } = response!.body
url = ocs?.data.url
expect(url).to.match(/^http:\/\//)
expect(response?.statusCode).to.eq(200)
const url = response?.body?.ocs?.data?.url
expect(url).to.match(/^https?:\/\//)
context.url = url
})
.then(() => cy.wrap(url))
.then(() => cy.wrap(context.url))
}

/**
* Adjust share permissions to be editable
*/
function adjustSharePermission() {
// Update the share to be a file drop
function adjustSharePermission(): void {
cy.findByRole('list', { name: 'Link shares' })
.findAllByRole('listitem')
.first()
.findByRole('button', { name: /Actions/i })
.click()
cy.findByRole('menuitem', { name: /Customize link/i })
.should('be.visible')
.click()
cy.findByRole('menuitem', { name: /Customize link/i }).click()

cy.get('[data-cy-files-sharing-share-permissions-bundle]').should('be.visible')
cy.get('[data-cy-files-sharing-share-permissions-bundle="upload-edit"]').click()

// Enable upload-edit
cy.get('[data-cy-files-sharing-share-permissions-bundle]')
.should('be.visible')
cy.get('[data-cy-files-sharing-share-permissions-bundle="upload-edit"]')
.click()
// save changes
cy.intercept('PUT', '**/ocs/v2.php/apps/files_sharing/api/v1/shares/*').as('updateShare')
cy.findByRole('button', { name: 'Update share' })
.click()
cy.wait('@updateShare')
cy.findByRole('button', { name: 'Update share' }).click()
cy.wait('@updateShare').its('response.statusCode').should('eq', 200)
}

/**
* Setup a public share and backup the state.
* If the setup was already done in another run, the state will be restored.
*
* @param shareName The name of the shared folder
* @return The URL of the share
*/
export function setupPublicShare(): Cypress.Chainable<string> {
const shareName = 'shared'
export function setupPublicShare(shareName = 'shared'): Cypress.Chainable<string> {

return cy.task('getVariable', { key: 'public-share-data' })
.then((data) => {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { dataSnapshot, shareUrl } = data as any || {}
if (dataSnapshot) {
cy.restoreState(dataSnapshot)
url = shareUrl
return cy.wrap(shareUrl as string)
} else {
const shareData: Record<string, unknown> = {}
return cy.createRandomUser()
.then(($user) => { user = $user })
.then(() => setupData(shareName))
.then(() => createShare(shareName))
.then((value) => { shareData.shareUrl = value })
.then(() => adjustSharePermission())
.then(() => cy.saveState().then((value) => { shareData.dataSnapshot = value }))
.then(() => cy.task('setVariable', { key: 'public-share-data', value: shareData }))
.then(() => cy.log(`Public share setup, URL: ${shareData.shareUrl}`))
.then(() => cy.wrap(url))
}
})
return cy.task('getVariable', { key: 'public-share-data' }).then((data) => {
// Leave dataSnapshot part unchanged
// eslint-disable-next-line @typescript-eslint/no-explicit-any
const { dataSnapshot, shareUrl } = data as any || {}
if (dataSnapshot) {
cy.restoreState(dataSnapshot)
defaultShareContext.url = shareUrl
return cy.wrap(shareUrl as string)
} else {
const shareData: Record<string, unknown> = {}
return cy.createRandomUser()
.then((user) => {
defaultShareContext.user = user
})
.then(() => setupData(defaultShareContext, shareName))
.then(() => createShare(defaultShareContext, shareName))
.then((url) => {
shareData.shareUrl = url
})
.then(() => adjustSharePermission())
.then(() =>
cy.saveState().then((snapshot) => {
shareData.dataSnapshot = snapshot
}),
)
.then(() => cy.task('setVariable', { key: 'public-share-data', value: shareData }))
.then(() => cy.log(`Public share setup, URL: ${shareData.shareUrl}`))
.then(() => cy.wrap(defaultShareContext.url))
}
})
}

0 comments on commit fe545ae

Please sign in to comment.