sso-widget.test.tsx 4.1 KB

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