[App Search] Load curation settings at root /curations/ path (#115690)

This commit is contained in:
Byron Hulcher 2021-10-20 11:51:00 -04:00 committed by GitHub
parent f1fe71650b
commit c9bca2cd59
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
10 changed files with 195 additions and 109 deletions

View file

@ -107,17 +107,6 @@ describe('CurationsLogic', () => {
describe('listeners', () => {
describe('loadCurations', () => {
it('should set dataLoading state', () => {
mount({ dataLoading: false });
CurationsLogic.actions.loadCurations();
expect(CurationsLogic.values).toEqual({
...DEFAULT_VALUES,
dataLoading: true,
});
});
it('should make an API call and set curations & meta state', async () => {
http.get.mockReturnValueOnce(Promise.resolve(MOCK_CURATIONS_RESPONSE));
mount();

View file

@ -61,7 +61,6 @@ export const CurationsLogic = kea<MakeLogicType<CurationsValues, CurationsAction
dataLoading: [
true,
{
loadCurations: () => true,
onCurationsLoad: () => false,
},
],

View file

@ -5,6 +5,9 @@
* 2.0.
*/
import '../../../__mocks__/shallow_useeffect.mock';
import '../../../__mocks__/react_router';
import { setMockActions, setMockValues } from '../../../__mocks__/kea_logic';
import '../../__mocks__/engine_logic.mock';
import React from 'react';
@ -12,13 +15,110 @@ import { Route, Switch } from 'react-router-dom';
import { shallow } from 'enzyme';
import { LogRetentionOptions } from '../log_retention';
import { CurationsRouter } from './';
const MOCK_VALUES = {
// CurationsSettingsLogic
dataLoading: false,
curationsSettings: {
enabled: true,
mode: 'automatic',
},
// LogRetentionLogic
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: true,
},
},
// LicensingLogic
hasPlatinumLicense: true,
};
const MOCK_ACTIONS = {
// CurationsSettingsLogic
loadCurationsSettings: jest.fn(),
onSkipLoadingCurationsSettings: jest.fn(),
// LogRetentionLogic
fetchLogRetention: jest.fn(),
};
describe('CurationsRouter', () => {
beforeEach(() => {
jest.clearAllMocks();
setMockActions(MOCK_ACTIONS);
});
it('renders', () => {
const wrapper = shallow(<CurationsRouter />);
expect(wrapper.find(Switch)).toHaveLength(1);
expect(wrapper.find(Route)).toHaveLength(4);
});
it('loads log retention settings', () => {
setMockValues(MOCK_VALUES);
shallow(<CurationsRouter />);
expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalled();
});
describe('when the user has no platinum license', () => {
beforeEach(() => {
setMockValues({
...MOCK_VALUES,
hasPlatinumLicense: false,
});
});
it('it does not fetch log retention', () => {
shallow(<CurationsRouter />);
expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalledTimes(0);
});
});
describe('loading curation settings based on log retention', () => {
it('loads curation settings when log retention is enabled', () => {
setMockValues({
...MOCK_VALUES,
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: true,
},
},
});
shallow(<CurationsRouter />);
expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(1);
});
it('skips loading curation settings when log retention is enabled', () => {
setMockValues({
...MOCK_VALUES,
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: false,
},
},
});
shallow(<CurationsRouter />);
expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(1);
});
it('takes no action if log retention has not yet been loaded', () => {
setMockValues({
...MOCK_VALUES,
logRetention: null,
});
shallow(<CurationsRouter />);
expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(0);
expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(0);
});
});
});

View file

@ -5,20 +5,53 @@
* 2.0.
*/
import React from 'react';
import React, { useEffect } from 'react';
import { Route, Switch } from 'react-router-dom';
import { useValues, useActions } from 'kea';
import { LicensingLogic } from '../../../shared/licensing';
import {
ENGINE_CURATIONS_PATH,
ENGINE_CURATIONS_NEW_PATH,
ENGINE_CURATION_PATH,
ENGINE_CURATION_SUGGESTION_PATH,
} from '../../routes';
import { LogRetentionLogic, LogRetentionOptions } from '../log_retention';
import { Curation } from './curation';
import { Curations, CurationCreation, CurationSuggestion } from './views';
import { CurationsSettingsLogic } from './views/curations_settings';
export const CurationsRouter: React.FC = () => {
// We need to loadCurationsSettings here so they are available across all views
const { hasPlatinumLicense } = useValues(LicensingLogic);
const { loadCurationsSettings, onSkipLoadingCurationsSettings } =
useActions(CurationsSettingsLogic);
const { logRetention } = useValues(LogRetentionLogic);
const { fetchLogRetention } = useActions(LogRetentionLogic);
const analyticsDisabled = !logRetention?.[LogRetentionOptions.Analytics].enabled;
useEffect(() => {
if (hasPlatinumLicense) {
fetchLogRetention();
}
}, [hasPlatinumLicense]);
useEffect(() => {
if (logRetention) {
if (!analyticsDisabled) {
loadCurationsSettings();
} else {
onSkipLoadingCurationsSettings();
}
}
}, [logRetention]);
return (
<Switch>
<Route exact path={ENGINE_CURATIONS_PATH}>

View file

@ -126,14 +126,14 @@ describe('Curations', () => {
describe('loading state', () => {
it('renders a full-page loading state on initial page load', () => {
setMockValues({ ...values, dataLoading: true, curations: [] });
setMockValues({ ...values, dataLoading: true });
const wrapper = shallow(<Curations />);
expect(wrapper.prop('isLoading')).toEqual(true);
});
it('does not re-render a full-page loading state after initial page load (uses component-level loading state instead)', () => {
setMockValues({ ...values, dataLoading: true, curations: [{}] });
it('does not re-render a full-page loading state when data is loaded', () => {
setMockValues({ ...values, dataLoading: false });
const wrapper = shallow(<Curations />);
expect(wrapper.prop('isLoading')).toEqual(false);

View file

@ -25,12 +25,13 @@ import { getCurationsBreadcrumbs } from '../utils';
import { CurationsHistory } from './curations_history/curations_history';
import { CurationsOverview } from './curations_overview';
import { CurationsSettings } from './curations_settings';
import { CurationsSettings, CurationsSettingsLogic } from './curations_settings';
export const Curations: React.FC = () => {
const { dataLoading, curations, meta, selectedPageTab } = useValues(CurationsLogic);
const { dataLoading: curationsDataLoading, meta, selectedPageTab } = useValues(CurationsLogic);
const { loadCurations, onSelectPageTab } = useActions(CurationsLogic);
const { hasPlatinumLicense } = useValues(LicensingLogic);
const { dataLoading: curationsSettingsDataLoading } = useValues(CurationsSettingsLogic);
const OVERVIEW_TAB = {
label: i18n.translate(
@ -92,7 +93,7 @@ export const Curations: React.FC = () => {
],
tabs: pageTabs,
}}
isLoading={dataLoading && !curations.length}
isLoading={curationsSettingsDataLoading || curationsDataLoading}
>
{selectedPageTab === 'overview' && <CurationsOverview />}
{selectedPageTab === 'history' && <CurationsHistory />}

View file

@ -19,13 +19,32 @@ import { SuggestionsTable } from '../components/suggestions_table';
import { CurationsOverview } from './curations_overview';
const MOCK_VALUES = {
// CurationsSettingsLogic
curationsSettings: {
enabled: true,
},
// CurationsLogic
curations: [
{
id: 'cur-id-1',
},
{
id: 'cur-id-2',
},
],
// LicensingLogics
hasPlatinumLicense: true,
};
describe('CurationsOverview', () => {
beforeEach(() => {
jest.clearAllMocks();
setMockValues(MOCK_VALUES);
});
it('renders an empty message when there are no curations', () => {
setMockValues({ curations: [] });
setMockValues({ ...MOCK_VALUES, curations: [] });
const wrapper = shallow(<CurationsOverview />);
expect(wrapper.find(EmptyState).exists()).toBe(true);
@ -33,6 +52,7 @@ describe('CurationsOverview', () => {
it('renders a curations table when there are curations present', () => {
setMockValues({
...MOCK_VALUES,
curations: [
{
id: 'cur-id-1',
@ -47,15 +67,36 @@ describe('CurationsOverview', () => {
expect(wrapper.find(CurationsTable)).toHaveLength(1);
});
it('renders a suggestions table when the user has a platinum license', () => {
setMockValues({ curations: [], hasPlatinumLicense: true });
it('renders a suggestions table when the user has a platinum license and curations suggestions enabled', () => {
setMockValues({
...MOCK_VALUES,
hasPlatinumLicense: true,
curationsSettings: {
enabled: true,
},
});
const wrapper = shallow(<CurationsOverview />);
expect(wrapper.find(SuggestionsTable).exists()).toBe(true);
});
it('doesn\t render a suggestions table when the user has no platinum license', () => {
setMockValues({ curations: [], hasPlatinumLicense: false });
setMockValues({
...MOCK_VALUES,
hasPlatinumLicense: false,
});
const wrapper = shallow(<CurationsOverview />);
expect(wrapper.find(SuggestionsTable).exists()).toBe(false);
});
it('doesn\t render a suggestions table when the user has disabled suggestions', () => {
setMockValues({
...MOCK_VALUES,
curationsSettings: {
enabled: false,
},
});
const wrapper = shallow(<CurationsOverview />);
expect(wrapper.find(SuggestionsTable).exists()).toBe(false);

View file

@ -16,11 +16,17 @@ import { CurationsTable, EmptyState } from '../components';
import { SuggestionsTable } from '../components/suggestions_table';
import { CurationsLogic } from '../curations_logic';
import { CurationsSettingsLogic } from './curations_settings';
export const CurationsOverview: React.FC = () => {
const { curations } = useValues(CurationsLogic);
const { hasPlatinumLicense } = useValues(LicensingLogic);
const shouldShowSuggestions = hasPlatinumLicense;
const {
curationsSettings: { enabled },
} = useValues(CurationsSettingsLogic);
const shouldShowSuggestions = enabled && hasPlatinumLicense;
return (
<>

View file

@ -17,8 +17,6 @@ import { shallow, ShallowWrapper } from 'enzyme';
import { EuiButtonEmpty, EuiCallOut, EuiSwitch } from '@elastic/eui';
import { mountWithIntl } from '@kbn/test/jest';
import { Loading } from '../../../../../shared/loading';
import { EuiButtonTo } from '../../../../../shared/react_router_helpers';
import { DataPanel } from '../../../data_panel';
@ -46,8 +44,6 @@ const MOCK_VALUES = {
const MOCK_ACTIONS = {
// CurationsSettingsLogic
loadCurationsSettings: jest.fn(),
onSkipLoadingCurationsSettings: jest.fn(),
toggleCurationsEnabled: jest.fn(),
toggleCurationsMode: jest.fn(),
// LogRetentionLogic
@ -60,14 +56,6 @@ describe('CurationsSettings', () => {
setMockActions(MOCK_ACTIONS);
});
it('loads curations and log retention settings on load', () => {
setMockValues(MOCK_VALUES);
mountWithIntl(<CurationsSettings />);
expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalled();
expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalled();
});
it('contains a switch to toggle curations settings', () => {
let wrapper: ShallowWrapper;
@ -166,50 +154,6 @@ describe('CurationsSettings', () => {
expect(wrapper.is(Loading)).toBe(true);
});
describe('loading curation settings based on log retention', () => {
it('loads curation settings when log retention is enabled', () => {
setMockValues({
...MOCK_VALUES,
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: true,
},
},
});
shallow(<CurationsSettings />);
expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(1);
});
it('skips loading curation settings when log retention is enabled', () => {
setMockValues({
...MOCK_VALUES,
logRetention: {
[LogRetentionOptions.Analytics]: {
enabled: false,
},
},
});
shallow(<CurationsSettings />);
expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(1);
});
it('takes no action if log retention has not yet been loaded', () => {
setMockValues({
...MOCK_VALUES,
logRetention: null,
});
shallow(<CurationsSettings />);
expect(MOCK_ACTIONS.loadCurationsSettings).toHaveBeenCalledTimes(0);
expect(MOCK_ACTIONS.onSkipLoadingCurationsSettings).toHaveBeenCalledTimes(0);
});
});
describe('when the user has no platinum license', () => {
beforeEach(() => {
setMockValues({
@ -218,11 +162,6 @@ describe('CurationsSettings', () => {
});
});
it('it does not fetch log retention', () => {
shallow(<CurationsSettings />);
expect(MOCK_ACTIONS.fetchLogRetention).toHaveBeenCalledTimes(0);
});
it('shows a CTA to upgrade your license when the user when the user', () => {
const wrapper = shallow(<CurationsSettings />);
expect(wrapper.is(DataPanel)).toBe(true);

View file

@ -5,7 +5,7 @@
* 2.0.
*/
import React, { useEffect } from 'react';
import React from 'react';
import { useActions, useValues } from 'kea';
@ -43,34 +43,12 @@ export const CurationsSettings: React.FC = () => {
curationsSettings: { enabled, mode },
dataLoading,
} = useValues(CurationsSettingsLogic);
const {
loadCurationsSettings,
onSkipLoadingCurationsSettings,
toggleCurationsEnabled,
toggleCurationsMode,
} = useActions(CurationsSettingsLogic);
const { toggleCurationsEnabled, toggleCurationsMode } = useActions(CurationsSettingsLogic);
const { isLogRetentionUpdating, logRetention } = useValues(LogRetentionLogic);
const { fetchLogRetention } = useActions(LogRetentionLogic);
const analyticsDisabled = !logRetention?.[LogRetentionOptions.Analytics].enabled;
useEffect(() => {
if (hasPlatinumLicense) {
fetchLogRetention();
}
}, [hasPlatinumLicense]);
useEffect(() => {
if (logRetention) {
if (!analyticsDisabled) {
loadCurationsSettings();
} else {
onSkipLoadingCurationsSettings();
}
}
}, [logRetention]);
if (!hasPlatinumLicense)
return (
<DataPanel