view_file-drop.cy.ts 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. /*!
  2. * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
  3. * SPDX-License-Identifier: AGPL-3.0-or-later
  4. */
  5. import { getRowForFile } from '../../files/FilesUtils.ts'
  6. import { openSharingPanel } from '../FilesSharingUtils.ts'
  7. describe('files_sharing: Public share - File drop', { testIsolation: true }, () => {
  8. let shareUrl: string
  9. let user: string
  10. const shareName = 'shared'
  11. before(() => {
  12. cy.createRandomUser().then(($user) => {
  13. user = $user.userId
  14. cy.mkdir($user, `/${shareName}`)
  15. cy.uploadContent($user, new Blob(['content']), 'text/plain', `/${shareName}/foo.txt`)
  16. cy.login($user)
  17. // open the files app
  18. cy.visit('/apps/files')
  19. // open the sidebar
  20. openSharingPanel(shareName)
  21. // create the share
  22. cy.intercept('POST', '**/ocs/v2.php/apps/files_sharing/api/v1/shares').as('createShare')
  23. cy.findByRole('button', { name: 'Create a new share link' })
  24. .click()
  25. // extract the link
  26. cy.wait('@createShare').should(({ response }) => {
  27. const { ocs } = response?.body ?? {}
  28. shareUrl = ocs?.data.url
  29. expect(shareUrl).to.match(/^http:\/\//)
  30. })
  31. // Update the share to be a file drop
  32. cy.findByRole('list', { name: 'Link shares' })
  33. .findAllByRole('listitem')
  34. .first()
  35. .findByRole('button', { name: /Actions/i })
  36. .click()
  37. cy.findByRole('menuitem', { name: /Customize link/i })
  38. .should('be.visible')
  39. .click()
  40. cy.get('[data-cy-files-sharing-share-permissions-bundle]')
  41. .should('be.visible')
  42. cy.get('[data-cy-files-sharing-share-permissions-bundle="file-drop"]')
  43. .click()
  44. // save the update
  45. cy.intercept('PUT', '**/ocs/v2.php/apps/files_sharing/api/v1/shares/*').as('updateShare')
  46. cy.findByRole('button', { name: 'Update share' })
  47. .click()
  48. cy.wait('@updateShare')
  49. })
  50. })
  51. beforeEach(() => {
  52. cy.logout()
  53. cy.visit(shareUrl)
  54. })
  55. it('Cannot see share content', () => {
  56. cy.contains(`Upload files to ${shareName}`)
  57. .should('be.visible')
  58. // foo exists
  59. cy.userFileExists(user, `${shareName}/foo.txt`).should('be.gt', 0)
  60. // but is not visible
  61. getRowForFile('foo.txt')
  62. .should('not.exist')
  63. })
  64. it('Can only see upload files and upload folders menu entries', () => {
  65. cy.contains(`Upload files to ${shareName}`)
  66. .should('be.visible')
  67. cy.findByRole('button', { name: 'New' })
  68. .should('be.visible')
  69. .click()
  70. // See upload actions
  71. cy.findByRole('menuitem', { name: 'Upload files' })
  72. .should('be.visible')
  73. cy.findByRole('menuitem', { name: 'Upload folders' })
  74. .should('be.visible')
  75. // But no other
  76. cy.findByRole('menu')
  77. .findAllByRole('menuitem')
  78. .should('have.length', 2)
  79. })
  80. it('Can only see dedicated upload button', () => {
  81. cy.contains(`Upload files to ${shareName}`)
  82. .should('be.visible')
  83. cy.findByRole('button', { name: 'Upload' })
  84. .should('be.visible')
  85. .click()
  86. // See upload actions
  87. cy.findByRole('menuitem', { name: 'Upload files' })
  88. .should('be.visible')
  89. cy.findByRole('menuitem', { name: 'Upload folders' })
  90. .should('be.visible')
  91. // But no other
  92. cy.findByRole('menu')
  93. .findAllByRole('menuitem')
  94. .should('have.length', 2)
  95. })
  96. it('Can upload files', () => {
  97. cy.contains(`Upload files to ${shareName}`)
  98. .should('be.visible')
  99. const { promise, resolve } = Promise.withResolvers()
  100. cy.intercept('PUT', '**/public.php/dav/files/**', (request) => {
  101. if (request.url.includes('first.txt')) {
  102. // just continue the first one
  103. request.continue()
  104. } else {
  105. // We delay the second one until we checked that the progress bar is visible
  106. request.on('response', async () => { await promise })
  107. }
  108. }).as('uploadFile')
  109. cy.get('[data-cy-files-sharing-file-drop] input[type="file"]')
  110. .should('exist')
  111. .selectFile([
  112. { fileName: 'first.txt', contents: Buffer.from('8 bytes!') },
  113. { fileName: 'second.md', contents: Buffer.from('x'.repeat(128)) },
  114. ], { force: true })
  115. cy.wait('@uploadFile')
  116. cy.findByRole('progressbar')
  117. .should('be.visible')
  118. .and((el) => { expect(Number.parseInt(el.attr('value') ?? '0')).be.gte(50) })
  119. // continue second request
  120. .then(() => resolve(null))
  121. cy.wait('@uploadFile')
  122. // Check files uploaded
  123. cy.userFileExists(user, `${shareName}/first.txt`).should('eql', 8)
  124. cy.userFileExists(user, `${shareName}/second.md`).should('eql', 128)
  125. })
  126. describe('Terms of service', { testIsolation: true }, () => {
  127. before(() => cy.runOccCommand('config:app:set --value "TEST: Some disclaimer text" --type string core shareapi_public_link_disclaimertext'))
  128. beforeEach(() => cy.visit(shareUrl))
  129. after(() => cy.runOccCommand('config:app:delete core shareapi_public_link_disclaimertext'))
  130. it('shows ToS on file-drop view', () => {
  131. cy.contains(`Upload files to ${shareName}`)
  132. .should('be.visible')
  133. .should('contain.text', 'agree to the terms of service')
  134. cy.findByRole('button', { name: /Terms of service/i })
  135. .should('be.visible')
  136. .click()
  137. cy.findByRole('dialog', { name: 'Terms of service' })
  138. .should('contain.text', 'TEST: Some disclaimer text')
  139. // close
  140. .findByRole('button', { name: 'Close' })
  141. .click()
  142. cy.findByRole('dialog', { name: 'Terms of service' })
  143. .should('not.exist')
  144. })
  145. })
  146. })