aboutsummaryrefslogtreecommitdiffstats
path: root/cypress/e2e/files_sharing/public-share/header-menu.cy.ts
blob: a89ee8eb90e533d4d034696ca7d0a01d45bc08b0 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
/*!
 * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
 * SPDX-License-Identifier: AGPL-3.0-or-later
 */
import { haveValidity, zipFileContains } from '../../../support/utils/assertions.ts'
import { getShareUrl, setupPublicShare } from './setup-public-share.ts'

/**
 * This tests ensures that on public shares the header actions menu correctly works
 */
describe('files_sharing: Public share - header actions menu', { testIsolation: true }, () => {

	before(() => setupPublicShare())
	beforeEach(() => {
		cy.logout()
		cy.visit(getShareUrl())
	})

	it('Can download all files', () => {
		cy.get('header')
			.findByRole('button', { name: 'Download' })
			.should('be.visible')
		cy.get('header')
			.findByRole('button', { name: 'Download' })
			.click()

		// check a file is downloaded
		const downloadsFolder = Cypress.config('downloadsFolder')
		cy.readFile(`${downloadsFolder}/shared.zip`, null, { timeout: 15000 })
			.should('exist')
			.and('have.length.gt', 30)
			// Check all files are included
			.and(zipFileContains([
				'shared/',
				'shared/foo.txt',
				'shared/subfolder/',
				'shared/subfolder/bar.txt',
			]))
	})

	it('Can copy direct link', () => {
		// Check the button
		cy.get('header')
			.findByRole('button', { name: /More actions/i })
			.should('be.visible')
		cy.get('header')
			.findByRole('button', { name: /More actions/i })
			.click()
		// See the menu
		cy.findByRole('menu', { name: /More action/i })
			.should('be.visible')
		// see correct link in item
		cy.findByRole('menuitem', { name: 'Direct link' })
			.should('be.visible')
			.and('have.attr', 'href')
			.then((attribute) => expect(attribute).to.match(/^http:\/\/.+\/download$/))
		// see menu closes on click
		cy.findByRole('menuitem', { name: 'Direct link' })
			.click()
		cy.findByRole('menu', { name: /More actions/i })
			.should('not.exist')
	})

	it('Can create federated share', () => {
		// Check the button
		cy.get('header')
			.findByRole('button', { name: /More actions/i })
			.should('be.visible')
		cy.get('header')
			.findByRole('button', { name: /More actions/i })
			.click()
		// See the menu
		cy.findByRole('menu', { name: /More action/i })
			.should('be.visible')
		// see correct button
		cy.findByRole('menuitem', { name: /Add to your/i })
			.should('be.visible')
			.click()
		// see the dialog
		cy.findByRole('dialog', { name: /Add to your Nextcloud/i })
			.should('be.visible')
		cy.findByRole('dialog', { name: /Add to your Nextcloud/i }).within(() => {
			cy.findByRole('textbox')
				.type('user@nextcloud.local')
			// create share
			cy.intercept('POST', '**/apps/federatedfilesharing/createFederatedShare')
				.as('createFederatedShare')
			cy.findByRole('button', { name: 'Create share' })
				.click()
			cy.wait('@createFederatedShare')
		})
	})

	it('Has user feedback while creating federated share', () => {
		// Check the button
		cy.get('header')
			.findByRole('button', { name: /More actions/i })
			.should('be.visible')
			.click()
		// see correct button
		cy.findByRole('menuitem', { name: /Add to your/i })
			.should('be.visible')
			.click()
		// see the dialog
		cy.findByRole('dialog', { name: /Add to your Nextcloud/i }).should('be.visible').within(() => {
			cy.findByRole('textbox')
				.type('user@nextcloud.local')
			// intercept request, the request is continued when the promise is resolved
			const { promise, resolve } = Promise.withResolvers()
			cy.intercept('POST', '**/apps/federatedfilesharing/createFederatedShare', (request) => {
				// we need to wait in the onResponse handler as the intercept handler times out otherwise
				request.on('response', async (response) => { await promise; response.statusCode = 503 })
			}).as('createFederatedShare')

			// create the share
			cy.findByRole('button', { name: 'Create share' })
				.click()
			// see that while the share is created the button is disabled
			cy.findByRole('button', { name: 'Create share' })
				.should('be.disabled')
				.then(() => {
					// continue the request
					resolve(null)
				})
			cy.wait('@createFederatedShare')
			// see that the button is no longer disabled
			cy.findByRole('button', { name: 'Create share' })
				.should('not.be.disabled')
		})
	})

	it('Has input validation for federated share', () => {
		// Check the button
		cy.get('header')
			.findByRole('button', { name: /More actions/i })
			.should('be.visible')
			.click()
		// see correct button
		cy.findByRole('menuitem', { name: /Add to your/i })
			.should('be.visible')
			.click()
		// see the dialog
		cy.findByRole('dialog', { name: /Add to your Nextcloud/i }).should('be.visible').within(() => {
			// Check domain only
			cy.findByRole('textbox')
				.type('nextcloud.local')
			cy.findByRole('textbox')
				.should(haveValidity(/user/i))
			// Check no valid domain
			cy.findByRole('textbox')
				.type('{selectAll}user@invalid')
			cy.findByRole('textbox')
				.should(haveValidity(/invalid.+url/i))
		})
	})

	it('See primary action is moved to menu on small screens', () => {
		cy.viewport(490, 490)
		// Check the button does not exist
		cy.get('header').within(() => {
			cy.findByRole('button', { name: 'Direct link' })
				.should('not.exist')
			cy.findByRole('button', { name: 'Download' })
				.should('not.exist')
			cy.findByRole('button', { name: /Add to your/i })
				.should('not.exist')
			// Open the menu
			cy.findByRole('button', { name: /More actions/i })
				.should('be.visible')
				.click()
		})

		// See correct number of menu item
		cy.findByRole('menu', { name: 'More actions' })
			.findAllByRole('menuitem')
			.should('have.length', 3)
		cy.findByRole('menu', { name: 'More actions' })
			.within(() => {
				// See that download, federated share and direct link are moved to the menu
				cy.findByRole('menuitem', { name: /^Download/ })
					.should('be.visible')
				cy.findByRole('menuitem', { name: /Add to your/i })
					.should('be.visible')
				cy.findByRole('menuitem', { name: 'Direct link' })
					.should('be.visible')

				// See that direct link works
				cy.findByRole('menuitem', { name: 'Direct link' })
					.should('be.visible')
					.and('have.attr', 'href')
					.then((attribute) => expect(attribute).to.match(/^http:\/\/.+\/download$/))
				// See remote share works
				cy.findByRole('menuitem', { name: /Add to your/i })
					.should('be.visible')
					.click()
			})
		cy.findByRole('dialog', { name: /Add to your Nextcloud/i }).should('be.visible')
	})
})