widget.test.tsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126
  1. import { expect } from 'chai'
  2. import sinon from 'sinon'
  3. import { screen, fireEvent, render, waitFor } from '@testing-library/react'
  4. import { SSOLinkingWidget } from '../../../../../../frontend/js/features/settings/components/sso-linking/widget'
  5. describe('<SSOLinkingWidget />', function () {
  6. const defaultProps = {
  7. providerId: 'integration_id',
  8. title: 'integration',
  9. description: 'integration description',
  10. helpPath: '/help/integration',
  11. linkPath: 'integration/link',
  12. onUnlink: () => Promise.resolve(),
  13. }
  14. it('should render', function () {
  15. render(<SSOLinkingWidget {...defaultProps} />)
  16. screen.getByText('integration')
  17. screen.getByText('integration description')
  18. expect(
  19. screen.getByRole('link', { name: 'Learn more' }).getAttribute('href')
  20. ).to.equal('/help/integration')
  21. })
  22. describe('when unlinked', function () {
  23. it('should render a link to `linkPath`', function () {
  24. render(<SSOLinkingWidget {...defaultProps} linked={false} />)
  25. expect(
  26. screen.getByRole('link', { name: 'Link' }).getAttribute('href')
  27. ).to.equal('integration/link')
  28. })
  29. })
  30. describe('when linked', function () {
  31. let unlinkFunction
  32. beforeEach(function () {
  33. unlinkFunction = sinon.stub()
  34. render(
  35. <SSOLinkingWidget {...defaultProps} linked onUnlink={unlinkFunction} />
  36. )
  37. })
  38. it('should display an `unlink` button', function () {
  39. screen.getByRole('button', { name: 'Unlink' })
  40. })
  41. it('should open a modal to confirm integration unlinking', function () {
  42. fireEvent.click(screen.getByRole('button', { name: 'Unlink' }))
  43. screen.getByText('Unlink integration Account')
  44. screen.getByText(
  45. 'Warning: When you unlink your account from integration you will not be able to sign in using integration anymore.'
  46. )
  47. })
  48. it('should cancel unlinking when clicking cancel in the confirmation modal', async function () {
  49. fireEvent.click(screen.getByRole('button', { name: 'Unlink' }))
  50. const cancelBtn = screen.getByRole('button', {
  51. name: 'Cancel',
  52. hidden: false,
  53. })
  54. fireEvent.click(cancelBtn)
  55. await waitFor(() =>
  56. screen.getByRole('button', { name: 'Cancel', hidden: true })
  57. )
  58. expect(unlinkFunction).not.to.have.been.called
  59. })
  60. })
  61. describe('unlinking an account', function () {
  62. let confirmBtn, unlinkFunction
  63. beforeEach(function () {
  64. unlinkFunction = sinon.stub()
  65. render(
  66. <SSOLinkingWidget {...defaultProps} linked onUnlink={unlinkFunction} />
  67. )
  68. fireEvent.click(screen.getByRole('button', { name: 'Unlink' }))
  69. confirmBtn = screen.getByRole('button', {
  70. name: 'Unlink',
  71. hidden: false,
  72. })
  73. })
  74. it('should make an `unlink` request', function () {
  75. unlinkFunction.resolves()
  76. fireEvent.click(confirmBtn)
  77. expect(unlinkFunction).to.have.been.called
  78. })
  79. it('should display feedback while the request is inflight', async function () {
  80. unlinkFunction.returns(
  81. new Promise<void>(resolve => {
  82. setTimeout(resolve, 500)
  83. })
  84. )
  85. fireEvent.click(confirmBtn)
  86. await waitFor(() =>
  87. expect(screen.getByRole('button', { name: 'Unlinking' }))
  88. )
  89. })
  90. })
  91. describe('when unlinking fails', function () {
  92. beforeEach(function () {
  93. const unlinkFunction = sinon.stub().rejects(new Error('unlinking failed'))
  94. render(
  95. <SSOLinkingWidget {...defaultProps} linked onUnlink={unlinkFunction} />
  96. )
  97. fireEvent.click(screen.getByRole('button', { name: 'Unlink' }))
  98. const confirmBtn = screen.getByRole('button', {
  99. name: 'Unlink',
  100. hidden: false,
  101. })
  102. fireEvent.click(confirmBtn)
  103. })
  104. it('should display an error message ', async function () {
  105. await waitFor(() => screen.getByText('unlinking failed'))
  106. })
  107. it('should display the unlink button ', async function () {
  108. await waitFor(() => screen.getByRole('button', { name: 'Unlink' }))
  109. })
  110. })
  111. })