Skip to content

Commit

Permalink
[SIEM] Changed job links have the job configuration in the search whe…
Browse files Browse the repository at this point in the history
…n the user clicks on them. (#46084) (#46209)

## Summary

* Adds the link for ML search when you click on it. 
* Adds more unit tests
* #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.
<img width="1405" alt="Screen Shot 2019-09-18 at 11 22 08 AM" src="https://user-images.githubusercontent.com/1151048/65170796-a7b7a480-da06-11e9-9cec-1a912129fb83.png">

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:
<img width="1357" alt="Screen Shot 2019-09-18 at 11 20 55 AM" src="https://user-images.githubusercontent.com/1151048/65170720-7a6af680-da06-11e9-9482-84e7cd62763f.png">

### 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)~~
  • Loading branch information
FrankHassanabad authored Sep 20, 2019
1 parent 0c498e4 commit 7c5e01f
Show file tree
Hide file tree
Showing 3 changed files with 139 additions and 4 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,71 @@
* 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 { 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(
<JobSwitch job={mockOpenedJob} isSummaryLoading={false} onJobStateChange={jest.fn()} />
);
expect(toJson(wrapper)).toMatchSnapshot();
});

test('should call onJobStateChange when the switch is clicked to be true/open', () => {
const wrapper = mount(
<JobSwitch
isSummaryLoading={false}
job={mockOpenedJob}
onJobStateChange={onJobStateChangeMock}
/>
);

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(
<JobSwitch
isSummaryLoading={false}
job={mockOpenedJob}
onJobStateChange={onJobStateChangeMock}
/>
);
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(
<JobSwitch
isSummaryLoading={true}
job={mockOpenedJob}
onJobStateChange={onJobStateChangeMock}
/>
);
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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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(
<JobsTable
isLoading={true}
jobs={mockJobsSummaryResponse}
onJobStateChange={onJobStateChangeMock}
/>
);
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(
<JobsTable
isLoading={true}
jobs={cloneJobsSummaryResponse}
onJobStateChange={onJobStateChangeMock}
/>
);
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(
<JobsTable
isLoading={false}
jobs={mockJobsSummaryResponse}
onJobStateChange={onJobStateChangeMock}
/>
);
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(
<JobsTable
isLoading={false}
jobs={mockJobsSummaryResponse}
onJobStateChange={onJobStateChangeMock}
/>
);
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(
<JobsTable
isLoading={true}
jobs={mockJobsSummaryResponse}
onJobStateChange={onJobStateChangeMock}
/>
);
expect(wrapper.find('[data-test-subj="job-switch"]').exists()).toBe(false);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,11 @@ const getJobsTableColumns = (
name: i18n.COLUMN_JOB_NAME,
render: ({ id, description }: Job) => (
<JobNameWrapper>
<EuiLink href={`${chrome.getBasePath()}/app/ml`} target="_blank">
<EuiLink
data-test-subj="jobs-table-link"
href={`${chrome.getBasePath()}/app/ml#/jobs?mlManagement=(jobId:${encodeURI(id)})`}
target="_blank"
>
<EuiText size="s">{id}</EuiText>
</EuiLink>
<EuiText color="subdued" size="xs">
Expand Down

0 comments on commit 7c5e01f

Please sign in to comment.