stacktraceLink.spec.jsx 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173
  1. import {mountWithTheme} from 'sentry-test/enzyme';
  2. import {StacktraceLink} from 'sentry/components/events/interfaces/frame/stacktraceLink';
  3. describe('StacktraceLink', function () {
  4. const org = TestStubs.Organization();
  5. const project = TestStubs.Project();
  6. const event = TestStubs.Event({projectID: project.id});
  7. const integration = TestStubs.GitHubIntegration();
  8. const repo = TestStubs.Repository({integrationId: integration.id});
  9. const frame = {filename: '/sentry/app.py', lineNo: 233};
  10. const platform = 'python';
  11. const config = TestStubs.RepositoryProjectPathConfig(project, repo, integration);
  12. beforeEach(function () {
  13. MockApiClient.clearMockResponses();
  14. });
  15. it('does not render setup CTA for members', async function () {
  16. const memberOrg = TestStubs.Organization({
  17. slug: 'hello-org',
  18. access: [],
  19. });
  20. MockApiClient.addMockResponse({
  21. url: `/projects/${memberOrg.slug}/${project.slug}/stacktrace-link/`,
  22. query: {file: frame.filename, commitId: 'master', platform},
  23. body: {config: null, sourceUrl: null, integrations: [integration]},
  24. });
  25. MockApiClient.addMockResponse({
  26. method: 'GET',
  27. url: '/prompts-activity/',
  28. body: {},
  29. });
  30. const wrapper = mountWithTheme(
  31. <StacktraceLink
  32. frame={frame}
  33. event={event}
  34. projects={[project]}
  35. organization={memberOrg}
  36. lineNo={frame.lineNo}
  37. />
  38. );
  39. await tick();
  40. wrapper.update();
  41. expect(wrapper.find('CodeMappingButtonContainer').exists()).toBe(false);
  42. });
  43. it('renders setup CTA with integration but no configs', async function () {
  44. MockApiClient.addMockResponse({
  45. url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`,
  46. query: {file: frame.filename, commitId: 'master', platform},
  47. body: {config: null, sourceUrl: null, integrations: [integration]},
  48. });
  49. MockApiClient.addMockResponse({
  50. method: 'GET',
  51. url: '/prompts-activity/',
  52. body: {},
  53. });
  54. const wrapper = mountWithTheme(
  55. <StacktraceLink
  56. frame={frame}
  57. event={event}
  58. projects={[project]}
  59. organization={org}
  60. lineNo={frame.lineNo}
  61. />
  62. );
  63. await tick();
  64. wrapper.update();
  65. expect(wrapper.find('CodeMappingButtonContainer').text()).toContain(
  66. 'Link your stack trace to your source code.'
  67. );
  68. });
  69. it('renders source url link', function () {
  70. MockApiClient.addMockResponse({
  71. url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`,
  72. query: {file: frame.filename, commitId: 'master', platform},
  73. body: {config, sourceUrl: 'https://something.io', integrations: [integration]},
  74. });
  75. const wrapper = mountWithTheme(
  76. <StacktraceLink
  77. frame={frame}
  78. event={event}
  79. projects={[project]}
  80. organization={org}
  81. lineNo={frame.lineNo}
  82. />
  83. );
  84. expect(wrapper.state('match').sourceUrl).toEqual('https://something.io');
  85. expect(wrapper.find('OpenInName').text()).toEqual('GitHub');
  86. });
  87. it('renders file_not_found message', function () {
  88. MockApiClient.addMockResponse({
  89. url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`,
  90. query: {file: frame.filename, commitId: 'master', platform},
  91. body: {
  92. config,
  93. sourceUrl: null,
  94. error: 'file_not_found',
  95. integrations: [integration],
  96. attemptedUrl: 'https://something.io/blah',
  97. },
  98. });
  99. const wrapper = mountWithTheme(
  100. <StacktraceLink
  101. frame={frame}
  102. event={event}
  103. projects={[project]}
  104. organization={org}
  105. lineNo={frame.lineNo}
  106. />
  107. );
  108. expect(wrapper.state('match').sourceUrl).toBeFalsy();
  109. expect(wrapper.find('CodeMappingButtonContainer').text()).toContain(
  110. 'Source file not found.'
  111. );
  112. expect(wrapper.state('match').attemptedUrl).toEqual('https://something.io/blah');
  113. });
  114. it('renders stack_root_mismatch message', function () {
  115. MockApiClient.addMockResponse({
  116. url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`,
  117. query: {file: frame.filename, commitId: 'master', platform},
  118. body: {
  119. config,
  120. sourceUrl: null,
  121. error: 'stack_root_mismatch',
  122. integrations: [integration],
  123. },
  124. });
  125. const wrapper = mountWithTheme(
  126. <StacktraceLink
  127. frame={frame}
  128. event={event}
  129. projects={[project]}
  130. organization={org}
  131. lineNo={frame.lineNo}
  132. />
  133. );
  134. expect(wrapper.state('match').sourceUrl).toBeFalsy();
  135. expect(wrapper.find('CodeMappingButtonContainer').text()).toContain(
  136. 'Error matching your configuration.'
  137. );
  138. });
  139. it('renders default error message', function () {
  140. MockApiClient.addMockResponse({
  141. url: `/projects/${org.slug}/${project.slug}/stacktrace-link/`,
  142. query: {file: frame.filename, commitId: 'master', platform},
  143. body: {
  144. config,
  145. sourceUrl: null,
  146. integrations: [integration],
  147. },
  148. });
  149. const wrapper = mountWithTheme(
  150. <StacktraceLink
  151. frame={frame}
  152. event={event}
  153. projects={[project]}
  154. organization={org}
  155. lineNo={frame.lineNo}
  156. />
  157. );
  158. expect(wrapper.state('match').sourceUrl).toBeFalsy();
  159. expect(wrapper.find('CodeMappingButtonContainer').text()).toContain(
  160. 'There was an error encountered with the code mapping for this project'
  161. );
  162. });
  163. });