[Crawler] Make domain validation optional (#120063)

This commit is contained in:
Orhan Toy 2021-12-01 19:38:01 +01:00 committed by GitHub
parent 4f733acd4f
commit e14496c865
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
4 changed files with 189 additions and 6 deletions

View file

@ -37,6 +37,7 @@ import { getDomainWithProtocol } from './utils';
const DEFAULT_VALUES: AddDomainLogicValues = {
addDomainFormInputValue: 'https://',
entryPointValue: '/',
canIgnoreValidationFailure: false,
displayValidation: false,
domainValidationResult: {
steps: {
@ -47,6 +48,7 @@ const DEFAULT_VALUES: AddDomainLogicValues = {
},
},
allowSubmit: false,
ignoreValidationFailure: false,
isValidationLoading: false,
hasBlockingFailure: false,
hasValidationCompleted: false,
@ -193,6 +195,31 @@ describe('AddDomainLogic', () => {
});
});
describe('setIgnoreValidationFailure', () => {
beforeEach(() => {
mount({
addDomainFormInputValue: 'https://elastic.co',
entryPointValue: '/customers',
hasValidationCompleted: true,
errors: ['first error', 'second error'],
domainValidationResult: {
steps: {
contentVerification: { state: 'loading' },
indexingRestrictions: { state: 'loading' },
initialValidation: { state: 'loading' },
networkConnectivity: { state: 'loading' },
},
},
});
AddDomainLogic.actions.setIgnoreValidationFailure(true);
});
it('should set the input value', () => {
expect(AddDomainLogic.values.ignoreValidationFailure).toEqual(true);
});
});
describe('submitNewDomain', () => {
it('should clear errors', () => {
mount({
@ -663,6 +690,32 @@ describe('AddDomainLogic', () => {
});
});
describe('canIgnoreValidationFailure', () => {
it('is true when any steps have blocking failures', () => {
mount({
hasValidationCompleted: true,
domainValidationResult: {
steps: {
contentVerification: { state: 'invalid', blockingFailure: true },
indexingRestrictions: { state: 'valid' },
initialValidation: { state: 'valid' },
networkConnectivity: { state: 'valid' },
},
},
});
expect(AddDomainLogic.values.canIgnoreValidationFailure).toEqual(true);
});
it('is false when validation has not completed', () => {
mount({
hasValidationCompleted: false,
});
expect(AddDomainLogic.values.canIgnoreValidationFailure).toEqual(false);
});
});
describe('allowSubmit', () => {
it('is true when a user has validated all steps and has no failures', () => {
mount({
@ -678,6 +731,22 @@ describe('AddDomainLogic', () => {
expect(AddDomainLogic.values.allowSubmit).toEqual(true);
});
it('is true when a user ignores validation failure', () => {
mount({
ignoreValidationFailure: true,
domainValidationResult: {
steps: {
contentVerification: { state: 'valid' },
indexingRestrictions: { state: 'valid' },
initialValidation: { state: 'invalid' },
networkConnectivity: { state: 'invalid' },
},
},
});
expect(AddDomainLogic.values.allowSubmit).toEqual(true);
});
});
describe('displayValidation', () => {

View file

@ -37,11 +37,13 @@ import {
export interface AddDomainLogicValues {
addDomainFormInputValue: string;
allowSubmit: boolean;
canIgnoreValidationFailure: boolean;
domainValidationResult: CrawlerDomainValidationResult;
entryPointValue: string;
errors: string[];
hasBlockingFailure: boolean;
hasValidationCompleted: boolean;
ignoreValidationFailure: boolean;
isValidationLoading: boolean;
displayValidation: boolean;
}
@ -61,6 +63,7 @@ export interface AddDomainLogicActions {
setDomainValidationResult(change: CrawlerDomainValidationResultChange): {
change: CrawlerDomainValidationResultChange;
};
setIgnoreValidationFailure(newValue: boolean): boolean;
startDomainValidation(): void;
submitNewDomain(): void;
validateDomainInitialVerification(
@ -84,6 +87,7 @@ const DEFAULT_SELECTOR_VALUES = {
},
} as CrawlerDomainValidationResult,
allowSubmit: false,
ignoreValidationFailure: false,
isValidationLoading: false,
};
@ -97,6 +101,7 @@ export const AddDomainLogic = kea<MakeLogicType<AddDomainLogicValues, AddDomainL
onSubmitNewDomainError: (errors) => ({ errors }),
setAddDomainFormInputValue: (newValue) => newValue,
setDomainValidationResult: (change: CrawlerDomainValidationResultChange) => ({ change }),
setIgnoreValidationFailure: (newValue) => newValue,
startDomainValidation: true,
submitNewDomain: true,
validateDomainInitialVerification: (newValue, newEntryPointValue) => ({
@ -155,6 +160,14 @@ export const AddDomainLogic = kea<MakeLogicType<AddDomainLogicValues, AddDomainL
onSubmitNewDomainError: (_, { errors }) => errors,
},
],
ignoreValidationFailure: [
DEFAULT_SELECTOR_VALUES.ignoreValidationFailure,
{
clearDomainFormInputValue: () => DEFAULT_SELECTOR_VALUES.ignoreValidationFailure,
setAddDomainFormInputValue: () => DEFAULT_SELECTOR_VALUES.ignoreValidationFailure,
setIgnoreValidationFailure: (_, newValue: boolean) => newValue,
},
],
}),
selectors: ({ selectors }) => ({
isValidationLoading: [
@ -174,9 +187,32 @@ export const AddDomainLogic = kea<MakeLogicType<AddDomainLogicValues, AddDomainL
(domainValidationResult: CrawlerDomainValidationResult) =>
!!Object.values(domainValidationResult.steps).find((step) => step.blockingFailure),
],
canIgnoreValidationFailure: [
() => [selectors.hasValidationCompleted, selectors.domainValidationResult],
(hasValidationCompleted: boolean, domainValidationResult: CrawlerDomainValidationResult) => {
if (!hasValidationCompleted) {
return false;
}
return (
domainValidationResult.steps.indexingRestrictions.blockingFailure ||
domainValidationResult.steps.contentVerification.blockingFailure
);
},
],
allowSubmit: [
() => [selectors.hasValidationCompleted, selectors.hasBlockingFailure],
(hasValidationCompleted, hasBlockingFailure) => hasValidationCompleted && !hasBlockingFailure,
() => [
selectors.ignoreValidationFailure,
selectors.hasValidationCompleted,
selectors.hasBlockingFailure,
],
(ignoreValidationFailure, hasValidationCompleted, hasBlockingFailure) => {
if (ignoreValidationFailure) {
return true;
}
return hasValidationCompleted && !hasBlockingFailure;
},
],
displayValidation: [
() => [selectors.isValidationLoading, selectors.hasValidationCompleted],

View file

@ -5,16 +5,22 @@
* 2.0.
*/
import { setMockValues } from '../../../../../__mocks__/kea_logic';
import { setMockActions, setMockValues } from '../../../../../__mocks__/kea_logic';
import React from 'react';
import { shallow } from 'enzyme';
import { EuiCheckbox } from '@elastic/eui';
import { AddDomainValidation } from './add_domain_validation';
import { ValidationStepPanel } from './validation_step_panel';
describe('AddDomainValidation', () => {
const actions = {
setIgnoreValidationFailure: jest.fn(),
};
it('contains four validation steps', () => {
setMockValues({
addDomainFormInputValue: 'https://elastic.co',
@ -32,4 +38,29 @@ describe('AddDomainValidation', () => {
expect(wrapper.find(ValidationStepPanel)).toHaveLength(4);
});
it('can ignore validation failure', () => {
setMockValues({
canIgnoreValidationFailure: true,
ignoreValidationFailure: false,
addDomainFormInputValue: 'https://elastic.co',
domainValidationResult: {
steps: {
contentVerification: { state: 'invalid', blockingFailure: true },
indexingRestrictions: { state: 'valid' },
initialValidation: { state: 'valid' },
networkConnectivity: { state: 'valid' },
},
},
});
setMockActions(actions);
const wrapper = shallow(<AddDomainValidation />);
wrapper
.find(EuiCheckbox)
.first()
.simulate('change', { target: { checked: true } });
expect(actions.setIgnoreValidationFailure).toHaveBeenCalledWith(true);
});
});

View file

@ -7,9 +7,17 @@
import React from 'react';
import { useValues } from 'kea';
import { useActions, useValues } from 'kea';
import { EuiButton, EuiFlexGroup, EuiFlexItem, EuiSpacer } from '@elastic/eui';
import {
EuiButton,
EuiCheckbox,
EuiFlexGroup,
EuiFlexItem,
EuiPanel,
EuiSpacer,
EuiText,
} from '@elastic/eui';
import { i18n } from '@kbn/i18n';
@ -17,7 +25,13 @@ import { AddDomainLogic } from './add_domain_logic';
import { ValidationStepPanel } from './validation_step_panel';
export const AddDomainValidation: React.FC = () => {
const { addDomainFormInputValue, domainValidationResult } = useValues(AddDomainLogic);
const {
addDomainFormInputValue,
canIgnoreValidationFailure,
domainValidationResult,
ignoreValidationFailure,
} = useValues(AddDomainLogic);
const { setIgnoreValidationFailure } = useActions(AddDomainLogic);
return (
<>
@ -77,6 +91,39 @@ export const AddDomainValidation: React.FC = () => {
)}
/>
</EuiFlexItem>
{canIgnoreValidationFailure && (
<EuiFlexItem>
<EuiPanel hasShadow={false}>
<EuiCheckbox
id={`crawler_domain_${addDomainFormInputValue}`}
label={
<>
<EuiText size="s">
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.addDomainForm.ignoreValidationTitle',
{
defaultMessage: 'Ignore validation failures and continue',
}
)}
</EuiText>
<EuiSpacer size="s" />
<EuiText color="subdued" size="xs">
{i18n.translate(
'xpack.enterpriseSearch.appSearch.crawler.addDomainForm.ignoreValidationDescription',
{
defaultMessage:
'The web crawler will be unable to index any content on this domain until the errors above are addressed.',
}
)}
</EuiText>
</>
}
checked={ignoreValidationFailure}
onChange={(e) => setIgnoreValidationFailure(e.target.checked)}
/>
</EuiPanel>
</EuiFlexItem>
)}
</EuiFlexGroup>
</>
);