diff options
author | guillaume-peoch-sonarsource <guillaume.peoch@sonarsource.com> | 2023-07-31 11:27:05 +0200 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2023-07-31 20:03:32 +0000 |
commit | 5a71bede94abbaea239c544130876c5f0e535815 (patch) | |
tree | 80f5c9e1c2d215066dd1ebabd676fbe55bd4083f /server/sonar-web | |
parent | e7d3f62c1c161b76230960bc4301eaf7f20f7f1a (diff) | |
download | sonarqube-5a71bede94abbaea239c544130876c5f0e535815.tar.gz sonarqube-5a71bede94abbaea239c544130876c5f0e535815.zip |
SONAR-19967 Use POST api/v2/users on the FE
Diffstat (limited to 'server/sonar-web')
6 files changed, 46 insertions, 30 deletions
diff --git a/server/sonar-web/src/main/js/api/mocks/UsersServiceMock.ts b/server/sonar-web/src/main/js/api/mocks/UsersServiceMock.ts index decdb9c4d53..ad4cf06f831 100644 --- a/server/sonar-web/src/main/js/api/mocks/UsersServiceMock.ts +++ b/server/sonar-web/src/main/js/api/mocks/UsersServiceMock.ts @@ -28,11 +28,11 @@ import { addUserToGroup, removeUserFromGroup } from '../user_groups'; import { UserGroup, changePassword, - createUser, deleteUser, getIdentityProviders, getUserGroups, getUsers, + postUser, updateUser, } from '../users'; @@ -125,7 +125,7 @@ export default class UsersServiceMock { jest.mocked(getSystemInfo).mockImplementation(this.handleGetSystemInfo); jest.mocked(getIdentityProviders).mockImplementation(this.handleGetIdentityProviders); jest.mocked(getUsers).mockImplementation((p) => this.handleGetUsers(p)); - jest.mocked(createUser).mockImplementation(this.handleCreateUser); + jest.mocked(postUser).mockImplementation(this.handlePostUser); jest.mocked(updateUser).mockImplementation(this.handleUpdateUser); jest.mocked(getUserGroups).mockImplementation(this.handleGetUserGroups); jest.mocked(addUserToGroup).mockImplementation(this.handleAddUserToGroup); @@ -248,19 +248,19 @@ export default class UsersServiceMock { }); }; - handleCreateUser = (data: { + handlePostUser = (data: { email?: string; local?: boolean; login: string; name: string; password?: string; - scmAccount: string[]; + scmAccounts: string[]; }) => { - const { email, local, login, name, scmAccount } = data; - if (scmAccount.some((a) => isEmpty(a.trim()))) { + const { email, local, login, name, scmAccounts } = data; + if (scmAccounts.some((a) => isEmpty(a.trim()))) { return Promise.reject({ status: 400, - json: () => Promise.resolve({ errors: [{ msg: 'Error: Empty SCM' }] }), + json: () => Promise.resolve({ message: 'Error: Empty SCM' }), }); } const newUser = mockRestUser({ @@ -268,7 +268,7 @@ export default class UsersServiceMock { local, login, name, - scmAccounts: scmAccount, + scmAccounts, }); this.users.push(newUser); return this.reply(undefined); @@ -373,7 +373,7 @@ export default class UsersServiceMock { const index = this.users.findIndex((u) => u.login === data.login); const user = this.users.splice(index, 1)[0]; user.active = false; - return this.reply({ user }); + return this.reply(undefined); }; reset = () => { diff --git a/server/sonar-web/src/main/js/api/users.ts b/server/sonar-web/src/main/js/api/users.ts index 68c37e2d869..73812ab046f 100644 --- a/server/sonar-web/src/main/js/api/users.ts +++ b/server/sonar-web/src/main/js/api/users.ts @@ -18,7 +18,15 @@ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ import { throwGlobalError } from '../helpers/error'; -import { deleteJSON, getJSON, HttpStatus, parseJSON, post, postJSON } from '../helpers/request'; +import { + deleteJSON, + getJSON, + HttpStatus, + parseJSON, + post, + postJSON, + postJSONBody, +} from '../helpers/request'; import { IdentityProvider, Paging } from '../types/types'; import { ChangePasswordResults, @@ -26,7 +34,6 @@ import { HomePage, NoticeType, RestUserBase, - RestUserDetailed, User, } from '../types/users'; @@ -89,15 +96,14 @@ export function getUsers<T extends RestUserBase>(data: { return getJSON('/api/v2/users', data).catch(throwGlobalError); } -export function createUser(data: { +export function postUser(data: { email?: string; - local?: boolean; login: string; name: string; password?: string; - scmAccount: string[]; + scmAccounts: string[]; }): Promise<void | Response> { - return post('/api/users/create', data); + return postJSONBody('/api/v2/users', data); } export function updateUser(data: { @@ -118,7 +124,7 @@ export function deleteUser({ }: { login: string; anonymize?: boolean; -}): Promise<{ user: RestUserDetailed }> { +}): Promise<void | Response> { return deleteJSON(`/api/v2/users/${login}`, { anonymize }).catch(throwGlobalError); } diff --git a/server/sonar-web/src/main/js/apps/issues/components/AssigneeSelect.tsx b/server/sonar-web/src/main/js/apps/issues/components/AssigneeSelect.tsx index 664518cad3d..111f4561a85 100644 --- a/server/sonar-web/src/main/js/apps/issues/components/AssigneeSelect.tsx +++ b/server/sonar-web/src/main/js/apps/issues/components/AssigneeSelect.tsx @@ -24,7 +24,7 @@ import { CurrentUserContext } from '../../../app/components/current-user/Current import Avatar from '../../../components/ui/Avatar'; import { translate, translateWithParameters } from '../../../helpers/l10n'; import { Issue } from '../../../types/types'; -import { RestUser, isLoggedIn, isUserActive } from '../../../types/users'; +import { RestUser, UserActive, isLoggedIn, isUserActive } from '../../../types/users'; import { searchAssignees } from '../utils'; // exported for test @@ -40,7 +40,7 @@ export interface AssigneeSelectProps { inputId: string; } -function userToOption(user: RestUser) { +function userToOption(user: RestUser | UserActive) { const userInfo = user.name || user.login; return { value: user.login, @@ -58,7 +58,7 @@ export default function AssigneeSelect(props: AssigneeSelectProps) { isLoggedIn(currentUser) && issues.some((issue) => currentUser.login !== issue.assignee); const defaultOptions = allowCurrentUserSelection - ? [UNASSIGNED, userToOption(currentUser as unknown as RestUser)] + ? [UNASSIGNED, userToOption(currentUser)] : [UNASSIGNED]; const controlLabel = assignee ? ( diff --git a/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx b/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx index b63ad7288ee..798ec561001 100644 --- a/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx +++ b/server/sonar-web/src/main/js/apps/users/components/UserForm.tsx @@ -25,8 +25,8 @@ import MandatoryFieldMarker from '../../../components/ui/MandatoryFieldMarker'; import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation'; import { throwGlobalError } from '../../../helpers/error'; import { translate, translateWithParameters } from '../../../helpers/l10n'; -import { parseError } from '../../../helpers/request'; -import { useCreateUserMutation, useUpdateUserMutation } from '../../../queries/users'; +import { parseMessage } from '../../../helpers/request'; +import { usePostUserMutation, useUpdateUserMutation } from '../../../queries/users'; import { RestUserDetailed } from '../../../types/users'; import UserScmAccountInput from './UserScmAccountInput'; @@ -41,7 +41,7 @@ const INTERNAL_SERVER_ERROR = 500; export default function UserForm(props: Props) { const { user } = props; - const { mutate: createUser } = useCreateUserMutation(); + const { mutate: createUser } = usePostUserMutation(); const { mutate: updateUser } = useUpdateUserMutation(); const [email, setEmail] = React.useState<string>(user?.email ?? ''); @@ -55,7 +55,7 @@ export default function UserForm(props: Props) { if (![BAD_REQUEST, INTERNAL_SERVER_ERROR].includes(response.status)) { throwGlobalError(response); } else { - parseError(response).then((errorMsg) => setError(errorMsg), throwGlobalError); + parseMessage(response).then((errorMsg) => setError(errorMsg), throwGlobalError); } }; @@ -66,7 +66,7 @@ export default function UserForm(props: Props) { login, name, password, - scmAccount: scmAccounts, + scmAccounts, }, { onSuccess: props.onClose, onError: handleError } ); diff --git a/server/sonar-web/src/main/js/helpers/request.ts b/server/sonar-web/src/main/js/helpers/request.ts index 9b40c1f14ed..5a1537dfb81 100644 --- a/server/sonar-web/src/main/js/helpers/request.ts +++ b/server/sonar-web/src/main/js/helpers/request.ts @@ -178,7 +178,7 @@ export function parseText(response: Response): Promise<string> { } /** - * Parse response of failed request + * Parse error response of failed request */ export function parseError(response: Response): Promise<string> { const DEFAULT_MESSAGE = translate('default_error_message'); @@ -188,6 +188,16 @@ export function parseError(response: Response): Promise<string> { } /** + * Parse message response of failed request + */ +export function parseMessage(response: Response): Promise<string> { + const DEFAULT_MESSAGE = translate('default_error_message'); + return parseJSON(response) + .then(({ message }) => message) + .catch(() => DEFAULT_MESSAGE); +} + +/** * Shortcut to do a GET request and return a Response */ export function get(url: string, data?: RequestData, bypassRedirect?: boolean): Promise<Response> { @@ -275,7 +285,7 @@ export function post(url: string, data?: RequestData, bypassRedirect?: boolean): /** * Shortcut to do a DELETE request */ -export function deleteJSON(url: string, data?: RequestData): Promise<any> { +export function deleteJSON(url: string, data?: RequestData): Promise<Response> { return request(url) .setMethod('DELETE') .setData(data) diff --git a/server/sonar-web/src/main/js/queries/users.ts b/server/sonar-web/src/main/js/queries/users.ts index 51e3ce0acb9..f74f5730f33 100644 --- a/server/sonar-web/src/main/js/queries/users.ts +++ b/server/sonar-web/src/main/js/queries/users.ts @@ -25,7 +25,7 @@ import { useQueryClient, } from '@tanstack/react-query'; import { range } from 'lodash'; -import { createUser, deleteUser, getUsers, updateUser } from '../api/users'; +import { deleteUser, getUsers, postUser, updateUser } from '../api/users'; import { RestUserBase } from '../types/users'; const STALE_TIME = 4 * 60 * 1000; @@ -65,12 +65,12 @@ export function useInvalidateUsersList() { return () => queryClient.invalidateQueries({ queryKey: ['user', 'list'] }); } -export function useCreateUserMutation() { +export function usePostUserMutation() { const queryClient = useQueryClient(); return useMutation({ - mutationFn: async (data: Parameters<typeof createUser>[0]) => { - await createUser(data); + mutationFn: async (data: Parameters<typeof postUser>[0]) => { + await postUser(data); }, onSuccess() { queryClient.invalidateQueries({ queryKey: ['user', 'list'] }); |