aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorguillaume-peoch-sonarsource <91735163+guillaume-peoch-sonarsource@users.noreply.github.com>2022-07-19 14:04:38 +0200
committersonartech <sonartech@sonarsource.com>2022-07-19 20:03:21 +0000
commit19e81c42496a55c85343d4692bb2daf559cb7882 (patch)
tree8a982965ac26eb743cbb2241a6c5d4b55ccaeb77
parent335dee8062f90f425daa5b41e3e2d6e1f98ffba9 (diff)
downloadsonarqube-19e81c42496a55c85343d4692bb2daf559cb7882.tar.gz
sonarqube-19e81c42496a55c85343d4692bb2daf559cb7882.zip
SONAR-16565 Preselect token type or project options if only one is available (#6297)
-rw-r--r--server/sonar-web/src/main/js/apps/account/__tests__/Account-it.tsx35
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/TokensForm.tsx33
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/TokensFormModal.tsx2
-rw-r--r--server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/TokensFormModal-test.tsx.snap2
4 files changed, 55 insertions, 17 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 7abb80758a5..3fc8c1bbe54 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
@@ -344,7 +344,7 @@ describe('security page', () => {
).not.toBeInTheDocument();
});
- it("should not suggest creating a Project token if the user doesn't have at least one scannable Projects", async () => {
+ it("should not suggest creating a Project token if the user doesn't have at least one scannable Projects", () => {
(getScannableProjects as jest.Mock).mockResolvedValueOnce({
projects: []
});
@@ -353,10 +353,41 @@ describe('security page', () => {
securityPagePath
);
- await selectEvent.openMenu(screen.getAllByRole('textbox')[1]);
+ selectEvent.openMenu(screen.getAllByRole('textbox')[1]);
expect(screen.queryByText(`users.tokens.${TokenType.Project}`)).not.toBeInTheDocument();
});
+ it('should preselect the user token type if the user has no scan rights', async () => {
+ (getScannableProjects as jest.Mock).mockResolvedValueOnce({
+ projects: []
+ });
+ renderAccountApp(mockLoggedInUser(), securityPagePath);
+
+ const globalToken = await screen.findByText(`users.tokens.${TokenType.User}`);
+ expect(globalToken).toBeInTheDocument();
+ });
+
+ it('should preselect the only project the user has access to if they select project token', async () => {
+ (getScannableProjects as jest.Mock).mockResolvedValueOnce({
+ projects: [
+ {
+ key: 'project-key-1',
+ name: 'Project Name 1'
+ }
+ ]
+ });
+ renderAccountApp(
+ mockLoggedInUser({ permissions: { global: [Permissions.Scan] } }),
+ securityPagePath
+ );
+
+ await selectEvent.select(screen.getAllByRole('textbox')[1], [
+ `users.tokens.${TokenType.Project}`
+ ]);
+
+ expect(screen.getByText('Project Name 1')).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 ec07f19b5e4..8d0d345907f 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
@@ -54,7 +54,7 @@ interface State {
newTokenType?: TokenType;
tokens: UserToken[];
projects: BasicSelectOption[];
- selectedProject: { key: string; name: string };
+ selectedProject?: BasicSelectOption;
newTokenExpiration: TokenExpiration;
tokenExpirationOptions: { value: TokenExpiration; label: string }[];
}
@@ -66,7 +66,6 @@ export class TokensForm extends React.PureComponent<Props, State> {
loading: true,
newTokenName: '',
newTokenType: this.props.displayTokenTypeInput ? undefined : TokenType.User,
- selectedProject: { key: '', name: '' },
tokens: [],
projects: [],
newTokenExpiration: TokenExpiration.OneMonth,
@@ -113,7 +112,8 @@ export class TokensForm extends React.PureComponent<Props, State> {
const { projects: projectArray } = await getScannableProjects();
const projects = projectArray.map(project => ({ label: project.name, value: project.key }));
this.setState({
- projects
+ projects,
+ selectedProject: projects.length === 1 ? projects[0] : undefined
});
};
@@ -139,7 +139,8 @@ export class TokensForm extends React.PureComponent<Props, State> {
name: newTokenName,
login,
type: newTokenType,
- ...(newTokenType === TokenType.Project && { projectKey: selectedProject.key }),
+ ...(newTokenType === TokenType.Project &&
+ selectedProject !== undefined && { projectKey: selectedProject.value }),
...(newTokenExpiration !== TokenExpiration.NoExpiration && {
expirationDate: computeTokenExpirationDate(newTokenExpiration)
})
@@ -155,17 +156,19 @@ export class TokensForm extends React.PureComponent<Props, State> {
isExpired: false,
expirationDate: newToken.expirationDate,
type: newTokenType,
- ...(newTokenType === TokenType.Project && {
- project: { key: selectedProject.key, name: selectedProject.name }
- })
+ ...(newTokenType === TokenType.Project &&
+ selectedProject !== undefined && {
+ project: { key: selectedProject.value, name: selectedProject.label }
+ })
}
];
return {
generating: false,
newToken,
newTokenName: '',
- selectedProject: { key: '', name: '' },
+ selectedProject: undefined,
newTokenType: undefined,
+ newTokenExpiration: TokenExpiration.OneMonth,
tokens
};
}, this.updateTokensCount);
@@ -198,7 +201,7 @@ export class TokensForm extends React.PureComponent<Props, State> {
return true;
}
if (newTokenType === TokenType.Project) {
- return !selectedProject.key;
+ return !selectedProject?.value;
}
return !newTokenType;
@@ -212,8 +215,8 @@ export class TokensForm extends React.PureComponent<Props, State> {
this.setState({ newTokenType: value });
};
- handleProjectChange = ({ value, label }: { value: string; label: string }) => {
- this.setState({ selectedProject: { key: value, name: label } });
+ handleProjectChange = (selectedProject: BasicSelectOption) => {
+ this.setState({ selectedProject });
};
handleNewTokenExpirationChange = ({ value }: { value: TokenExpiration }) => {
@@ -277,7 +280,11 @@ export class TokensForm extends React.PureComponent<Props, State> {
onChange={this.handleNewTokenTypeChange}
options={tokenTypeOptions}
placeholder={translate('users.tokens.select_type')}
- value={tokenTypeOptions.find(option => option.value === newTokenType) || null}
+ value={
+ tokenTypeOptions.length === 1
+ ? tokenTypeOptions[0]
+ : tokenTypeOptions.find(option => option.value === newTokenType) || null
+ }
/>
</div>
{newTokenType === TokenType.Project && (
@@ -291,7 +298,7 @@ export class TokensForm extends React.PureComponent<Props, State> {
onChange={this.handleProjectChange}
options={projects}
placeholder={translate('users.tokens.select_project')}
- value={projects.find(project => project.value === selectedProject.key)}
+ value={selectedProject}
/>
</div>
)}
diff --git a/server/sonar-web/src/main/js/apps/users/components/TokensFormModal.tsx b/server/sonar-web/src/main/js/apps/users/components/TokensFormModal.tsx
index 10f9f3ff748..1c987644588 100644
--- a/server/sonar-web/src/main/js/apps/users/components/TokensFormModal.tsx
+++ b/server/sonar-web/src/main/js/apps/users/components/TokensFormModal.tsx
@@ -33,7 +33,7 @@ interface Props {
export default function TokensFormModal(props: Props) {
return (
- <Modal size="medium" contentLabel={translate('users.tokens')} onRequestClose={props.onClose}>
+ <Modal size="large" contentLabel={translate('users.tokens')} onRequestClose={props.onClose}>
<header className="modal-head">
<h2>
<FormattedMessage
diff --git a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/TokensFormModal-test.tsx.snap b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/TokensFormModal-test.tsx.snap
index df708de673e..d52a6fcd165 100644
--- a/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/TokensFormModal-test.tsx.snap
+++ b/server/sonar-web/src/main/js/apps/users/components/__tests__/__snapshots__/TokensFormModal-test.tsx.snap
@@ -4,7 +4,7 @@ exports[`should render correctly 1`] = `
<Modal
contentLabel="users.tokens"
onRequestClose={[MockFunction]}
- size="medium"
+ size="large"
>
<header
className="modal-head"