organizationSettingsForm.spec.tsx 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  3. import * as indicatorActions from 'sentry/actionCreators/indicator';
  4. import Indicators from 'sentry/components/indicators';
  5. import OrganizationSettingsForm from 'sentry/views/settings/organizationGeneralSettings/organizationSettingsForm';
  6. jest.mock('sentry/actionCreators/indicator');
  7. describe('OrganizationSettingsForm', function () {
  8. const {organization, routerProps} = initializeOrg();
  9. let putMock: jest.Mock;
  10. const onSave = jest.fn();
  11. beforeEach(function () {
  12. MockApiClient.clearMockResponses();
  13. MockApiClient.addMockResponse({
  14. url: `/organizations/${organization.slug}/auth-provider/`,
  15. method: 'GET',
  16. });
  17. MockApiClient.addMockResponse({
  18. url: `/organizations/${organization.slug}/integrations/?provider_key=github`,
  19. method: 'GET',
  20. body: {
  21. providers: [{canAdd: true}],
  22. },
  23. });
  24. onSave.mockReset();
  25. });
  26. it('can change a form field', async function () {
  27. putMock = MockApiClient.addMockResponse({
  28. url: `/organizations/${organization.slug}/`,
  29. method: 'PUT',
  30. body: organization,
  31. });
  32. render(
  33. <OrganizationSettingsForm
  34. {...routerProps}
  35. access={new Set(['org:write'])}
  36. initialData={TestStubs.Organization()}
  37. onSave={onSave}
  38. />
  39. );
  40. render(<Indicators />);
  41. const input = screen.getByRole('textbox', {name: 'Display Name'});
  42. const saveOnBlur = jest.spyOn(indicatorActions, 'saveOnBlurUndoMessage');
  43. await userEvent.clear(input);
  44. await userEvent.type(input, 'New Name');
  45. await userEvent.tab();
  46. expect(putMock).toHaveBeenCalledWith(
  47. `/organizations/${organization.slug}/`,
  48. expect.objectContaining({
  49. method: 'PUT',
  50. data: {
  51. name: 'New Name',
  52. },
  53. })
  54. );
  55. expect(saveOnBlur).toHaveBeenCalledWith(
  56. {
  57. new: 'New Name',
  58. old: 'Organization Name',
  59. },
  60. expect.anything(),
  61. 'name'
  62. );
  63. const model = saveOnBlur.mock.calls[0][1];
  64. // Test "undo" call undo directly
  65. expect(model.getValue('name')).toBe('New Name');
  66. model.undo();
  67. expect(model.getValue('name')).toBe('Organization Name');
  68. // `saveOnBlurUndoMessage` saves the new field, so reimplement this
  69. await model.saveField('name', 'Organization Name');
  70. // Initial data should be updated to original name
  71. expect(model.initialData.name).toBe('Organization Name');
  72. putMock.mockReset();
  73. // Blurring the name field again should NOT trigger a save
  74. await userEvent.click(input);
  75. await userEvent.tab();
  76. expect(putMock).not.toHaveBeenCalled();
  77. });
  78. it('can change slug', async function () {
  79. putMock = MockApiClient.addMockResponse({
  80. url: `/organizations/${organization.slug}/`,
  81. method: 'PUT',
  82. body: organization,
  83. });
  84. render(
  85. <OrganizationSettingsForm
  86. {...routerProps}
  87. access={new Set(['org:write'])}
  88. initialData={TestStubs.Organization()}
  89. onSave={onSave}
  90. />
  91. );
  92. const input = screen.getByRole('textbox', {name: 'Organization Slug'});
  93. await userEvent.clear(input);
  94. await userEvent.type(input, 'NEW SLUG');
  95. await userEvent.tab();
  96. expect(putMock).not.toHaveBeenCalled();
  97. await userEvent.click(screen.getByRole('button', {name: 'Save'}));
  98. expect(putMock).toHaveBeenCalledWith(
  99. '/organizations/org-slug/',
  100. expect.objectContaining({
  101. data: {
  102. slug: 'new-slug',
  103. },
  104. })
  105. );
  106. });
  107. it('can enable codecov', async function () {
  108. putMock = MockApiClient.addMockResponse({
  109. url: `/organizations/${organization.slug}/`,
  110. method: 'PUT',
  111. body: {...organization, codecovAccess: true},
  112. });
  113. render(
  114. <OrganizationSettingsForm
  115. {...routerProps}
  116. access={new Set(['org:write'])}
  117. initialData={TestStubs.Organization({codecovAccess: false})}
  118. onSave={onSave}
  119. />,
  120. {
  121. organization: {
  122. ...organization,
  123. features: ['codecov-integration'],
  124. },
  125. }
  126. );
  127. await userEvent.click(
  128. screen.getByRole('checkbox', {name: /Enable Code Coverage Insights/})
  129. );
  130. expect(putMock).toHaveBeenCalledWith(
  131. '/organizations/org-slug/',
  132. expect.objectContaining({
  133. data: {
  134. codecovAccess: true,
  135. },
  136. })
  137. );
  138. });
  139. });