index.spec.tsx 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {
  3. render,
  4. renderGlobalModal,
  5. screen,
  6. userEvent,
  7. waitFor,
  8. } from 'sentry-test/reactTestingLibrary';
  9. import ProjectKeys from 'sentry/views/settings/project/projectKeys/list';
  10. describe('ProjectKeys', function () {
  11. const {organization, project, routerProps} = initializeOrg();
  12. const projectKeys = TestStubs.ProjectKeys();
  13. let deleteMock: jest.Mock;
  14. beforeEach(function () {
  15. MockApiClient.clearMockResponses();
  16. MockApiClient.addMockResponse({
  17. url: `/projects/${organization.slug}/${project.slug}/keys/`,
  18. method: 'GET',
  19. body: projectKeys,
  20. });
  21. deleteMock = MockApiClient.addMockResponse({
  22. url: `/projects/${organization.slug}/${project.slug}/keys/${projectKeys[0].id}/`,
  23. method: 'DELETE',
  24. });
  25. });
  26. it('renders empty', function () {
  27. MockApiClient.clearMockResponses();
  28. MockApiClient.addMockResponse({
  29. url: `/projects/${organization.slug}/${project.slug}/keys/`,
  30. method: 'GET',
  31. body: [],
  32. });
  33. render(
  34. <ProjectKeys
  35. {...routerProps}
  36. project={project}
  37. params={{projectId: project.slug}}
  38. organization={organization}
  39. />
  40. );
  41. expect(
  42. screen.getByText('There are no keys active for this project.')
  43. ).toBeInTheDocument();
  44. });
  45. it('has clippable box', async function () {
  46. render(
  47. <ProjectKeys
  48. {...routerProps}
  49. organization={organization}
  50. params={{projectId: project.slug}}
  51. project={TestStubs.Project()}
  52. />
  53. );
  54. const expandButton = screen.getByRole('button', {name: 'Expand'});
  55. await userEvent.click(expandButton);
  56. expect(expandButton).not.toBeInTheDocument();
  57. });
  58. it('renders for default project', function () {
  59. render(
  60. <ProjectKeys
  61. {...routerProps}
  62. organization={organization}
  63. params={{projectId: project.slug}}
  64. project={TestStubs.Project({platform: 'other'})}
  65. />
  66. );
  67. const allDsn = screen.getAllByRole('textbox', {name: 'DSN URL'});
  68. expect(allDsn.length).toBe(1);
  69. const expandButton = screen.getByRole('button', {name: 'Expand'});
  70. const dsn = screen.getByRole('textbox', {name: 'DSN URL'});
  71. const minidumpEndpoint = screen.queryByRole('textbox', {
  72. name: 'Minidump Endpoint URL',
  73. });
  74. const unrealEndpoint = screen.queryByRole('textbox', {
  75. name: 'Unreal Engine 4 Endpoint URL',
  76. });
  77. const securityHeaderEndpoint = screen.queryByRole('textbox', {
  78. name: 'Security Header Endpoint URL',
  79. });
  80. expect(expandButton).toBeInTheDocument();
  81. expect(dsn).toHaveValue(projectKeys[0].dsn.public);
  82. expect(minidumpEndpoint).toHaveValue(projectKeys[0].dsn.minidump);
  83. // this is empty in the default ProjectKey
  84. expect(unrealEndpoint).toHaveValue('');
  85. expect(securityHeaderEndpoint).toHaveValue(projectKeys[0].dsn.security);
  86. });
  87. it('renders for javascript project', function () {
  88. render(
  89. <ProjectKeys
  90. {...routerProps}
  91. organization={organization}
  92. params={{projectId: project.slug}}
  93. project={TestStubs.Project({platform: 'javascript'})}
  94. />
  95. );
  96. const expandButton = screen.queryByRole('button', {name: 'Expand'});
  97. const dsn = screen.getByRole('textbox', {name: 'DSN URL'});
  98. const minidumpEndpoint = screen.queryByRole('textbox', {
  99. name: 'Minidump Endpoint URL',
  100. });
  101. const unrealEndpoint = screen.queryByRole('textbox', {
  102. name: 'Unreal Engine 4 Endpoint URL',
  103. });
  104. const securityHeaderEndpoint = screen.queryByRole('textbox', {
  105. name: 'Security Header Endpoint URL',
  106. });
  107. expect(expandButton).not.toBeInTheDocument();
  108. expect(dsn).toHaveValue(projectKeys[0].dsn.public);
  109. expect(minidumpEndpoint).not.toBeInTheDocument();
  110. expect(unrealEndpoint).not.toBeInTheDocument();
  111. expect(securityHeaderEndpoint).not.toBeInTheDocument();
  112. // Loader Script is rendered
  113. expect(screen.getByText('Loader Script')).toBeInTheDocument();
  114. const loaderScript = screen.getByRole<HTMLInputElement>('textbox', {
  115. name: 'Loader Script',
  116. });
  117. expect(loaderScript).toHaveValue(
  118. `<script src='${projectKeys[0].dsn.cdn}' crossorigin="anonymous"></script>`
  119. );
  120. });
  121. it('renders for javascript-react project', function () {
  122. render(
  123. <ProjectKeys
  124. {...routerProps}
  125. organization={organization}
  126. params={{projectId: project.slug}}
  127. project={TestStubs.Project({platform: 'javascript-react'})}
  128. />
  129. );
  130. const expandButton = screen.queryByRole('button', {name: 'Expand'});
  131. const dsn = screen.getByRole('textbox', {name: 'DSN URL'});
  132. const minidumpEndpoint = screen.queryByRole('textbox', {
  133. name: 'Minidump Endpoint URL',
  134. });
  135. const unrealEndpoint = screen.queryByRole('textbox', {
  136. name: 'Unreal Engine 4 Endpoint URL',
  137. });
  138. const securityHeaderEndpoint = screen.queryByRole('textbox', {
  139. name: 'Security Header Endpoint URL',
  140. });
  141. expect(expandButton).not.toBeInTheDocument();
  142. expect(dsn).toHaveValue(projectKeys[0].dsn.public);
  143. expect(minidumpEndpoint).not.toBeInTheDocument();
  144. expect(unrealEndpoint).not.toBeInTheDocument();
  145. expect(securityHeaderEndpoint).not.toBeInTheDocument();
  146. expect(screen.queryByText('Loader Script')).not.toBeInTheDocument();
  147. });
  148. it('renders multiple keys', function () {
  149. const multipleProjectKeys = TestStubs.ProjectKeys([
  150. {
  151. dsn: {
  152. secret:
  153. 'http://188ee45a58094d939428d8585aa6f662:a33bf9aba64c4bbdaf873bb9023b6d2c@dev.getsentry.net:8000/1',
  154. minidump:
  155. 'http://dev.getsentry.net:8000/api/1/minidump?sentry_key=188ee45a58094d939428d8585aa6f662',
  156. public: 'http://188ee45a58094d939428d8585aa6f662@dev.getsentry.net:8000/1',
  157. csp: 'http://dev.getsentry.net:8000/api/1/csp-report/?sentry_key=188ee45a58094d939428d8585aa6f662',
  158. security:
  159. 'http://dev.getsentry.net:8000/api/1/security-report/?sentry_key=188ee45a58094d939428d8585aa6f662',
  160. },
  161. public: '188ee45a58094d939428d8585aa6f662',
  162. secret: 'a33bf9aba64c4bbdaf873bb9023b6d2c',
  163. name: 'Key 2',
  164. rateLimit: null,
  165. projectId: 1,
  166. dateCreated: '2018-02-28T07:13:51.087Z',
  167. id: '188ee45a58094d939428d8585aa6f662',
  168. isActive: true,
  169. label: 'Key 2',
  170. browserSdkVersion: 'latest',
  171. browserSdk: {
  172. choices: [
  173. ['latest', 'latest'],
  174. ['7.x', '7.x'],
  175. ['6.x', '6.x'],
  176. ['5.x', '5.x'],
  177. ['4.x', '4.x'],
  178. ],
  179. },
  180. dynamicSdkLoaderOptions: {
  181. hasPerformance: false,
  182. hasReplay: false,
  183. hasDebug: false,
  184. },
  185. },
  186. ]);
  187. MockApiClient.addMockResponse({
  188. url: `/projects/${organization.slug}/${project.slug}/keys/`,
  189. method: 'GET',
  190. body: multipleProjectKeys,
  191. });
  192. render(
  193. <ProjectKeys
  194. {...routerProps}
  195. organization={organization}
  196. params={{projectId: project.slug}}
  197. project={TestStubs.Project({platform: 'other'})}
  198. />
  199. );
  200. const allDsn = screen.getAllByRole('textbox', {name: 'DSN URL'});
  201. expect(allDsn.length).toBe(2);
  202. });
  203. it('deletes key', async function () {
  204. render(
  205. <ProjectKeys
  206. {...routerProps}
  207. organization={organization}
  208. params={{projectId: project.slug}}
  209. project={TestStubs.Project()}
  210. />
  211. );
  212. await userEvent.click(screen.getByRole('button', {name: 'Delete'}));
  213. renderGlobalModal();
  214. await userEvent.click(screen.getByTestId('confirm-button'));
  215. expect(deleteMock).toHaveBeenCalled();
  216. });
  217. it('disable and enables key', async function () {
  218. render(
  219. <ProjectKeys
  220. {...routerProps}
  221. organization={organization}
  222. params={{projectId: project.slug}}
  223. project={TestStubs.Project()}
  224. />
  225. );
  226. const enableMock = MockApiClient.addMockResponse({
  227. url: `/projects/${organization.slug}/${project.slug}/keys/${projectKeys[0].id}/`,
  228. method: 'PUT',
  229. });
  230. renderGlobalModal();
  231. await userEvent.click(screen.getByRole('button', {name: 'Disable'}));
  232. await userEvent.click(screen.getByTestId('confirm-button'));
  233. await waitFor(() => {
  234. expect(screen.queryByRole('dialog')).not.toBeInTheDocument();
  235. });
  236. expect(enableMock).toHaveBeenCalledWith(
  237. expect.anything(),
  238. expect.objectContaining({
  239. data: {isActive: false},
  240. })
  241. );
  242. await userEvent.click(screen.getByRole('button', {name: 'Enable'}));
  243. await userEvent.click(screen.getByTestId('confirm-button'));
  244. expect(enableMock).toHaveBeenCalledWith(
  245. expect.anything(),
  246. expect.objectContaining({
  247. data: {isActive: true},
  248. })
  249. );
  250. });
  251. });