Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Validation to Create User Flow #1581

Closed
Prev Previous commit
Next Next commit
clean up and add tests
Signed-off-by: Derek Ho <dxho@amazon.com>
derek-ho committed Sep 11, 2023
commit dc9897b9272bab6c56b941da9fbc3d07cecce077
Original file line number Diff line number Diff line change
@@ -64,13 +64,14 @@ const TITLE_TEXT_DICT = {
export function InternalUserEdit(props: InternalUserEditDeps) {
const [userName, setUserName] = useState<string>('');
const [password, setPassword] = useState<string>('');
const [isPasswordInvalid, setIsPasswordInvalid] = React.useState<boolean>(true);
const [isPasswordInvalid, setIsPasswordInvalid] = React.useState<boolean>(
props.sourceUserName && props.action === 'edit' ? false : true
);
const [attributes, setAttributes] = useState<UserAttributeStateClass[]>([]);
const [backendRoles, setBackendRoles] = useState<string[]>([]);

const [toasts, addToast, removeToast] = useToastState();

// Assuming in the edit user scenario the username is valid
const [isUsernameValid, setIsUsernameValid] = useState<boolean>(
props.sourceUserName ? true : false
);
@@ -193,7 +194,14 @@ export function InternalUserEdit(props: InternalUserEditDeps) {
id="submit"
fill
onClick={updateUserHandler}
disabled={!isUsernameValid || isPasswordInvalid}
disabled={
(!props.sourceUserName && (!isUsernameValid || isPasswordInvalid)) ||
(props.sourceUserName &&
props.action === 'edit' &&
password !== '' &&
isPasswordInvalid) ||
(props.sourceUserName && props.action === 'duplicate' && isPasswordInvalid)
}
>
{props.action === 'edit' ? 'Save changes' : 'Create'}
</EuiButton>
Original file line number Diff line number Diff line change
@@ -14,6 +14,9 @@
*/

import { shallow } from 'enzyme';
import { act, fireEvent, render, screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import '@testing-library/jest-dom/extend-expect';
import React from 'react';
import { InternalUserUpdate } from '../../../types';
import { getUserDetail, updateUser } from '../../../utils/internal-user-detail-utils';
@@ -144,4 +147,60 @@ describe('Internal user edit', () => {
expect(createErrorToast).toBeCalled();
expect(updateUser).toBeCalledTimes(0);
});

it('Create button should be disabled if no password or username on create', async () => {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we should split this test into there to ensure both cases work. One where username is provided but password is not, other where password is provided and username is not, and last where both are provided

const action = 'create';
useState.mockImplementation((initialValue) => ['', setState]);

render(
<InternalUserEdit
action={action}
buildBreadcrumbs={buildBreadcrumbs}
coreStart={mockCoreStart as any}
navigation={{} as any}
params={{} as any}
config={{} as any}
/>
);
// Button is disabled since there is no username and password on create
expect(screen.getByText('Create').closest('button')).toBeDisabled();
});

it('Save changes button should be enabled if no password on edit', async () => {
const action = 'edit';
useState.mockImplementation((initialValue) => [initialValue, setState]);

render(
<InternalUserEdit
action={action}
sourceUserName={sampleUsername}
buildBreadcrumbs={buildBreadcrumbs}
coreStart={mockCoreStart as any}
navigation={{} as any}
params={{} as any}
config={{} as any}
/>
);
// Button is enabled since the page is on edit
expect(screen.getByText('Save changes').closest('button')).not.toBeDisabled();
});

it('Create button should be disabled if no password on duplicate', async () => {
const action = 'duplicate';
useState.mockImplementation((initialValue) => [initialValue, setState]);

render(
<InternalUserEdit
action={action}
sourceUserName={sampleUsername}
buildBreadcrumbs={buildBreadcrumbs}
coreStart={mockCoreStart as any}
navigation={{} as any}
params={{} as any}
config={{} as any}
/>
);
// Button is enabled since the page is on edit
expect(screen.getByText('Create').closest('button')).toBeDisabled();
});
});
1 change: 1 addition & 0 deletions public/apps/configuration/utils/name-row.tsx
Original file line number Diff line number Diff line change
@@ -57,6 +57,7 @@ export function NameRow(props: NameRowDeps) {
}}
disabled={props.action === 'edit'}
isInvalid={errors.length > 0}
aria-label="name-text"
/>
</FormRow>
);
3 changes: 3 additions & 0 deletions public/apps/configuration/utils/password-edit-panel.tsx
Original file line number Diff line number Diff line change
@@ -60,6 +60,7 @@ export function PasswordEditPanel(props: {
React.useEffect(() => {
props.updatePassword(password);
const isInvalid = repeatPassword !== password || !password.match(passwordValidationRegex);
console.log(password, passwordValidationRegex);
setIsRepeatPasswordInvalid(repeatPassword !== password);
props.updateIsInvalid(isInvalid);
}, [password, props, repeatPassword, passwordValidationRegex]);
@@ -87,6 +88,7 @@ export function PasswordEditPanel(props: {
onChange={passwordChangeHandler}
isInvalid={passwordErrors.length > 0}
onBlur={() => validatePassword()}
aria-label="password"
/>
</FormRow>

@@ -104,6 +106,7 @@ export function PasswordEditPanel(props: {
type="password"
isInvalid={isRepeatPasswordInvalid}
onChange={repeatPasswordChangeHandler}
aria-label="re-enter-password"
/>
</FormRow>
</>