index.spec.tsx 6.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. import {SentryAppWebhookRequest} from 'sentry-fixture/sentryAppWebhookRequest';
  2. import {render, screen, within} from 'sentry-test/reactTestingLibrary';
  3. import SentryApplicationDashboard from './index';
  4. jest.mock('sentry/components/charts/baseChart', () => {
  5. return jest.fn().mockImplementation(() => <div data-test-id="chart" />);
  6. });
  7. describe('Sentry Application Dashboard', function () {
  8. const NUM_INSTALLS = 5;
  9. const NUM_UNINSTALLS = 2;
  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 = 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
  62. {...TestStubs.routeComponentProps()}
  63. params={{appSlug: sentryApp.slug}}
  64. />
  65. );
  66. expect(screen.getByTestId('installs')).toHaveTextContent('Total installs5');
  67. expect(screen.getByTestId('uninstalls')).toHaveTextContent('Total uninstalls2');
  68. });
  69. it('shows the request log', () => {
  70. render(
  71. <SentryApplicationDashboard
  72. {...TestStubs.routeComponentProps()}
  73. params={{appSlug: sentryApp.slug}}
  74. />
  75. );
  76. // The mock response has 1 request
  77. expect(screen.getByTestId('request-item')).toBeInTheDocument();
  78. const requestLog = within(screen.getByTestId('request-item'));
  79. // Make sure that all the info is displayed
  80. expect(requestLog.getByText('https://example.com/webhook')).toBeInTheDocument();
  81. expect(requestLog.getByText('400')).toBeInTheDocument();
  82. expect(requestLog.getByText('issue.assigned')).toBeInTheDocument();
  83. expect(requestLog.getByText('Test Org')).toBeInTheDocument();
  84. });
  85. it('shows an empty message if there are no requests', () => {
  86. MockApiClient.addMockResponse({
  87. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  88. body: [],
  89. });
  90. render(
  91. <SentryApplicationDashboard
  92. {...TestStubs.routeComponentProps()}
  93. params={{appSlug: sentryApp.slug}}
  94. />
  95. );
  96. expect(
  97. screen.getByText('No requests found in the last 30 days.')
  98. ).toBeInTheDocument();
  99. });
  100. it('shows integration and interactions chart', () => {
  101. render(
  102. <SentryApplicationDashboard
  103. {...TestStubs.routeComponentProps()}
  104. params={{appSlug: sentryApp.slug}}
  105. />
  106. );
  107. expect(screen.getAllByTestId('chart')).toHaveLength(3);
  108. });
  109. });
  110. describe('Viewing the Sentry App Dashboard for an internal integration', () => {
  111. beforeEach(() => {
  112. sentryApp = TestStubs.SentryApp({
  113. status: 'internal',
  114. schema: {
  115. elements: [{type: 'stacktrace-link', uri: '/test'}],
  116. },
  117. });
  118. webhookRequest = SentryAppWebhookRequest();
  119. MockApiClient.addMockResponse({
  120. url: `/sentry-apps/${sentryApp.slug}/stats/`,
  121. body: {
  122. totalInstalls: 1,
  123. totalUninstalls: 0,
  124. installStats: [[1569783600, 1]],
  125. uninstallStats: [[1569783600, 0]],
  126. },
  127. });
  128. MockApiClient.addMockResponse({
  129. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  130. body: [webhookRequest],
  131. });
  132. MockApiClient.addMockResponse({
  133. url: `/sentry-apps/${sentryApp.slug}/interaction/`,
  134. body: {
  135. componentInteractions: {
  136. 'stacktrace-link': [[1569783600, 1]],
  137. },
  138. views: [[1569783600, 1]],
  139. },
  140. });
  141. MockApiClient.addMockResponse({
  142. url: `/sentry-apps/${sentryApp.slug}/`,
  143. body: sentryApp,
  144. });
  145. });
  146. it('shows the request log', () => {
  147. render(
  148. <SentryApplicationDashboard
  149. {...TestStubs.routeComponentProps()}
  150. params={{appSlug: sentryApp.slug}}
  151. />
  152. );
  153. // The mock response has 1 request
  154. expect(screen.getByTestId('request-item')).toBeInTheDocument();
  155. const requestLog = within(screen.getByTestId('request-item'));
  156. // Make sure that all the info is displayed
  157. expect(requestLog.getByText('https://example.com/webhook')).toBeInTheDocument();
  158. expect(requestLog.getByText('400')).toBeInTheDocument();
  159. expect(requestLog.getByText('issue.assigned')).toBeInTheDocument();
  160. // Does not show the integration views
  161. expect(screen.queryByText('Integration Views')).not.toBeInTheDocument();
  162. });
  163. it('shows an empty message if there are no requests', () => {
  164. MockApiClient.addMockResponse({
  165. url: `/sentry-apps/${sentryApp.slug}/requests/`,
  166. body: [],
  167. });
  168. render(
  169. <SentryApplicationDashboard
  170. {...TestStubs.routeComponentProps()}
  171. params={{appSlug: sentryApp.slug}}
  172. />
  173. );
  174. expect(
  175. screen.getByText('No requests found in the last 30 days.')
  176. ).toBeInTheDocument();
  177. });
  178. it('shows the component interactions in a line chart', () => {
  179. render(
  180. <SentryApplicationDashboard
  181. {...TestStubs.routeComponentProps()}
  182. params={{appSlug: sentryApp.slug}}
  183. />
  184. );
  185. expect(screen.getByTestId('chart')).toBeInTheDocument();
  186. });
  187. });
  188. });