Skip to content

Commit

Permalink
[SIEM] Import timeline fix (#65448) (#70145)
Browse files Browse the repository at this point in the history
* fix import timeline and clean up

fix unit tests

apply failure checker

clean up error message

fix update template

* add unit tests

* clean up common libs

* rename variables

* add unit tests

* fix types

* Fix imports

* rename file

* poc

* fix unit test

* review

* cleanup fallback values

* cleanup

* check if title exists

* fix unit test

* add unit test

* lint error

* put the flag for disableTemplate into common

* add immutiable

* fix unit

* check templateTimelineVersion only when update via import

* update template timeline via import with response

* add template filter

* add filter count

* add filter numbers

* rename

* enable pin events and note under active status

* disable comment and pinnedEvents for template timelines

* add timelineType for openTimeline

* enable note icon for template

* add timeline type for propertyLeft

* fix types

* duplicate elastic template

* update schema

* fix status check

* fix import

* add templateTimelineType

* disable note for immutable timeline

* fix unit

* fix error message

* fix update

* fix types

* rollback change

* rollback change

* fix create template timeline

* add i18n for error message

* fix unit test

* fix wording and disable delete btn for immutable timeline

* fix unit test provider

* fix types

* fix toaster

* fix notes and pins

* add i18n

* fix selected items

* set disableTemplateto true

* move templateInfo to helper

* review + imporvement

* fix review

* fix types

* fix types

Co-authored-by: Patryk Kopycinski <[email protected]>
Co-authored-by: Xavier Mouligneau <[email protected]>
# Conflicts:
#	x-pack/plugins/security_solution/public/timelines/store/timeline/epic.ts
  • Loading branch information
angorayc authored Jun 27, 2020
1 parent abb659c commit ade2b57
Show file tree
Hide file tree
Showing 126 changed files with 4,541 additions and 1,366 deletions.
8 changes: 7 additions & 1 deletion x-pack/plugins/security_solution/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -158,6 +158,12 @@ export const showAllOthersBucket: string[] = [

/**
* CreateTemplateTimelineBtn
* https://github.com/elastic/kibana/pull/66613
* Remove the comment here to enable template timeline
*/
export const disableTemplate = true;
export const disableTemplate = false;

/*
* This should be set to true after https://github.com/elastic/kibana/pull/67496 is merged
*/
export const enableElasticFilter = false;
32 changes: 32 additions & 0 deletions x-pack/plugins/security_solution/common/types/timeline/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -137,11 +137,13 @@ const SavedSortRuntimeType = runtimeTypes.partial({
export enum TimelineStatus {
active = 'active',
draft = 'draft',
immutable = 'immutable',
}

export const TimelineStatusLiteralRt = runtimeTypes.union([
runtimeTypes.literal(TimelineStatus.active),
runtimeTypes.literal(TimelineStatus.draft),
runtimeTypes.literal(TimelineStatus.immutable),
]);

const TimelineStatusLiteralWithNullRt = unionWithNullType(TimelineStatusLiteralRt);
Expand All @@ -151,6 +153,29 @@ export type TimelineStatusLiteralWithNull = runtimeTypes.TypeOf<
typeof TimelineStatusLiteralWithNullRt
>;

/**
* Template timeline type
*/

export enum TemplateTimelineType {
elastic = 'elastic',
custom = 'custom',
}

export const TemplateTimelineTypeLiteralRt = runtimeTypes.union([
runtimeTypes.literal(TemplateTimelineType.elastic),
runtimeTypes.literal(TemplateTimelineType.custom),
]);

export const TemplateTimelineTypeLiteralWithNullRt = unionWithNullType(
TemplateTimelineTypeLiteralRt
);

export type TemplateTimelineTypeLiteral = runtimeTypes.TypeOf<typeof TemplateTimelineTypeLiteralRt>;
export type TemplateTimelineTypeLiteralWithNull = runtimeTypes.TypeOf<
typeof TemplateTimelineTypeLiteralWithNullRt
>;

/*
* Timeline Types
*/
Expand Down Expand Up @@ -273,6 +298,13 @@ export const TimelineResponseType = runtimeTypes.type({
}),
});

export const TimelineErrorResponseType = runtimeTypes.type({
status_code: runtimeTypes.number,
message: runtimeTypes.string,
});

export interface TimelineErrorResponse
extends runtimeTypes.TypeOf<typeof TimelineErrorResponseType> {}
export interface TimelineResponse extends runtimeTypes.TypeOf<typeof TimelineResponseType> {}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -215,8 +215,8 @@ describe('alert actions', () => {
columnId: '@timestamp',
sortDirection: 'desc',
},
status: TimelineStatus.draft,
title: '',
status: TimelineStatus.active,
title: 'Test rule - Duplicate',
timelineType: TimelineType.default,
templateTimelineId: null,
templateTimelineVersion: null,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
mockGlobalState,
TestProviders,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../mock';
import { createStore, State } from '../../store';
Expand All @@ -35,10 +36,22 @@ jest.mock('../../lib/kibana', () => ({
describe('AddFilterToGlobalSearchBar Component', () => {
const state: State = mockGlobalState;
const { storage } = createSecuritySolutionStorageMock();
let store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
let store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);

beforeEach(() => {
store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);
mockAddFilters.mockClear();
});

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
apolloClientObservable,
mockGlobalState,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../mock';
import { createStore } from '../../store/store';
Expand All @@ -22,10 +23,22 @@ import { State } from '../../store/types';
describe('Error Toast Dispatcher', () => {
const state: State = mockGlobalState;
const { storage } = createSecuritySolutionStorageMock();
let store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
let store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);

beforeEach(() => {
store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);
});

describe('rendering', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
mockGlobalState,
apolloClientObservable,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../mock';
import { createStore, State } from '../../store';
Expand All @@ -36,13 +37,25 @@ describe('Inspect Button', () => {
state: state.inputs,
};

let store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
let store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);

describe('Render', () => {
beforeEach(() => {
const myState = cloneDeep(state);
myState.inputs = upsertQuery(newQuery);
store = createStore(myState, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
store = createStore(
myState,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);
});
test('Eui Empty Button', () => {
const wrapper = mount(
Expand Down Expand Up @@ -146,7 +159,13 @@ describe('Inspect Button', () => {
response: ['my response'],
};
myState.inputs = upsertQuery(myQuery);
store = createStore(myState, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
store = createStore(
myState,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);
});
test('Open Inspect Modal', () => {
const wrapper = mount(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import {
mockGlobalState,
apolloClientObservable,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../mock';
import { State, createStore } from '../../store';
Expand All @@ -55,7 +56,13 @@ describe('Stat Items Component', () => {
const theme = () => ({ eui: euiDarkVars, darkMode: true });
const state: State = mockGlobalState;
const { storage } = createSecuritySolutionStorageMock();
const store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
const store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);

describe.each([
[
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import {
apolloClientObservable,
mockGlobalState,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../mock';
import { createUseUiSetting$Mock } from '../../mock/kibana_react';
Expand Down Expand Up @@ -81,11 +82,23 @@ describe('SIEM Super Date Picker', () => {
describe('#SuperDatePicker', () => {
const state: State = mockGlobalState;
const { storage } = createSecuritySolutionStorageMock();
let store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
let store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);

beforeEach(() => {
jest.clearAllMocks();
store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);
mockUseUiSetting$.mockImplementation((key, defaultValue) => {
const useUiSetting$Mock = createUseUiSetting$Mock();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
mockGlobalState,
TestProviders,
SUB_PLUGINS_REDUCER,
kibanaObservable,
createSecuritySolutionStorageMock,
} from '../../mock';
import { createKibanaCoreStartMock } from '../../mock/kibana_core';
Expand Down Expand Up @@ -156,7 +157,13 @@ const state: State = {
};

const { storage } = createSecuritySolutionStorageMock();
const store = createStore(state, SUB_PLUGINS_REDUCER, apolloClientObservable, storage);
const store = createStore(
state,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage
);

describe('StatefulTopN', () => {
// Suppress warnings about "react-beautiful-dnd"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ import ApolloClient from 'apollo-client';
import { ApolloLink } from 'apollo-link';

// eslint-disable-next-line @kbn/eslint/no-restricted-paths
import { CoreStart } from '../../../../../../../src/core/public';
import introspectionQueryResultData from '../../../graphql/introspection.json';
import { AppFrontendLibs } from '../lib';
import { getLinks } from './helpers';
import { CoreStart } from '../../../../../../../src/core/public';

export function composeLibs(core: CoreStart): AppFrontendLibs {
const cache = new InMemoryCache({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { coreMock } from '../../../../../../../src/core/public/mocks';
import { StartPlugins } from '../../../types';
import { depsStartMock } from './dependencies_start_mock';
import { MiddlewareActionSpyHelper, createSpyMiddleware } from '../../store/test_utils';
import { apolloClientObservable } from '../test_providers';
import { apolloClientObservable, kibanaObservable } from '../test_providers';
import { createStore, State, substateMiddlewareFactory } from '../../store';
import { alertMiddlewareFactory } from '../../../endpoint_alerts/store/middleware';
import { AppRootProvider } from './app_root_provider';
Expand Down Expand Up @@ -58,14 +58,21 @@ export const createAppRootMockRenderer = (): AppContextTestRender => {
const middlewareSpy = createSpyMiddleware();
const { storage } = createSecuritySolutionStorageMock();

const store = createStore(mockGlobalState, SUB_PLUGINS_REDUCER, apolloClientObservable, storage, [
substateMiddlewareFactory(
(globalState) => globalState.alertList,
alertMiddlewareFactory(coreStart, depsStart)
),
...managementMiddlewareFactory(coreStart, depsStart),
middlewareSpy.actionSpyMiddleware,
]);
const store = createStore(
mockGlobalState,
SUB_PLUGINS_REDUCER,
apolloClientObservable,
kibanaObservable,
storage,
[
substateMiddlewareFactory(
(globalState) => globalState.alertList,
alertMiddlewareFactory(coreStart, depsStart)
),
...managementMiddlewareFactory(coreStart, depsStart),
middlewareSpy.actionSpyMiddleware,
]
);

const MockKibanaContextProvider = createKibanaContextProviderMock();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ import {
DEFAULT_INDEX_PATTERN,
} from '../../../common/constants';
import { createKibanaCoreStartMock, createKibanaPluginsStartMock } from './kibana_core';
import { StartServices } from '../../types';
import { createSecuritySolutionStorageMock } from './mock_local_storage';

// eslint-disable-next-line @typescript-eslint/no-explicit-any
Expand Down Expand Up @@ -71,6 +72,8 @@ export const createUseUiSetting$Mock = () => {
): [T, () => void] | undefined => [useUiSettingMock(key, defaultValue), jest.fn()];
};

export const createKibanaObservable$Mock = createKibanaCoreStartMock;

export const createUseKibanaMock = () => {
const core = createKibanaCoreStartMock();
const plugins = createKibanaPluginsStartMock();
Expand All @@ -90,6 +93,36 @@ export const createUseKibanaMock = () => {
return () => ({ services });
};

export const createStartServices = () => {
const core = createKibanaCoreStartMock();
const plugins = createKibanaPluginsStartMock();
const security = {
authc: {
getCurrentUser: jest.fn(),
areAPIKeysEnabled: jest.fn(),
},
sessionTimeout: {
start: jest.fn(),
stop: jest.fn(),
extend: jest.fn(),
},
license: {
isEnabled: jest.fn(),
getFeatures: jest.fn(),
features$: jest.fn(),
},
__legacyCompat: { logoutUrl: 'logoutUrl', tenant: 'tenant' },
};

const services = ({
...core,
...plugins,
security,
} as unknown) as StartServices;

return services;
};

export const createWithKibanaMock = () => {
const kibana = createUseKibanaMock()();

Expand Down
Loading

0 comments on commit ade2b57

Please sign in to comment.