createProject.spec.tsx 7.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252
  1. import {initializeOrg} from 'sentry-test/initializeOrg';
  2. import {
  3. render,
  4. renderGlobalModal,
  5. screen,
  6. userEvent,
  7. waitFor,
  8. } from 'sentry-test/reactTestingLibrary';
  9. import OrganizationStore from 'sentry/stores/organizationStore';
  10. import TeamStore from 'sentry/stores/teamStore';
  11. import {Organization} from 'sentry/types';
  12. import {CreateProject} from 'sentry/views/projectInstall/createProject';
  13. function renderFrameworkModalMockRequests({
  14. organization,
  15. teamSlug,
  16. }: {
  17. organization: Organization;
  18. teamSlug: string;
  19. }) {
  20. MockApiClient.addMockResponse({
  21. url: `/projects/${organization.slug}/rule-conditions/`,
  22. body: [],
  23. });
  24. MockApiClient.addMockResponse({
  25. url: `/organizations/${organization.slug}/teams/`,
  26. body: [TestStubs.Team({slug: teamSlug})],
  27. });
  28. MockApiClient.addMockResponse({
  29. url: `/organizations/${organization.slug}/`,
  30. body: organization,
  31. });
  32. MockApiClient.addMockResponse({
  33. url: `/organizations/${organization.slug}/projects/`,
  34. body: [],
  35. });
  36. const projectCreationMockRequest = MockApiClient.addMockResponse({
  37. url: `/teams/${organization.slug}/${teamSlug}/projects/`,
  38. method: 'POST',
  39. });
  40. return {projectCreationMockRequest};
  41. }
  42. describe('CreateProject', function () {
  43. const teamNoAccess = TestStubs.Team({
  44. slug: 'test',
  45. id: '1',
  46. name: 'test',
  47. hasAccess: false,
  48. });
  49. const teamWithAccess = {...teamNoAccess, hasAccess: true};
  50. beforeEach(() => {
  51. TeamStore.reset();
  52. TeamStore.loadUserTeams([teamNoAccess]);
  53. MockApiClient.addMockResponse({
  54. url: `/projects/testOrg/rule-conditions/`,
  55. body: {},
  56. // Not required for these tests
  57. statusCode: 500,
  58. });
  59. });
  60. afterEach(() => {
  61. MockApiClient.clearMockResponses();
  62. });
  63. it('should block if you have access to no teams', function () {
  64. const {container} = render(<CreateProject />, {
  65. context: TestStubs.routerContext([{organization: {id: '1', slug: 'testOrg'}}]),
  66. });
  67. expect(container).toSnapshot();
  68. });
  69. it('can create a new team', async function () {
  70. render(<CreateProject />, {
  71. context: TestStubs.routerContext([{organization: {id: '1', slug: 'testOrg'}}]),
  72. });
  73. renderGlobalModal();
  74. await userEvent.click(screen.getByRole('button', {name: 'Create a team'}));
  75. expect(
  76. await screen.findByText(
  77. 'Members of a team have access to specific areas, such as a new release or a new application feature.'
  78. )
  79. ).toBeInTheDocument();
  80. await userEvent.click(screen.getByRole('button', {name: 'Close Modal'}));
  81. });
  82. it('should fill in project name if its empty when platform is chosen', async function () {
  83. const organization = TestStubs.Organization();
  84. const {container} = render(<CreateProject />, {
  85. context: TestStubs.routerContext([{organization: {id: '1', slug: 'testOrg'}}]),
  86. organization,
  87. });
  88. await userEvent.click(screen.getByTestId('platform-apple-ios'));
  89. expect(screen.getByPlaceholderText('project-name')).toHaveValue('apple-ios');
  90. await userEvent.click(screen.getByTestId('platform-ruby-rails'));
  91. expect(screen.getByPlaceholderText('project-name')).toHaveValue('ruby-rails');
  92. // but not replace it when project name is something else:
  93. await userEvent.clear(screen.getByPlaceholderText('project-name'));
  94. await userEvent.type(screen.getByPlaceholderText('project-name'), 'another');
  95. await userEvent.click(screen.getByTestId('platform-apple-ios'));
  96. expect(screen.getByPlaceholderText('project-name')).toHaveValue('another');
  97. expect(container).toSnapshot();
  98. });
  99. it('does not render framework selection modal if vanilla js is NOT selected', async function () {
  100. const {organization} = initializeOrg({
  101. organization: {
  102. features: ['onboarding-sdk-selection'],
  103. },
  104. });
  105. const frameWorkModalMockRequests = renderFrameworkModalMockRequests({
  106. organization,
  107. teamSlug: teamWithAccess.slug,
  108. });
  109. TeamStore.loadUserTeams([teamWithAccess]);
  110. OrganizationStore.onUpdate(organization, {replace: true});
  111. render(<CreateProject />, {
  112. organization,
  113. });
  114. // Select the React platform
  115. await userEvent.click(screen.getByTestId('platform-javascript-react'));
  116. await userEvent.type(screen.getByLabelText('Select a Team'), 'test');
  117. await userEvent.click(screen.getByText('#test'));
  118. await waitFor(() => {
  119. expect(screen.getByRole('button', {name: 'Create Project'})).toBeEnabled();
  120. });
  121. renderGlobalModal();
  122. // Click on 'configure SDK' button
  123. await userEvent.click(screen.getByRole('button', {name: 'Create Project'}));
  124. // Modal shall not be open
  125. expect(screen.queryByText('Do you use a framework?')).not.toBeInTheDocument();
  126. expect(frameWorkModalMockRequests.projectCreationMockRequest).toHaveBeenCalled();
  127. });
  128. it('renders framework selection modal if vanilla js is selected', async function () {
  129. const {organization} = initializeOrg({
  130. organization: {
  131. features: ['onboarding-sdk-selection'],
  132. },
  133. });
  134. const frameWorkModalMockRequests = renderFrameworkModalMockRequests({
  135. organization,
  136. teamSlug: teamWithAccess.slug,
  137. });
  138. TeamStore.loadUserTeams([teamWithAccess]);
  139. OrganizationStore.onUpdate(organization, {replace: true});
  140. render(<CreateProject />, {
  141. organization,
  142. });
  143. // Select the JavaScript platform
  144. await userEvent.click(screen.getByTestId('platform-javascript'));
  145. await userEvent.type(screen.getByLabelText('Select a Team'), 'test');
  146. await userEvent.click(screen.getByText('#test'));
  147. await waitFor(() => {
  148. expect(screen.getByRole('button', {name: 'Create Project'})).toBeEnabled();
  149. });
  150. renderGlobalModal();
  151. // Click on 'configure SDK' button
  152. await userEvent.click(screen.getByRole('button', {name: 'Create Project'}));
  153. // Modal is open
  154. await screen.findByText('Do you use a framework?');
  155. // Close modal
  156. await userEvent.click(screen.getByRole('button', {name: 'Close Modal'}));
  157. expect(frameWorkModalMockRequests.projectCreationMockRequest).not.toHaveBeenCalled();
  158. });
  159. describe('Issue Alerts Options', function () {
  160. const organization = TestStubs.Organization();
  161. beforeEach(() => {
  162. TeamStore.loadUserTeams([teamWithAccess]);
  163. MockApiClient.addMockResponse({
  164. url: `/projects/${organization.slug}/rule-conditions/`,
  165. // @ts-ignore TODO: fix this type
  166. body: TestStubs.MOCK_RESP_VERBOSE,
  167. });
  168. });
  169. afterEach(() => {
  170. MockApiClient.clearMockResponses();
  171. });
  172. it('should enabled the submit button if and only if all the required information has been filled', async function () {
  173. render(<CreateProject />);
  174. const createProjectButton = screen.getByRole('button', {name: 'Create Project'});
  175. await userEvent.click(screen.getByText(/When there are more than/));
  176. expect(createProjectButton).toBeDisabled();
  177. await userEvent.type(screen.getByTestId('range-input'), '2');
  178. expect(screen.getByTestId('range-input')).toHaveValue(2);
  179. expect(createProjectButton).toBeDisabled();
  180. await userEvent.click(screen.getByTestId('platform-apple-ios'));
  181. expect(createProjectButton).toBeEnabled();
  182. await userEvent.clear(screen.getByTestId('range-input'));
  183. expect(createProjectButton).toBeDisabled();
  184. await userEvent.type(screen.getByTestId('range-input'), '2712');
  185. expect(createProjectButton).toBeEnabled();
  186. await userEvent.clear(screen.getByTestId('range-input'));
  187. expect(createProjectButton).toBeDisabled();
  188. await userEvent.click(screen.getByText("I'll create my own alerts later"));
  189. expect(createProjectButton).toBeEnabled();
  190. });
  191. });
  192. });