guideAnchor.spec.jsx 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. import React from 'react';
  2. import {mountWithTheme, shallow} from 'sentry-test/enzyme';
  3. import GuideAnchor from 'app/components/assistant/guideAnchor';
  4. import GuideActions from 'app/actions/guideActions';
  5. import ConfigStore from 'app/stores/configStore';
  6. describe('GuideAnchor', function() {
  7. const guides = {
  8. guide1: {
  9. id: 1,
  10. required_targets: [],
  11. steps: [
  12. {message: 'abc', target: 'target 1', title: 'title 1'},
  13. {message: 'xyz', target: 'target 2', title: 'title 2'},
  14. ],
  15. },
  16. };
  17. const routerContext = TestStubs.routerContext();
  18. let wrapper1, wrapper2;
  19. beforeEach(function() {
  20. ConfigStore.config = {
  21. user: {
  22. isSuperuser: true,
  23. },
  24. };
  25. wrapper1 = mountWithTheme(<GuideAnchor target="target 1" />, routerContext);
  26. wrapper2 = mountWithTheme(<GuideAnchor target="target 2" />, routerContext);
  27. });
  28. afterEach(function() {
  29. wrapper1.unmount();
  30. wrapper2.unmount();
  31. });
  32. it('renders, advances, and finishes', async function() {
  33. const data = JSON.parse(JSON.stringify(guides)); // deep copy
  34. GuideActions.fetchSucceeded(data);
  35. await tick();
  36. wrapper1.update();
  37. expect(wrapper1).toMatchSnapshot();
  38. // Clicking on next should deactivate the current card and activate the next one.
  39. wrapper1
  40. .find('Button')
  41. .first()
  42. .simulate('click');
  43. await tick();
  44. wrapper1.update();
  45. wrapper2.update();
  46. expect(wrapper1.state('active')).toBeFalsy();
  47. expect(wrapper2.state('active')).toBeTruthy();
  48. expect(wrapper2).toMatchSnapshot();
  49. // Clicking on the button in the last step should finish the guide.
  50. const finishMock = MockApiClient.addMockResponse({
  51. method: 'PUT',
  52. url: '/assistant/',
  53. });
  54. wrapper2
  55. .find('Button')
  56. .last()
  57. .simulate('click');
  58. expect(finishMock).toHaveBeenCalledWith(
  59. '/assistant/',
  60. expect.objectContaining({
  61. method: 'PUT',
  62. data: {
  63. guide_id: 1,
  64. status: 'viewed',
  65. },
  66. })
  67. );
  68. });
  69. it('dismisses', async function() {
  70. const data = JSON.parse(JSON.stringify(guides)); // deep copy
  71. GuideActions.fetchSucceeded(data);
  72. await tick();
  73. wrapper1.update();
  74. const dismissMock = MockApiClient.addMockResponse({
  75. method: 'PUT',
  76. url: '/assistant/',
  77. });
  78. wrapper1
  79. .find('[data-test-id="close-button"]')
  80. .first()
  81. .simulate('click');
  82. expect(dismissMock).toHaveBeenCalledWith(
  83. '/assistant/',
  84. expect.objectContaining({
  85. method: 'PUT',
  86. data: {
  87. guide_id: 1,
  88. status: 'dismissed',
  89. },
  90. })
  91. );
  92. await tick();
  93. expect(wrapper1.state('active')).toBeFalsy();
  94. });
  95. it('renders no container when inactive', function() {
  96. const wrapper = shallow(
  97. <GuideAnchor target="target 1">
  98. <span>A child</span>
  99. </GuideAnchor>
  100. );
  101. const component = wrapper.instance();
  102. wrapper.update();
  103. expect(component.state).toMatchObject({active: false});
  104. expect(wrapper.find('Hovercard')).toHaveLength(0);
  105. });
  106. });