Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
b829eb9
Add optional suggestion field to Curation type
byronhulcher Sep 27, 2021
153a7d6
Make Curation view tests suggestion status aware
byronhulcher Sep 27, 2021
74bf26c
Added 'Automated' badge to automated curations
byronhulcher Sep 27, 2021
45f2a04
Added new PUT /internal/app_search/engines/{name}/search_relevance_su…
byronhulcher Sep 28, 2021
4afc3e3
Add convertToManual action to CurationLogic
byronhulcher Sep 28, 2021
263c33f
Added new Convert to Manual action for automated curations
byronhulcher Sep 28, 2021
9449d8d
Display query in title for automated curations
byronhulcher Sep 28, 2021
39dae4a
Hide ActiveQuerySelect and ManageQueriesModal on Curation view when c…
byronhulcher Sep 28, 2021
1ce3681
Implement isAutomated selector in CurationLogic
byronhulcher Sep 28, 2021
8115c14
Disable promoted documents UX when curation is automated
byronhulcher Sep 28, 2021
fba7976
Disable AddResultButton when curation is automated
byronhulcher Sep 28, 2021
df1f8bb
Split Curation into AutomatedCuration and ManualCuration components
byronhulcher Sep 29, 2021
6b94e3d
Disable organic documents UX when curation is automated
byronhulcher Sep 29, 2021
20070b4
Clean-up after rebase
byronhulcher Sep 29, 2021
1cfd06a
Get rid of getShallowPageTitle
byronhulcher Sep 29, 2021
91aa2ee
Fix types after rebase
byronhulcher Sep 30, 2021
4c4dec0
Fix import
byronhulcher Sep 30, 2021
fed6a08
Hide UX instead of disabling
byronhulcher Sep 30, 2021
1d29af1
Remove translations
byronhulcher Sep 30, 2021
8f5948e
Merge remote-tracking branch 'origin/master' into automated-curation-…
byronhulcher Oct 1, 2021
07defaa
Merge remote-tracking branch 'origin/master' into automated-curation-…
byronhulcher Oct 1, 2021
0746093
Merge remote-tracking branch 'origin/master' into automated-curation-…
byronhulcher Oct 1, 2021
b8e4af0
Merge remote-tracking branch 'origin/master' into automated-curation-…
byronhulcher Oct 4, 2021
9930246
Clean-up AutomatedCuration
byronhulcher Oct 4, 2021
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