integrationExternalMappings.spec.jsx 4.6 KB

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