integrationExternalMappings.spec.jsx 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {mountGlobalModal} from 'sentry-test/modal';
  3. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  4. import IntegrationExternalMappings from 'sentry/components/integrationExternalMappings';
  5. describe('IntegrationExternalMappings', function () {
  6. const {organization, routerContext} = initializeOrg();
  7. const onCreateMock = jest.fn();
  8. const onDeleteMock = jest.fn();
  9. const MOCK_USER_SUGGESTIONS = ['@peter', '@ned', '@mj'];
  10. const MOCK_TEAM_SUGGESTIONS = [
  11. '@getsentry/snacks',
  12. '@getsentry/sports',
  13. '@getsentry/hype',
  14. ];
  15. const MOCK_USER_MAPPINGS = [
  16. {
  17. id: '1',
  18. userId: '1',
  19. externalName: '@gwen',
  20. sentryName: 'gwen@mcu.org',
  21. },
  22. {
  23. id: '2',
  24. userId: '2',
  25. externalName: '@eddie',
  26. sentryName: 'eddie@mcu.org',
  27. },
  28. ];
  29. const MOCK_TEAM_MAPPINGS = [
  30. {
  31. id: '1',
  32. teamId: '1',
  33. externalName: '@getsentry/animals',
  34. sentryName: '#zoo',
  35. },
  36. {
  37. id: '2',
  38. teamId: '2',
  39. externalName: '@getsentry/ghosts',
  40. sentryName: '#boo',
  41. },
  42. ];
  43. const createMockSuggestions = () => {
  44. MockApiClient.addMockResponse({
  45. url: `/organizations/${organization.slug}/codeowners-associations/`,
  46. method: 'GET',
  47. body: {
  48. 'project-1': {
  49. errors: {
  50. missing_external_users: MOCK_USER_SUGGESTIONS,
  51. missing_external_teams: MOCK_TEAM_SUGGESTIONS,
  52. },
  53. },
  54. },
  55. });
  56. };
  57. it('renders empty if not mappings are provided or found', async function () {
  58. MockApiClient.addMockResponse({
  59. url: `/organizations/${organization.slug}/codeowners-associations/`,
  60. method: 'GET',
  61. body: {},
  62. });
  63. render(
  64. <IntegrationExternalMappings
  65. organization={organization}
  66. integration={TestStubs.GitHubIntegration()}
  67. mappings={[]}
  68. type="user"
  69. onCreate={onCreateMock}
  70. onDelete={onDeleteMock}
  71. defaultOptions={[]}
  72. />,
  73. {
  74. context: routerContext,
  75. }
  76. );
  77. await act(tick);
  78. expect(screen.getByTestId('empty-message')).toBeInTheDocument();
  79. });
  80. it('still renders suggestions if no mappings are provided', async function () {
  81. createMockSuggestions();
  82. render(
  83. <IntegrationExternalMappings
  84. organization={organization}
  85. integration={TestStubs.GitHubIntegration()}
  86. mappings={[]}
  87. type="user"
  88. onCreate={onCreateMock}
  89. onDelete={onDeleteMock}
  90. defaultOptions={[]}
  91. />,
  92. {
  93. context: routerContext,
  94. }
  95. );
  96. await act(tick);
  97. expect(await screen.findByTestId('mapping-table')).toBeInTheDocument();
  98. for (const user of MOCK_USER_SUGGESTIONS) {
  99. expect(await screen.findByText(user)).toBeInTheDocument();
  100. }
  101. expect(await screen.findAllByTestId('suggestion-option')).toHaveLength(3);
  102. });
  103. it('renders suggestions along with the provided mappings', async function () {
  104. createMockSuggestions();
  105. render(
  106. <IntegrationExternalMappings
  107. organization={organization}
  108. integration={TestStubs.GitHubIntegration()}
  109. mappings={MOCK_TEAM_MAPPINGS}
  110. type="team"
  111. onCreate={onCreateMock}
  112. onDelete={onDeleteMock}
  113. defaultOptions={[]}
  114. />,
  115. {
  116. context: routerContext,
  117. }
  118. );
  119. await act(tick);
  120. expect(await screen.findByTestId('mapping-table')).toBeInTheDocument();
  121. for (const team of MOCK_TEAM_SUGGESTIONS) {
  122. expect(await screen.findByText(team)).toBeInTheDocument();
  123. }
  124. expect(await screen.findAllByTestId('mapping-option')).toHaveLength(2);
  125. for (const team of MOCK_TEAM_MAPPINGS) {
  126. expect(await screen.findByText(team.externalName)).toBeInTheDocument();
  127. expect(await screen.findByText(team.sentryName)).toBeInTheDocument();
  128. }
  129. expect(await screen.findAllByTestId('suggestion-option')).toHaveLength(3);
  130. });
  131. it('uses the methods passed down from props appropriately', async function () {
  132. render(
  133. <IntegrationExternalMappings
  134. organization={organization}
  135. integration={TestStubs.GitHubIntegration()}
  136. mappings={MOCK_USER_MAPPINGS}
  137. type="user"
  138. onCreate={onCreateMock}
  139. onDelete={onDeleteMock}
  140. defaultOptions={[]}
  141. />,
  142. {
  143. context: routerContext,
  144. }
  145. );
  146. await act(tick);
  147. expect(await screen.findByTestId('mapping-table')).toBeInTheDocument();
  148. userEvent.click(screen.getByTestId('add-mapping-button'));
  149. expect(onCreateMock).toHaveBeenCalled();
  150. userEvent.click(screen.getAllByTestId('delete-mapping-button')[0]);
  151. await act(tick);
  152. mountGlobalModal();
  153. userEvent.click(screen.getByTestId('confirm-button'));
  154. expect(onDeleteMock).toHaveBeenCalled();
  155. });
  156. });