columnEditorModal.spec.tsx 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. import {act, renderGlobalModal, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import {openModal} from 'sentry/actionCreators/modal';
  3. import type {TagCollection} from 'sentry/types/group';
  4. import {ColumnEditorModal} from 'sentry/views/explore/tables/columnEditorModal';
  5. const stringTags: TagCollection = {
  6. id: {
  7. key: 'id',
  8. name: 'id',
  9. },
  10. project: {
  11. key: 'project',
  12. name: 'project',
  13. },
  14. 'span.op': {
  15. key: 'span.op',
  16. name: 'span.op',
  17. },
  18. };
  19. const numberTags: TagCollection = {
  20. 'span.duration': {
  21. key: 'span.duration',
  22. name: 'span.duration',
  23. },
  24. };
  25. describe('ColumnEditorModal', function () {
  26. beforeEach(function () {
  27. // without this the `CompactSelect` component errors with a bunch of async updates
  28. jest.spyOn(console, 'error').mockImplementation();
  29. });
  30. it('allows closes modal on apply', async function () {
  31. const onClose = jest.fn();
  32. renderGlobalModal();
  33. act(() => {
  34. openModal(
  35. modalProps => (
  36. <ColumnEditorModal
  37. {...modalProps}
  38. columns={['id', 'project']}
  39. onColumnsChange={() => {}}
  40. stringTags={stringTags}
  41. numberTags={numberTags}
  42. />
  43. ),
  44. {onClose}
  45. );
  46. });
  47. expect(onClose).not.toHaveBeenCalled();
  48. await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
  49. expect(onClose).toHaveBeenCalled();
  50. });
  51. it('allows deleting a column', async function () {
  52. const onColumnsChange = jest.fn();
  53. renderGlobalModal();
  54. act(() => {
  55. openModal(
  56. modalProps => (
  57. <ColumnEditorModal
  58. {...modalProps}
  59. columns={['id', 'project']}
  60. onColumnsChange={onColumnsChange}
  61. stringTags={stringTags}
  62. numberTags={numberTags}
  63. />
  64. ),
  65. {onClose: jest.fn()}
  66. );
  67. });
  68. const columns1 = ['id', 'project'];
  69. screen.getAllByTestId('editor-column').forEach((column, i) => {
  70. expect(column).toHaveTextContent(columns1[i]);
  71. });
  72. await userEvent.click(screen.getAllByLabelText('Remove Column')[0]);
  73. const columns2 = ['project'];
  74. screen.getAllByTestId('editor-column').forEach((column, i) => {
  75. expect(column).toHaveTextContent(columns2[i]);
  76. });
  77. // only 1 column remaining, disable the delete option
  78. expect(screen.getByLabelText('Remove Column')).toBeDisabled();
  79. await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
  80. expect(onColumnsChange).toHaveBeenCalledWith(['project']);
  81. });
  82. it('allows adding a column', async function () {
  83. const onColumnsChange = jest.fn();
  84. renderGlobalModal();
  85. act(() => {
  86. openModal(
  87. modalProps => (
  88. <ColumnEditorModal
  89. {...modalProps}
  90. columns={['id', 'project']}
  91. onColumnsChange={onColumnsChange}
  92. stringTags={stringTags}
  93. numberTags={numberTags}
  94. />
  95. ),
  96. {onClose: jest.fn()}
  97. );
  98. });
  99. const columns1 = ['id', 'project'];
  100. screen.getAllByTestId('editor-column').forEach((column, i) => {
  101. expect(column).toHaveTextContent(columns1[i]);
  102. });
  103. await userEvent.click(screen.getByRole('button', {name: 'Add a Column'}));
  104. const columns2 = ['id', 'project', 'None'];
  105. screen.getAllByTestId('editor-column').forEach((column, i) => {
  106. expect(column).toHaveTextContent(columns2[i]);
  107. });
  108. const options: [string, 'string' | 'number'][] = [
  109. ['id', 'string'],
  110. ['project', 'string'],
  111. ['span.duration', 'number'],
  112. ['span.op', 'string'],
  113. ];
  114. await userEvent.click(screen.getByRole('button', {name: 'Column None'}));
  115. const columnOptions = await screen.findAllByRole('option');
  116. columnOptions.forEach((option, i) => {
  117. expect(option).toHaveTextContent(options[i][0]);
  118. expect(option).toHaveTextContent(options[i][1]);
  119. });
  120. await userEvent.click(columnOptions[3]);
  121. const columns3 = ['id', 'project', 'span.op'];
  122. screen.getAllByTestId('editor-column').forEach((column, i) => {
  123. expect(column).toHaveTextContent(columns3[i]);
  124. });
  125. await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
  126. expect(onColumnsChange).toHaveBeenCalledWith(['id', 'project', 'span.op']);
  127. });
  128. it('allows changing a column', async function () {
  129. const onColumnsChange = jest.fn();
  130. renderGlobalModal();
  131. act(() => {
  132. openModal(
  133. modalProps => (
  134. <ColumnEditorModal
  135. {...modalProps}
  136. columns={['id', 'project']}
  137. onColumnsChange={onColumnsChange}
  138. stringTags={stringTags}
  139. numberTags={numberTags}
  140. />
  141. ),
  142. {onClose: jest.fn()}
  143. );
  144. });
  145. const columns1 = ['id', 'project'];
  146. screen.getAllByTestId('editor-column').forEach((column, i) => {
  147. expect(column).toHaveTextContent(columns1[i]);
  148. });
  149. const options: [string, 'string' | 'number'][] = [
  150. ['id', 'string'],
  151. ['project', 'string'],
  152. ['span.duration', 'number'],
  153. ['span.op', 'string'],
  154. ];
  155. await userEvent.click(screen.getByRole('button', {name: 'Column project string'}));
  156. const columnOptions = await screen.findAllByRole('option');
  157. columnOptions.forEach((option, i) => {
  158. expect(option).toHaveTextContent(options[i][0]);
  159. expect(option).toHaveTextContent(options[i][1]);
  160. });
  161. await userEvent.click(columnOptions[3]);
  162. const columns2 = ['id', 'span.op'];
  163. screen.getAllByTestId('editor-column').forEach((column, i) => {
  164. expect(column).toHaveTextContent(columns2[i]);
  165. });
  166. await userEvent.click(screen.getByRole('button', {name: 'Apply'}));
  167. expect(onColumnsChange).toHaveBeenCalledWith(['id', 'span.op']);
  168. });
  169. });