csp.spec.tsx 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  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. const {container} = 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. expect(container).toSnapshot();
  36. });
  37. it('can enable default ignored sources', async function () {
  38. render(
  39. <ProjectCspReports
  40. route={{}}
  41. routeParams={router.params}
  42. router={router}
  43. routes={router.routes}
  44. location={TestStubs.location({pathname: routeUrl})}
  45. organization={organization}
  46. params={{projectId: project.slug}}
  47. />
  48. );
  49. const mock = MockApiClient.addMockResponse({
  50. url: projectUrl,
  51. method: 'PUT',
  52. });
  53. expect(mock).not.toHaveBeenCalled();
  54. // Click Regenerate Token
  55. await userEvent.click(
  56. screen.getByRole('checkbox', {name: 'Use default ignored sources'})
  57. );
  58. expect(mock).toHaveBeenCalledWith(
  59. projectUrl,
  60. expect.objectContaining({
  61. method: 'PUT',
  62. data: {
  63. options: {
  64. 'sentry:csp_ignored_sources_defaults': true,
  65. },
  66. },
  67. })
  68. );
  69. });
  70. it('can set additional ignored sources', async function () {
  71. render(
  72. <ProjectCspReports
  73. route={{}}
  74. routeParams={router.params}
  75. router={router}
  76. routes={router.routes}
  77. location={TestStubs.location({pathname: routeUrl})}
  78. organization={organization}
  79. params={{projectId: project.slug}}
  80. />
  81. );
  82. const mock = MockApiClient.addMockResponse({
  83. url: projectUrl,
  84. method: 'PUT',
  85. });
  86. expect(mock).not.toHaveBeenCalled();
  87. await userEvent.type(
  88. screen.getByRole('textbox', {name: 'Additional ignored sources'}),
  89. 'test\ntest2'
  90. );
  91. // Focus on other element, trigerring onBlur
  92. await userEvent.tab();
  93. expect(mock).toHaveBeenCalledWith(
  94. projectUrl,
  95. expect.objectContaining({
  96. method: 'PUT',
  97. data: {
  98. // 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
  99. options: {
  100. 'sentry:csp_ignored_sources': `test\ntest2`,
  101. },
  102. },
  103. })
  104. );
  105. });
  106. });