Skip to content

Commit

Permalink
[Crawler] Make domain validation optional (elastic#120063) (elastic#1…
Browse files Browse the repository at this point in the history
…20149)

Co-authored-by: Orhan Toy <[email protected]>
  • Loading branch information
kibanamachine and orhantoy authored Dec 1, 2021
1 parent 81ef176 commit 3ee01e9
Show file tree
Hide file tree
Showing 4 changed files with 189 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ import { getDomainWithProtocol } from './utils';
const DEFAULT_VALUES: AddDomainLogicValues = {
addDomainFormInputValue: 'https://',
entryPointValue: '/',
canIgnoreValidationFailure: false,
displayValidation: false,
domainValidationResult: {
steps: {
Expand All @@ -47,6 +48,7 @@ const DEFAULT_VALUES: AddDomainLogicValues = {
},
},
allowSubmit: false,
ignoreValidationFailure: false,
isValidationLoading: false,
hasBlockingFailure: false,
hasValidationCompleted: false,
Expand Down Expand Up @@ -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({
Expand Down Expand Up @@ -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({
Expand All @@ -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', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand All @@ -61,6 +63,7 @@ export interface AddDomainLogicActions {
setDomainValidationResult(change: CrawlerDomainValidationResultChange): {
change: CrawlerDomainValidationResultChange;
};
setIgnoreValidationFailure(newValue: boolean): boolean;
startDomainValidation(): void;
submitNewDomain(): void;
validateDomainInitialVerification(
Expand All @@ -84,6 +87,7 @@ const DEFAULT_SELECTOR_VALUES = {
},
} as CrawlerDomainValidationResult,
allowSubmit: false,
ignoreValidationFailure: false,
isValidationLoading: false,
};

Expand All @@ -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) => ({
Expand Down Expand Up @@ -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: [
Expand All @@ -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],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand All @@ -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);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,31 @@

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';

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 (
<>
Expand Down Expand Up @@ -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>
</>
);
Expand Down

0 comments on commit 3ee01e9

Please sign in to comment.