featureTourModal.spec.jsx 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. import {Fragment} from 'react';
  2. import {mountWithTheme} from 'sentry-test/enzyme';
  3. import GlobalModal from 'sentry/components/globalModal';
  4. import FeatureTourModal from 'sentry/components/modals/featureTourModal';
  5. const steps = [
  6. {
  7. title: 'First',
  8. body: 'First step',
  9. image: <em data-test-id="step-image">Image</em>,
  10. actions: (
  11. <a href="#" data-test-id="step-action">
  12. additional action
  13. </a>
  14. ),
  15. },
  16. {title: 'Second', body: 'Second step'},
  17. ];
  18. describe('FeatureTourModal', function () {
  19. let onAdvance, onCloseModal;
  20. const createWrapper = (props = {}) =>
  21. mountWithTheme(
  22. <Fragment>
  23. <GlobalModal />
  24. <FeatureTourModal
  25. steps={steps}
  26. onAdvance={onAdvance}
  27. onCloseModal={onCloseModal}
  28. {...props}
  29. >
  30. {({showModal}) => (
  31. <a href="#" onClick={showModal} data-test-id="reveal">
  32. Open
  33. </a>
  34. )}
  35. </FeatureTourModal>
  36. </Fragment>
  37. );
  38. const showModal = async wrapper => {
  39. wrapper.find('[data-test-id="reveal"]').simulate('click');
  40. await tick();
  41. wrapper.update();
  42. };
  43. beforeEach(function () {
  44. onAdvance = jest.fn();
  45. onCloseModal = jest.fn();
  46. });
  47. it('shows the modal on click', async function () {
  48. const wrapper = createWrapper();
  49. // No modal showing
  50. expect(wrapper.find('GlobalModal').props().visible).toEqual(false);
  51. await showModal(wrapper);
  52. // Modal is now showing
  53. expect(wrapper.find('GlobalModal').props().visible).toEqual(true);
  54. });
  55. it('advances on click', async function () {
  56. const wrapper = createWrapper();
  57. await showModal(wrapper);
  58. // Should start on the first step.
  59. expect(wrapper.find('TourHeader h4').text()).toEqual(steps[0].title);
  60. // Advance to the next step.
  61. wrapper.find('Button[data-test-id="next-step"]').simulate('click');
  62. // Should move to next step.
  63. expect(wrapper.find('TourHeader h4').text()).toEqual(steps[1].title);
  64. expect(onAdvance).toHaveBeenCalled();
  65. });
  66. it('shows step content', async function () {
  67. const wrapper = createWrapper();
  68. await showModal(wrapper);
  69. // Should show title, image and actions
  70. expect(wrapper.find('TourHeader h4').text()).toEqual(steps[0].title);
  71. expect(wrapper.find('TourContent em[data-test-id="step-image"]')).toHaveLength(1);
  72. expect(wrapper.find('TourContent a[data-test-id="step-action"]')).toHaveLength(1);
  73. expect(wrapper.find('StepCounter').text()).toEqual('1 of 2');
  74. });
  75. it('last step shows done', async function () {
  76. const wrapper = createWrapper();
  77. await showModal(wrapper);
  78. // Advance to the the last step.
  79. wrapper.find('Button[data-test-id="next-step"]').simulate('click');
  80. // Click the done
  81. wrapper.find('Button[data-test-id="complete-tour"]').simulate('click');
  82. // Wait for the ModalStore action to propagate.
  83. await tick();
  84. expect(onAdvance).toHaveBeenCalledTimes(1);
  85. expect(onCloseModal).toHaveBeenCalledTimes(1);
  86. });
  87. it('last step shows doneText and uses doneUrl', async function () {
  88. const props = {doneText: 'Finished', doneUrl: 'http://example.org'};
  89. const wrapper = createWrapper(props);
  90. await showModal(wrapper);
  91. // Advance to the the last step.
  92. wrapper.find('Button[data-test-id="next-step"]').simulate('click');
  93. // Ensure button looks right
  94. const button = wrapper.find('Button[data-test-id="complete-tour"]');
  95. expect(button.text()).toEqual(props.doneText);
  96. expect(button.props().href).toEqual(props.doneUrl);
  97. // Click the done
  98. button.simulate('click');
  99. // Wait for the ModalStore action to propagate.
  100. await tick();
  101. expect(onCloseModal).toHaveBeenCalledTimes(1);
  102. });
  103. it('close button dismisses modal', async function () {
  104. const wrapper = createWrapper();
  105. await showModal(wrapper);
  106. wrapper.find('CloseButton').simulate('click');
  107. // Wait for the ModalStore action to propagate.
  108. await tick();
  109. expect(onCloseModal).toHaveBeenCalled();
  110. });
  111. });