mirror of https://github.com/grafana/grafana
parent
5ac5a08e9e
commit
22510be450
@ -1,69 +1,159 @@ |
||||
import React from 'react'; |
||||
import moment from 'moment'; |
||||
import { AlertRuleList } from './AlertRuleList'; |
||||
import { RootStore } from 'app/stores/RootStore/RootStore'; |
||||
import { backendSrv, createNavTree } from 'test/mocks/common'; |
||||
import { mount } from 'enzyme'; |
||||
import toJson from 'enzyme-to-json'; |
||||
|
||||
describe('AlertRuleList', () => { |
||||
let page, store; |
||||
|
||||
beforeAll(() => { |
||||
backendSrv.get.mockReturnValue( |
||||
Promise.resolve([ |
||||
import { shallow } from 'enzyme'; |
||||
import AlertRuleList, { Props } from './AlertRuleList'; |
||||
import { AlertRule, NavModel } from '../../types'; |
||||
import appEvents from '../../core/app_events'; |
||||
|
||||
jest.mock('react-redux', () => ({ |
||||
connect: () => params => params, |
||||
})); |
||||
|
||||
jest.mock('../../core/app_events', () => ({ |
||||
emit: jest.fn(), |
||||
})); |
||||
|
||||
const setup = (propOverrides?: object) => { |
||||
const props: Props = { |
||||
navModel: {} as NavModel, |
||||
alertRules: [] as AlertRule[], |
||||
updateLocation: jest.fn(), |
||||
getAlertRulesAsync: jest.fn(), |
||||
setSearchQuery: jest.fn(), |
||||
stateFilter: '', |
||||
search: '', |
||||
}; |
||||
|
||||
Object.assign(props, propOverrides); |
||||
|
||||
const wrapper = shallow(<AlertRuleList {...props} />); |
||||
|
||||
return { |
||||
wrapper, |
||||
instance: wrapper.instance() as AlertRuleList, |
||||
}; |
||||
}; |
||||
|
||||
describe('Render', () => { |
||||
it('should render component', () => { |
||||
const { wrapper } = setup(); |
||||
|
||||
expect(wrapper).toMatchSnapshot(); |
||||
}); |
||||
|
||||
it('should render alert rules', () => { |
||||
const { wrapper } = setup({ |
||||
alertRules: [ |
||||
{ |
||||
id: 11, |
||||
dashboardId: 58, |
||||
id: 1, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 3, |
||||
name: 'Panel Title alert', |
||||
name: 'TestData - Always OK', |
||||
state: 'ok', |
||||
newStateDate: moment() |
||||
.subtract(5, 'minutes') |
||||
.format(), |
||||
newStateDate: '2018-09-04T10:01:01+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: {}, |
||||
executionError: '', |
||||
url: 'd/ufkcofof/my-goal', |
||||
canEdit: true, |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
{ |
||||
id: 3, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 3, |
||||
name: 'TestData - ok', |
||||
state: 'ok', |
||||
newStateDate: '2018-09-04T10:01:01+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: {}, |
||||
executionError: 'error', |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
]) |
||||
); |
||||
|
||||
store = RootStore.create( |
||||
{}, |
||||
{ |
||||
backendSrv: backendSrv, |
||||
navTree: createNavTree('alerting', 'alert-list'), |
||||
} |
||||
); |
||||
|
||||
page = mount(<AlertRuleList {...store} />); |
||||
], |
||||
}); |
||||
|
||||
expect(wrapper).toMatchSnapshot(); |
||||
}); |
||||
}); |
||||
|
||||
describe('Life cycle', () => { |
||||
describe('component did mount', () => { |
||||
it('should call fetchrules', () => { |
||||
const { instance } = setup(); |
||||
instance.fetchRules = jest.fn(); |
||||
instance.componentDidMount(); |
||||
expect(instance.fetchRules).toHaveBeenCalled(); |
||||
}); |
||||
}); |
||||
|
||||
it('should call api to get rules', () => { |
||||
expect(backendSrv.get.mock.calls[0][0]).toEqual('/api/alerts'); |
||||
describe('component did update', () => { |
||||
it('should call fetchrules if props differ', () => { |
||||
const { instance } = setup(); |
||||
instance.fetchRules = jest.fn(); |
||||
|
||||
instance.componentDidUpdate({ stateFilter: 'ok' }); |
||||
|
||||
expect(instance.fetchRules).toHaveBeenCalled(); |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
describe('Functions', () => { |
||||
describe('Get state filter', () => { |
||||
it('should get all if prop is not set', () => { |
||||
const { instance } = setup(); |
||||
|
||||
const stateFilter = instance.getStateFilter(); |
||||
|
||||
expect(stateFilter).toEqual('all'); |
||||
}); |
||||
|
||||
it('should return state filter if set', () => { |
||||
const { instance } = setup({ |
||||
stateFilter: 'ok', |
||||
}); |
||||
|
||||
it('should render 1 rule', () => { |
||||
page.update(); |
||||
const ruleNode = page.find('.alert-rule-item'); |
||||
expect(toJson(ruleNode)).toMatchSnapshot(); |
||||
const stateFilter = instance.getStateFilter(); |
||||
|
||||
expect(stateFilter).toEqual('ok'); |
||||
}); |
||||
}); |
||||
|
||||
describe('State filter changed', () => { |
||||
it('should update location', () => { |
||||
const { instance } = setup(); |
||||
const mockEvent = { target: { value: 'alerting' } }; |
||||
|
||||
instance.onStateFilterChanged(mockEvent); |
||||
|
||||
expect(instance.props.updateLocation).toHaveBeenCalledWith({ query: { state: 'alerting' } }); |
||||
}); |
||||
}); |
||||
|
||||
it('toggle state should change pause rule if not paused', async () => { |
||||
backendSrv.post.mockReturnValue( |
||||
Promise.resolve({ |
||||
state: 'paused', |
||||
}) |
||||
); |
||||
describe('Open how to', () => { |
||||
it('should emit show-modal event', () => { |
||||
const { instance } = setup(); |
||||
|
||||
instance.onOpenHowTo(); |
||||
|
||||
expect(appEvents.emit).toHaveBeenCalledWith('show-modal', { |
||||
src: 'public/app/features/alerting/partials/alert_howto.html', |
||||
modalClass: 'confirm-modal', |
||||
model: {}, |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
page.find('.fa-pause').simulate('click'); |
||||
describe('Search query change', () => { |
||||
it('should set search query', () => { |
||||
const { instance } = setup(); |
||||
const mockEvent = { target: { value: 'dashboard' } }; |
||||
|
||||
// wait for api call to resolve
|
||||
await Promise.resolve(); |
||||
page.update(); |
||||
instance.onSearchQueryChange(mockEvent); |
||||
|
||||
expect(store.alertList.rules[0].state).toBe('paused'); |
||||
expect(page.find('.fa-play')).toHaveLength(1); |
||||
expect(instance.props.setSearchQuery).toHaveBeenCalledWith('dashboard'); |
||||
}); |
||||
}); |
||||
}); |
||||
|
||||
@ -1,103 +1,254 @@ |
||||
// Jest Snapshot v1, https://goo.gl/fbAQLP |
||||
|
||||
exports[`AlertRuleList should render 1 rule 1`] = ` |
||||
<li |
||||
className="alert-rule-item" |
||||
> |
||||
<span |
||||
className="alert-rule-item__icon alert-state-ok" |
||||
> |
||||
<i |
||||
className="icon-gf icon-gf-online" |
||||
/> |
||||
</span> |
||||
exports[`Render should render alert rules 1`] = ` |
||||
<div> |
||||
<PageHeader |
||||
model={Object {}} |
||||
/> |
||||
<div |
||||
className="alert-rule-item__body" |
||||
className="page-container page-body" |
||||
> |
||||
<div |
||||
className="alert-rule-item__header" |
||||
className="page-action-bar" |
||||
> |
||||
<div |
||||
className="alert-rule-item__name" |
||||
className="gf-form gf-form--grow" |
||||
> |
||||
<a |
||||
href="d/ufkcofof/my-goal?panelId=3&fullscreen=true&edit=true&tab=alert" |
||||
<label |
||||
className="gf-form--has-input-icon gf-form--grow" |
||||
> |
||||
<Highlighter |
||||
highlightClassName="highlight-search-match" |
||||
searchWords={ |
||||
Array [ |
||||
"", |
||||
] |
||||
} |
||||
textToHighlight="Panel Title alert" |
||||
> |
||||
<span> |
||||
<span |
||||
className="" |
||||
key="0" |
||||
> |
||||
Panel Title alert |
||||
</span> |
||||
</span> |
||||
</Highlighter> |
||||
</a> |
||||
<input |
||||
className="gf-form-input" |
||||
onChange={[Function]} |
||||
placeholder="Search alerts" |
||||
type="text" |
||||
value="" |
||||
/> |
||||
<i |
||||
className="gf-form-input-icon fa fa-search" |
||||
/> |
||||
</label> |
||||
</div> |
||||
<div |
||||
className="alert-rule-item__text" |
||||
className="gf-form" |
||||
> |
||||
<span |
||||
className="alert-state-ok" |
||||
<label |
||||
className="gf-form-label" |
||||
> |
||||
<Highlighter |
||||
highlightClassName="highlight-search-match" |
||||
searchWords={ |
||||
Array [ |
||||
"", |
||||
] |
||||
} |
||||
textToHighlight="OK" |
||||
> |
||||
<span> |
||||
<span |
||||
className="" |
||||
key="0" |
||||
> |
||||
OK |
||||
</span> |
||||
</span> |
||||
</Highlighter> |
||||
</span> |
||||
<span |
||||
className="alert-rule-item__time" |
||||
States |
||||
</label> |
||||
<div |
||||
className="gf-form-select-wrapper width-13" |
||||
> |
||||
for |
||||
5 minutes |
||||
</span> |
||||
<select |
||||
className="gf-form-input" |
||||
onChange={[Function]} |
||||
value="all" |
||||
> |
||||
<option |
||||
key="all" |
||||
value="all" |
||||
> |
||||
All |
||||
</option> |
||||
<option |
||||
key="ok" |
||||
value="ok" |
||||
> |
||||
OK |
||||
</option> |
||||
<option |
||||
key="not_ok" |
||||
value="not_ok" |
||||
> |
||||
Not OK |
||||
</option> |
||||
<option |
||||
key="alerting" |
||||
value="alerting" |
||||
> |
||||
Alerting |
||||
</option> |
||||
<option |
||||
key="no_data" |
||||
value="no_data" |
||||
> |
||||
No Data |
||||
</option> |
||||
<option |
||||
key="paused" |
||||
value="paused" |
||||
> |
||||
Paused |
||||
</option> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
<div |
||||
className="page-action-bar__spacer" |
||||
/> |
||||
<a |
||||
className="btn btn-secondary" |
||||
onClick={[Function]} |
||||
> |
||||
<i |
||||
className="fa fa-info-circle" |
||||
/> |
||||
How to add an alert |
||||
</a> |
||||
</div> |
||||
<section> |
||||
<ol |
||||
className="alert-rule-list" |
||||
> |
||||
<AlertRuleItem |
||||
key="1" |
||||
rule={ |
||||
Object { |
||||
"dashboardId": 7, |
||||
"dashboardSlug": "alerting-with-testdata", |
||||
"dashboardUid": "ggHbN42mk", |
||||
"evalData": Object {}, |
||||
"evalDate": "0001-01-01T00:00:00Z", |
||||
"executionError": "", |
||||
"id": 1, |
||||
"name": "TestData - Always OK", |
||||
"newStateDate": "2018-09-04T10:01:01+02:00", |
||||
"panelId": 3, |
||||
"state": "ok", |
||||
"url": "/d/ggHbN42mk/alerting-with-testdata", |
||||
} |
||||
} |
||||
search="" |
||||
/> |
||||
<AlertRuleItem |
||||
key="3" |
||||
rule={ |
||||
Object { |
||||
"dashboardId": 7, |
||||
"dashboardSlug": "alerting-with-testdata", |
||||
"dashboardUid": "ggHbN42mk", |
||||
"evalData": Object {}, |
||||
"evalDate": "0001-01-01T00:00:00Z", |
||||
"executionError": "error", |
||||
"id": 3, |
||||
"name": "TestData - ok", |
||||
"newStateDate": "2018-09-04T10:01:01+02:00", |
||||
"panelId": 3, |
||||
"state": "ok", |
||||
"url": "/d/ggHbN42mk/alerting-with-testdata", |
||||
} |
||||
} |
||||
search="" |
||||
/> |
||||
</ol> |
||||
</section> |
||||
</div> |
||||
</div> |
||||
`; |
||||
|
||||
exports[`Render should render component 1`] = ` |
||||
<div> |
||||
<PageHeader |
||||
model={Object {}} |
||||
/> |
||||
<div |
||||
className="alert-rule-item__actions" |
||||
className="page-container page-body" |
||||
> |
||||
<button |
||||
className="btn btn-small btn-inverse alert-list__btn width-2" |
||||
onClick={[Function]} |
||||
title="Pausing an alert rule prevents it from executing" |
||||
<div |
||||
className="page-action-bar" |
||||
> |
||||
<i |
||||
className="fa fa-pause" |
||||
<div |
||||
className="gf-form gf-form--grow" |
||||
> |
||||
<label |
||||
className="gf-form--has-input-icon gf-form--grow" |
||||
> |
||||
<input |
||||
className="gf-form-input" |
||||
onChange={[Function]} |
||||
placeholder="Search alerts" |
||||
type="text" |
||||
value="" |
||||
/> |
||||
<i |
||||
className="gf-form-input-icon fa fa-search" |
||||
/> |
||||
</label> |
||||
</div> |
||||
<div |
||||
className="gf-form" |
||||
> |
||||
<label |
||||
className="gf-form-label" |
||||
> |
||||
States |
||||
</label> |
||||
<div |
||||
className="gf-form-select-wrapper width-13" |
||||
> |
||||
<select |
||||
className="gf-form-input" |
||||
onChange={[Function]} |
||||
value="all" |
||||
> |
||||
<option |
||||
key="all" |
||||
value="all" |
||||
> |
||||
All |
||||
</option> |
||||
<option |
||||
key="ok" |
||||
value="ok" |
||||
> |
||||
OK |
||||
</option> |
||||
<option |
||||
key="not_ok" |
||||
value="not_ok" |
||||
> |
||||
Not OK |
||||
</option> |
||||
<option |
||||
key="alerting" |
||||
value="alerting" |
||||
> |
||||
Alerting |
||||
</option> |
||||
<option |
||||
key="no_data" |
||||
value="no_data" |
||||
> |
||||
No Data |
||||
</option> |
||||
<option |
||||
key="paused" |
||||
value="paused" |
||||
> |
||||
Paused |
||||
</option> |
||||
</select> |
||||
</div> |
||||
</div> |
||||
<div |
||||
className="page-action-bar__spacer" |
||||
/> |
||||
</button> |
||||
<a |
||||
className="btn btn-small btn-inverse alert-list__btn width-2" |
||||
href="d/ufkcofof/my-goal?panelId=3&fullscreen=true&edit=true&tab=alert" |
||||
title="Edit alert rule" |
||||
> |
||||
<i |
||||
className="icon-gf icon-gf-settings" |
||||
<a |
||||
className="btn btn-secondary" |
||||
onClick={[Function]} |
||||
> |
||||
<i |
||||
className="fa fa-info-circle" |
||||
/> |
||||
How to add an alert |
||||
</a> |
||||
</div> |
||||
<section> |
||||
<ol |
||||
className="alert-rule-list" |
||||
/> |
||||
</a> |
||||
</section> |
||||
</div> |
||||
</li> |
||||
</div> |
||||
`; |
||||
|
||||
@ -0,0 +1,91 @@ |
||||
import { ActionTypes, Action } from './actions'; |
||||
import { alertRulesReducer, initialState } from './reducers'; |
||||
import { AlertRuleApi } from '../../../types'; |
||||
|
||||
describe('Alert rules', () => { |
||||
const payload: AlertRuleApi[] = [ |
||||
{ |
||||
id: 2, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 4, |
||||
name: 'TestData - Always Alerting', |
||||
state: 'alerting', |
||||
newStateDate: '2018-09-04T10:00:30+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: { evalMatches: [{ metric: 'A-series', tags: null, value: 215 }] }, |
||||
executionError: '', |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
{ |
||||
id: 1, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 3, |
||||
name: 'TestData - Always OK', |
||||
state: 'ok', |
||||
newStateDate: '2018-09-04T10:01:01+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: {}, |
||||
executionError: '', |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
{ |
||||
id: 3, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 3, |
||||
name: 'TestData - ok', |
||||
state: 'ok', |
||||
newStateDate: '2018-09-04T10:01:01+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: {}, |
||||
executionError: 'error', |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
{ |
||||
id: 4, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 3, |
||||
name: 'TestData - Paused', |
||||
state: 'paused', |
||||
newStateDate: '2018-09-04T10:01:01+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: {}, |
||||
executionError: 'error', |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
{ |
||||
id: 5, |
||||
dashboardId: 7, |
||||
dashboardUid: 'ggHbN42mk', |
||||
dashboardSlug: 'alerting-with-testdata', |
||||
panelId: 3, |
||||
name: 'TestData - Ok', |
||||
state: 'ok', |
||||
newStateDate: '2018-09-04T10:01:01+02:00', |
||||
evalDate: '0001-01-01T00:00:00Z', |
||||
evalData: { |
||||
noData: true, |
||||
}, |
||||
executionError: 'error', |
||||
url: '/d/ggHbN42mk/alerting-with-testdata', |
||||
}, |
||||
]; |
||||
|
||||
it('should set alert rules', () => { |
||||
const action: Action = { |
||||
type: ActionTypes.LoadAlertRules, |
||||
payload: payload, |
||||
}; |
||||
|
||||
const result = alertRulesReducer(initialState, action); |
||||
|
||||
expect(result.items).toEqual(payload); |
||||
}); |
||||
}); |
||||
Loading…
Reference in new issue