profilingOnboardingModal.spec.tsx 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. import {act, render, screen, userEvent} from 'sentry-test/reactTestingLibrary';
  2. import {ModalRenderProps} from 'sentry/actionCreators/modal';
  3. import {ProfilingOnboardingModal} from 'sentry/components/profiling/ProfilingOnboarding/profilingOnboardingModal';
  4. import ProjectsStore from 'sentry/stores/projectsStore';
  5. import {Project} from 'sentry/types/project';
  6. const MockRenderModalProps: ModalRenderProps = {
  7. Body: ({children}) => <div>{children}</div>,
  8. Header: ({children}) => <div>{children}</div>,
  9. Footer: ({children}) => <div>{children}</div>,
  10. CloseButton: ({children}) => <div>{children}</div>,
  11. closeModal: jest.fn(),
  12. onDismiss: jest.fn(),
  13. } as unknown as ModalRenderProps;
  14. function selectProject(project: Project) {
  15. if (!project.name) {
  16. throw new Error(`Selected project requires a name, received ${project.name}`);
  17. }
  18. userEvent.click(screen.getAllByRole('textbox')[0]);
  19. userEvent.click(screen.getByText(project.name));
  20. }
  21. describe('ProfilingOnboarding', function () {
  22. beforeEach(() => {
  23. // @ts-ignore no-console
  24. // eslint-disable-next-line no-console
  25. jest.spyOn(console, 'error').mockImplementation(jest.fn());
  26. });
  27. afterEach(() => {
  28. MockApiClient.clearMockResponses();
  29. // @ts-ignore no-console
  30. // eslint-disable-next-line no-console
  31. console.error.mockRestore();
  32. });
  33. it('renders default step', () => {
  34. const organization = TestStubs.Organization();
  35. MockApiClient.addMockResponse({
  36. url: `/organizations/${organization.slug}/sdk-updates/`,
  37. body: [],
  38. });
  39. render(
  40. <ProfilingOnboardingModal organization={organization} {...MockRenderModalProps} />
  41. );
  42. expect(screen.getByText(/Select a Project/i)).toBeInTheDocument();
  43. });
  44. it('goes to next step and previous step if project is supported', () => {
  45. const organization = TestStubs.Organization();
  46. ProjectsStore.loadInitialData([
  47. TestStubs.Project({name: 'iOS Project', platform: 'apple-ios'}),
  48. ]);
  49. MockApiClient.addMockResponse({
  50. url: `/organizations/${organization.slug}/sdk-updates/`,
  51. body: [],
  52. });
  53. render(
  54. <ProfilingOnboardingModal organization={organization} {...MockRenderModalProps} />
  55. );
  56. selectProject(TestStubs.Project({name: 'iOS Project'}));
  57. act(() => {
  58. userEvent.click(screen.getAllByText('Next')[0]);
  59. });
  60. expect(screen.getByText(/Step 2 of 2/i)).toBeInTheDocument();
  61. act(() => {
  62. userEvent.click(screen.getAllByText('Back')[0]);
  63. });
  64. expect(screen.getByText(/Select a Project/i)).toBeInTheDocument();
  65. });
  66. it('does not allow going to next step if project is unsupported', () => {
  67. const organization = TestStubs.Organization();
  68. ProjectsStore.loadInitialData([
  69. TestStubs.Project({name: 'javascript', platform: 'javascript'}),
  70. ]);
  71. MockApiClient.addMockResponse({
  72. url: `/organizations/${organization.slug}/sdk-updates/`,
  73. body: [],
  74. });
  75. render(
  76. <ProfilingOnboardingModal organization={organization} {...MockRenderModalProps} />
  77. );
  78. selectProject(TestStubs.Project({name: 'javascript'}));
  79. userEvent.click(screen.getAllByText('Next')[0]);
  80. expect(screen.getByRole('button', {name: /Next/i})).toBeDisabled();
  81. });
  82. it('shows sdk updates are required if version is lower than required', async () => {
  83. const organization = TestStubs.Organization();
  84. const project = TestStubs.Project({name: 'iOS Project', platform: 'apple-ios'});
  85. ProjectsStore.loadInitialData([project]);
  86. MockApiClient.addMockResponse({
  87. url: `/organizations/${organization.slug}/sdk-updates/`,
  88. body: [
  89. {
  90. projectId: project.id,
  91. sdkName: 'sentry ios',
  92. sdkVersion: '6.0.0',
  93. suggestions: [],
  94. },
  95. ],
  96. });
  97. render(
  98. <ProfilingOnboardingModal organization={organization} {...MockRenderModalProps} />
  99. );
  100. selectProject(project);
  101. expect(
  102. await screen.findByText(/Update your projects SDK version/)
  103. ).toBeInTheDocument();
  104. });
  105. it('shows a sdk update URL when receiving a updateSdk suggestion if a version is lower than required', async () => {
  106. const organization = TestStubs.Organization();
  107. const project = TestStubs.Project({name: 'iOS Project', platform: 'apple-ios'});
  108. ProjectsStore.loadInitialData([project]);
  109. MockApiClient.addMockResponse({
  110. url: `/organizations/${organization.slug}/sdk-updates/`,
  111. body: [
  112. {
  113. projectId: project.id,
  114. sdkName: 'sentry ios',
  115. sdkVersion: '6.0.0',
  116. suggestions: [
  117. {
  118. type: 'updateSdk',
  119. sdkName: 'sentry-ios',
  120. newSdkVersion: '9.0.0',
  121. sdkUrl: 'http://test/fake-slug',
  122. },
  123. ],
  124. },
  125. ],
  126. });
  127. render(
  128. <ProfilingOnboardingModal organization={organization} {...MockRenderModalProps} />
  129. );
  130. selectProject(project);
  131. const link = (await screen.findByText(/sentry-ios@9.0.0/)) as HTMLAnchorElement;
  132. expect(link).toBeInTheDocument();
  133. expect(link.href).toBe('http://test/fake-slug');
  134. });
  135. });