index.spec.jsx 8.5 KB

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