dashboard-transloadit.spec.ts 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189
  1. const FLAKY = {
  2. retries: {
  3. runMode: 3, // retry flaky test
  4. },
  5. }
  6. describe('Dashboard with Transloadit', () => {
  7. beforeEach(() => {
  8. cy.visit('/dashboard-transloadit')
  9. cy.get('.uppy-Dashboard-input:first').as('file-input')
  10. cy.intercept('/assemblies').as('createAssemblies')
  11. cy.intercept('/assemblies/*').as('assemblies')
  12. cy.intercept('/resumable/*').as('resumable')
  13. })
  14. it('should upload cat image successfully', () => {
  15. cy.get('@file-input').selectFile('cypress/fixtures/images/cat.jpg', { force:true })
  16. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  17. cy.wait('@assemblies')
  18. cy.wait('@resumable')
  19. cy.get('.uppy-StatusBar-statusPrimary').should('contain', 'Complete')
  20. })
  21. it('should close assembly polling when cancelled', () => {
  22. cy.get('@file-input').selectFile(['cypress/fixtures/images/cat.jpg', 'cypress/fixtures/images/traffic.jpg'], { force:true })
  23. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  24. cy.intercept({
  25. method: 'GET',
  26. url: '/assemblies/*',
  27. }).as('assemblyPolling')
  28. cy.intercept(
  29. { method: 'PATCH', pathname: '/files/*', times: 1 },
  30. { statusCode: 204, body: {} },
  31. )
  32. cy.intercept(
  33. { method: 'DELETE', pathname: '/resumable/files/*', times: 1 },
  34. { statusCode: 204, body: {} },
  35. )
  36. cy.wait('@assemblyPolling')
  37. cy.window().then(({ uppy }) => {
  38. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).every((a: any) => a.pollInterval)).to.equal(true)
  39. })
  40. cy.get('button[data-cy=cancel]').click()
  41. cy.window().then(({ uppy }) => {
  42. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).some((a: any) => a.pollInterval)).to.equal(false)
  43. })
  44. })
  45. it('should emit one assembly-cancelled event when cancelled', FLAKY, () => {
  46. const spy = cy.spy()
  47. cy.get('@file-input').selectFile(['cypress/fixtures/images/cat.jpg', 'cypress/fixtures/images/traffic.jpg'], { force:true })
  48. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  49. cy.intercept({
  50. method: 'GET',
  51. url: '/assemblies/*',
  52. }).as('assemblyPolling')
  53. cy.intercept(
  54. { method: 'PATCH', pathname: '/files/*', times: 1 },
  55. { statusCode: 204, body: {} },
  56. )
  57. cy.intercept(
  58. { method: 'DELETE', pathname: '/resumable/files/*', times: 2 },
  59. { statusCode: 204, body: {} },
  60. ).as('fileDeletion')
  61. cy.intercept(
  62. { method: 'DELETE', pathname: '/assemblies/*', times: 1 },
  63. ).as('assemblyDeletion')
  64. cy.wait('@assemblyPolling')
  65. cy.window().then(({ uppy }) => {
  66. uppy.on('transloadit:assembly-cancelled', spy)
  67. })
  68. cy.get('button[data-cy=cancel]').click()
  69. cy.wait('@assemblyDeletion').then(() => {
  70. expect(spy).to.be.calledOnce
  71. })
  72. })
  73. it('should close assembly polling when all files are removed', FLAKY, () => {
  74. const spy = cy.spy()
  75. cy.get('@file-input').selectFile(['cypress/fixtures/images/cat.jpg', 'cypress/fixtures/images/traffic.jpg'], { force:true })
  76. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  77. cy.intercept({
  78. method: 'GET',
  79. url: '/assemblies/*',
  80. }).as('assemblyPolling')
  81. cy.intercept(
  82. { method: 'PATCH', pathname: '/files/*', times: 1 },
  83. { statusCode: 204, body: {} },
  84. )
  85. cy.intercept(
  86. { method: 'DELETE', pathname: '/resumable/files/*', times: 2 },
  87. { statusCode: 204, body: {} },
  88. ).as('fileDeletion')
  89. cy.intercept(
  90. { method: 'DELETE', pathname: '/assemblies/*', times: 1 },
  91. ).as('assemblyDeletion')
  92. cy.wait('@assemblyPolling')
  93. cy.window().then(({ uppy }) => {
  94. uppy.on('transloadit:assembly-cancelled', spy)
  95. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).every((a: any) => a.pollInterval)).to.equal(true)
  96. const { files } = uppy.getState()
  97. uppy.removeFiles(Object.keys(files))
  98. cy.wait('@assemblyDeletion').then(() => {
  99. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).some((a: any) => a.pollInterval)).to.equal(false)
  100. expect(spy).to.be.calledOnce
  101. })
  102. })
  103. })
  104. it('should not create assembly when all individual files have been cancelled', () => {
  105. cy.get('@file-input').selectFile(['cypress/fixtures/images/cat.jpg', 'cypress/fixtures/images/traffic.jpg'], { force:true })
  106. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  107. cy.window().then(({ uppy }) => {
  108. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).length).to.equal(0)
  109. const { files } = uppy.getState()
  110. uppy.removeFiles(Object.keys(files))
  111. cy.wait('@createAssemblies').then(() => {
  112. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).some((a: any) => a.pollInterval)).to.equal(false)
  113. })
  114. })
  115. })
  116. // Not working, the upstream changes have not landed yet.
  117. it.skip('should create assembly if there is still one file to upload', () => {
  118. cy.get('@file-input').selectFile(['cypress/fixtures/images/cat.jpg', 'cypress/fixtures/images/traffic.jpg'], { force:true })
  119. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  120. cy.window().then(({ uppy }) => {
  121. expect(Object.values(uppy.getPlugin('Transloadit').activeAssemblies).length).to.equal(0)
  122. const { files } = uppy.getState()
  123. const [fileID] = Object.keys(files)
  124. uppy.removeFile(fileID)
  125. cy.wait('@createAssemblies').then(() => {
  126. cy.wait('@resumable')
  127. cy.get('.uppy-StatusBar-statusPrimary').should('contain', 'Complete')
  128. })
  129. })
  130. })
  131. // Not working, the upstream changes have not landed yet.
  132. it.skip('should complete upload if one gets cancelled mid-flight', () => {
  133. cy.get('@file-input').selectFile(['cypress/fixtures/images/cat.jpg', 'cypress/fixtures/images/traffic.jpg'], { force:true })
  134. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  135. cy.wait('@createAssemblies')
  136. cy.wait('@resumable')
  137. cy.window().then(({ uppy }) => {
  138. const { files } = uppy.getState()
  139. const [fileID] = Object.keys(files)
  140. uppy.removeFile(fileID)
  141. cy.get('.uppy-StatusBar-statusPrimary').should('contain', 'Complete')
  142. })
  143. })
  144. it('should not emit error if upload is cancelled right away', () => {
  145. cy.get('@file-input').selectFile('cypress/fixtures/images/cat.jpg', { force:true })
  146. cy.get('.uppy-StatusBar-actionBtn--upload').click()
  147. const handler = cy.spy()
  148. cy.window().then(({ uppy }) => {
  149. const { files } = uppy.getState()
  150. uppy.on('upload-error', handler)
  151. const [fileID] = Object.keys(files)
  152. uppy.removeFile(fileID)
  153. uppy.removeFile(fileID)
  154. cy.wait('@createAssemblies').then(() => expect(handler).not.to.be.called)
  155. })
  156. })
  157. })