projectReleaseTracking.spec.tsx 4.2 KB

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