From 7c5e01fb94a21ae04eb5eca4182c6d73c3885e43 Mon Sep 17 00:00:00 2001 From: Frank Hassanabad Date: Fri, 20 Sep 2019 10:05:38 -0600 Subject: [PATCH] [SIEM] Changed job links have the job configuration in the search when the user clicks on them. (#46084) (#46209) ## Summary * Adds the link for ML search when you click on it. * Adds more unit tests * https://github.com/elastic/kibana/issues/46052 When you are an ML admin and open the ML Anomaly detection button and then click on the hyper link to a job it will take you to the ML job page of: ```ts /app/ml ``` Which lists all of the jobs. Screen Shot 2019-09-18 at 11 22 08 AM If you have a lot of jobs to sort through this non-optimal. As an ML admin, you will want to go directly to the job you clicked on by having the search populated. That is possible by changing the link and adding the ml job: Now when you click on a job id you are going to have the job ID populated like so: Screen Shot 2019-09-18 at 11 20 55 AM ### Checklist Use ~~strikethroughs~~ to remove checklist items you don't feel are applicable to this PR. ~~- [ ] This was checked for cross-browser compatibility, [including a check against IE11](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility)~~ ~~- [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/master/packages/kbn-i18n/README.md)~~ ~~- [ ] [Documentation](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#writing-documentation) was added for features that require explanation or tutorials~~ ~~- [ ] [Unit or functional tests](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#cross-browser-compatibility) were updated or added to match the most common scenarios~~ ~~- [ ] This was checked for [keyboard-only and screenreader accessibility](https://developer.mozilla.org/en-US/docs/Learn/Tools_and_testing/Cross_browser_testing/Accessibility#Accessibility_testing_checklist)~~ ### For maintainers ~~- [ ] This was checked for breaking API changes and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~~ ~~- [ ] This includes a feature addition or change that requires a release note and was [labeled appropriately](https://github.com/elastic/kibana/blob/master/CONTRIBUTING.md#release-notes-process)~~ --- .../ml_popover/jobs_table/job_switch.test.tsx | 52 +++++++++++- .../ml_popover/jobs_table/jobs_table.test.tsx | 85 ++++++++++++++++++- .../ml_popover/jobs_table/jobs_table.tsx | 6 +- 3 files changed, 139 insertions(+), 4 deletions(-) diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx index 69a029956e8e2..844d346405e0e 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/job_switch.test.tsx @@ -4,7 +4,7 @@ * you may not use this file except in compliance with the Elastic License. */ -import { shallow } from 'enzyme'; +import { shallow, mount } from 'enzyme'; import toJson from 'enzyme-to-json'; import * as React from 'react'; @@ -12,6 +12,11 @@ import { isChecked, isFailure, isJobLoading, JobSwitch } from './job_switch'; import { mockOpenedJob } from '../__mocks__/api'; describe('JobSwitch', () => { + let onJobStateChangeMock = jest.fn(); + beforeEach(() => { + onJobStateChangeMock = jest.fn(); + }); + test('renders correctly against snapshot', () => { const wrapper = shallow( @@ -19,6 +24,51 @@ describe('JobSwitch', () => { expect(toJson(wrapper)).toMatchSnapshot(); }); + test('should call onJobStateChange when the switch is clicked to be true/open', () => { + const wrapper = mount( + + ); + + wrapper + .find('[data-test-subj="job-switch"] input') + .first() + .simulate('change', { + target: { checked: true }, + }); + + expect(onJobStateChangeMock.mock.calls[0]).toEqual([ + 'siem-api-rare_process_linux_ecs', + 1562870521264, + true, + ]); + }); + + test('should have a switch when it is not in the loading state', () => { + const wrapper = mount( + + ); + expect(wrapper.find('[data-test-subj="job-switch"]').exists()).toBe(true); + }); + + test('should not have a switch when it is in the loading state', () => { + const wrapper = mount( + + ); + expect(wrapper.find('[data-test-subj="job-switch"]').exists()).toBe(false); + }); + describe('isChecked', () => { test('returns false if only jobState is enabled', () => { expect(isChecked('started', 'closing')).toBe(false); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx index 23763896ea90e..932dad267e3fa 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.test.tsx @@ -4,14 +4,18 @@ * you may not use this file except in compliance with the Elastic License. */ -import { shallow } from 'enzyme'; +import { shallow, mount } from 'enzyme'; import toJson from 'enzyme-to-json'; import * as React from 'react'; import { JobsTable } from './jobs_table'; import { mockJobsSummaryResponse } from '../__mocks__/api'; +import { cloneDeep } from 'lodash/fp'; describe('JobsTable', () => { - const onJobStateChangeMock = jest.fn(); + let onJobStateChangeMock = jest.fn(); + beforeEach(() => { + onJobStateChangeMock = jest.fn(); + }); test('renders correctly against snapshot', () => { const wrapper = shallow( @@ -23,4 +27,81 @@ describe('JobsTable', () => { ); expect(toJson(wrapper)).toMatchSnapshot(); }); + + test('should render the hyperlink which points specifically to the job id', () => { + const wrapper = mount( + + ); + expect( + wrapper + .find('[data-test-subj="jobs-table-link"]') + .first() + .props().href + ).toEqual('/test/base/path/app/ml#/jobs?mlManagement=(jobId:rc-rare-process-windows-5)'); + }); + + test('should render the hyperlink with URI encodings which points specifically to the job id', () => { + const cloneJobsSummaryResponse = cloneDeep(mockJobsSummaryResponse); + cloneJobsSummaryResponse[0].id = 'job id with spaces'; + const wrapper = mount( + + ); + expect( + wrapper + .find('[data-test-subj="jobs-table-link"]') + .first() + .props().href + ).toEqual('/test/base/path/app/ml#/jobs?mlManagement=(jobId:job%20id%20with%20spaces)'); + }); + + test('should call onJobStateChange when the switch is clicked to be true/open', () => { + const wrapper = mount( + + ); + wrapper + .find('[data-test-subj="job-switch"] input') + .first() + .simulate('change', { + target: { checked: true }, + }); + expect(onJobStateChangeMock.mock.calls[0]).toEqual([ + 'rc-rare-process-windows-5', + 1561402325194, + true, + ]); + }); + + test('should have a switch when it is not in the loading state', () => { + const wrapper = mount( + + ); + expect(wrapper.find('[data-test-subj="job-switch"]').exists()).toBe(true); + }); + + test('should not have a switch when it is in the loading state', () => { + const wrapper = mount( + + ); + expect(wrapper.find('[data-test-subj="job-switch"]').exists()).toBe(false); + }); }); diff --git a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx index 9ce5e9fbdf362..1cd429f92b6a9 100644 --- a/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx +++ b/x-pack/legacy/plugins/siem/public/components/ml_popover/jobs_table/jobs_table.tsx @@ -38,7 +38,11 @@ const getJobsTableColumns = ( name: i18n.COLUMN_JOB_NAME, render: ({ id, description }: Job) => ( - + {id}