clone-project-modal.test.js 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. import React from 'react'
  2. import { fireEvent, render, screen, waitFor } from '@testing-library/react'
  3. import { expect } from 'chai'
  4. import CloneProjectModal from '../../../../../frontend/js/features/clone-project-modal/components/clone-project-modal'
  5. import sinon from 'sinon'
  6. import fetchMock from 'fetch-mock'
  7. describe('<CloneProjectModal />', function() {
  8. afterEach(function() {
  9. fetchMock.reset()
  10. })
  11. const modalProps = {
  12. handleHide: sinon.stub(),
  13. projectId: 'project-1',
  14. projectName: 'Test Project',
  15. openProject: sinon.stub(),
  16. show: true
  17. }
  18. it('renders the translated modal title', async function() {
  19. render(<CloneProjectModal {...modalProps} />)
  20. await screen.findByText('Copy Project')
  21. })
  22. it('posts the generated project name', async function() {
  23. fetchMock.post(
  24. 'express:/project/:projectId/clone',
  25. {
  26. status: 200,
  27. body: { project_id: modalProps.projectId }
  28. },
  29. { delay: 10 }
  30. )
  31. const openProject = sinon.stub()
  32. render(<CloneProjectModal {...modalProps} openProject={openProject} />)
  33. const cancelButton = await screen.findByRole('button', { name: 'Cancel' })
  34. expect(cancelButton.disabled).to.be.false
  35. const submitButton = await screen.findByRole('button', { name: 'Copy' })
  36. expect(submitButton.disabled).to.be.false
  37. const input = await screen.getByLabelText('New Name')
  38. fireEvent.change(input, {
  39. target: { value: '' }
  40. })
  41. expect(submitButton.disabled).to.be.true
  42. fireEvent.change(input, {
  43. target: { value: 'A Cloned Project' }
  44. })
  45. expect(submitButton.disabled).to.be.false
  46. fireEvent.click(submitButton)
  47. expect(submitButton.disabled).to.be.true
  48. await fetchMock.flush(true)
  49. expect(fetchMock.done()).to.be.true
  50. const [url, options] = fetchMock.lastCall(
  51. 'express:/project/:projectId/clone'
  52. )
  53. expect(url).to.equal('/project/project-1/clone')
  54. expect(JSON.parse(options.body)).to.deep.equal({
  55. projectName: 'A Cloned Project'
  56. })
  57. expect(openProject).to.be.calledOnce
  58. const errorMessage = screen.queryByText('Sorry, something went wrong')
  59. expect(errorMessage).to.be.null
  60. await waitFor(() => {
  61. expect(submitButton.disabled).to.be.false
  62. expect(cancelButton.disabled).to.be.false
  63. })
  64. })
  65. it('handles a generic error response', async function() {
  66. const matcher = 'express:/project/:projectId/clone'
  67. fetchMock.postOnce(matcher, {
  68. status: 500,
  69. body: 'There was an error!'
  70. })
  71. const openProject = sinon.stub()
  72. render(<CloneProjectModal {...modalProps} openProject={openProject} />)
  73. const button = await screen.findByRole('button', { name: 'Copy' })
  74. expect(button.disabled).to.be.false
  75. const cancelButton = await screen.findByRole('button', { name: 'Cancel' })
  76. expect(cancelButton.disabled).to.be.false
  77. fireEvent.click(button)
  78. expect(fetchMock.done(matcher)).to.be.true
  79. expect(openProject).not.to.be.called
  80. await screen.findByText('Sorry, something went wrong')
  81. expect(button.disabled).to.be.false
  82. expect(cancelButton.disabled).to.be.false
  83. })
  84. it('handles a specific error response', async function() {
  85. const matcher = 'express:/project/:projectId/clone'
  86. fetchMock.postOnce(matcher, {
  87. status: 400,
  88. body: 'There was an error!'
  89. })
  90. const openProject = sinon.stub()
  91. render(<CloneProjectModal {...modalProps} openProject={openProject} />)
  92. const button = await screen.findByRole('button', { name: 'Copy' })
  93. expect(button.disabled).to.be.false
  94. const cancelButton = await screen.findByRole('button', { name: 'Cancel' })
  95. expect(cancelButton.disabled).to.be.false
  96. fireEvent.click(button)
  97. await fetchMock.flush(true)
  98. expect(fetchMock.done(matcher)).to.be.true
  99. expect(openProject).not.to.be.called
  100. await screen.findByText('There was an error!')
  101. expect(button.disabled).to.be.false
  102. expect(cancelButton.disabled).to.be.false
  103. })
  104. })