diff options
author | stanislavh <stanislav.honcharov@sonarsource.com> | 2023-11-06 11:13:33 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-11-08 20:02:53 +0000 |
commit | 19c131bdfccb98c24bcf432c5e5968bc5d4ffd5c (patch) | |
tree | 459256e361a1f8a308e1d244737e11b979dab683 /server/sonar-web/src/main/js/apps/issues/__tests__ | |
parent | c8d1b7eb2494d92f20fb8b498efdbb2e3f8ea12c (diff) | |
download | sonarqube-19c131bdfccb98c24bcf432c5e5968bc5d4ffd5c.tar.gz sonarqube-19c131bdfccb98c24bcf432c5e5968bc5d4ffd5c.zip |
SONAR-20873 Create new education tour for accepting issues
Diffstat (limited to 'server/sonar-web/src/main/js/apps/issues/__tests__')
-rw-r--r-- | server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx | 31 | ||||
-rw-r--r-- | server/sonar-web/src/main/js/apps/issues/__tests__/IssuesNewStatusAndTransitionGuide-it.tsx | 174 |
2 files changed, 201 insertions, 4 deletions
diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx index fe8b8d36bb2..93c5f8b24ea 100644 --- a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesAppGuide-it.tsx @@ -64,7 +64,12 @@ beforeEach(() => { it('should display guide', async () => { const user = userEvent.setup(); - renderIssueApp(mockCurrentUser({ isLoggedIn: true })); + renderIssueApp( + mockCurrentUser({ + isLoggedIn: true, + dismissedNotices: { [NoticeType.ISSUE_NEW_STATUS_AND_TRANSITION_GUIDE]: true }, + }), + ); expect(await ui.guidePopup.find()).toBeInTheDocument(); @@ -106,7 +111,13 @@ it('should display guide', async () => { it('should not show guide for those who dismissed it', async () => { renderIssueApp( - mockCurrentUser({ isLoggedIn: true, dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true } }), + mockCurrentUser({ + isLoggedIn: true, + dismissedNotices: { + [NoticeType.ISSUE_GUIDE]: true, + [NoticeType.ISSUE_NEW_STATUS_AND_TRANSITION_GUIDE]: true, + }, + }), ); expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0); @@ -115,7 +126,12 @@ it('should not show guide for those who dismissed it', async () => { it('should skip guide', async () => { const user = userEvent.setup(); - renderIssueApp(mockCurrentUser({ isLoggedIn: true })); + renderIssueApp( + mockCurrentUser({ + isLoggedIn: true, + dismissedNotices: { [NoticeType.ISSUE_NEW_STATUS_AND_TRANSITION_GUIDE]: true }, + }), + ); expect(await ui.guidePopup.find()).toBeInTheDocument(); expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_list.1.title'); @@ -127,7 +143,14 @@ it('should skip guide', async () => { }); it('should not show guide if issues need sync', async () => { - renderProjectIssuesApp(undefined, { needIssueSync: true }, mockCurrentUser({ isLoggedIn: true })); + renderProjectIssuesApp( + undefined, + { needIssueSync: true }, + mockCurrentUser({ + isLoggedIn: true, + dismissedNotices: { [NoticeType.ISSUE_NEW_STATUS_AND_TRANSITION_GUIDE]: true }, + }), + ); expect((await ui.issueItems.findAll()).length).toBeGreaterThan(0); expect(ui.guidePopup.query()).not.toBeInTheDocument(); diff --git a/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesNewStatusAndTransitionGuide-it.tsx b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesNewStatusAndTransitionGuide-it.tsx new file mode 100644 index 00000000000..43708b804d5 --- /dev/null +++ b/server/sonar-web/src/main/js/apps/issues/__tests__/IssuesNewStatusAndTransitionGuide-it.tsx @@ -0,0 +1,174 @@ +/* + * SonarQube + * Copyright (C) 2009-2023 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +import { act } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import React from 'react'; +import IssuesServiceMock from '../../../api/mocks/IssuesServiceMock'; +import CurrentUserContextProvider from '../../../app/components/current-user/CurrentUserContextProvider'; +import IssueTransitionComponent from '../../../components/issue/components/IssueTransition'; +import { mockCurrentUser, mockIssue } from '../../../helpers/testMocks'; +import { renderComponent } from '../../../helpers/testReactTestingUtils'; +import { IssueTransition } from '../../../types/issues'; +import { Issue } from '../../../types/types'; +import { NoticeType } from '../../../types/users'; +import IssueNewStatusAndTransitionGuide from '../components/IssueNewStatusAndTransitionGuide'; +import { ui } from '../test-utils'; + +const issuesHandler = new IssuesServiceMock(); + +beforeEach(() => { + issuesHandler.reset(); +}); + +it('should display status guide', async () => { + const user = userEvent.setup(); + renderIssueNewStatusGuide(); + + expect(await ui.guidePopup.find()).toBeInTheDocument(); + expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_accept.1.title'); + + await act(async () => { + await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get()); + }); + + expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_accept.2.title'); + + await act(async () => { + await user.click(ui.guidePopup.byRole('button', { name: 'go_back' }).get()); + }); + expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_accept.1.title'); + + await act(async () => { + await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get()); + }); + await act(async () => { + await user.click(ui.guidePopup.byRole('button', { name: 'next' }).get()); + }); + expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_accept.3.title'); + expect(ui.guidePopup.byRole('button', { name: 'Next' }).query()).not.toBeInTheDocument(); + + await act(async () => { + await user.click(ui.guidePopup.byRole('button', { name: 'close' }).get()); + }); + + expect(ui.guidePopup.query()).not.toBeInTheDocument(); +}); + +it('should not show guide for those who dismissed it', () => { + renderIssueNewStatusGuide( + mockCurrentUser({ + isLoggedIn: true, + dismissedNotices: { + [NoticeType.ISSUE_GUIDE]: true, + [NoticeType.ISSUE_NEW_STATUS_AND_TRANSITION_GUIDE]: true, + }, + }), + ); + + expect(ui.guidePopup.query()).not.toBeInTheDocument(); +}); + +it('should skip guide', async () => { + const user = userEvent.setup(); + renderIssueNewStatusGuide(); + + expect(await ui.guidePopup.find()).toBeInTheDocument(); + expect(ui.guidePopup.get()).toHaveTextContent('guiding.issue_accept.1.title'); + + await user.click(ui.guidePopup.byRole('button', { name: 'skip' }).get()); + + expect(ui.guidePopup.query()).not.toBeInTheDocument(); +}); + +it('should not show guide if user is not logged in', () => { + renderIssueNewStatusGuide(mockCurrentUser({ isLoggedIn: false })); + + expect(ui.guidePopup.query()).not.toBeInTheDocument(); +}); + +it('should not show guide if there are no issues', () => { + renderIssueNewStatusGuide(mockCurrentUser({ isLoggedIn: true }), []); + + expect(ui.guidePopup.query()).not.toBeInTheDocument(); +}); + +it('should not show guide if CCT guide is shown', () => { + renderIssueNewStatusGuide( + mockCurrentUser({ isLoggedIn: true, dismissedNotices: { [NoticeType.ISSUE_GUIDE]: false } }), + [], + ); + + expect(ui.guidePopup.query()).not.toBeInTheDocument(); +}); + +function IssueNewStatusGuide({ issues }: { issues: Issue[] }) { + const [open, setOpen] = React.useState(false); + const issue = mockIssue(false, { + transitions: [ + IssueTransition.Accept, + IssueTransition.Confirm, + IssueTransition.Resolve, + IssueTransition.FalsePositive, + IssueTransition.WontFix, + ], + }); + + return ( + <div data-guiding-id={`issue-transition-${issue.key}`}> + <div data-guiding-id="issue-accept-transition">/</div> + <IssueTransitionComponent + isOpen={open} + togglePopup={() => setOpen(!open)} + issue={issue} + onChange={jest.fn()} + /> + <IssueNewStatusAndTransitionGuide + togglePopup={(_, __, show) => setOpen(Boolean(show))} + run + issues={issues} + /> + </div> + ); +} + +function renderIssueNewStatusGuide( + currentUser = mockCurrentUser({ + isLoggedIn: true, + dismissedNotices: { [NoticeType.ISSUE_GUIDE]: true }, + }), + issues = [ + mockIssue(false, { + transitions: [ + IssueTransition.Accept, + IssueTransition.Confirm, + IssueTransition.Resolve, + IssueTransition.FalsePositive, + IssueTransition.WontFix, + ], + }), + ], +) { + return renderComponent( + <CurrentUserContextProvider currentUser={currentUser}> + <IssueNewStatusGuide issues={issues} /> + </CurrentUserContextProvider>, + ); +} |