mirror of
https://github.com/elastic/kibana.git
synced 2025-04-24 09:48:58 -04:00
Rename ActionStatus and WatchStatus models to ActionStatusModel and WatchStatusModel to differentiate between models, POJOs, and client-side components. (#137631)
Co-authored-by: Kibana Machine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
parent
4226cbf2e6
commit
2b2b92e6bf
13 changed files with 704 additions and 698 deletions
|
@ -1,360 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { ActionStatus } from './action_status';
|
||||
import { ACTION_STATES } from '../../../common/constants';
|
||||
import moment from 'moment';
|
||||
|
||||
describe('action_status', () => {
|
||||
describe('ActionStatus', () => {
|
||||
describe('fromUpstreamJson factory method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`throws an error if no 'id' property in json`, () => {
|
||||
delete upstreamJson.id;
|
||||
expect(() => {
|
||||
ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow('JSON argument must contain an "id" property');
|
||||
});
|
||||
|
||||
it(`throws an error if no 'actionStatusJson' property in json`, () => {
|
||||
delete upstreamJson.actionStatusJson;
|
||||
expect(() => {
|
||||
ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow('JSON argument must contain an "actionStatusJson" property');
|
||||
});
|
||||
|
||||
it('returns correct ActionStatus instance', () => {
|
||||
const actionStatus = ActionStatus.fromUpstreamJson({
|
||||
...upstreamJson,
|
||||
errors: { foo: 'bar' },
|
||||
});
|
||||
|
||||
expect(actionStatus.id).toBe(upstreamJson.id);
|
||||
expect(actionStatus.lastAcknowledged).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.ack.timestamp)
|
||||
);
|
||||
expect(actionStatus.lastExecution).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.last_execution.timestamp)
|
||||
);
|
||||
expect(actionStatus.lastExecutionSuccessful).toEqual(
|
||||
upstreamJson.actionStatusJson.last_execution.successful
|
||||
);
|
||||
expect(actionStatus.lastExecutionReason).toBe(
|
||||
upstreamJson.actionStatusJson.last_execution.reason
|
||||
);
|
||||
expect(actionStatus.lastThrottled).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.last_throttle.timestamp)
|
||||
);
|
||||
expect(actionStatus.lastSuccessfulExecution).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.last_successful_execution.timestamp)
|
||||
);
|
||||
expect(actionStatus.errors).toEqual({ foo: 'bar' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('state getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
lastCheckedRawFormat: '2017-03-01T20:55:49.679Z',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.ERROR`, () => {
|
||||
it('lastExecutionSuccessful is equal to false and it is the most recent execution', () => {
|
||||
upstreamJson.actionStatusJson.last_execution.successful = false;
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
|
||||
it('action is acked and lastAcknowledged is less than lastExecution', () => {
|
||||
const actionStatus = ActionStatus.fromUpstreamJson({
|
||||
...upstreamJson,
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
state: 'acked',
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-02T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
|
||||
it('action is ackable and lastSuccessfulExecution is less than lastExecution', () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly calculates ACTION_STATES.CONFIG_ERROR', () => {
|
||||
const actionStatus = ActionStatus.fromUpstreamJson({
|
||||
...upstreamJson,
|
||||
errors: { foo: 'bar' },
|
||||
});
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.CONFIG_ERROR);
|
||||
});
|
||||
|
||||
it(`correctly calculates ACTION_STATES.OK`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'awaits_successful_execution';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.OK);
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.ACKNOWLEDGED`, () => {
|
||||
it(`when lastAcknowledged is equal to lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'acked';
|
||||
upstreamJson.actionStatusJson.ack.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`when lastAcknowledged is greater than lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'acked';
|
||||
upstreamJson.actionStatusJson.ack.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.THROTTLED`, () => {
|
||||
it(`when lastThrottled is equal to lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_throttle.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.THROTTLED);
|
||||
});
|
||||
|
||||
it(`when lastThrottled is greater than lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_throttle.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.THROTTLED);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.FIRING`, () => {
|
||||
it(`when lastSuccessfulExecution is equal to lastExecution`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.FIRING);
|
||||
});
|
||||
|
||||
it(`when lastSuccessfulExecution is greater than lastExecution`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-02T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.FIRING);
|
||||
});
|
||||
});
|
||||
|
||||
it(`correctly calculates ACTION_STATES.UNKNOWN if it can not determine state`, () => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: { state: 'foo' },
|
||||
last_successful_execution: { successful: true },
|
||||
},
|
||||
};
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.UNKNOWN);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAckable getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.OK`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'awaits_successful_execution';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.OK);
|
||||
expect(actionStatus.isAckable).toBe(false);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.ACKNOWLEDGED`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'acked';
|
||||
upstreamJson.actionStatusJson.ack.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
expect(actionStatus.isAckable).toBe(false);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.THROTTLED`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_throttle.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.THROTTLED);
|
||||
expect(actionStatus.isAckable).toBe(true);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.FIRING`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.FIRING);
|
||||
expect(actionStatus.isAckable).toBe(true);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.ERROR`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
expect(actionStatus.isAckable).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('downstreamJson getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('returns correct JSON for client', () => {
|
||||
const actionStatus = ActionStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
const json = actionStatus.downstreamJson;
|
||||
|
||||
expect(json.id).toBe(actionStatus.id);
|
||||
expect(json.state).toBe(actionStatus.state);
|
||||
expect(json.isAckable).toBe(actionStatus.isAckable);
|
||||
expect(json.lastAcknowledged).toBe(actionStatus.lastAcknowledged);
|
||||
expect(json.lastThrottled).toBe(actionStatus.lastThrottled);
|
||||
expect(json.lastExecution).toBe(actionStatus.lastExecution);
|
||||
expect(json.lastExecutionSuccessful).toBe(actionStatus.lastExecutionSuccessful);
|
||||
expect(json.lastExecutionReason).toBe(actionStatus.lastExecutionReason);
|
||||
expect(json.lastSuccessfulExecution).toBe(actionStatus.lastSuccessfulExecution);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -7,11 +7,12 @@
|
|||
|
||||
import { get } from 'lodash';
|
||||
import { badRequest } from '@hapi/boom';
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { ACTION_STATES } from '../../../common/constants';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
export class ActionStatus {
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { ACTION_STATES } from '../../../common/constants';
|
||||
|
||||
export class ActionStatusModel {
|
||||
constructor(props) {
|
||||
this.id = props.id;
|
||||
this.actionStatusJson = props.actionStatusJson;
|
||||
|
@ -119,7 +120,7 @@ export class ActionStatus {
|
|||
throw badRequest(missingPropertyError('actionStatusJson'));
|
||||
}
|
||||
|
||||
return new ActionStatus(json);
|
||||
return new ActionStatusModel(json);
|
||||
}
|
||||
|
||||
/*
|
|
@ -0,0 +1,359 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
|
||||
import { ACTION_STATES } from '../../../common/constants';
|
||||
import { ActionStatusModel } from './action_status_model';
|
||||
|
||||
describe('ActionStatusModel', () => {
|
||||
describe('fromUpstreamJson factory method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`throws an error if no 'id' property in json`, () => {
|
||||
delete upstreamJson.id;
|
||||
expect(() => {
|
||||
ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow('JSON argument must contain an "id" property');
|
||||
});
|
||||
|
||||
it(`throws an error if no 'actionStatusJson' property in json`, () => {
|
||||
delete upstreamJson.actionStatusJson;
|
||||
expect(() => {
|
||||
ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow('JSON argument must contain an "actionStatusJson" property');
|
||||
});
|
||||
|
||||
it('returns correct ActionStatus instance', () => {
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson({
|
||||
...upstreamJson,
|
||||
errors: { foo: 'bar' },
|
||||
});
|
||||
|
||||
expect(actionStatus.id).toBe(upstreamJson.id);
|
||||
expect(actionStatus.lastAcknowledged).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.ack.timestamp)
|
||||
);
|
||||
expect(actionStatus.lastExecution).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.last_execution.timestamp)
|
||||
);
|
||||
expect(actionStatus.lastExecutionSuccessful).toEqual(
|
||||
upstreamJson.actionStatusJson.last_execution.successful
|
||||
);
|
||||
expect(actionStatus.lastExecutionReason).toBe(
|
||||
upstreamJson.actionStatusJson.last_execution.reason
|
||||
);
|
||||
expect(actionStatus.lastThrottled).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.last_throttle.timestamp)
|
||||
);
|
||||
expect(actionStatus.lastSuccessfulExecution).toEqual(
|
||||
moment(upstreamJson.actionStatusJson.last_successful_execution.timestamp)
|
||||
);
|
||||
expect(actionStatus.errors).toEqual({ foo: 'bar' });
|
||||
});
|
||||
});
|
||||
|
||||
describe('state getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
lastCheckedRawFormat: '2017-03-01T20:55:49.679Z',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.ERROR`, () => {
|
||||
it('lastExecutionSuccessful is equal to false and it is the most recent execution', () => {
|
||||
upstreamJson.actionStatusJson.last_execution.successful = false;
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
|
||||
it('action is acked and lastAcknowledged is less than lastExecution', () => {
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson({
|
||||
...upstreamJson,
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
state: 'acked',
|
||||
timestamp: '2017-03-01T00:00:00.000Z',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-02T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
});
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
|
||||
it('action is ackable and lastSuccessfulExecution is less than lastExecution', () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly calculates ACTION_STATES.CONFIG_ERROR', () => {
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson({
|
||||
...upstreamJson,
|
||||
errors: { foo: 'bar' },
|
||||
});
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.CONFIG_ERROR);
|
||||
});
|
||||
|
||||
it(`correctly calculates ACTION_STATES.OK`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'awaits_successful_execution';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.OK);
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.ACKNOWLEDGED`, () => {
|
||||
it(`when lastAcknowledged is equal to lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'acked';
|
||||
upstreamJson.actionStatusJson.ack.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`when lastAcknowledged is greater than lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'acked';
|
||||
upstreamJson.actionStatusJson.ack.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.THROTTLED`, () => {
|
||||
it(`when lastThrottled is equal to lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_throttle.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.THROTTLED);
|
||||
});
|
||||
|
||||
it(`when lastThrottled is greater than lastExecution`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_throttle.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.THROTTLED);
|
||||
});
|
||||
});
|
||||
|
||||
describe(`correctly calculates ACTION_STATES.FIRING`, () => {
|
||||
it(`when lastSuccessfulExecution is equal to lastExecution`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.FIRING);
|
||||
});
|
||||
|
||||
it(`when lastSuccessfulExecution is greater than lastExecution`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-02T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.FIRING);
|
||||
});
|
||||
});
|
||||
|
||||
it(`correctly calculates ACTION_STATES.UNKNOWN if it can not determine state`, () => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: { state: 'foo' },
|
||||
last_successful_execution: { successful: true },
|
||||
},
|
||||
};
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.UNKNOWN);
|
||||
});
|
||||
});
|
||||
|
||||
describe('isAckable getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.OK`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'awaits_successful_execution';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.OK);
|
||||
expect(actionStatus.isAckable).toBe(false);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.ACKNOWLEDGED`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'acked';
|
||||
upstreamJson.actionStatusJson.ack.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ACKNOWLEDGED);
|
||||
expect(actionStatus.isAckable).toBe(false);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.THROTTLED`, () => {
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_throttle.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.THROTTLED);
|
||||
expect(actionStatus.isAckable).toBe(true);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.FIRING`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-01T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.FIRING);
|
||||
expect(actionStatus.isAckable).toBe(true);
|
||||
});
|
||||
|
||||
it(`correctly calculated isAckable when in ACTION_STATES.ERROR`, () => {
|
||||
delete upstreamJson.actionStatusJson.last_throttle;
|
||||
upstreamJson.actionStatusJson.ack.state = 'ackable';
|
||||
upstreamJson.actionStatusJson.last_successful_execution.timestamp =
|
||||
'2017-03-01T00:00:00.000Z';
|
||||
upstreamJson.actionStatusJson.last_execution.timestamp = '2017-03-02T00:00:00.000Z';
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(actionStatus.state).toBe(ACTION_STATES.ERROR);
|
||||
expect(actionStatus.isAckable).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
describe('downstreamJson getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-action',
|
||||
actionStatusJson: {
|
||||
ack: {
|
||||
timestamp: '2017-03-01T20:56:58.442Z',
|
||||
state: 'acked',
|
||||
},
|
||||
last_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
reason: 'reasons',
|
||||
},
|
||||
last_throttle: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
},
|
||||
last_successful_execution: {
|
||||
timestamp: '2017-03-01T20:55:49.679Z',
|
||||
successful: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('returns correct JSON for client', () => {
|
||||
const actionStatus = ActionStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
const json = actionStatus.downstreamJson;
|
||||
|
||||
expect(json.id).toBe(actionStatus.id);
|
||||
expect(json.state).toBe(actionStatus.state);
|
||||
expect(json.isAckable).toBe(actionStatus.isAckable);
|
||||
expect(json.lastAcknowledged).toBe(actionStatus.lastAcknowledged);
|
||||
expect(json.lastThrottled).toBe(actionStatus.lastThrottled);
|
||||
expect(json.lastExecution).toBe(actionStatus.lastExecution);
|
||||
expect(json.lastExecutionSuccessful).toBe(actionStatus.lastExecutionSuccessful);
|
||||
expect(json.lastExecutionReason).toBe(actionStatus.lastExecutionReason);
|
||||
expect(json.lastSuccessfulExecution).toBe(actionStatus.lastSuccessfulExecution);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { WatchStatus } from './watch_status';
|
||||
export { ActionStatusModel } from './action_status_model';
|
|
@ -7,9 +7,10 @@
|
|||
|
||||
import { get, map, pick } from 'lodash';
|
||||
import { badRequest } from '@hapi/boom';
|
||||
import { Action } from '../../../common/models/action';
|
||||
import { WatchStatus } from '../watch_status';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { Action } from '../../../common/models/action';
|
||||
import { WatchStatusModel } from '../watch_status_model';
|
||||
import { WatchErrors } from '../watch_errors';
|
||||
|
||||
export class BaseWatch {
|
||||
|
@ -137,7 +138,7 @@ export class BaseWatch {
|
|||
|
||||
const watchErrors = WatchErrors.fromUpstreamJson(this.getWatchErrors(actions));
|
||||
|
||||
const watchStatus = WatchStatus.fromUpstreamJson({
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson({
|
||||
id,
|
||||
watchStatusJson,
|
||||
watchErrors,
|
||||
|
|
|
@ -6,11 +6,12 @@
|
|||
*/
|
||||
|
||||
import { badRequest } from '@hapi/boom';
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { get, cloneDeep } from 'lodash';
|
||||
import { WatchStatus } from '../watch_status';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { WatchStatusModel } from '../watch_status_model';
|
||||
|
||||
export class WatchHistoryItem {
|
||||
constructor(props) {
|
||||
this.id = props.id;
|
||||
|
@ -23,7 +24,11 @@ export class WatchHistoryItem {
|
|||
|
||||
const watchStatusJson = get(this.watchHistoryItemJson, 'status');
|
||||
const state = get(this.watchHistoryItemJson, 'state');
|
||||
this.watchStatus = WatchStatus.fromUpstreamJson({ id: this.watchId, watchStatusJson, state });
|
||||
this.watchStatus = WatchStatusModel.fromUpstreamJson({
|
||||
id: this.watchId,
|
||||
watchStatusJson,
|
||||
state,
|
||||
});
|
||||
}
|
||||
|
||||
get downstreamJson() {
|
||||
|
|
|
@ -1,314 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import { WatchStatus } from './watch_status';
|
||||
import { ACTION_STATES, WATCH_STATES, WATCH_STATE_COMMENTS } from '../../../common/constants';
|
||||
import moment from 'moment';
|
||||
|
||||
describe('watch_status', () => {
|
||||
describe('WatchStatus', () => {
|
||||
describe('fromUpstreamJson factory method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
last_checked: '2017-03-02T14:25:31.139Z',
|
||||
last_met_condition: '2017-07-05T14:25:31.139Z',
|
||||
actions: {
|
||||
foo: {},
|
||||
bar: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`throws an error if no 'id' property in json`, () => {
|
||||
delete upstreamJson.id;
|
||||
expect(() => {
|
||||
WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow(/must contain an id property/i);
|
||||
});
|
||||
|
||||
it(`throws an error if no 'watchStatusJson' property in json`, () => {
|
||||
delete upstreamJson.watchStatusJson;
|
||||
expect(() => {
|
||||
WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow(/must contain a watchStatusJson property/i);
|
||||
});
|
||||
|
||||
it('returns correct WatchStatus instance', () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(watchStatus.id).toBe(upstreamJson.id);
|
||||
expect(watchStatus.watchStatusJson).toEqual(upstreamJson.watchStatusJson);
|
||||
expect(watchStatus.isActive).toEqual(true);
|
||||
expect(watchStatus.lastChecked).toEqual(moment(upstreamJson.watchStatusJson.last_checked));
|
||||
expect(watchStatus.lastMetCondition).toEqual(
|
||||
moment(upstreamJson.watchStatusJson.last_met_condition)
|
||||
);
|
||||
expect(watchStatus.actionStatuses.length).toBe(2);
|
||||
|
||||
expect(watchStatus.actionStatuses[0].constructor.name).toBe('ActionStatus');
|
||||
expect(watchStatus.actionStatuses[1].constructor.name).toBe('ActionStatus');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lastFired getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
actions: {
|
||||
foo: {
|
||||
last_execution: {
|
||||
timestamp: '2017-07-05T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
bar: {
|
||||
last_execution: {
|
||||
timestamp: '2025-07-05T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
baz: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`returns the latest lastExecution from it's actions`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
expect(watchStatus.lastFired).toEqual(
|
||||
moment(upstreamJson.watchStatusJson.actions.bar.last_execution.timestamp)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('comment getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.OK there are no actions`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = true;
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.OK);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.OK },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.THROTTLED`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.THROTTLED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.ACKNOWLEDGED`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.FAILING`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.FAILING);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.OK when watch is inactive`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = false;
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.OK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('state getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.OK there are no actions`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = true;
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.OK);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.FIRING`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [{ state: ACTION_STATES.OK }, { state: ACTION_STATES.FIRING }];
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.FIRING);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
];
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.FIRING);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
];
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.FIRING);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.ERROR`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.ERROR);
|
||||
});
|
||||
|
||||
it('correctly calculates WATCH_STATE.CONFIG_ERROR', () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.CONFIG_ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.CONFIG_ERROR);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.DISABLED when watch is inactive`, () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = false;
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.DISABLED);
|
||||
});
|
||||
});
|
||||
|
||||
describe('downstreamJson getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
last_checked: '2017-03-02T14:25:31.139Z',
|
||||
last_met_condition: '2017-07-05T14:25:31.139Z',
|
||||
actions: {
|
||||
foo: {},
|
||||
bar: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('returns correct downstream JSON object', () => {
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.actionStatuses = [
|
||||
{ id: 'foo', state: ACTION_STATES.OK },
|
||||
{ id: 'bar', state: ACTION_STATES.OK },
|
||||
];
|
||||
|
||||
const actual = watchStatus.downstreamJson;
|
||||
|
||||
expect(actual.id).toBe(watchStatus.id);
|
||||
expect(actual.state).toBe(watchStatus.state);
|
||||
expect(actual.comment).toBe(watchStatus.comment);
|
||||
expect(actual.isActive).toBe(watchStatus.isActive);
|
||||
expect(actual.lastChecked).toBe(watchStatus.lastChecked);
|
||||
expect(actual.lastMetCondition).toBe(watchStatus.lastMetCondition);
|
||||
expect(actual.lastFired).toBe(watchStatus.lastFired);
|
||||
expect(actual.actionStatuses.length).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
|
@ -5,4 +5,4 @@
|
|||
* 2.0.
|
||||
*/
|
||||
|
||||
export { ActionStatus } from './action_status';
|
||||
export { WatchStatusModel } from './watch_status_model';
|
|
@ -7,11 +7,12 @@
|
|||
|
||||
import { get, map, forEach, maxBy } from 'lodash';
|
||||
import { badRequest } from '@hapi/boom';
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { ActionStatus } from '../action_status';
|
||||
import { ACTION_STATES, WATCH_STATES, WATCH_STATE_COMMENTS } from '../../../common/constants';
|
||||
import { i18n } from '@kbn/i18n';
|
||||
|
||||
import { ACTION_STATES, WATCH_STATES, WATCH_STATE_COMMENTS } from '../../../common/constants';
|
||||
import { getMoment } from '../../../common/lib/get_moment';
|
||||
import { ActionStatusModel } from '../action_status_model';
|
||||
|
||||
function getActionStatusTotals(watchStatus) {
|
||||
const result = {};
|
||||
|
||||
|
@ -27,7 +28,7 @@ function getActionStatusTotals(watchStatus) {
|
|||
|
||||
const WATCH_STATE_FAILED = 'failed';
|
||||
|
||||
export class WatchStatus {
|
||||
export class WatchStatusModel {
|
||||
constructor(props) {
|
||||
this.id = props.id;
|
||||
this.watchState = props.state;
|
||||
|
@ -46,7 +47,7 @@ export class WatchStatus {
|
|||
errors: this.watchErrors.actions && this.watchErrors.actions[id],
|
||||
lastCheckedRawFormat: get(this.watchStatusJson, 'last_checked'),
|
||||
};
|
||||
return ActionStatus.fromUpstreamJson(json);
|
||||
return ActionStatusModel.fromUpstreamJson(json);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -168,7 +169,7 @@ export class WatchStatus {
|
|||
);
|
||||
}
|
||||
|
||||
return new WatchStatus(json);
|
||||
return new WatchStatusModel(json);
|
||||
}
|
||||
|
||||
/*
|
|
@ -0,0 +1,313 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License
|
||||
* 2.0; you may not use this file except in compliance with the Elastic License
|
||||
* 2.0.
|
||||
*/
|
||||
|
||||
import moment from 'moment';
|
||||
|
||||
import { ACTION_STATES, WATCH_STATES, WATCH_STATE_COMMENTS } from '../../../common/constants';
|
||||
import { WatchStatusModel } from './watch_status_model';
|
||||
|
||||
describe('WatchStatusModel', () => {
|
||||
describe('fromUpstreamJson factory method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
last_checked: '2017-03-02T14:25:31.139Z',
|
||||
last_met_condition: '2017-07-05T14:25:31.139Z',
|
||||
actions: {
|
||||
foo: {},
|
||||
bar: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`throws an error if no 'id' property in json`, () => {
|
||||
delete upstreamJson.id;
|
||||
expect(() => {
|
||||
WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow(/must contain an id property/i);
|
||||
});
|
||||
|
||||
it(`throws an error if no 'watchStatusJson' property in json`, () => {
|
||||
delete upstreamJson.watchStatusJson;
|
||||
expect(() => {
|
||||
WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
}).toThrow(/must contain a watchStatusJson property/i);
|
||||
});
|
||||
|
||||
it('returns correct WatchStatus instance', () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
expect(watchStatus.id).toBe(upstreamJson.id);
|
||||
expect(watchStatus.watchStatusJson).toEqual(upstreamJson.watchStatusJson);
|
||||
expect(watchStatus.isActive).toEqual(true);
|
||||
expect(watchStatus.lastChecked).toEqual(moment(upstreamJson.watchStatusJson.last_checked));
|
||||
expect(watchStatus.lastMetCondition).toEqual(
|
||||
moment(upstreamJson.watchStatusJson.last_met_condition)
|
||||
);
|
||||
expect(watchStatus.actionStatuses.length).toBe(2);
|
||||
|
||||
expect(watchStatus.actionStatuses[0].constructor.name).toBe('ActionStatusModel');
|
||||
expect(watchStatus.actionStatuses[1].constructor.name).toBe('ActionStatusModel');
|
||||
});
|
||||
});
|
||||
|
||||
describe('lastFired getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
actions: {
|
||||
foo: {
|
||||
last_execution: {
|
||||
timestamp: '2017-07-05T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
bar: {
|
||||
last_execution: {
|
||||
timestamp: '2025-07-05T00:00:00.000Z',
|
||||
},
|
||||
},
|
||||
baz: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`returns the latest lastExecution from it's actions`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
expect(watchStatus.lastFired).toEqual(
|
||||
moment(upstreamJson.watchStatusJson.actions.bar.last_execution.timestamp)
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('comment getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.OK there are no actions`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = true;
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.OK);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.OK },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.PARTIALLY_THROTTLED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.THROTTLED`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.THROTTLED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.PARTIALLY_ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.ACKNOWLEDGED`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.ACKNOWLEDGED);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.FAILING`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.FAILING);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATE_COMMENTS.OK when watch is inactive`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = false;
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.comment).toBe(WATCH_STATE_COMMENTS.OK);
|
||||
});
|
||||
});
|
||||
|
||||
describe('state getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.OK there are no actions`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = true;
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.OK);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.FIRING`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [{ state: ACTION_STATES.OK }, { state: ACTION_STATES.FIRING }];
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.FIRING);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
];
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.FIRING);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
];
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.FIRING);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.ERROR`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.ERROR);
|
||||
});
|
||||
|
||||
it('correctly calculates WATCH_STATE.CONFIG_ERROR', () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.CONFIG_ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.CONFIG_ERROR);
|
||||
});
|
||||
|
||||
it(`correctly calculates WATCH_STATES.DISABLED when watch is inactive`, () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.isActive = false;
|
||||
|
||||
watchStatus.actionStatuses = [
|
||||
{ state: ACTION_STATES.OK },
|
||||
{ state: ACTION_STATES.FIRING },
|
||||
{ state: ACTION_STATES.THROTTLED },
|
||||
{ state: ACTION_STATES.ACKNOWLEDGED },
|
||||
{ state: ACTION_STATES.ERROR },
|
||||
];
|
||||
|
||||
expect(watchStatus.state).toBe(WATCH_STATES.DISABLED);
|
||||
});
|
||||
});
|
||||
|
||||
describe('downstreamJson getter method', () => {
|
||||
let upstreamJson;
|
||||
beforeEach(() => {
|
||||
upstreamJson = {
|
||||
id: 'my-watch',
|
||||
watchStatusJson: {
|
||||
state: {
|
||||
active: true,
|
||||
},
|
||||
last_checked: '2017-03-02T14:25:31.139Z',
|
||||
last_met_condition: '2017-07-05T14:25:31.139Z',
|
||||
actions: {
|
||||
foo: {},
|
||||
bar: {},
|
||||
},
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
it('returns correct downstream JSON object', () => {
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(upstreamJson);
|
||||
watchStatus.actionStatuses = [
|
||||
{ id: 'foo', state: ACTION_STATES.OK },
|
||||
{ id: 'bar', state: ACTION_STATES.OK },
|
||||
];
|
||||
|
||||
const actual = watchStatus.downstreamJson;
|
||||
|
||||
expect(actual.id).toBe(watchStatus.id);
|
||||
expect(actual.state).toBe(watchStatus.state);
|
||||
expect(actual.comment).toBe(watchStatus.comment);
|
||||
expect(actual.isActive).toBe(watchStatus.isActive);
|
||||
expect(actual.lastChecked).toBe(watchStatus.lastChecked);
|
||||
expect(actual.lastMetCondition).toBe(watchStatus.lastMetCondition);
|
||||
expect(actual.lastFired).toBe(watchStatus.lastFired);
|
||||
expect(actual.actionStatuses.length).toBe(2);
|
||||
});
|
||||
});
|
||||
});
|
|
@ -9,7 +9,7 @@ import { schema } from '@kbn/config-schema';
|
|||
import { get } from 'lodash';
|
||||
import { IScopedClusterClient } from '@kbn/core/server';
|
||||
// @ts-ignore
|
||||
import { WatchStatus } from '../../../../models/watch_status';
|
||||
import { WatchStatusModel } from '../../../../models/watch_status_model';
|
||||
import { RouteDependencies } from '../../../../types';
|
||||
|
||||
const paramsSchema = schema.object({
|
||||
|
@ -48,7 +48,7 @@ export function registerAcknowledgeRoute({
|
|||
watchStatusJson,
|
||||
};
|
||||
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(json);
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(json);
|
||||
return response.ok({
|
||||
body: { watchStatus: watchStatus.downstreamJson },
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IScopedClusterClient } from '@kbn/core/server';
|
|||
import { get } from 'lodash';
|
||||
import { RouteDependencies } from '../../../types';
|
||||
// @ts-ignore
|
||||
import { WatchStatus } from '../../../models/watch_status';
|
||||
import { WatchStatusModel } from '../../../models/watch_status_model';
|
||||
|
||||
function activateWatch(dataClient: IScopedClusterClient, watchId: string) {
|
||||
return dataClient.asCurrentUser.watcher.activateWatch({
|
||||
|
@ -46,7 +46,7 @@ export function registerActivateRoute({
|
|||
watchStatusJson,
|
||||
};
|
||||
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(json);
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(json);
|
||||
return response.ok({
|
||||
body: {
|
||||
watchStatus: watchStatus.downstreamJson,
|
||||
|
|
|
@ -10,7 +10,7 @@ import { IScopedClusterClient } from '@kbn/core/server';
|
|||
import { get } from 'lodash';
|
||||
import { RouteDependencies } from '../../../types';
|
||||
// @ts-ignore
|
||||
import { WatchStatus } from '../../../models/watch_status';
|
||||
import { WatchStatusModel } from '../../../models/watch_status_model';
|
||||
|
||||
const paramsSchema = schema.object({
|
||||
watchId: schema.string(),
|
||||
|
@ -46,7 +46,7 @@ export function registerDeactivateRoute({
|
|||
watchStatusJson,
|
||||
};
|
||||
|
||||
const watchStatus = WatchStatus.fromUpstreamJson(json);
|
||||
const watchStatus = WatchStatusModel.fromUpstreamJson(json);
|
||||
return response.ok({
|
||||
body: {
|
||||
watchStatus: watchStatus.downstreamJson,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue