]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-16263 User can't select project token if no scannable projects
authorGuillaume Peoc'h <guillaume.peoch@sonarsource.com>
Wed, 11 May 2022 14:06:19 +0000 (16:06 +0200)
committersonartech <sonartech@sonarsource.com>
Thu, 12 May 2022 20:02:58 +0000 (20:02 +0000)
server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx
server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx

index 48bcfb2f2ef5afd204135c2f087608dcb28d1c5d..5fc50ba13bc4ad962db78151c0bb8937524cbda6 100644 (file)
@@ -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);
index 8d6f1be57103f2264710d14f230e8d1c51a69fa2..7fdb7e4f64886f8e115376ab873363c21ade5bf6 100644 (file)
@@ -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<Props, State> {
   componentDidMount() {
     this.mounted = true;
     this.fetchTokens();
+    if (this.props.displayTokenTypeInput) {
+      this.fetchProjects();
+    }
   }
 
   componentWillUnmount() {
@@ -178,9 +182,6 @@ export class TokensForm extends React.PureComponent<Props, State> {
   };
 
   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<Props, State> {
     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 (
       <form autoComplete="off" className="display-flex-center" onSubmit={this.handleGenerateToken}>