import { isAfter, isBefore } from 'date-fns';
import { cloneDeep, isEmpty, isUndefined, omitBy } from 'lodash';
-import { mockClusterSysInfo, mockIdentityProvider, mockUser } from '../../helpers/testMocks';
+import { mockClusterSysInfo, mockIdentityProvider, mockRestUser } from '../../helpers/testMocks';
import { IdentityProvider, Paging, SysInfoCluster } from '../../types/types';
import { ChangePasswordResults, User } from '../../types/users';
import { getSystemInfo } from '../system';
import { addUserToGroup, removeUserFromGroup } from '../user_groups';
import {
+ GetUsersParams,
+ RestUser,
UserGroup,
changePassword,
createUser,
deactivateUser,
getIdentityProviders,
getUserGroups,
- searchUsers,
+ getUsers,
updateUser,
} from '../users';
jest.mock('../system');
const DEFAULT_USERS = [
- mockUser({
+ mockRestUser({
managed: true,
login: 'bob.marley',
name: 'Bob Marley',
- lastConnectionDate: '2023-06-27T17:08:59+0200',
+ sonarQubeLastConnectionDate: '2023-06-27T17:08:59+0200',
sonarLintLastConnectionDate: '2023-06-27T17:08:59+0200',
}),
- mockUser({
+ mockRestUser({
managed: false,
login: 'alice.merveille',
name: 'Alice Merveille',
- lastConnectionDate: '2023-06-27T17:08:59+0200',
+ sonarQubeLastConnectionDate: '2023-06-27T17:08:59+0200',
sonarLintLastConnectionDate: '2023-05-27T17:08:59+0200',
- groups: ['group1', 'group2', 'group3', 'group4'],
+ email: 'alice.merveille@wonderland.com',
+ // groups: ['group1', 'group2', 'group3', 'group4'],
+ groupsCount: 4,
}),
- mockUser({
+ mockRestUser({
managed: false,
local: false,
login: 'charlie.cox',
name: 'Charlie Cox',
- lastConnectionDate: '2023-06-25T17:08:59+0200',
+ sonarQubeLastConnectionDate: '2023-06-25T17:08:59+0200',
sonarLintLastConnectionDate: '2023-06-20T12:10:59+0200',
externalProvider: 'test',
- externalIdentity: 'ExternalTest',
+ externalLogin: 'ExternalTest',
}),
- mockUser({
+ mockRestUser({
managed: true,
local: false,
externalProvider: 'test2',
- externalIdentity: 'UnknownExternalProvider',
+ externalLogin: 'UnknownExternalProvider',
login: 'denis.villeneuve',
name: 'Denis Villeneuve',
- lastConnectionDate: '2023-06-20T15:08:59+0200',
+ sonarQubeLastConnectionDate: '2023-06-20T15:08:59+0200',
sonarLintLastConnectionDate: '2023-05-25T10:08:59+0200',
}),
- mockUser({
+ mockRestUser({
managed: true,
login: 'eva.green',
name: 'Eva Green',
- lastConnectionDate: '2023-05-27T17:08:59+0200',
+ sonarQubeLastConnectionDate: '2023-05-27T17:08:59+0200',
}),
- mockUser({
+ mockRestUser({
managed: false,
login: 'franck.grillo',
name: 'Franck Grillo',
constructor() {
jest.mocked(getSystemInfo).mockImplementation(this.handleGetSystemInfo);
jest.mocked(getIdentityProviders).mockImplementation(this.handleGetIdentityProviders);
- jest.mocked(searchUsers).mockImplementation((p) => this.handleSearchUsers(p));
+ jest.mocked(getUsers).mockImplementation((p) => this.handleGetUsers(p));
jest.mocked(createUser).mockImplementation(this.handleCreateUser);
jest.mocked(updateUser).mockImplementation(this.handleUpdateUser);
jest.mocked(getUserGroups).mockImplementation(this.handleGetUserGroups);
this.isManaged = managed;
}
- getFilteredUsers = (filterParams: {
- managed: boolean;
+ getFilteredRestUsers = (filterParams: {
q: string;
- lastConnectedAfter?: string;
- lastConnectedBefore?: string;
- slLastConnectedAfter?: string;
- slLastConnectedBefore?: string;
+ managed?: boolean;
+ sonarQubeLastConnectionDateFrom?: string;
+ sonarQubeLastConnectionDateTo?: string;
+ sonarLintLastConnectionDateFrom?: string;
+ sonarLintLastConnectionDateTo?: string;
}) => {
const {
managed,
q,
- lastConnectedAfter,
- lastConnectedBefore,
- slLastConnectedAfter,
- slLastConnectedBefore,
+ sonarQubeLastConnectionDateFrom,
+ sonarQubeLastConnectionDateTo,
+ sonarLintLastConnectionDateFrom,
+ sonarLintLastConnectionDateTo,
} = filterParams;
return this.users.filter((user) => {
}
if (
- lastConnectedAfter &&
- (user.lastConnectionDate === undefined ||
- isBefore(new Date(user.lastConnectionDate), new Date(lastConnectedAfter)))
+ sonarQubeLastConnectionDateFrom &&
+ (user.sonarQubeLastConnectionDate === null ||
+ isBefore(
+ new Date(user.sonarQubeLastConnectionDate),
+ new Date(sonarQubeLastConnectionDateFrom)
+ ))
) {
return false;
}
if (
- lastConnectedBefore &&
- user.lastConnectionDate !== undefined &&
- isAfter(new Date(user.lastConnectionDate), new Date(lastConnectedBefore))
+ sonarQubeLastConnectionDateTo &&
+ user.sonarQubeLastConnectionDate &&
+ isAfter(new Date(user.sonarQubeLastConnectionDate), new Date(sonarQubeLastConnectionDateTo))
) {
return false;
}
if (
- slLastConnectedAfter &&
- (user.sonarLintLastConnectionDate === undefined ||
- isBefore(new Date(user.sonarLintLastConnectionDate), new Date(slLastConnectedAfter)))
+ sonarLintLastConnectionDateFrom &&
+ (user.sonarLintLastConnectionDate === null ||
+ isBefore(
+ new Date(user.sonarLintLastConnectionDate),
+ new Date(sonarLintLastConnectionDateFrom)
+ ))
) {
return false;
}
if (
- slLastConnectedBefore &&
- user.sonarLintLastConnectionDate !== undefined &&
- isAfter(new Date(user.sonarLintLastConnectionDate), new Date(slLastConnectedBefore))
+ sonarLintLastConnectionDateTo &&
+ user.sonarLintLastConnectionDate &&
+ isAfter(new Date(user.sonarLintLastConnectionDate), new Date(sonarLintLastConnectionDateTo))
) {
return false;
}
});
};
- handleSearchUsers = (data: any): Promise<{ paging: Paging; users: User[] }> => {
- let paging = {
+ handleGetUsers = (
+ data: GetUsersParams
+ ): Promise<{ pageRestResponse: Paging; users: RestUser<'admin'>[] }> => {
+ let pageRestResponse = {
pageIndex: 1,
pageSize: 0,
total: 10,
};
- if (data.p !== undefined && data.p !== paging.pageIndex) {
- paging = { pageIndex: 2, pageSize: 2, total: 10 };
+ if (data.pageIndex !== undefined && data.pageIndex !== pageRestResponse.pageIndex) {
+ pageRestResponse = { pageIndex: 2, pageSize: 2, total: 10 };
const users = [
- mockUser({
+ mockRestUser({
name: `Local User ${this.users.length + 4}`,
login: `local-user-${this.users.length + 4}`,
}),
- mockUser({
+ mockRestUser({
name: `Local User ${this.users.length + 5}`,
login: `local-user-${this.users.length + 5}`,
}),
];
- return this.reply({ paging, users });
+ return this.reply({ pageRestResponse, users });
}
- const users = this.getFilteredUsers(data);
+ const users = this.getFilteredRestUsers({
+ managed: data.managed,
+ q: data.q,
+ sonarQubeLastConnectionDateFrom: data.sonarQubeLastConnectionDateFrom,
+ sonarQubeLastConnectionDateTo: data.sonarQubeLastConnectionDateTo,
+ sonarLintLastConnectionDateFrom: data.sonarLintLastConnectionDateFrom,
+ sonarLintLastConnectionDateTo: data.sonarLintLastConnectionDateTo,
+ }) as RestUser<'admin'>[];
+
return this.reply({
- paging: {
+ pageRestResponse: {
pageIndex: 1,
pageSize: users.length,
total: 10,
json: () => Promise.resolve({ errors: [{ msg: 'Error: Empty SCM' }] }),
});
}
- const newUser = mockUser({
+ const newUser = mockRestUser({
email,
local,
login,
scmAccount: string[];
}) => {
const { email, login, name, scmAccount } = data;
- const user = this.users.find((u) => u.login === login);
+ const user = this.users.find((u) => u.login === login) as User;
if (!user) {
return Promise.reject('No such user');
}
useQueryClient,
} from '@tanstack/react-query';
import { range } from 'lodash';
-import { User } from '../../types/users';
import {
CreateUserParams,
DeactivateUserParams,
- SearchUsersParams,
+ GetUsersParams,
+ Permission,
+ RestUser,
UpdateUserParams,
createUser,
deactivateUser,
- searchUsers,
+ getUsers,
updateUser,
} from '../users';
-export function useUsersQueries(
- searchParam: Omit<SearchUsersParams, 'p' | 'ps'>,
+export function useUsersQueries<P extends Permission>(
+ getParams: Omit<GetUsersParams, 'pageSize' | 'pageIndex'>,
numberOfPages: number
) {
- type QueryKey = ['user', 'list', number, Omit<SearchUsersParams, 'p' | 'ps'>];
+ type QueryKey = ['user', 'list', number, Omit<GetUsersParams, 'pageSize' | 'pageIndex'>];
const results = useQueries({
queries: range(1, numberOfPages + 1).map((page: number) => ({
- queryKey: ['user', 'list', page, searchParam],
- queryFn: ({ queryKey: [_u, _l, page, searchParam] }: QueryFunctionContext<QueryKey>) =>
- searchUsers({ ...searchParam, p: page }),
+ queryKey: ['user', 'list', page, getParams],
+ queryFn: ({ queryKey: [_u, _l, page, getParams] }: QueryFunctionContext<QueryKey>) =>
+ getUsers<P>({ ...getParams, pageIndex: page }),
})),
});
return results.reduce(
(acc, { data, isLoading }) => ({
users: acc.users.concat(data?.users ?? []),
- total: data?.paging.total,
+ total: data?.pageRestResponse.total,
isLoading: acc.isLoading || isLoading,
}),
- { users: [] as User[], total: 0, isLoading: false }
+ { users: [] as RestUser<P>[], total: 0, isLoading: false }
);
}
return getJSON('/api/users/search', data).catch(throwGlobalError);
}
+export interface GetUsersParams {
+ q: string;
+ active?: boolean;
+ managed?: boolean;
+ sonarQubeLastConnectionDateFrom?: string;
+ sonarQubeLastConnectionDateTo?: string;
+ sonarLintLastConnectionDateFrom?: string;
+ sonarLintLastConnectionDateTo?: string;
+ pageSize?: number;
+ pageIndex?: number;
+}
+
+export type Permission = 'admin' | 'anonymous' | 'user';
+
+export type RestUser<T extends Permission> = T extends 'admin'
+ ? {
+ id: string;
+ login: string;
+ name: string;
+ email: string;
+ active: boolean;
+ local: boolean;
+ externalProvider: string;
+ avatar: string;
+ managed: boolean;
+ externalLogin: string;
+ sonarQubeLastConnectionDate: string | null;
+ sonarLintLastConnectionDate: string | null;
+ scmAccounts: string[];
+ groupsCount: number;
+ tokensCount: number;
+ }
+ : T extends 'anonymous'
+ ? { id: string; login: string; name: string }
+ : {
+ id: string;
+ login: string;
+ name: string;
+ email: string;
+ active: boolean;
+ local: boolean;
+ externalProvider: string;
+ avatar: string;
+ };
+
+export function getUsers<T extends Permission>(
+ data: GetUsersParams
+): Promise<{ pageRestResponse: Paging; users: RestUser<T>[] }> {
+ return getJSON('/api/v2/users', data).catch(throwGlobalError);
+}
+
export interface CreateUserParams {
email?: string;
local?: boolean;
anonymize?: boolean;
}
-export function deactivateUser(data: DeactivateUserParams): Promise<{ user: User }> {
+export function deactivateUser(data: DeactivateUserParams): Promise<{ user: RestUser<'admin'> }> {
return postJSON('/api/users/deactivate', data).catch(throwGlobalError);
}
switch (usersActivity) {
case UserActivity.ActiveSonarLintUser:
return {
- slLastConnectedAfter: toISO8601WithOffsetString(nowDateMinus30Days),
+ sonarLintLastConnectionDateFrom: toISO8601WithOffsetString(nowDateMinus30Days),
};
case UserActivity.ActiveSonarQubeUser:
return {
- lastConnectedAfter: toISO8601WithOffsetString(nowDateMinus30Days),
- slLastConnectedBefore: toISO8601WithOffsetString(nowDateMinus30DaysAnd1Second),
+ sonarQubeLastConnectionDateFrom: toISO8601WithOffsetString(nowDateMinus30Days),
+ sonarLintLastConnectionDateTo: toISO8601WithOffsetString(nowDateMinus30DaysAnd1Second),
};
case UserActivity.InactiveUser:
return {
- lastConnectedBefore: toISO8601WithOffsetString(nowDateMinus30DaysAnd1Second),
+ sonarQubeLastConnectionDateTo: toISO8601WithOffsetString(nowDateMinus30DaysAnd1Second),
};
default:
return {};
}
}, [usersActivity]);
- const { users, total, isLoading } = useUsersQueries(
+ const { users, total, isLoading } = useUsersQueries<'admin'>(
{
q: search,
managed,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { RestUser } from '../../api/users';
import { CurrentUserContext } from '../../app/components/current-user/CurrentUserContext';
import HelpTooltip from '../../components/controls/HelpTooltip';
import { translate } from '../../helpers/l10n';
import { IdentityProvider } from '../../types/types';
-import { isLoggedIn, User } from '../../types/users';
+import { isLoggedIn } from '../../types/users';
import UserListItem from './components/UserListItem';
interface Props {
identityProviders: IdentityProvider[];
- users: User[];
+ users: RestUser<'admin'>[];
manageProvider: string | undefined;
}
}),
aliceRowWithLocalBadge: byRole('row', {
name: (accessibleName) =>
- accessibleName.startsWith('AM Alice Merveille alice.merveille local '),
+ accessibleName.startsWith(
+ 'AM Alice Merveille alice.merveille alice.merveille@wonderland.com local '
+ ),
}),
bobRow: byRole('row', {
name: (accessibleName) => accessibleName.startsWith('BM Bob Marley bob.marley '),
expect(await ui.dialogUpdateUser.find()).toBeInTheDocument();
expect(ui.userNameInput.get()).toHaveValue('Alice Merveille');
- expect(ui.emailInput.get()).toHaveValue('');
+ expect(ui.emailInput.get()).toHaveValue('alice.merveille@wonderland.com');
await user.type(ui.userNameInput.get(), '1');
+ await user.clear(ui.emailInput.get());
await user.type(ui.emailInput.get(), 'test@test.com');
await act(() => user.click(ui.updateButton.get()));
expect(ui.dialogUpdateUser.query()).not.toBeInTheDocument();
renderUsersApp();
await act(async () => expect(await ui.charlieRow.find()).toHaveTextContent(/ExternalTest/));
+ // logRoles(document.body);
expect(await ui.denisRow.find()).toHaveTextContent(/test2: UnknownExternalProvider/);
});
import * as React from 'react';
import { useInvalidateUsersList } from '../../../api/queries/users';
import { addUserToGroup, removeUserFromGroup } from '../../../api/user_groups';
-import { UserGroup, getUserGroups } from '../../../api/users';
+import { RestUser, UserGroup, getUserGroups } from '../../../api/users';
import Modal from '../../../components/controls/Modal';
import SelectList, {
SelectListFilter,
} from '../../../components/controls/SelectList';
import { ResetButtonLink } from '../../../components/controls/buttons';
import { translate } from '../../../helpers/l10n';
-import { User } from '../../../types/users';
interface Props {
onClose: () => void;
- user: User;
+ user: RestUser<'admin'>;
}
export default function GroupsForm(props: Props) {
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
-import { changePassword } from '../../../api/users';
+import { RestUser, changePassword } from '../../../api/users';
import Modal from '../../../components/controls/Modal';
import { ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import { Alert } from '../../../components/ui/Alert';
import MandatoryFieldsExplanation from '../../../components/ui/MandatoryFieldsExplanation';
import { addGlobalSuccessMessage } from '../../../helpers/globalMessages';
import { translate } from '../../../helpers/l10n';
-import { ChangePasswordResults, User } from '../../../types/users';
+import { ChangePasswordResults } from '../../../types/users';
interface Props {
isCurrentUser: boolean;
onClose: () => void;
- user: User;
+ user: RestUser<'admin'>;
}
interface State {
import * as React from 'react';
import { FormattedMessage } from 'react-intl';
import { useInvalidateUsersList } from '../../../api/queries/users';
+import { RestUser } from '../../../api/users';
import Modal from '../../../components/controls/Modal';
import { ResetButtonLink } from '../../../components/controls/buttons';
import { translate } from '../../../helpers/l10n';
-import { User } from '../../../types/users';
import TokensForm from './TokensForm';
interface Props {
- user: User;
+ user: RestUser<'admin'>;
onClose: () => void;
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { RestUser } from '../../../api/users';
import ActionsDropdown, {
ActionsDropdownDivider,
ActionsDropdownItem,
} from '../../../components/controls/ActionsDropdown';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { User, isUserActive } from '../../../types/users';
+import { isUserActive } from '../../../types/users';
import DeactivateForm from './DeactivateForm';
import PasswordForm from './PasswordForm';
import UserForm from './UserForm';
interface Props {
isCurrentUser: boolean;
- user: User;
+ user: RestUser<'admin'>;
manageProvider: string | undefined;
}
*/
import * as React from 'react';
import { useCreateUserMutation, useUpdateUserMutation } from '../../../api/queries/users';
+import { RestUser } from '../../../api/users';
import SimpleModal from '../../../components/controls/SimpleModal';
import { Button, ResetButtonLink, SubmitButton } from '../../../components/controls/buttons';
import { Alert } from '../../../components/ui/Alert';
import { throwGlobalError } from '../../../helpers/error';
import { translate, translateWithParameters } from '../../../helpers/l10n';
import { parseError } from '../../../helpers/request';
-import { User } from '../../../types/users';
import UserScmAccountInput from './UserScmAccountInput';
export interface Props {
onClose: () => void;
- user?: User;
+ user?: RestUser<'admin'>;
}
export default function UserForm(props: Props) {
const handleError = (response: Response) => {
if (![400, 500].includes(response.status)) {
- return throwGlobalError(response);
+ throwGlobalError(response);
+ } else {
+ parseError(response).then((errorMsg) => setError(errorMsg), throwGlobalError);
}
- return parseError(response).then((errorMsg) => setError(errorMsg), throwGlobalError);
};
const handleCreateUser = () => {
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { RestUser } from '../../../api/users';
import { ButtonIcon, ButtonLink } from '../../../components/controls/buttons';
import BulletListIcon from '../../../components/icons/BulletListIcon';
import { translate, translateWithParameters } from '../../../helpers/l10n';
-import { User } from '../../../types/users';
import GroupsForm from './GroupsForm';
interface Props {
groups: string[];
- user: User;
+ user: RestUser<'admin'>;
manageProvider: string | undefined;
}
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
import * as React from 'react';
+import { RestUser } from '../../../api/users';
import { ButtonIcon } from '../../../components/controls/buttons';
import BulletListIcon from '../../../components/icons/BulletListIcon';
import DateFromNow from '../../../components/intl/DateFromNow';
import LegacyAvatar from '../../../components/ui/LegacyAvatar';
import { translateWithParameters } from '../../../helpers/l10n';
import { IdentityProvider } from '../../../types/types';
-import { User } from '../../../types/users';
import TokensFormModal from './TokensFormModal';
import UserActions from './UserActions';
-import UserGroups from './UserGroups';
import UserListItemIdentity from './UserListItemIdentity';
import UserScmAccounts from './UserScmAccounts';
export interface UserListItemProps {
identityProvider?: IdentityProvider;
isCurrentUser: boolean;
- user: User;
+ user: RestUser<'admin'>;
manageProvider: string | undefined;
}
export default function UserListItem(props: UserListItemProps) {
- const [openTokenForm, setOpenTokenForm] = React.useState(false);
-
const { identityProvider, user, manageProvider, isCurrentUser } = props;
+ const {
+ name,
+ login,
+ managed,
+ tokensCount,
+ avatar,
+ sonarQubeLastConnectionDate,
+ sonarLintLastConnectionDate,
+ scmAccounts,
+ } = user;
+
+ const [openTokenForm, setOpenTokenForm] = React.useState(false);
return (
<tr>
<td className="thin text-middle">
<div className="sw-flex sw-items-center">
- <LegacyAvatar
- className="sw-shrink-0 sw-mr-4"
- hash={user.avatar}
- name={user.name}
- size={36}
- />
+ <LegacyAvatar className="sw-shrink-0 sw-mr-4" hash={avatar} name={name} size={36} />
<UserListItemIdentity
identityProvider={identityProvider}
user={user}
</div>
</td>
<td className="thin text-middle">
- <UserScmAccounts scmAccounts={user.scmAccounts || []} />
+ <UserScmAccounts scmAccounts={scmAccounts || []} />
</td>
<td className="thin nowrap text-middle">
- <DateFromNow date={user.lastConnectionDate} hourPrecision />
+ <DateFromNow date={sonarQubeLastConnectionDate ?? ''} hourPrecision />
</td>
<td className="thin nowrap text-middle">
- <DateFromNow date={user.sonarLintLastConnectionDate} hourPrecision />
+ <DateFromNow date={sonarLintLastConnectionDate ?? ''} hourPrecision />
</td>
<td className="thin nowrap text-middle">
- <UserGroups groups={user.groups ?? []} manageProvider={manageProvider} user={user} />
+ {user.groupsCount}
+ {/* <UserGroups groups={user.groupsCount} manageProvider={manageProvider} user={user} /> */}
</td>
<td className="thin nowrap text-middle">
- {user.tokensCount}
+ {tokensCount}
<ButtonIcon
className="js-user-tokens spacer-left button-small"
onClick={() => setOpenTokenForm(true)}
tooltip={translateWithParameters('users.update_tokens')}
- aria-label={translateWithParameters('users.update_tokens_for_x', user.name ?? user.login)}
+ aria-label={translateWithParameters('users.update_tokens_for_x', name ?? login)}
>
<BulletListIcon />
</ButtonIcon>
</td>
- {(manageProvider === undefined || !user.managed) && (
+ {(manageProvider === undefined || !managed) && (
<td className="thin nowrap text-right text-middle">
<UserActions isCurrentUser={isCurrentUser} user={user} manageProvider={manageProvider} />
</td>
import { getTextColor } from 'design-system';
import * as React from 'react';
+import { RestUser } from '../../../api/users';
import { colors } from '../../../app/theme';
import { translate } from '../../../helpers/l10n';
import { getBaseUrl } from '../../../helpers/system';
import { IdentityProvider } from '../../../types/types';
-import { User } from '../../../types/users';
export interface Props {
identityProvider?: IdentityProvider;
- user: User;
+ user: RestUser<'admin'>;
manageProvider?: string;
}
return (
<div className="js-user-identity-provider little-spacer-top">
<span>
- {user.externalProvider}: {user.externalIdentity}
+ {user.externalProvider}: {user.externalLogin}
</span>
</div>
);
src={getBaseUrl() + identityProvider.iconPath}
width="14"
/>
- {user.externalIdentity}
+ {user.externalLogin}
</div>
</div>
);
*/
import { To } from 'react-router-dom';
import { CompareResponse } from '../api/quality-profiles';
+import { RestUser } from '../api/users';
import { RuleDescriptionSections } from '../apps/coding-rules/rule';
import { Exporter, Profile, ProfileChangelogEvent } from '../apps/quality-profiles/types';
import { LogsLevels } from '../apps/system/utils';
};
}
+export function mockRestUser(overrides: Partial<RestUser<'admin'>> = {}): RestUser<'admin'> {
+ return {
+ id: Math.random().toString(),
+ login: 'buzz.aldrin',
+ name: 'Buzz Aldrin',
+ email: 'buzz.aldrin@nasa.com',
+ active: true,
+ local: true,
+ managed: false,
+ externalProvider: '',
+ externalLogin: '',
+ sonarQubeLastConnectionDate: null,
+ sonarLintLastConnectionDate: null,
+ scmAccounts: [],
+ tokensCount: 0,
+ groupsCount: 0,
+ avatar: 'buzzonthemoon',
+ ...overrides,
+ };
+}
+
export function mockUserSelected(overrides: Partial<UserSelected> = {}): UserSelected {
return {
active: true,