hook.spec.jsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. import {render, screen} from 'sentry-test/reactTestingLibrary';
  2. import Hook from 'sentry/components/hook';
  3. import HookStore from 'sentry/stores/hookStore';
  4. const HookWrapper = props => (
  5. <div data-test-id="hook-wrapper">
  6. {props.children}
  7. <span>{JSON.stringify(props?.organization ?? {}, null, 2)}</span>
  8. </div>
  9. );
  10. describe('Hook', function () {
  11. afterEach(function () {
  12. HookStore.teardown();
  13. HookStore.init();
  14. });
  15. it('renders component from a hook', function () {
  16. HookStore.add('footer', ({organization} = {}) => (
  17. <HookWrapper key={0} organization={organization}>
  18. {organization.slug}
  19. </HookWrapper>
  20. ));
  21. render(
  22. <div>
  23. <Hook name="footer" organization={TestStubs.Organization()} />
  24. </div>
  25. );
  26. expect(HookStore.hooks.footer).toHaveLength(1);
  27. expect(screen.getByTestId('hook-wrapper')).toBeInTheDocument();
  28. expect(screen.getByTestId('hook-wrapper')).toHaveTextContent('org-slug');
  29. });
  30. it('renders an invalid hook', function () {
  31. HookStore.add('footer', ({organization} = {}) => (
  32. <HookWrapper key={0} organization={organization}>
  33. {organization.slug}
  34. </HookWrapper>
  35. ));
  36. render(
  37. <div>
  38. <Hook name="invalid-hook" organization={TestStubs.Organization()} />
  39. invalid
  40. </div>
  41. );
  42. expect(screen.queryByText('org-slug')).not.toBeInTheDocument();
  43. expect(screen.getByText('invalid')).toBeInTheDocument();
  44. });
  45. it('can re-render when hooks get after initial render', function () {
  46. HookStore.add('footer', ({organization} = {}) => (
  47. <HookWrapper key={0} organization={organization}>
  48. Old Hook
  49. </HookWrapper>
  50. ));
  51. const {rerender} = render(
  52. <Hook name="footer" organization={TestStubs.Organization()} />
  53. );
  54. expect(screen.getByTestId('hook-wrapper')).toBeInTheDocument();
  55. HookStore.add('footer', () => (
  56. <HookWrapper key="new" organization={null}>
  57. New Hook
  58. </HookWrapper>
  59. ));
  60. rerender(<Hook name="footer" organization={TestStubs.Organization()} />);
  61. expect(screen.getAllByTestId('hook-wrapper')).toHaveLength(2);
  62. expect(screen.getByText(/New Hook/)).toBeInTheDocument();
  63. expect(screen.getByText(/Old Hook/)).toBeInTheDocument();
  64. });
  65. it('can use children as a render prop', function () {
  66. let idx = 0;
  67. render(
  68. <Hook name="footer" organization={TestStubs.Organization()}>
  69. {({hooks}) =>
  70. hooks.map((hook, i) => (
  71. <HookWrapper key={i}>
  72. {hook} {`hook: ${++idx}`}
  73. </HookWrapper>
  74. ))
  75. }
  76. </Hook>
  77. );
  78. HookStore.add('footer', () => (
  79. <HookWrapper key="new" organization={null}>
  80. First Hook
  81. </HookWrapper>
  82. ));
  83. HookStore.add('footer', () => (
  84. <HookWrapper key="new" organization={null}>
  85. Second Hook
  86. </HookWrapper>
  87. ));
  88. for (let i = 0; i < idx; i++) {
  89. expect(screen.getByText(`hook: ${idx}`)).toBeInTheDocument();
  90. }
  91. // Has 2 Wrappers from store, and each is wrapped by another Wrapper
  92. expect(screen.getAllByTestId('hook-wrapper')).toHaveLength(4);
  93. });
  94. });