releasesSelectControl.spec.tsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141
  1. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  2. import {ReleasesContext} from 'sentry/utils/releases/releasesProvider';
  3. import ReleasesSelectControl from 'sentry/views/dashboards/releasesSelectControl';
  4. import {DashboardFilters} from 'sentry/views/dashboards/types';
  5. function renderReleasesSelect({
  6. onSearch,
  7. handleChangeFilter,
  8. }: {
  9. handleChangeFilter?: (activeFilters: DashboardFilters) => void;
  10. onSearch?: (searchTerm: string) => void;
  11. }) {
  12. render(
  13. <ReleasesContext.Provider
  14. value={{
  15. releases: [
  16. TestStubs.Release({
  17. id: '1',
  18. shortVersion: 'sentry-android-shop@1.2.0',
  19. version: 'sentry-android-shop@1.2.0',
  20. }),
  21. TestStubs.Release({
  22. id: '2',
  23. shortVersion: 'sentry-android-shop@1.3.0',
  24. version: 'sentry-android-shop@1.3.0',
  25. }),
  26. TestStubs.Release({
  27. id: '3',
  28. shortVersion: 'sentry-android-shop@1.4.0',
  29. version: 'sentry-android-shop@1.4.0',
  30. }),
  31. ],
  32. loading: false,
  33. onSearch: onSearch ?? jest.fn(),
  34. }}
  35. >
  36. <ReleasesSelectControl
  37. selectedReleases={[]}
  38. handleChangeFilter={handleChangeFilter}
  39. />
  40. </ReleasesContext.Provider>
  41. );
  42. }
  43. describe('Dashboards > ReleasesSelectControl', function () {
  44. it('updates menu title with selection', async function () {
  45. renderReleasesSelect({});
  46. expect(screen.getByText('All Releases')).toBeInTheDocument();
  47. await userEvent.click(screen.getByText('All Releases'));
  48. expect(screen.getByText('Latest Release(s)')).toBeInTheDocument();
  49. await userEvent.click(screen.getByText('sentry-android-shop@1.2.0'));
  50. await userEvent.click(document.body);
  51. expect(screen.getByText('sentry-android-shop@1.2.0')).toBeInTheDocument();
  52. expect(screen.queryByText('+1')).not.toBeInTheDocument();
  53. });
  54. it('updates menu title with multiple selections', async function () {
  55. renderReleasesSelect({});
  56. expect(screen.getByText('All Releases')).toBeInTheDocument();
  57. await userEvent.click(screen.getByText('All Releases'));
  58. await userEvent.click(screen.getByText('sentry-android-shop@1.2.0'));
  59. await userEvent.click(screen.getByText('sentry-android-shop@1.4.0'));
  60. await userEvent.click(document.body);
  61. expect(screen.getByText('sentry-android-shop@1.2.0')).toBeInTheDocument();
  62. expect(screen.getByText('+1')).toBeInTheDocument();
  63. });
  64. it('calls onSearch when filtering by releases', async function () {
  65. const mockOnSearch = jest.fn();
  66. renderReleasesSelect({onSearch: mockOnSearch});
  67. expect(screen.getByText('All Releases')).toBeInTheDocument();
  68. await userEvent.click(screen.getByText('All Releases'));
  69. await userEvent.type(screen.getByPlaceholderText('Search\u2026'), 'se');
  70. await waitFor(() => expect(mockOnSearch).toHaveBeenCalledWith('se'));
  71. });
  72. it('resets search on close', async function () {
  73. const mockOnSearch = jest.fn();
  74. renderReleasesSelect({onSearch: mockOnSearch});
  75. expect(screen.getByText('All Releases')).toBeInTheDocument();
  76. await userEvent.click(screen.getByText('All Releases'));
  77. await userEvent.type(screen.getByPlaceholderText('Search\u2026'), 'se');
  78. await waitFor(() => expect(mockOnSearch).toHaveBeenCalledWith('se'));
  79. await userEvent.click(document.body);
  80. await waitFor(() => expect(mockOnSearch).toHaveBeenCalledWith(''));
  81. });
  82. it('triggers handleChangeFilter with the release versions', async function () {
  83. const mockHandleChangeFilter = jest.fn();
  84. renderReleasesSelect({handleChangeFilter: mockHandleChangeFilter});
  85. expect(screen.getByText('All Releases')).toBeInTheDocument();
  86. await userEvent.click(screen.getByText('All Releases'));
  87. await userEvent.click(screen.getByText('Latest Release(s)'));
  88. await userEvent.click(screen.getByText('sentry-android-shop@1.2.0'));
  89. await userEvent.click(screen.getByText('sentry-android-shop@1.4.0'));
  90. await userEvent.click(document.body);
  91. expect(mockHandleChangeFilter).toHaveBeenCalledWith({
  92. release: ['latest', 'sentry-android-shop@1.2.0', 'sentry-android-shop@1.4.0'],
  93. });
  94. });
  95. it('includes Latest Release(s) even if no matching releases', async function () {
  96. render(
  97. <ReleasesContext.Provider
  98. value={{
  99. releases: [],
  100. loading: false,
  101. onSearch: jest.fn(),
  102. }}
  103. >
  104. <ReleasesSelectControl selectedReleases={[]} handleChangeFilter={jest.fn()} />
  105. </ReleasesContext.Provider>
  106. );
  107. expect(screen.getByText('All Releases')).toBeInTheDocument();
  108. await userEvent.click(screen.getByText('All Releases'));
  109. await userEvent.type(screen.getByPlaceholderText('Search\u2026'), 'latest');
  110. screen.getByText('Latest Release(s)');
  111. });
  112. });