projectReleaseTracking.spec.jsx 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. import {mountWithTheme} from 'sentry-test/enzyme';
  2. import {mountGlobalModal} from 'sentry-test/modal';
  3. import {fetchPlugins} from 'sentry/actionCreators/plugins';
  4. import ProjectReleaseTrackingContainer, {
  5. ProjectReleaseTracking,
  6. } from 'sentry/views/settings/project/projectReleaseTracking';
  7. jest.mock('sentry/actionCreators/plugins', () => ({
  8. fetchPlugins: jest.fn().mockResolvedValue([]),
  9. }));
  10. describe('ProjectReleaseTracking', function () {
  11. const org = TestStubs.Organization();
  12. const project = TestStubs.Project();
  13. const url = `/projects/${org.slug}/${project.slug}/releases/token/`;
  14. beforeEach(function () {
  15. MockApiClient.clearMockResponses();
  16. MockApiClient.addMockResponse({
  17. url: `/projects/${org.slug}/${project.slug}/plugins/`,
  18. method: 'GET',
  19. body: TestStubs.Plugins(),
  20. });
  21. MockApiClient.addMockResponse({
  22. url,
  23. method: 'GET',
  24. body: {
  25. webhookUrl: 'webhook-url',
  26. token: 'token token token',
  27. },
  28. });
  29. });
  30. it('renders with token', function () {
  31. const wrapper = mountWithTheme(
  32. <ProjectReleaseTracking
  33. organization={org}
  34. project={project}
  35. plugins={{loading: false, plugins: TestStubs.Plugins()}}
  36. params={{orgId: org.slug, projectId: project.slug}}
  37. />
  38. );
  39. expect(wrapper.find('TextCopyInput').prop('children')).toBe('token token token');
  40. });
  41. it('can regenerate token', async function () {
  42. const wrapper = mountWithTheme(
  43. <ProjectReleaseTracking
  44. organization={org}
  45. project={project}
  46. plugins={{loading: false, plugins: TestStubs.Plugins()}}
  47. params={{orgId: org.slug, projectId: project.slug}}
  48. />
  49. );
  50. const mock = MockApiClient.addMockResponse({
  51. url,
  52. method: 'POST',
  53. body: {
  54. webhookUrl: 'webhook-url',
  55. token: 'token token token',
  56. },
  57. });
  58. // Click Regenerate Token
  59. wrapper.find('Field[label="Regenerate Token"] Button').simulate('click');
  60. const modal = await mountGlobalModal();
  61. expect(modal.find('Modal')).toHaveLength(1);
  62. expect(mock).not.toHaveBeenCalled();
  63. modal.find('Button[priority="danger"]').simulate('click');
  64. await tick();
  65. expect(mock).toHaveBeenCalledWith(
  66. url,
  67. expect.objectContaining({
  68. method: 'POST',
  69. data: {
  70. project: project.slug,
  71. },
  72. })
  73. );
  74. });
  75. it('fetches new plugins when project changes', function () {
  76. const wrapper = mountWithTheme(
  77. <ProjectReleaseTrackingContainer
  78. organization={org}
  79. project={project}
  80. params={{orgId: org.slug, projectId: project.slug}}
  81. />
  82. );
  83. expect(fetchPlugins).toHaveBeenCalled();
  84. fetchPlugins.mockClear();
  85. // For example, this happens when we switch to a new project using settings breadcrumb
  86. wrapper.setProps({...wrapper.props(), project: {...project, slug: 'new-project'}});
  87. wrapper.update();
  88. expect(fetchPlugins).toHaveBeenCalledWith(
  89. expect.objectContaining({
  90. projectId: 'new-project',
  91. })
  92. );
  93. fetchPlugins.mockClear();
  94. // Does not call fetchPlugins if slug is the same
  95. wrapper.setProps({...wrapper.props(), project: {...project, slug: 'new-project'}});
  96. wrapper.update();
  97. expect(fetchPlugins).not.toHaveBeenCalled();
  98. });
  99. });