integration-widget.test.tsx 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import { expect } from 'chai'
  2. import sinon from 'sinon'
  3. import { screen, fireEvent, render, within } from '@testing-library/react'
  4. import { IntegrationLinkingWidget } from '../../../../../../frontend/js/features/settings/components/linking/integration-widget'
  5. import * as eventTracking from '@/infrastructure/event-tracking'
  6. describe('<IntegrationLinkingWidgetTest/>', function () {
  7. const defaultProps = {
  8. id: 'integration-widget-id',
  9. logo: <div />,
  10. title: 'Integration',
  11. description: 'paragraph1',
  12. helpPath: '/learn',
  13. linkPath: '/link',
  14. unlinkPath: '/unlink',
  15. unlinkConfirmationTitle: 'confirm unlink',
  16. unlinkConfirmationText: 'you will be unlinked',
  17. }
  18. describe('when the feature is not available', function () {
  19. let sendMBSpy: sinon.SinonSpy
  20. beforeEach(function () {
  21. sendMBSpy = sinon.spy(eventTracking, 'sendMB')
  22. render(<IntegrationLinkingWidget {...defaultProps} hasFeature={false} />)
  23. })
  24. afterEach(function () {
  25. sendMBSpy.restore()
  26. })
  27. it("should render 'Premium feature' label", function () {
  28. screen.getByText('Premium feature')
  29. })
  30. it('should render an upgrade link and track clicks', function () {
  31. const upgradeLink = screen.getByRole('button', { name: /upgrade/i })
  32. expect(upgradeLink.getAttribute('href')).to.equal(
  33. '/user/subscription/plans'
  34. )
  35. fireEvent.click(upgradeLink)
  36. expect(sendMBSpy).to.be.calledOnce
  37. expect(sendMBSpy).calledWith('settings-upgrade-click')
  38. })
  39. })
  40. describe('when the integration is not linked', function () {
  41. beforeEach(function () {
  42. render(
  43. <IntegrationLinkingWidget {...defaultProps} hasFeature linked={false} />
  44. )
  45. })
  46. it('should render a link to initiate integration linking', function () {
  47. expect(
  48. screen.getByRole('button', { name: 'Link' }).getAttribute('href')
  49. ).to.equal('/link')
  50. })
  51. it("should not render 'premium feature' labels", function () {
  52. expect(screen.queryByText('premium_feature')).to.not.exist
  53. expect(screen.queryByText('integration_is_a_premium_feature')).to.not
  54. .exist
  55. })
  56. })
  57. describe('when the integration is linked', function () {
  58. beforeEach(function () {
  59. render(
  60. <IntegrationLinkingWidget
  61. {...defaultProps}
  62. hasFeature
  63. linked
  64. statusIndicator={<div>status indicator</div>}
  65. />
  66. )
  67. })
  68. it('should render a status indicator', function () {
  69. screen.getByText('status indicator')
  70. })
  71. it("should not render 'premium feature' labels", function () {
  72. expect(screen.queryByText('premium_feature')).to.not.exist
  73. expect(screen.queryByText('integration_is_a_premium_feature')).to.not
  74. .exist
  75. })
  76. it('should display an `unlink` button', function () {
  77. screen.getByRole('button', { name: 'Unlink' })
  78. })
  79. it('should open a modal with a link to confirm integration unlinking', function () {
  80. fireEvent.click(screen.getByRole('button', { name: 'Unlink' }))
  81. const withinModal = within(screen.getByRole('dialog'))
  82. withinModal.getByText('confirm unlink')
  83. withinModal.getByText('you will be unlinked')
  84. withinModal.getByRole('button', { name: 'Cancel' })
  85. withinModal.getByRole('button', { name: 'Unlink' })
  86. })
  87. it('should cancel unlinking when clicking "cancel" in the confirmation modal', async function () {
  88. fireEvent.click(screen.getByRole('button', { name: 'Unlink' }))
  89. screen.getByText('confirm unlink')
  90. const cancelBtn = screen.getByRole('button', {
  91. name: 'Cancel',
  92. hidden: false,
  93. })
  94. fireEvent.click(cancelBtn)
  95. await screen.findByRole('button', { name: 'Cancel', hidden: true })
  96. })
  97. })
  98. })