index.spec.tsx 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239
  1. import selectEvent from 'react-select-event';
  2. import {OrganizationFixture} from 'sentry-fixture/organization';
  3. import {render, screen, userEvent, waitFor} from 'sentry-test/reactTestingLibrary';
  4. import ConfigStore from 'sentry/stores/configStore';
  5. import OrganizationCreate from 'sentry/views/organizationCreate';
  6. describe('OrganizationCreate', function () {
  7. let oldRegions: any[] = [];
  8. beforeEach(() => {
  9. ConfigStore.get('termsUrl');
  10. ConfigStore.get('privacyUrl');
  11. oldRegions = ConfigStore.get('regions');
  12. // Set only a single region in the config store by default
  13. ConfigStore.set('regions', [{name: '--monolith--', url: 'https://example.com'}]);
  14. });
  15. afterEach(() => {
  16. MockApiClient.clearMockResponses();
  17. jest.resetAllMocks();
  18. ConfigStore.set('regions', oldRegions);
  19. });
  20. it('renders without terms', function () {
  21. render(<OrganizationCreate />);
  22. });
  23. it('renders with terms', function () {
  24. ConfigStore.set('termsUrl', 'https://example.com/terms');
  25. ConfigStore.set('privacyUrl', 'https://example.com/privacy');
  26. render(<OrganizationCreate />);
  27. });
  28. it('creates a new org', async function () {
  29. const orgCreateMock = MockApiClient.addMockResponse({
  30. url: '/organizations/',
  31. method: 'POST',
  32. body: OrganizationFixture(),
  33. });
  34. ConfigStore.set('termsUrl', 'https://example.com/terms');
  35. ConfigStore.set('privacyUrl', 'https://example.com/privacy');
  36. render(<OrganizationCreate />);
  37. expect(screen.getByText('Create a New Organization')).toBeInTheDocument();
  38. await userEvent.type(screen.getByPlaceholderText('e.g. My Company'), 'Good Burger');
  39. await userEvent.click(
  40. screen.getByRole('checkbox', {
  41. name: 'I agree to the Terms of Service and the Privacy Policy',
  42. })
  43. );
  44. await userEvent.click(screen.getByText('Create Organization'));
  45. await waitFor(() => {
  46. expect(orgCreateMock).toHaveBeenCalledWith('/organizations/', {
  47. success: expect.any(Function),
  48. error: expect.any(Function),
  49. method: 'POST',
  50. data: {agreeTerms: true, defaultTeam: true, name: 'Good Burger'},
  51. host: undefined,
  52. });
  53. });
  54. expect(window.location.assign).toHaveBeenCalledTimes(1);
  55. expect(window.location.assign).toHaveBeenCalledWith(
  56. '/organizations/org-slug/projects/new/'
  57. );
  58. });
  59. it('creates a new org with customer domain feature', async function () {
  60. const orgCreateMock = MockApiClient.addMockResponse({
  61. url: '/organizations/',
  62. method: 'POST',
  63. body: OrganizationFixture({
  64. features: ['customer-domains'],
  65. }),
  66. });
  67. ConfigStore.set('termsUrl', 'https://example.com/terms');
  68. ConfigStore.set('privacyUrl', 'https://example.com/privacy');
  69. render(<OrganizationCreate />);
  70. expect(screen.getByText('Create a New Organization')).toBeInTheDocument();
  71. await userEvent.type(screen.getByPlaceholderText('e.g. My Company'), 'Good Burger');
  72. await userEvent.click(
  73. screen.getByRole('checkbox', {
  74. name: 'I agree to the Terms of Service and the Privacy Policy',
  75. })
  76. );
  77. await userEvent.click(screen.getByText('Create Organization'));
  78. await waitFor(() => {
  79. expect(orgCreateMock).toHaveBeenCalledWith('/organizations/', {
  80. data: {agreeTerms: true, defaultTeam: true, name: 'Good Burger'},
  81. method: 'POST',
  82. success: expect.any(Function),
  83. error: expect.any(Function),
  84. host: undefined,
  85. });
  86. });
  87. expect(window.location.assign).toHaveBeenCalledTimes(1);
  88. expect(window.location.assign).toHaveBeenCalledWith(
  89. 'https://org-slug.sentry.io/projects/new/'
  90. );
  91. });
  92. function multiRegionSetup() {
  93. const orgCreateMock = MockApiClient.addMockResponse({
  94. url: '/organizations/',
  95. method: 'POST',
  96. body: OrganizationFixture({
  97. features: ['customer-domains'],
  98. }),
  99. });
  100. ConfigStore.set('features', new Set(['organizations:multi-region-selector']));
  101. ConfigStore.set('regions', [
  102. {url: 'https://us.example.com', name: 'us'},
  103. {
  104. url: 'https://de.example.com',
  105. name: 'de',
  106. },
  107. ]);
  108. return orgCreateMock;
  109. }
  110. it('renders without region data and submits without host when only a single region is defined', async function () {
  111. const orgCreateMock = multiRegionSetup();
  112. // Set only a single region in the config store
  113. ConfigStore.set('regions', [{name: '--monolith--', url: 'https://example.com'}]);
  114. render(<OrganizationCreate />);
  115. expect(screen.queryByLabelText('Data Storage Location')).not.toBeInTheDocument();
  116. await userEvent.type(screen.getByPlaceholderText('e.g. My Company'), 'Good Burger');
  117. await userEvent.click(screen.getByText('Create Organization'));
  118. await waitFor(() => {
  119. expect(orgCreateMock).toHaveBeenCalledWith('/organizations/', {
  120. success: expect.any(Function),
  121. error: expect.any(Function),
  122. method: 'POST',
  123. host: undefined,
  124. data: {defaultTeam: true, name: 'Good Burger'},
  125. });
  126. });
  127. expect(window.location.assign).toHaveBeenCalledTimes(1);
  128. expect(window.location.assign).toHaveBeenCalledWith(
  129. 'https://org-slug.sentry.io/projects/new/'
  130. );
  131. });
  132. it('renders without a pre-selected region, and does not submit until one is selected', async function () {
  133. const orgCreateMock = multiRegionSetup();
  134. render(<OrganizationCreate />);
  135. expect(screen.getByLabelText('Data Storage Location')).toBeInTheDocument();
  136. await userEvent.type(screen.getByPlaceholderText('e.g. My Company'), 'Good Burger');
  137. await userEvent.click(screen.getByText('Create Organization'));
  138. expect(orgCreateMock).not.toHaveBeenCalled();
  139. expect(window.location.assign).not.toHaveBeenCalled();
  140. await selectEvent.select(
  141. screen.getByRole('textbox', {name: 'Data Storage Location'}),
  142. '🇺🇸 United States of America (US)'
  143. );
  144. await userEvent.click(screen.getByText('Create Organization'));
  145. const expectedHost = 'https://us.example.com';
  146. await waitFor(() => {
  147. expect(orgCreateMock).toHaveBeenCalledWith('/organizations/', {
  148. success: expect.any(Function),
  149. error: expect.any(Function),
  150. method: 'POST',
  151. host: expectedHost,
  152. data: {defaultTeam: true, name: 'Good Burger'},
  153. });
  154. });
  155. expect(window.location.assign).toHaveBeenCalledTimes(1);
  156. expect(window.location.assign).toHaveBeenCalledWith(
  157. 'https://org-slug.sentry.io/projects/new/'
  158. );
  159. });
  160. it('renders without region data and submits without host when the feature flag is not enabled', async function () {
  161. const orgCreateMock = multiRegionSetup();
  162. ConfigStore.set('features', new Set());
  163. render(<OrganizationCreate />);
  164. expect(screen.queryByLabelText('Data Storage Location')).not.toBeInTheDocument();
  165. await userEvent.type(screen.getByPlaceholderText('e.g. My Company'), 'Good Burger');
  166. await userEvent.click(screen.getByText('Create Organization'));
  167. await waitFor(() => {
  168. expect(orgCreateMock).toHaveBeenCalledWith('/organizations/', {
  169. success: expect.any(Function),
  170. error: expect.any(Function),
  171. method: 'POST',
  172. host: undefined,
  173. data: {defaultTeam: true, name: 'Good Burger'},
  174. });
  175. });
  176. expect(window.location.assign).toHaveBeenCalledTimes(1);
  177. expect(window.location.assign).toHaveBeenCalledWith(
  178. 'https://org-slug.sentry.io/projects/new/'
  179. );
  180. });
  181. it('uses the host of the selected region when submitting', async function () {
  182. const orgCreateMock = multiRegionSetup();
  183. render(<OrganizationCreate />);
  184. expect(screen.getByLabelText('Data Storage Location')).toBeInTheDocument();
  185. await userEvent.type(screen.getByPlaceholderText('e.g. My Company'), 'Good Burger');
  186. await selectEvent.select(
  187. screen.getByRole('textbox', {name: 'Data Storage Location'}),
  188. '🇪🇺 European Union (EU)'
  189. );
  190. await userEvent.click(screen.getByText('Create Organization'));
  191. const expectedHost = 'https://de.example.com';
  192. await waitFor(() => {
  193. expect(orgCreateMock).toHaveBeenCalledWith('/organizations/', {
  194. success: expect.any(Function),
  195. error: expect.any(Function),
  196. method: 'POST',
  197. host: expectedHost,
  198. data: {defaultTeam: true, name: 'Good Burger'},
  199. });
  200. });
  201. expect(window.location.assign).toHaveBeenCalledTimes(1);
  202. expect(window.location.assign).toHaveBeenCalledWith(
  203. 'https://org-slug.sentry.io/projects/new/'
  204. );
  205. });
  206. });