From 16d748240c573e2fd1cd0a0d4f2e97ef4cc91de3 Mon Sep 17 00:00:00 2001 From: Guillaume Peoc'h Date: Wed, 11 May 2022 16:06:19 +0200 Subject: [PATCH] SONAR-16263 User can't select project token if no scannable projects --- .../js/apps/account/__tests__/Account-it.tsx | 15 ++++++++++++++- .../main/js/apps/users/components/TokensForm.tsx | 16 +++++++++++----- 2 files changed, 25 insertions(+), 6 deletions(-) diff --git a/server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx b/server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx index 48bcfb2f2ef..5fc50ba13bc 100644 --- a/server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx +++ b/server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx @@ -21,7 +21,7 @@ import { screen, waitFor, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { UserEvent } from '@testing-library/user-event/dist/types/setup'; import selectEvent from 'react-select-event'; -import { getMyProjects } from '../../../api/components'; +import { getMyProjects, getScannableProjects } from '../../../api/components'; import NotificationsMock from '../../../api/mocks/NotificationsMock'; import UserTokensMock from '../../../api/mocks/UserTokensMock'; import getHistory from '../../../helpers/getHistory'; @@ -286,6 +286,19 @@ describe('security page', () => { } ); + it("should not suggest creating a Project token if the user doesn't have at least one scannable Projects", async () => { + (getScannableProjects as jest.Mock).mockResolvedValueOnce({ + projects: [] + }); + renderAccountApp( + mockLoggedInUser({ permissions: { global: [Permissions.Scan] } }), + securityPagePath + ); + + await selectEvent.openMenu(screen.getAllByRole('textbox')[1]); + expect(screen.queryByText(`users.tokens.${TokenType.Project}`)).not.toBeInTheDocument(); + }); + it('should allow local users to change password', async () => { const user = userEvent.setup(); renderAccountApp(mockLoggedInUser({ local: true }), securityPagePath); diff --git a/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx b/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx index 8d6f1be5710..7fdb7e4f648 100644 --- a/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx +++ b/server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx @@ -17,6 +17,7 @@ * along with this program; if not, write to the Free Software Foundation, * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ +import { isEmpty } from 'lodash'; import * as React from 'react'; import { getScannableProjects } from '../../../api/components'; import { generateToken, getTokens } from '../../../api/user-tokens'; @@ -66,6 +67,9 @@ export class TokensForm extends React.PureComponent { componentDidMount() { this.mounted = true; this.fetchTokens(); + if (this.props.displayTokenTypeInput) { + this.fetchProjects(); + } } componentWillUnmount() { @@ -178,9 +182,6 @@ export class TokensForm extends React.PureComponent { }; handleNewTokenTypeChange = ({ value }: { value: TokenType }) => { - if (value === TokenType.Project && this.state.projects.length === 0) { - this.fetchProjects(); - } this.setState({ newTokenType: value }); }; @@ -193,15 +194,20 @@ export class TokensForm extends React.PureComponent { const { displayTokenTypeInput, currentUser } = this.props; const tokenTypeOptions = [ - { label: translate('users.tokens', TokenType.Project), value: TokenType.Project }, { label: translate('users.tokens', TokenType.User), value: TokenType.User } ]; if (hasGlobalPermission(currentUser, Permissions.Scan)) { - tokenTypeOptions.push({ + tokenTypeOptions.unshift({ label: translate('users.tokens', TokenType.Global), value: TokenType.Global }); } + if (!isEmpty(projects)) { + tokenTypeOptions.unshift({ + label: translate('users.tokens', TokenType.Project), + value: TokenType.Project + }); + } return (
-- 2.39.5