projectReleaseTracking.spec.jsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131
  1. import {
  2. render,
  3. renderGlobalModal,
  4. screen,
  5. userEvent,
  6. } from 'sentry-test/reactTestingLibrary';
  7. import {fetchPlugins} from 'sentry/actionCreators/plugins';
  8. import ProjectReleaseTrackingContainer, {
  9. ProjectReleaseTracking,
  10. } from 'sentry/views/settings/project/projectReleaseTracking';
  11. jest.mock('sentry/actionCreators/plugins', () => ({
  12. fetchPlugins: jest.fn().mockResolvedValue([]),
  13. }));
  14. describe('ProjectReleaseTracking', function () {
  15. const org = TestStubs.Organization();
  16. const project = TestStubs.Project();
  17. const url = `/projects/${org.slug}/${project.slug}/releases/token/`;
  18. beforeEach(function () {
  19. MockApiClient.clearMockResponses();
  20. MockApiClient.addMockResponse({
  21. url: `/projects/${org.slug}/${project.slug}/plugins/`,
  22. method: 'GET',
  23. body: TestStubs.Plugins(),
  24. });
  25. MockApiClient.addMockResponse({
  26. url,
  27. method: 'GET',
  28. body: {
  29. webhookUrl: 'webhook-url',
  30. token: 'token token token',
  31. },
  32. });
  33. });
  34. it('renders with token', function () {
  35. render(
  36. <ProjectReleaseTracking
  37. organization={org}
  38. project={project}
  39. plugins={{loading: false, plugins: TestStubs.Plugins()}}
  40. params={{projectId: project.slug}}
  41. />
  42. );
  43. expect(screen.getByRole('textbox')).toHaveValue('token token token');
  44. });
  45. it('can regenerate token', async function () {
  46. render(
  47. <ProjectReleaseTracking
  48. organization={org}
  49. project={project}
  50. plugins={{loading: false, plugins: TestStubs.Plugins()}}
  51. params={{projectId: project.slug}}
  52. />
  53. );
  54. const mock = MockApiClient.addMockResponse({
  55. url,
  56. method: 'POST',
  57. body: {
  58. webhookUrl: 'webhook-url',
  59. token: 'token token token',
  60. },
  61. });
  62. // Click Regenerate Token
  63. await userEvent.click(screen.getByRole('button', {name: 'Regenerate Token'}));
  64. renderGlobalModal();
  65. expect(screen.getByRole('dialog')).toBeInTheDocument();
  66. expect(mock).not.toHaveBeenCalled();
  67. await userEvent.click(screen.getByRole('button', {name: 'Confirm'}));
  68. expect(mock).toHaveBeenCalledWith(
  69. url,
  70. expect.objectContaining({
  71. method: 'POST',
  72. data: {
  73. project: project.slug,
  74. },
  75. })
  76. );
  77. });
  78. it('fetches new plugins when project changes', function () {
  79. const {rerender} = render(
  80. <ProjectReleaseTrackingContainer
  81. organization={org}
  82. project={project}
  83. params={{projectId: project.slug}}
  84. />
  85. );
  86. expect(fetchPlugins).toHaveBeenCalled();
  87. fetchPlugins.mockClear();
  88. // For example, this happens when we switch to a new project using settings breadcrumb
  89. rerender(
  90. <ProjectReleaseTrackingContainer
  91. organization={org}
  92. project={{...project, slug: 'new-project'}}
  93. params={{projectId: 'new-project'}}
  94. />
  95. );
  96. expect(fetchPlugins).toHaveBeenCalledWith(
  97. expect.objectContaining({
  98. projectId: 'new-project',
  99. })
  100. );
  101. fetchPlugins.mockClear();
  102. // Does not call fetchPlugins if slug is the same
  103. rerender(
  104. <ProjectReleaseTrackingContainer
  105. organization={org}
  106. project={{...project, slug: 'new-project'}}
  107. params={{projectId: 'new-project'}}
  108. />
  109. );
  110. expect(fetchPlugins).not.toHaveBeenCalled();
  111. });
  112. });