index.spec.jsx 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import {render, screen, within} from 'sentry-test/reactTestingLibrary';
  2. import SentryApplicationDashboard from './index';
  3. jest.mock('sentry/components/charts/baseChart', () => {
  4. return jest.fn().mockImplementation(() => <div data-test-id="chart" />);
  5. });
  6. describe('Sentry Application Dashboard', function () {
  7. const NUM_INSTALLS = 5;
  8. const NUM_UNINSTALLS = 2;
  9. const org = TestStubs.Organization();
  10. let sentryApp;
  11. let webhookRequest;
  12. afterEach(() => {
  13. MockApiClient.clearMockResponses();
  14. });
  15. describe('Viewing the Sentry App Dashboard for a published integration', () => {
  16. beforeEach(() => {
  17. sentryApp = TestStubs.SentryApp({
  18. status: 'published',
  19. schema: {
  20. elements: [
  21. {type: 'stacktrace-link', uri: '/test'},
  22. {
  23. type: 'issue-link',
  24. create: {uri: '/test', required_fields: []},
  25. link: {uri: '/test', required_fields: []},
  26. },
  27. ],
  28. },
  29. });
  30. webhookRequest = TestStubs.SentryAppWebhookRequest();
  31. MockApiClient.addMockResponse({
  32. url: `/sentry-apps/${sentryApp.slug}/stats/`,
  33. body: {
  34. totalInstalls: NUM_INSTALLS,
  35. totalUninstalls: NUM_UNINSTALLS,
  36. installStats: [[1569783600, NUM_INSTALLS]],
  37. uninstallStats: [[1569783600, NUM_UNINSTALLS]],
  38. },
  39. });
  40. MockApiClient.addMockResponse({
  41. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  42. body: [webhookRequest],
  43. });
  44. MockApiClient.addMockResponse({
  45. url: `/sentry-apps/${sentryApp.slug}/interaction/`,
  46. body: {
  47. componentInteractions: {
  48. 'stacktrace-link': [[1569783600, 1]],
  49. 'issue-link': [[1569783600, 1]],
  50. },
  51. views: [[1569783600, 1]],
  52. },
  53. });
  54. MockApiClient.addMockResponse({
  55. url: `/sentry-apps/${sentryApp.slug}/`,
  56. body: sentryApp,
  57. });
  58. });
  59. it('shows the total install/uninstall stats', () => {
  60. render(
  61. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  62. );
  63. expect(screen.getByTestId('installs')).toHaveTextContent('Total installs5');
  64. expect(screen.getByTestId('uninstalls')).toHaveTextContent('Total uninstalls2');
  65. });
  66. it('shows the request log', () => {
  67. render(
  68. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  69. );
  70. // The mock response has 1 request
  71. expect(screen.getByTestId('request-item')).toBeInTheDocument();
  72. const requestLog = within(screen.getByTestId('request-item'));
  73. // Make sure that all the info is displayed
  74. expect(requestLog.getByText('https://example.com/webhook')).toBeInTheDocument();
  75. expect(requestLog.getByText('400')).toBeInTheDocument();
  76. expect(requestLog.getByText('issue.assigned')).toBeInTheDocument();
  77. expect(requestLog.getByText('Test Org')).toBeInTheDocument();
  78. });
  79. it('shows an empty message if there are no requests', () => {
  80. MockApiClient.addMockResponse({
  81. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  82. body: [],
  83. });
  84. render(
  85. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  86. );
  87. expect(
  88. screen.getByText('No requests found in the last 30 days.')
  89. ).toBeInTheDocument();
  90. });
  91. it('shows integration and interactions chart', () => {
  92. render(
  93. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  94. );
  95. expect(screen.getAllByTestId('chart')).toHaveLength(3);
  96. });
  97. });
  98. describe('Viewing the Sentry App Dashboard for an internal integration', () => {
  99. beforeEach(() => {
  100. sentryApp = TestStubs.SentryApp({
  101. status: 'internal',
  102. schema: {
  103. elements: [{type: 'stacktrace-link', uri: '/test'}],
  104. },
  105. });
  106. webhookRequest = TestStubs.SentryAppWebhookRequest();
  107. MockApiClient.addMockResponse({
  108. url: `/sentry-apps/${sentryApp.slug}/stats/`,
  109. body: {
  110. totalInstalls: 1,
  111. totalUninstalls: 0,
  112. installStats: [[1569783600, 1]],
  113. uninstallStats: [[1569783600, 0]],
  114. },
  115. });
  116. MockApiClient.addMockResponse({
  117. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  118. body: [webhookRequest],
  119. });
  120. MockApiClient.addMockResponse({
  121. url: `/sentry-apps/${sentryApp.slug}/interaction/`,
  122. body: {
  123. componentInteractions: {
  124. 'stacktrace-link': [[1569783600, 1]],
  125. },
  126. views: [[1569783600, 1]],
  127. },
  128. });
  129. MockApiClient.addMockResponse({
  130. url: `/sentry-apps/${sentryApp.slug}/`,
  131. body: sentryApp,
  132. });
  133. });
  134. it('shows the request log', () => {
  135. render(
  136. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  137. );
  138. // The mock response has 1 request
  139. expect(screen.getByTestId('request-item')).toBeInTheDocument();
  140. const requestLog = within(screen.getByTestId('request-item'));
  141. // Make sure that all the info is displayed
  142. expect(requestLog.getByText('https://example.com/webhook')).toBeInTheDocument();
  143. expect(requestLog.getByText('400')).toBeInTheDocument();
  144. expect(requestLog.getByText('issue.assigned')).toBeInTheDocument();
  145. // Does not show the integration views
  146. expect(screen.queryByText('Integration Views')).not.toBeInTheDocument();
  147. });
  148. it('shows an empty message if there are no requests', () => {
  149. MockApiClient.addMockResponse({
  150. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  151. body: [],
  152. });
  153. render(
  154. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  155. );
  156. expect(
  157. screen.getByText('No requests found in the last 30 days.')
  158. ).toBeInTheDocument();
  159. });
  160. it('shows the component interactions in a line chart', () => {
  161. render(
  162. <SentryApplicationDashboard params={{appSlug: sentryApp.slug, orgId: org.slug}} />
  163. );
  164. expect(screen.getByTestId('chart')).toBeInTheDocument();
  165. });
  166. });
  167. });