csp.spec.tsx 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  3. import ProjectCspReports from 'sentry/views/settings/projectSecurityHeaders/csp';
  4. describe('ProjectCspReports', function () {
  5. const {project, organization, router} = initializeOrg();
  6. const projectUrl = `/projects/${organization.slug}/${project.slug}/`;
  7. const routeUrl = `/projects/${organization.slug}/${project.slug}/csp/`;
  8. beforeEach(function () {
  9. MockApiClient.clearMockResponses();
  10. MockApiClient.addMockResponse({
  11. url: `/projects/${organization.slug}/${project.slug}/keys/`,
  12. method: 'GET',
  13. body: [],
  14. });
  15. MockApiClient.addMockResponse({
  16. url: projectUrl,
  17. method: 'GET',
  18. body: {
  19. options: {},
  20. },
  21. });
  22. });
  23. it('renders', function () {
  24. render(
  25. <ProjectCspReports
  26. route={{}}
  27. routeParams={router.params}
  28. router={router}
  29. routes={router.routes}
  30. location={TestStubs.location({pathname: routeUrl})}
  31. organization={organization}
  32. params={{projectId: project.slug}}
  33. />
  34. );
  35. });
  36. it('can enable default ignored sources', async function () {
  37. render(
  38. <ProjectCspReports
  39. route={{}}
  40. routeParams={router.params}
  41. router={router}
  42. routes={router.routes}
  43. location={TestStubs.location({pathname: routeUrl})}
  44. organization={organization}
  45. params={{projectId: project.slug}}
  46. />
  47. );
  48. const mock = MockApiClient.addMockResponse({
  49. url: projectUrl,
  50. method: 'PUT',
  51. });
  52. expect(mock).not.toHaveBeenCalled();
  53. // Click Regenerate Token
  54. await userEvent.click(
  55. screen.getByRole('checkbox', {name: 'Use default ignored sources'})
  56. );
  57. expect(mock).toHaveBeenCalledWith(
  58. projectUrl,
  59. expect.objectContaining({
  60. method: 'PUT',
  61. data: {
  62. options: {
  63. 'sentry:csp_ignored_sources_defaults': true,
  64. },
  65. },
  66. })
  67. );
  68. });
  69. it('can set additional ignored sources', async function () {
  70. render(
  71. <ProjectCspReports
  72. route={{}}
  73. routeParams={router.params}
  74. router={router}
  75. routes={router.routes}
  76. location={TestStubs.location({pathname: routeUrl})}
  77. organization={organization}
  78. params={{projectId: project.slug}}
  79. />
  80. );
  81. const mock = MockApiClient.addMockResponse({
  82. url: projectUrl,
  83. method: 'PUT',
  84. });
  85. expect(mock).not.toHaveBeenCalled();
  86. await userEvent.type(
  87. screen.getByRole('textbox', {name: 'Additional ignored sources'}),
  88. 'test\ntest2'
  89. );
  90. // Focus on other element, trigerring onBlur
  91. await userEvent.tab();
  92. expect(mock).toHaveBeenCalledWith(
  93. projectUrl,
  94. expect.objectContaining({
  95. method: 'PUT',
  96. data: {
  97. // XXX: Org details endpoints accept these multiline inputs as a list, where as it looks like project details accepts it as a string with newlines
  98. options: {
  99. 'sentry:csp_ignored_sources': `test\ntest2`,
  100. },
  101. },
  102. })
  103. );
  104. });
  105. });