Skip to content

Commit

Permalink
Use password message from /dashboardsinfo (#1503)
Browse files Browse the repository at this point in the history
* Use password message from /dashboardsinfo

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Run eslint --fix

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Remove unused attribute

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Clean up test

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Remove redundant mock

Signed-off-by: Craig Perkins <cwperx@amazon.com>

* Removed TODO messages

Signed-off-by: Craig Perkins <cwperx@amazon.com>

---------

Signed-off-by: Craig Perkins <cwperx@amazon.com>
(cherry picked from commit f774ae4)
  • Loading branch information
cwperks authored and github-actions[bot] committed Jul 11, 2023
1 parent d466db9 commit f3a3811
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 10 deletions.
19 changes: 18 additions & 1 deletion public/apps/account/password-reset-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import { logout, updateNewPassword } from './utils';
import { PASSWORD_INSTRUCTION } from '../apps-constants';
import { constructErrorMessageAndLog } from '../error-utils';
import { validateCurrentPassword } from '../../utils/login-utils';
import { getDashboardsInfo } from '../../utils/dashboards-info-utils';

interface PasswordResetPanelProps {
coreStart: CoreStart;
Expand All @@ -57,6 +58,22 @@ export function PasswordResetPanel(props: PasswordResetPanelProps) {

const [errorCallOut, setErrorCallOut] = React.useState<string>('');

const [passwordHelpText, setPasswordHelpText] = React.useState<string>(PASSWORD_INSTRUCTION);

React.useEffect(() => {
const fetchData = async () => {
try {
setPasswordHelpText(

Check warning on line 66 in public/apps/account/password-reset-panel.tsx

View check run for this annotation

Codecov / codecov/patch

public/apps/account/password-reset-panel.tsx#L64-L66

Added lines #L64 - L66 were not covered by tests
(await getDashboardsInfo(props.coreStart.http)).password_validation_error_message
);
} catch (e) {
console.error(e);

Check warning on line 70 in public/apps/account/password-reset-panel.tsx

View check run for this annotation

Codecov / codecov/patch

public/apps/account/password-reset-panel.tsx#L70

Added line #L70 was not covered by tests
}
};

fetchData();

Check warning on line 74 in public/apps/account/password-reset-panel.tsx

View check run for this annotation

Codecov / codecov/patch

public/apps/account/password-reset-panel.tsx#L74

Added line #L74 was not covered by tests
}, [props.coreStart.http]);

const handleReset = async () => {
const http = props.coreStart.http;
// validate the current password
Expand Down Expand Up @@ -107,7 +124,7 @@ export function PasswordResetPanel(props: PasswordResetPanelProps) {

<FormRow
headerText="New password"
helpText={PASSWORD_INSTRUCTION}
helpText={passwordHelpText}
isInvalid={isNewPasswordInvalid}
>
<EuiFieldPassword
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,11 @@ export function InternalUserEdit(props: InternalUserEditDeps) {
setNameState={setUserName}
setIsFormValid={setIsFormValid}
/>
<PasswordEditPanel updatePassword={setPassword} updateIsInvalid={setIsPasswordInvalid} />
<PasswordEditPanel
coreStart={props.coreStart}
updatePassword={setPassword}
updateIsInvalid={setIsPasswordInvalid}
/>
</EuiForm>
</PanelWithHeader>
<EuiSpacer size="m" />
Expand Down
20 changes: 19 additions & 1 deletion public/apps/configuration/utils/password-edit-panel.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,35 @@
*/

import React from 'react';
import { CoreStart } from 'opensearch-dashboards/public';
import { EuiFieldText, EuiIcon } from '@elastic/eui';
import { FormRow } from './form-row';
import { PASSWORD_INSTRUCTION } from '../../apps-constants';
import { getDashboardsInfo } from '../../../utils/dashboards-info-utils';

export function PasswordEditPanel(props: {
coreStart: CoreStart;
updatePassword: (p: string) => void;
updateIsInvalid: (v: boolean) => void;
}) {
const [password, setPassword] = React.useState<string>('');
const [repeatPassword, setRepeatPassword] = React.useState<string>('');
const [isRepeatPasswordInvalid, setIsRepeatPasswordInvalid] = React.useState<boolean>(false);
const [passwordHelpText, setPasswordHelpText] = React.useState<string>(PASSWORD_INSTRUCTION);

React.useEffect(() => {
const fetchData = async () => {
try {
setPasswordHelpText(
(await getDashboardsInfo(props.coreStart.http)).password_validation_error_message
);
} catch (e) {
console.error(e);

Check warning on line 40 in public/apps/configuration/utils/password-edit-panel.tsx

View check run for this annotation

Codecov / codecov/patch

public/apps/configuration/utils/password-edit-panel.tsx#L40

Added line #L40 was not covered by tests
}
};

fetchData();
}, [props.coreStart.http]);

React.useEffect(() => {
props.updatePassword(password);
Expand All @@ -43,7 +61,7 @@ export function PasswordEditPanel(props: {

return (
<>
<FormRow headerText="Password" helpText={PASSWORD_INSTRUCTION}>
<FormRow headerText="Password" helpText={passwordHelpText}>
<EuiFieldText
data-test-subj="password"
prepend={<EuiIcon type="lock" />}
Expand Down
58 changes: 51 additions & 7 deletions public/apps/configuration/utils/test/password-edit-panel.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,24 @@
* permissions and limitations under the License.
*/

import { shallow } from 'enzyme';
import { mount, shallow } from 'enzyme';
import React from 'react';
import { PasswordEditPanel } from '../password-edit-panel';
import { getDashboardsInfo } from '../../../../utils/dashboards-info-utils';

const mockDashboardsInfo = {
multitenancy_enabled: true,
private_tenant_enabled: true,
default_tenant: '',
password_validation_error_message:
'Password must be minimum 5 characters long and must contain at least one uppercase letter, one lowercase letter, one digit, and one special character.',
};

jest.mock('../../../../utils/dashboards-info-utils', () => ({
getDashboardsInfo: jest.fn().mockImplementation(() => {
return mockDashboardsInfo;
}),
}));

describe('Password edit panel', () => {
let component;
Expand All @@ -24,21 +39,43 @@ describe('Password edit panel', () => {
const updateIsInvalid = jest.fn();
const useState = jest.spyOn(React, 'useState');
const useEffect = jest.spyOn(React, 'useEffect');
const mockCoreStart = {
http: 1,
};

beforeEach(() => {
useEffect.mockImplementationOnce((f) => f());
useState.mockImplementation((initialValue) => [initialValue, setState]);
component = shallow(
<PasswordEditPanel updatePassword={updatePassword} updateIsInvalid={updateIsInvalid} />
);
});

it('renders', () => {
expect(updatePassword).toHaveBeenCalledTimes(1);
expect(updateIsInvalid).toHaveBeenCalledTimes(1);
afterEach(() => {
jest.clearAllMocks();
});

it('renders', (done) => {
mount(
<PasswordEditPanel
coreStart={mockCoreStart as any}
updatePassword={updatePassword}
updateIsInvalid={updateIsInvalid}
/>
);
process.nextTick(() => {
expect(updatePassword).toHaveBeenCalledTimes(1);
expect(updateIsInvalid).toHaveBeenCalledTimes(1);
expect(setState).toBeCalledWith(mockDashboardsInfo.password_validation_error_message);
done();
});
});

it('password field update', () => {
component = shallow(
<PasswordEditPanel
coreStart={mockCoreStart as any}
updatePassword={updatePassword}
updateIsInvalid={updateIsInvalid}
/>
);
const event = {
target: { value: 'dummy' },
} as React.ChangeEvent<HTMLInputElement>;
Expand All @@ -47,6 +84,13 @@ describe('Password edit panel', () => {
});

it('repeat password field update', () => {
component = shallow(
<PasswordEditPanel
coreStart={mockCoreStart as any}
updatePassword={updatePassword}
updateIsInvalid={updateIsInvalid}
/>
);
const event = {
target: { value: 'dummy' },
} as React.ChangeEvent<HTMLInputElement>;
Expand Down
1 change: 1 addition & 0 deletions public/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export interface DashboardsInfo {
multitenancy_enabled?: boolean;
private_tenant_enabled?: boolean;
default_tenant: string;
password_validation_error_message: string;
}

export interface ClientConfigType {
Expand Down

0 comments on commit f3a3811

Please sign in to comment.