Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { nextTick } from '@kbn/test/jest';

import { DEFAULT_META } from '../../../../shared/constants';

import { SuggestionsLogic } from './suggestions_logic';
import { SuggestionsAPIResponse, SuggestionsLogic } from './suggestions_logic';

const DEFAULT_VALUES = {
dataLoading: true,
Expand All @@ -30,7 +30,7 @@ const DEFAULT_VALUES = {
},
};

const MOCK_RESPONSE = {
const MOCK_RESPONSE: SuggestionsAPIResponse = {
meta: {
page: {
current: 1,
Expand All @@ -44,6 +44,7 @@ const MOCK_RESPONSE = {
query: 'foo',
updated_at: '2021-07-08T14:35:50Z',
promoted: ['1', '2'],
status: 'applied',
},
],
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import { updateMetaPageIndex } from '../../../../shared/table_pagination';
import { EngineLogic } from '../../engine';
import { CurationSuggestion } from '../types';

interface SuggestionsAPIResponse {
export interface SuggestionsAPIResponse {
results: CurationSuggestion[];
meta: Meta;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ export const RESTORE_CONFIRMATION = i18n.translate(
}
);

export const CONVERT_TO_MANUAL_CONFIRMATION = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.curations.convertToManualCurationConfirmation',
{
defaultMessage: 'Are you sure you want to convert this to a manual curation?',
}
);

export const RESULT_ACTIONS_DIRECTIONS = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.curations.resultActionsDescription',
{ defaultMessage: 'Promote results by clicking the star, hide them by clicking the eye.' }
Expand Down Expand Up @@ -82,3 +89,13 @@ export const SHOW_DOCUMENT_ACTION = {
iconType: 'eye',
iconColor: 'primary' as EuiButtonIconColor,
};

export const AUTOMATED_LABEL = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.curation.automatedLabel',
{ defaultMessage: 'Automated' }
);

export const COVERT_TO_MANUAL_BUTTON_LABEL = i18n.translate(
'xpack.enterpriseSearch.appSearch.engine.curation.convertToManualCurationButtonLabel',
{ defaultMessage: 'Convert to manual curation' }
);
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import '../../../../__mocks__/shallow_useeffect.mock';
import { setMockActions, setMockValues } from '../../../../__mocks__/kea_logic';
import { mockUseParams } from '../../../../__mocks__/react_router';
import '../../../__mocks__/engine_logic.mock';

import React from 'react';

import { shallow, ShallowWrapper } from 'enzyme';

import { EuiBadge } from '@elastic/eui';

import { getPageHeaderActions, getPageTitle } from '../../../../test_helpers';

jest.mock('./curation_logic', () => ({ CurationLogic: jest.fn() }));

import { AppSearchPageTemplate } from '../../layout';

import { AutomatedCuration } from './automated_curation';
import { CurationLogic } from './curation_logic';

import { PromotedDocuments, OrganicDocuments } from './documents';

describe('AutomatedCuration', () => {
const values = {
dataLoading: false,
queries: ['query A', 'query B'],
isFlyoutOpen: false,
curation: {
suggestion: {
status: 'applied',
},
},
activeQuery: 'query A',
isAutomated: true,
};

const actions = {
convertToManual: jest.fn(),
};

beforeEach(() => {
jest.clearAllMocks();
setMockValues(values);
setMockActions(actions);
mockUseParams.mockReturnValue({ curationId: 'test' });
});

it('renders', () => {
const wrapper = shallow(<AutomatedCuration />);

expect(wrapper.is(AppSearchPageTemplate));
expect(wrapper.find(PromotedDocuments)).toHaveLength(1);
expect(wrapper.find(OrganicDocuments)).toHaveLength(1);
});

it('initializes CurationLogic with a curationId prop from URL param', () => {
mockUseParams.mockReturnValueOnce({ curationId: 'hello-world' });
shallow(<AutomatedCuration />);

expect(CurationLogic).toHaveBeenCalledWith({ curationId: 'hello-world' });
});

it('displays the query in the title with a badge', () => {
const wrapper = shallow(<AutomatedCuration />);
const pageTitle = shallow(<div>{getPageTitle(wrapper)}</div>);

expect(pageTitle.text()).toContain('query A');
expect(pageTitle.find(EuiBadge)).toHaveLength(1);
});

describe('convert to manual button', () => {
let convertToManualButton: ShallowWrapper;
let confirmSpy: jest.SpyInstance;

beforeAll(() => {
const wrapper = shallow(<AutomatedCuration />);
convertToManualButton = getPageHeaderActions(wrapper).childAt(0);

confirmSpy = jest.spyOn(window, 'confirm');
});

afterAll(() => {
confirmSpy.mockRestore();
});

it('converts the curation upon user confirmation', () => {
confirmSpy.mockReturnValueOnce(true);
convertToManualButton.simulate('click');
expect(actions.convertToManual).toHaveBeenCalled();
});

it('does not convert the curation if the user cancels', () => {
confirmSpy.mockReturnValueOnce(false);
convertToManualButton.simulate('click');
expect(actions.convertToManual).not.toHaveBeenCalled();
});
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

import React from 'react';
import { useParams } from 'react-router-dom';

import { useValues, useActions } from 'kea';

import { EuiSpacer, EuiButton, EuiBadge } from '@elastic/eui';

import { AppSearchPageTemplate } from '../../layout';
import { AutomatedIcon } from '../components/automated_icon';
import {
AUTOMATED_LABEL,
COVERT_TO_MANUAL_BUTTON_LABEL,
CONVERT_TO_MANUAL_CONFIRMATION,
} from '../constants';
import { getCurationsBreadcrumbs } from '../utils';

import { CurationLogic } from './curation_logic';
import { PromotedDocuments, OrganicDocuments } from './documents';

export const AutomatedCuration: React.FC = () => {
const { curationId } = useParams<{ curationId: string }>();
const logic = CurationLogic({ curationId });
const { convertToManual } = useActions(logic);
const { activeQuery, dataLoading, queries } = useValues(logic);

return (
<AppSearchPageTemplate
pageChrome={getCurationsBreadcrumbs([queries.join(', ')])}
pageHeader={{
pageTitle: (
<>
{activeQuery}{' '}
<EuiBadge iconType={AutomatedIcon} color="accent">
{AUTOMATED_LABEL}
</EuiBadge>
</>
),
rightSideItems: [
<EuiButton
color="primary"
fill
iconType="exportAction"
onClick={() => {
if (window.confirm(CONVERT_TO_MANUAL_CONFIRMATION)) convertToManual();
}}
>
{COVERT_TO_MANUAL_BUTTON_LABEL}
</EuiButton>,
],
}}
isLoading={dataLoading}
>
<PromotedDocuments />
<EuiSpacer />
<OrganicDocuments />
</AppSearchPageTemplate>
);
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,26 +12,25 @@ import '../../../__mocks__/engine_logic.mock';

import React from 'react';

import { shallow, ShallowWrapper } from 'enzyme';
import { shallow } from 'enzyme';

import { rerender, getPageTitle, getPageHeaderActions } from '../../../../test_helpers';
import { rerender } from '../../../../test_helpers';

jest.mock('./curation_logic', () => ({ CurationLogic: jest.fn() }));
import { CurationLogic } from './curation_logic';

import { AddResultFlyout } from './results';
import { AutomatedCuration } from './automated_curation';

import { ManualCuration } from './manual_curation';

import { Curation } from './';

describe('Curation', () => {
const values = {
dataLoading: false,
queries: ['query A', 'query B'],
isFlyoutOpen: false,
isAutomated: true,
};

const actions = {
loadCuration: jest.fn(),
resetCuration: jest.fn(),
};

beforeEach(() => {
Expand All @@ -40,32 +39,6 @@ describe('Curation', () => {
setMockActions(actions);
});

it('renders', () => {
const wrapper = shallow(<Curation />);

expect(getPageTitle(wrapper)).toEqual('Manage curation');
expect(wrapper.prop('pageChrome')).toEqual([
'Engines',
'some-engine',
'Curations',
'query A, query B',
]);
});

it('renders the add result flyout when open', () => {
setMockValues({ ...values, isFlyoutOpen: true });
const wrapper = shallow(<Curation />);

expect(wrapper.find(AddResultFlyout)).toHaveLength(1);
});

it('initializes CurationLogic with a curationId prop from URL param', () => {
mockUseParams.mockReturnValueOnce({ curationId: 'hello-world' });
shallow(<Curation />);

expect(CurationLogic).toHaveBeenCalledWith({ curationId: 'hello-world' });
});

it('calls loadCuration on page load & whenever the curationId URL param changes', () => {
mockUseParams.mockReturnValueOnce({ curationId: 'cur-123456789' });
const wrapper = shallow(<Curation />);
Expand All @@ -76,31 +49,17 @@ describe('Curation', () => {
expect(actions.loadCuration).toHaveBeenCalledTimes(2);
});

describe('restore defaults button', () => {
let restoreDefaultsButton: ShallowWrapper;
let confirmSpy: jest.SpyInstance;

beforeAll(() => {
const wrapper = shallow(<Curation />);
restoreDefaultsButton = getPageHeaderActions(wrapper).childAt(0);

confirmSpy = jest.spyOn(window, 'confirm');
});
it('renders a view for automated curations', () => {
setMockValues({ isAutomated: true });
const wrapper = shallow(<Curation />);

afterAll(() => {
confirmSpy.mockRestore();
});
expect(wrapper.is(AutomatedCuration)).toBe(true);
});

it('resets the curation upon user confirmation', () => {
confirmSpy.mockReturnValueOnce(true);
restoreDefaultsButton.simulate('click');
expect(actions.resetCuration).toHaveBeenCalled();
});
it('renders a view for manual curations', () => {
setMockValues({ isAutomated: false });
const wrapper = shallow(<Curation />);

it('does not reset the curation if the user cancels', () => {
confirmSpy.mockReturnValueOnce(false);
restoreDefaultsButton.simulate('click');
expect(actions.resetCuration).not.toHaveBeenCalled();
});
expect(wrapper.is(ManualCuration)).toBe(true);
});
});
Loading