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

[Multiple Datasource Test] Add test for edit data source form #6742

Merged
merged 5 commits into from
May 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions changelogs/fragments/6742.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
fix:
- Add test for edit data source form ([#6742](https://github.com/opensearch-project/OpenSearch-Dashboards/pull/6742))
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
existingDatasourceNamesList,
mockDataSourceAttributesWithNoAuth,
mockDataSourceAttributesWithRegisteredAuth,
mockDataSourceAttributesWithSigV4Auth,
} from '../../../../mocks';
import { OpenSearchDashboardsContextProvider } from '../../../../../../opensearch_dashboards_react/public';
import { EditDataSourceForm } from './edit_data_source_form';
Expand All @@ -34,6 +35,13 @@ const usernameFieldIdentifier = 'datasourceUsername';
const usernameFormRowIdentifier = '[data-test-subj="editDatasourceUsernameFormRow"]';
const passwordFieldIdentifier = '[data-test-subj="updateDataSourceFormPasswordField"]';
const updatePasswordBtnIdentifier = '[data-test-subj="editDatasourceUpdatePasswordBtn"]';
const updateAwsCredsBtnIdentifier = '[data-test-subj="editDatasourceUpdateAwsCredentialBtn"]';
const regionFieldIdentifier = 'dataSourceRegion';
const accessKeyFieldIdentifier = 'dataSourceAccessKey';
const accessKeyFormRowIdentifier = '[data-test-subj="editDataSourceFormAccessKeyField"]';
const secretKeyFieldIdentifier = 'dataSourceSecretKey';
const secretKeyFormRowIdentifier = '[data-test-subj="editDataSourceFormSecretKeyField"]';

describe('Datasource Management: Edit Datasource Form', () => {
const mockedContext = mockManagementPlugin.createDataSourceManagementContext();
mockedContext.authenticationMethodRegistry.registerAuthenticationMethod(
Expand Down Expand Up @@ -351,6 +359,192 @@ describe('Datasource Management: Edit Datasource Form', () => {
expect(mockFn).toHaveBeenCalled();
});
});

describe('Case 3: With AWSsigv4', () => {
beforeEach(() => {
component = mount(
wrapWithIntl(
<EditDataSourceForm
existingDataSource={mockDataSourceAttributesWithSigV4Auth}
existingDatasourceNamesList={existingDatasourceNamesList}
isDefault={false}
onDeleteDataSource={mockFn}
handleSubmit={mockFn}
onSetDefaultDataSource={mockFn}
handleTestConnection={mockFn}
displayToastMessage={mockFn}
/>
),
{
wrappingComponent: OpenSearchDashboardsContextProvider,
wrappingComponentProps: {
services: mockedContext,
},
}
);
component.update();
});

test('should render normally', () => {
// @ts-ignore
expect(component.find({ name: titleFieldIdentifier }).first().props().value).toBe(
mockDataSourceAttributesWithSigV4Auth.title
);
expect(component.find(endpointFieldIdentifier).first().props().disabled).toBe(true);
});

/* Validation */
test('should validate title as required field & no duplicates allowed', () => {
/* Validate empty title - required */
updateInputFieldAndBlur(component, titleFieldIdentifier, '');
// @ts-ignore
expect(component.find(titleFormRowIdentifier).first().props().isInvalid).toBe(true);

/* Validate duplicate title */
updateInputFieldAndBlur(component, titleFieldIdentifier, 'DuP20');
// @ts-ignore
expect(component.find(titleFormRowIdentifier).first().props().isInvalid).toBe(true);

/* change to original title */
updateInputFieldAndBlur(
component,
titleFieldIdentifier,
mockDataSourceAttributesWithSigV4Auth.title
);
// @ts-ignore
expect(component.find(titleFormRowIdentifier).first().props().isInvalid).toBe(false);

/* change to valid updated title */
updateInputFieldAndBlur(component, titleFieldIdentifier, 'test007');
// @ts-ignore
expect(component.find(titleFormRowIdentifier).first().props().isInvalid).toBe(false);
});
test('should validate access key as required field', () => {
/* Validate empty accessKey - required */
updateInputFieldAndBlur(component, accessKeyFieldIdentifier, '');
// @ts-ignore
expect(component.find(accessKeyFormRowIdentifier).first().props().isInvalid).toBe(true);

/* change to original accessKey */
updateInputFieldAndBlur(
component,
accessKeyFieldIdentifier,
mockDataSourceAttributesWithSigV4Auth.auth.credentials.accessKey
);
// @ts-ignore
expect(component.find(accessKeyFormRowIdentifier).first().props().isInvalid).toBe(false);
/* change to valid updated accessKey */
updateInputFieldAndBlur(component, accessKeyFieldIdentifier, 'test123');
// @ts-ignore
expect(component.find(accessKeyFormRowIdentifier).first().props().isInvalid).toBe(false);
});
test('should validate secret key as required field', () => {
/* Validate empty secretKey - required */
updateInputFieldAndBlur(component, secretKeyFieldIdentifier, '');
// @ts-ignore
expect(component.find(secretKeyFormRowIdentifier).first().props().isInvalid).toBe(true);

/* change to original secretKey */
updateInputFieldAndBlur(
component,
secretKeyFieldIdentifier,
mockDataSourceAttributesWithSigV4Auth.auth.credentials.secretKey
);
// @ts-ignore
expect(component.find(secretKeyFormRowIdentifier).first().props().isInvalid).toBe(false);
/* change to valid updated secretKey */
updateInputFieldAndBlur(component, secretKeyFieldIdentifier, 'test123');
// @ts-ignore
expect(component.find(secretKeyFormRowIdentifier).first().props().isInvalid).toBe(false);
});
/* Functionality */
test('should display update aws credential modal on update button click and should update the credentials', () => {
act(() => {
component.find(updateAwsCredsBtnIdentifier).first().simulate('click');
});
component.update();
expect(component.find('UpdateAwsCredentialModal').exists()).toBe(true);

/* Update password */
act(() => {
// @ts-ignore
component.find('UpdateAwsCredentialModal').prop('handleUpdateAwsCredential')('test123');
});
component.update();
expect(mockFn).toHaveBeenCalled();
expect(component.find('UpdateAwsCredentialModal').exists()).toBe(false);
});
test("should hide username & password fields when 'AWS Sigv4' is selected as the credential type", () => {
setAuthTypeValue(authTypeSelectIdentifier, AuthType.SigV4);
component.update();
expect(component.find(usernameFormRowIdentifier).exists()).toBe(false);
expect(component.find(passwordFieldIdentifier).exists()).toBe(false);
});

/* Cancel Changes */
test('should reset form on click cancel changes', async () => {
await new Promise((resolve) =>
setTimeout(() => {
updateInputFieldAndBlur(component, descriptionFieldIdentifier, '');
expect(
// @ts-ignore
component.find(descriptionFormRowIdentifier).first().props().isInvalid
).toBeUndefined();
resolve();
}, 100)
);
await new Promise((resolve) =>
setTimeout(() => {
/* Updated description*/
updateInputFieldAndBlur(component, descriptionFieldIdentifier, 'testDescription');
expect(
// @ts-ignore
component.find(descriptionFormRowIdentifier).first().props().isInvalid
).toBeUndefined();

expect(component.find('[data-test-subj="datasource-edit-cancelButton"]').exists()).toBe(
true
);
component
.find('[data-test-subj="datasource-edit-cancelButton"]')
.first()
.simulate('click');
resolve();
}, 100)
);
});

/* Save Changes */
test('should update the form with Username&Password on click save changes', async () => {
await new Promise((resolve) =>
setTimeout(() => {
updateInputFieldAndBlur(component, descriptionFieldIdentifier, '');
expect(
// @ts-ignore
component.find(descriptionFormRowIdentifier).first().props().isInvalid
).toBeUndefined();
resolve();
}, 100)
);
await new Promise((resolve) =>
setTimeout(() => {
/* Updated description*/
updateInputFieldAndBlur(component, descriptionFieldIdentifier, 'testDescription');
expect(
// @ts-ignore
component.find(descriptionFormRowIdentifier).first().props().isInvalid
).toBeUndefined();

expect(component.find('[data-test-subj="datasource-edit-saveButton"]').exists()).toBe(
true
);
component.find('[data-test-subj="datasource-edit-saveButton"]').first().simulate('click');
expect(mockFn).toHaveBeenCalled();
resolve();
}, 100)
);
});
});
});

describe('With Registered Authentication', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -882,6 +882,7 @@ export class EditDataSourceForm extends React.Component<EditDataSourceProps, Edi
onChange={this.onChangeRegion}
onBlur={this.validateRegion}
data-test-subj="editDataSourceFormRegionField"
name="dataSourceRegion"
/>
</EuiFormRow>
<EuiFormRow
Expand Down Expand Up @@ -923,6 +924,7 @@ export class EditDataSourceForm extends React.Component<EditDataSourceProps, Edi
spellCheck={false}
disabled={this.props.existingDataSource.auth.type === AuthType.SigV4}
data-test-subj="editDataSourceFormAccessKeyField"
name="dataSourceAccessKey"
/>
</EuiFormRow>
<EuiFormRow
Expand Down Expand Up @@ -951,6 +953,7 @@ export class EditDataSourceForm extends React.Component<EditDataSourceProps, Edi
spellCheck={false}
disabled={this.props.existingDataSource.auth.type === AuthType.SigV4}
data-test-subj="editDataSourceFormSecretKeyField"
name="dataSourceSecretKey"
/>
</EuiFormRow>
<EuiSpacer />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
/*
* Copyright OpenSearch Contributors
* SPDX-License-Identifier: Apache-2.0
*/

import React from 'react';
import { mount, shallow } from 'enzyme';
import { render } from '@testing-library/react';
import { UpdateAwsCredentialModal } from './update_aws_credential_modal';
import { SigV4ServiceName } from '../../../../../../data_source/common/data_sources';
import { EuiFormRow, EuiModalHeaderTitle } from '@elastic/eui';
import { FormattedMessage } from 'react-intl';

describe('UpdateAwsCredentialModal', () => {
const mockHandleUpdateAwsCredential = jest.fn();
const mockCloseUpdateAwsCredentialModal = jest.fn();

const props = {
region: 'us-east-1',
service: SigV4ServiceName.OpenSearch,
handleUpdateAwsCredential: mockHandleUpdateAwsCredential,
closeUpdateAwsCredentialModal: mockCloseUpdateAwsCredentialModal,
};

it('updates new access key state on input change', () => {
const wrapper = shallow(<UpdateAwsCredentialModal {...props} />);
const newAccessKeyInput = wrapper.find('[name="updatedAccessKey"]');
newAccessKeyInput.simulate('change', { target: { value: 'new_access_key' } });
expect(wrapper.find('[name="updatedAccessKey"]').prop('value')).toEqual('new_access_key');
});

it('renders modal with correct header title', () => {
const wrapper = shallow(<UpdateAwsCredentialModal {...props} />);
const headerTitle = wrapper.find(EuiModalHeaderTitle).props().children;
expect(headerTitle).toEqual(
<h1>
<FormattedMessage
defaultMessage="Update stored AWS credential"
id="dataSourcesManagement.editDataSource.updateStoredAwsCredential"
values={{}}
/>
</h1>
);
});

it('renders modal with correct label for updated secret key', () => {
const wrapper = shallow(<UpdateAwsCredentialModal {...props} />);
expect(wrapper.find(EuiFormRow).at(4).props().label).toEqual('Updated secret key');
});

it('renders modal with correct label for updated access key', () => {
const wrapper = shallow(<UpdateAwsCredentialModal {...props} />);
expect(wrapper.find(EuiFormRow).at(3).props().label).toEqual('Updated access key');
});

it('renders modal with correct region', () => {
const container = render(<UpdateAwsCredentialModal {...props} />);
expect(container.getByTestId('data-source-update-credential-region')).toBeVisible();
const text = container.getByTestId('data-source-update-credential-region');
expect(text.textContent).toBe(props.region);
});

it('renders modal with service name select', () => {
const container = render(<UpdateAwsCredentialModal {...props} />);
expect(container.getByTestId('data-source-update-credential-service-name')).toBeVisible();
});
});
15 changes: 15 additions & 0 deletions src/plugins/data_source_management/public/mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,21 @@ export const mockDataSourceAttributesWithAuth = {
},
};

export const mockDataSourceAttributesWithSigV4Auth = {
id: 'test',
title: 'create-test-ds',
description: 'jest testing',
endpoint: 'https://test.com',
auth: {
type: AuthType.SigV4,
credentials: {
accessKey: 'test123',
secretKey: 'test123',
region: 'us-east-1',
},
},
};

export const mockDataSourceAttributesWithNoAuth = {
id: 'test123',
title: 'create-test-ds123',
Expand Down
Loading