integrationCodeMappings.spec.jsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191
  1. import {mountWithTheme} from 'sentry-test/enzyme';
  2. import {mountGlobalModal} from 'sentry-test/modal';
  3. import {selectByValue} from 'sentry-test/select-new';
  4. import {Client} from 'sentry/api';
  5. import ModalStore from 'sentry/stores/modalStore';
  6. import ProjectsStore from 'sentry/stores/projectsStore';
  7. import IntegrationCodeMappings from 'sentry/views/organizationIntegrations/integrationCodeMappings';
  8. const mockResponse = mocks => {
  9. mocks.forEach(([url, body]) =>
  10. Client.addMockResponse({
  11. url,
  12. body,
  13. })
  14. );
  15. };
  16. describe('IntegrationCodeMappings', function () {
  17. const projects = [
  18. TestStubs.Project(),
  19. TestStubs.Project({
  20. id: '3',
  21. slug: 'some-project',
  22. name: 'Some Project',
  23. }),
  24. ];
  25. ProjectsStore.loadInitialData(projects);
  26. const org = TestStubs.Organization();
  27. const integration = TestStubs.GitHubIntegration();
  28. const repos = [
  29. TestStubs.Repository({
  30. integrationId: integration.id,
  31. }),
  32. TestStubs.Repository({
  33. integrationId: integration.id,
  34. id: '5',
  35. name: 'example/hello-there',
  36. }),
  37. ];
  38. const pathConfig1 = TestStubs.RepositoryProjectPathConfig({
  39. project: projects[0],
  40. repo: repos[0],
  41. integration,
  42. stackRoot: 'stack/root',
  43. sourceRoot: 'source/root',
  44. });
  45. const pathConfig2 = TestStubs.RepositoryProjectPathConfig({
  46. project: projects[1],
  47. repo: repos[1],
  48. integration,
  49. id: '12',
  50. stackRoot: 'one/path',
  51. sourceRoot: 'another/root',
  52. });
  53. let wrapper;
  54. beforeEach(() => {
  55. ModalStore.init();
  56. Client.clearMockResponses();
  57. mockResponse([
  58. [`/organizations/${org.slug}/code-mappings/`, [pathConfig1, pathConfig2]],
  59. [`/organizations/${org.slug}/repos/`, repos],
  60. ]);
  61. wrapper = mountWithTheme(
  62. <IntegrationCodeMappings organization={org} integration={integration} />
  63. );
  64. });
  65. afterEach(() => {
  66. // Clear the fields from the GlobalModal after every test
  67. ModalStore.reset();
  68. });
  69. it('shows the paths', () => {
  70. expect(wrapper.find('RepoName').length).toEqual(2);
  71. expect(wrapper.find('RepoName').at(0).text()).toEqual(repos[0].name);
  72. expect(wrapper.find('RepoName').at(1).text()).toEqual(repos[1].name);
  73. });
  74. it('opens modal', async () => {
  75. const modal = await mountGlobalModal();
  76. expect(modal.find('input[name="stackRoot"]')).toHaveLength(0);
  77. wrapper.find('button[data-test-id="add-mapping-button"]').first().simulate('click');
  78. await tick();
  79. modal.update();
  80. expect(modal.find('input[name="stackRoot"]')).toHaveLength(1);
  81. });
  82. it('create new config', async () => {
  83. const stackRoot = 'my/root';
  84. const sourceRoot = 'hey/dude';
  85. const defaultBranch = 'release';
  86. const url = `/organizations/${org.slug}/code-mappings/`;
  87. const createMock = Client.addMockResponse({
  88. url,
  89. method: 'POST',
  90. body: TestStubs.RepositoryProjectPathConfig({
  91. project: projects[1],
  92. repo: repos[1],
  93. integration,
  94. stackRoot,
  95. sourceRoot,
  96. defaultBranch,
  97. }),
  98. });
  99. wrapper.find('button[data-test-id="add-mapping-button"]').first().simulate('click');
  100. const modal = await mountGlobalModal();
  101. selectByValue(modal, projects[1].id, {control: true, name: 'projectId'});
  102. selectByValue(modal, repos[1].id, {control: true, name: 'repositoryId'});
  103. modal
  104. .find('input[name="stackRoot"]')
  105. .simulate('change', {target: {value: stackRoot}});
  106. modal
  107. .find('input[name="sourceRoot"]')
  108. .simulate('change', {target: {value: sourceRoot}});
  109. modal
  110. .find('input[name="defaultBranch"]')
  111. .simulate('change', {target: {value: defaultBranch}});
  112. modal.find('form').simulate('submit');
  113. expect(createMock).toHaveBeenCalledWith(
  114. url,
  115. expect.objectContaining({
  116. data: expect.objectContaining({
  117. projectId: projects[1].id,
  118. repositoryId: repos[1].id,
  119. stackRoot,
  120. sourceRoot,
  121. defaultBranch,
  122. integrationId: integration.id,
  123. }),
  124. })
  125. );
  126. });
  127. it('edit existing config', async () => {
  128. const stackRoot = 'new/root';
  129. const sourceRoot = 'source/root';
  130. const defaultBranch = 'master';
  131. const url = `/organizations/${org.slug}/code-mappings/${pathConfig1.id}/`;
  132. const editMock = Client.addMockResponse({
  133. url,
  134. method: 'PUT',
  135. body: TestStubs.RepositoryProjectPathConfig({
  136. project: projects[0],
  137. repo: repos[0],
  138. integration,
  139. stackRoot,
  140. sourceRoot,
  141. defaultBranch,
  142. }),
  143. });
  144. wrapper.find('button[aria-label="edit"]').first().simulate('click');
  145. await tick();
  146. const modal = await mountGlobalModal();
  147. modal
  148. .find('input[name="stackRoot"]')
  149. .simulate('change', {target: {value: stackRoot}});
  150. modal.find('form').simulate('submit');
  151. expect(editMock).toHaveBeenCalledWith(
  152. url,
  153. expect.objectContaining({
  154. data: expect.objectContaining({
  155. defaultBranch,
  156. projectId: '2',
  157. repositoryId: '4',
  158. sourceRoot,
  159. stackRoot,
  160. }),
  161. })
  162. );
  163. });
  164. });