columnEditorModal.spec.tsx 4.9 KB

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