-
Notifications
You must be signed in to change notification settings - Fork 8.5k
[App Search] Added the log retention confirmation modal to the Settings page #83009
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
Changes from all commits
1f3cd7d
99463bb
ee43a03
2737c20
e847930
5df1e78
e220982
42ebfdc
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,81 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import React from 'react'; | ||
| import { shallow } from 'enzyme'; | ||
|
|
||
| import { GenericConfirmationModal } from './generic_confirmation_modal'; | ||
|
|
||
| describe('GenericConfirmationModal', () => { | ||
| let wrapper: any; | ||
| const onClose = jest.fn(); | ||
| const onSave = jest.fn(); | ||
|
|
||
| beforeEach(() => { | ||
| jest.clearAllMocks(); | ||
| wrapper = shallow( | ||
| <GenericConfirmationModal | ||
| title="A title" | ||
| subheading="A subheading" | ||
| description="A description" | ||
| target="DISABLE" | ||
| onClose={onClose} | ||
| onSave={onSave} | ||
| /> | ||
| ); | ||
| }); | ||
|
|
||
| it('calls onSave callback when save is pressed', () => { | ||
| const button = wrapper.find('[data-test-subj="GenericConfirmationModalSave"]'); | ||
| button.simulate('click'); | ||
| expect(onSave).toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('calls onClose callback when Cancel is pressed', () => { | ||
| const button = wrapper.find('[data-test-subj="GenericConfirmationModalCancel"]'); | ||
| button.simulate('click'); | ||
| expect(onClose).toHaveBeenCalled(); | ||
| }); | ||
|
|
||
| it('disables the Save button when the input is empty', () => { | ||
| const button = wrapper.find('[data-test-subj="GenericConfirmationModalSave"]'); | ||
| expect(button.prop('disabled')).toEqual(true); | ||
| }); | ||
|
|
||
| it('disables the Save button when the input is not equal to the target', () => { | ||
| const input = wrapper.find('[data-test-subj="GenericConfirmationModalInput"]'); | ||
| input.prop('onChange')({ | ||
| target: { | ||
| value: 'NOT_GOOD', | ||
| }, | ||
| }); | ||
|
|
||
| const button = wrapper.find('[data-test-subj="GenericConfirmationModalSave"]'); | ||
| expect(button.prop('disabled')).toEqual(true); | ||
| }); | ||
|
|
||
| it('enables the Save button when the current input equals the target prop', () => { | ||
| const input = wrapper.find('[data-test-subj="GenericConfirmationModalInput"]'); | ||
| input.prop('onChange')({ | ||
| target: { | ||
| value: 'DISABLE', | ||
| }, | ||
| }); | ||
| const button = wrapper.find('[data-test-subj="GenericConfirmationModalSave"]'); | ||
| expect(button.prop('disabled')).toEqual(false); | ||
| }); | ||
|
|
||
| it('is not case sensitive', () => { | ||
| const input = wrapper.find('[data-test-subj="GenericConfirmationModalInput"]'); | ||
| input.prop('onChange')({ | ||
| target: { | ||
| value: 'diSable', | ||
| }, | ||
| }); | ||
| const button = wrapper.find('[data-test-subj="GenericConfirmationModalSave"]'); | ||
| expect(button.prop('disabled')).toEqual(false); | ||
| }); | ||
| }); | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,95 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import React, { ReactNode, useState } from 'react'; | ||
| import { i18n } from '@kbn/i18n'; | ||
|
|
||
| import { | ||
| EuiButton, | ||
| EuiButtonEmpty, | ||
| EuiFieldText, | ||
| EuiFormRow, | ||
| EuiModal, | ||
| EuiModalBody, | ||
| EuiModalFooter, | ||
| EuiModalHeader, | ||
| EuiModalHeaderTitle, | ||
| EuiSpacer, | ||
| EuiText, | ||
| } from '@elastic/eui'; | ||
|
|
||
| interface GenericConfirmationModalProps { | ||
| description: ReactNode; | ||
| subheading: ReactNode; | ||
| target: string; | ||
| title: string; | ||
| onClose(): void; | ||
| onSave(): void; | ||
| } | ||
|
|
||
| export const GenericConfirmationModal: React.FC<GenericConfirmationModalProps> = ({ | ||
| description, | ||
| onClose, | ||
| onSave, | ||
| subheading, | ||
| target, | ||
| title, | ||
| }) => { | ||
| const [inputValue, setInputValue] = useState(''); | ||
|
|
||
| const onConfirm = () => { | ||
| setInputValue(''); | ||
| onSave(); | ||
| }; | ||
|
|
||
| return ( | ||
| <EuiModal onClose={onClose} initialFocus=".euiFieldText" aria-label={title}> | ||
| <EuiModalHeader> | ||
| <EuiModalHeaderTitle>{title}</EuiModalHeaderTitle> | ||
| </EuiModalHeader> | ||
| <EuiModalBody> | ||
| <EuiText> | ||
| <p> | ||
| <strong>{subheading}</strong> | ||
| </p> | ||
| <p>{description}</p> | ||
| </EuiText> | ||
| <EuiSpacer /> | ||
| <EuiFormRow | ||
| label={i18n.translate( | ||
| 'xpack.enterpriseSearch.appSearch.settings.logRetention.modal.prompt', | ||
| { | ||
| defaultMessage: 'Type "{target}" to confirm.', | ||
cee-chen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| values: { target }, | ||
| } | ||
| )} | ||
| > | ||
| <EuiFieldText | ||
| data-test-subj="GenericConfirmationModalInput" | ||
| value={inputValue} | ||
| onChange={(e) => setInputValue(e.target.value)} | ||
| /> | ||
| </EuiFormRow> | ||
| </EuiModalBody> | ||
| <EuiModalFooter> | ||
| <EuiButtonEmpty data-test-subj="GenericConfirmationModalCancel" onClick={onClose}> | ||
| {i18n.translate('xpack.enterpriseSearch.appSearch.settings.logRetention.modal.cancel', { | ||
| defaultMessage: 'Cancel', | ||
|
Comment on lines
+79
to
+80
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [not a change request, just me thinking out loud] Happy to do this is a tech debt refactor in a separate PR later if you think it's a good idea 🤷
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah that's a good point! |
||
| })} | ||
| </EuiButtonEmpty> | ||
| <EuiButton | ||
| data-test-subj="GenericConfirmationModalSave" | ||
cee-chen marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| onClick={onConfirm} | ||
| disabled={inputValue.toLowerCase() !== target.toLowerCase()} | ||
| > | ||
| {i18n.translate('xpack.enterpriseSearch.appSearch.settings.logRetention.modal.save', { | ||
| defaultMessage: 'Save setting', | ||
| })} | ||
| </EuiButton> | ||
| </EuiModalFooter> | ||
| </EuiModal> | ||
| ); | ||
| }; | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,129 @@ | ||
| /* | ||
| * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
| * or more contributor license agreements. Licensed under the Elastic License; | ||
| * you may not use this file except in compliance with the Elastic License. | ||
| */ | ||
|
|
||
| import '../../../../__mocks__/kea.mock'; | ||
| import { setMockActions, setMockValues } from '../../../../__mocks__'; | ||
|
|
||
| import React from 'react'; | ||
| import { shallow } from 'enzyme'; | ||
|
|
||
| import { LogRetentionConfirmationModal } from './log_retention_confirmation_modal'; | ||
| import { LogRetentionOptions } from './types'; | ||
| import { GenericConfirmationModal } from './generic_confirmation_modal'; | ||
|
|
||
| describe('<LogRetentionConfirmationModal />', () => { | ||
| const actions = { | ||
| closeModals: jest.fn(), | ||
| saveLogRetention: jest.fn(), | ||
| }; | ||
|
|
||
| const values = { | ||
| openedModal: null, | ||
| logRetention: { | ||
| analytics: { | ||
| enabled: true, | ||
| retentionPolicy: { | ||
| isDefault: true, | ||
| minAgeDays: 180, | ||
| }, | ||
| }, | ||
| api: { | ||
| enabled: true, | ||
| retentionPolicy: { | ||
| isDefault: true, | ||
| minAgeDays: 7, | ||
| }, | ||
| }, | ||
| }, | ||
| }; | ||
|
|
||
| beforeEach(() => { | ||
| jest.clearAllMocks(); | ||
| setMockActions(actions); | ||
| setMockValues(values); | ||
| }); | ||
|
|
||
| it('renders nothing by default', () => { | ||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| expect(logRetentionPanel.isEmptyRender()).toBe(true); | ||
| }); | ||
|
|
||
| describe('analytics', () => { | ||
| it('renders the Analytics panel when openedModal is set to Analytics', () => { | ||
| setMockValues({ | ||
| ...values, | ||
| openedModal: LogRetentionOptions.Analytics, | ||
| }); | ||
|
|
||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| expect( | ||
| logRetentionPanel.find('[data-test-subj="AnalyticsLogRetentionConfirmationModal"]').length | ||
| ).toBe(1); | ||
| }); | ||
|
|
||
| it('calls saveLogRetention on save when showing analytics', () => { | ||
| setMockValues({ | ||
| ...values, | ||
| openedModal: LogRetentionOptions.Analytics, | ||
| }); | ||
|
|
||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| const genericConfirmationModal = logRetentionPanel.find(GenericConfirmationModal); | ||
| genericConfirmationModal.prop('onSave')(); | ||
| expect(actions.saveLogRetention).toHaveBeenCalledWith(LogRetentionOptions.Analytics, false); | ||
| }); | ||
|
|
||
| it('calls closeModals on close', () => { | ||
| setMockValues({ | ||
| ...values, | ||
| openedModal: LogRetentionOptions.Analytics, | ||
| }); | ||
|
|
||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| const genericConfirmationModal = logRetentionPanel.find(GenericConfirmationModal); | ||
| genericConfirmationModal.prop('onClose')(); | ||
| expect(actions.closeModals).toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
|
|
||
| describe('api', () => { | ||
| it('renders the API panel when openedModal is set to API', () => { | ||
| setMockValues({ | ||
| ...values, | ||
| openedModal: LogRetentionOptions.API, | ||
| }); | ||
|
|
||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| expect( | ||
| logRetentionPanel.find('[data-test-subj="APILogRetentionConfirmationModal"]').length | ||
| ).toBe(1); | ||
| }); | ||
|
|
||
| it('calls saveLogRetention on save when showing api', () => { | ||
| setMockValues({ | ||
| ...values, | ||
| openedModal: LogRetentionOptions.API, | ||
| }); | ||
|
|
||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| const genericConfirmationModal = logRetentionPanel.find(GenericConfirmationModal); | ||
| genericConfirmationModal.prop('onSave')(); | ||
| expect(actions.saveLogRetention).toHaveBeenCalledWith(LogRetentionOptions.API, false); | ||
| }); | ||
|
|
||
| it('calls closeModals on close', () => { | ||
| setMockValues({ | ||
| ...values, | ||
| openedModal: LogRetentionOptions.API, | ||
| }); | ||
|
|
||
| const logRetentionPanel = shallow(<LogRetentionConfirmationModal />); | ||
| const genericConfirmationModal = logRetentionPanel.find(GenericConfirmationModal); | ||
| genericConfirmationModal.prop('onClose')(); | ||
| expect(actions.closeModals).toHaveBeenCalled(); | ||
| }); | ||
| }); | ||
| }); |
Uh oh!
There was an error while loading. Please reload this page.