Files
cgm-remote-monitor/tests/openaps.test.js
T
Sulka HaroandGitHub d7e011d8f5 Refactoring organisation, bundling and security improvements (#6765)
* * Simplified bundling to just one bundle
* Removed cache invalidation token from bundling
* Generate strong persistent random string on deploy to use for JWT signing
* WIP: moving api-secret and JWT signing to a separate centralized security component
* Moved some server components away from project root
* Fix issues reported by linter

* Ignore detect-object-injection everywhere but the client

* Make admin message button red

* Remove alarms for some security alerts on code

* api_secret is now fully contained in the enclave
2021-02-02 19:53:30 +02:00

408 lines
11 KiB
JavaScript

'use strict';
const _ = require('lodash');
const should = require('should');
const moment = require('moment');
const fs = require('fs');
const language = require('../lib/language')(fs);
var top_ctx = {
language: language
, settings: require('../lib/settings')()
};
top_ctx.language.set('en');
var levels = require('../lib/levels');
top_ctx.levels = levels;
var env = require('../lib/server/env')();
var openaps = require('../lib/plugins/openaps')(top_ctx);
var sandbox = require('../lib/sandbox')(top_ctx);
var statuses = [{
created_at: '2015-12-05T19:05:00.000Z',
device: 'openaps://abusypi'
, pump: {
battery: {
status: 'normal',
voltage: 1.52
},
status: {
status: 'normal',
timestamp: '2015-12-05T18:59:37.000Z',
bolusing: false,
suspended: false
},
reservoir: 86.4,
clock: '2015-12-05T10:58:47-08:00'
},
mmtune: {
scanDetails: [
['916.640',4,-64]
, ['916.660',5,-55]
, ['916.680',5,-59]
]
, setFreq: 916.66
, timestamp:' 2015-12-05T18:59:37.000Z'
, usedDefault: false
},
openaps: {
suggested: {
bg: 147,
temp: 'absolute',
snoozeBG: 125,
timestamp: '2015-12-05T19:02:42.000Z',
rate: 0.75,
reason: 'Eventual BG 125>120, no temp, setting 0.75U/hr',
eventualBG: 125,
duration: 30,
tick: '+1'
},
iob: {
timestamp: '2015-12-05T19:02:42.000Z',
bolusiob: 0,
iob: 0.6068340736133333,
activity: 0.016131569664902996
},
enacted: {
bg: 147,
temp: 'absolute',
snoozeBG: 125,
recieved: true,
reason: 'Eventual BG 125>120, no temp, setting 0.75U/hr',
rate: 0.75,
eventualBG: 125,
timestamp: '2015-12-05T19:03:00.000Z',
duration: 30,
tick: '+1',
predBGs: {
IOB: [100, 100, 100, 100]
, aCOB: [100, 100, 100, 100]
, COB: [100, 100, 100, 100]
}
}
}
}
, {
created_at: '2015-12-05T18:05:00.000Z',
device: 'openaps://awaitingpi'
, pump: {
battery: {
status: 'normal',
voltage: 1.52
},
status: {
status: 'normal',
timestamp: '2015-12-05T16:59:37.000Z',
bolusing: false,
suspended: false
},
reservoir: 86.4,
clock: '2015-12-05T08:58:47-08:00'
},
openaps: {
suggested: {
bg: 147,
temp: 'absolute',
snoozeBG: 125,
timestamp: '2015-12-05T16:02:42.000Z',
rate: 0.75,
reason: 'Eventual BG 125>120, no temp, setting 0.75U/hr',
eventualBG: 125,
duration: 30,
tick: '+1'
},
iob: {
timestamp: '2015-12-05T16:02:42.000Z',
bolusiob: 0,
iob: 0.6068340736133333,
activity: 0.016131569664902996
},
enacted: {
bg: 147,
temp: 'absolute',
snoozeBG: 125,
recieved: true,
reason: 'Eventual BG 125>120, no temp, setting 0.75U/hr',
rate: 0.75,
eventualBG: 125,
timestamp: '2015-12-05T16:03:00.000Z',
duration: 30,
tick: '+1'
}
}
}
,{
"_id": {
"$oid": "59aef8cb444d1500109fc8fd"
},
"device": "openaps://edi1",
"openaps": {
"iob": {
"iob": 1.016,
"activity": 0.0143,
"bolussnooze": 0,
"basaliob": 0.893,
"netbasalinsulin": 0.7,
"hightempinsulin": 2.5,
"microBolusInsulin": 1.7,
"microBolusIOB": 0.933,
"lastBolusTime": 1504638182000,
"timestamp": "2017-09-05T19:18:31.000Z"
},
"suggested": {
"insulinReq": -0.06,
"bg": 117,
"reservoir": "104.5",
"temp": "absolute",
"snoozeBG": 80,
"rate": 0.75,
"minPredBG": 78,
"IOB": 1.016,
"reason": "COB: 0, Dev: -6, BGI: -2.22, ISF: 31, Target: 80, minPredBG 78, IOBpredBG 78; Eventual BG 80 >= 80, insulinReq -0.06. temp 0.2<0.75U/hr. ",
"COB": 0,
"eventualBG": 80,
"duration": 30,
"tick": -3,
"deliverAt": "2017-09-05T19:18:43.563Z",
"timestamp": "2017-09-05T19:18:43.000Z"
},
"enacted": {
"insulinReq": -0.06,
"received": true,
"bg": 117,
"reservoir": "104.5",
"temp": "absolute",
"snoozeBG": 80,
"timestamp": "2017-09-05T19:18:49.000Z",
"predBGs": {
"IOB": [
117,
114,
111,
108,
106,
104,
102,
100,
98,
97,
96,
95,
94,
93,
92,
91,
90,
89,
88,
87,
86,
86,
85,
84,
83,
83,
82,
81,
81,
81,
80,
80,
79,
79,
79,
79,
78
]
},
"minPredBG": 78,
"deliverAt": "2017-09-05T19:18:43.563Z",
"duration": 30,
"rate": 0.75,
"COB": 0,
"eventualBG": 80,
"reason": "COB: 0, Dev: -6, BGI: -2.22, ISF: 31, Target: 80, minPredBG 78, IOBpredBG 78; Eventual BG 80 >= 80, insulinReq -0.06. temp 0.2<0.75U/hr. ",
"tick": -3,
"IOB": 1.016
}
},
"pump": {
"clock": "2017-09-05T21:18:31+02:00",
"battery": {
"status": "normal",
"voltage": 1.55
},
"reservoir": 104.5,
"status": {
"status": "normal",
"bolusing": false,
"suspended": false,
"timestamp": "2017-09-05T19:18:29.000Z"
}
},
"uploader": {
"batteryVoltage": 4131,
"battery": 95
},
"created_at": "2017-09-05T19:19:39.899Z"
}];
var now = moment(statuses[0].created_at);
_.forEach(statuses, function updateMills (status) {
status.mills = moment(status.created_at).valueOf();
});
describe('openaps', function ( ) {
it('set the property and update the pill and add forecast points', function (done) {
var ctx = {
settings: {
units: 'mg/dl'
}
, pluginBase: {
updatePillText: function mockedUpdatePillText (plugin, options) {
options.label.should.equal('OpenAPS ⌁');
options.value.should.equal('2m ago');
var first = _.first(options.info);
first.label.should.equal('1m ago');
first.value.should.equal('abusypi ⌁ Enacted @ -55dB');
var last = _.last(options.info);
last.label.should.equal('1h ago');
last.value.should.equal('awaitingpi ◉ Waiting');
}
, addForecastPoints: function mockAddForecastPoints (points) {
points.length.should.equal(12);
done();
}
}
, language: language
};
var sbx = sandbox.clientInit(ctx, now.valueOf(), {devicestatus: statuses});
var unmockedOfferProperty = sbx.offerProperty;
sbx.offerProperty = function mockedOfferProperty (name, setter) {
name.should.equal('openaps');
var result = setter();
should.exist(result);
result.status.symbol.should.equal('⌁');
result.status.code.should.equal('enacted');
sbx.offerProperty = unmockedOfferProperty;
unmockedOfferProperty(name, setter);
};
openaps.setProperties(sbx);
openaps.updateVisualisation(sbx);
});
it('check the recieved flag to see if it was received', function (done) {
var ctx = {
settings: {
units: 'mg/dl'
}
, notifications: require('../lib/notifications')(env, top_ctx)
, language: language
, levels: levels
};
ctx.notifications.initRequests();
var notStatuses = _.cloneDeep(statuses);
notStatuses[0].openaps.enacted.recieved = false;
var sbx = require('../lib/sandbox')().clientInit(ctx, now, {devicestatus: notStatuses});
sbx.offerProperty = function mockedOfferProperty (name, setter) {
name.should.equal('openaps');
var result = setter();
should.exist(result);
result.status.symbol.should.equal('x');
result.status.code.should.equal('notenacted');
done();
};
openaps.setProperties(sbx);
});
it('generate an alert for a stuck loop', function (done) {
var ctx = {
settings: {
units: 'mg/dl'
}
, notifications: require('../lib/notifications')(env, top_ctx)
, language: language
};
ctx.notifications.initRequests();
var sbx = sandbox.clientInit(ctx, now.clone().add(1, 'hours').valueOf(), {devicestatus: statuses});
sbx.extendedSettings = { 'enableAlerts': 'TRUE' };
openaps.setProperties(sbx);
openaps.checkNotifications(sbx);
var highest = ctx.notifications.findHighestAlarm('OpenAPS');
highest.level.should.equal(levels.URGENT);
highest.title.should.equal('OpenAPS isn\'t looping');
done();
});
it('not generate an alert for a stuck loop, when there is an offline marker', function (done) {
var ctx = {
settings: {
units: 'mg/dl'
}
, notifications: require('../lib/notifications')(env, top_ctx)
, language: language
};
ctx.notifications.initRequests();
var sbx = sandbox.clientInit(ctx, now.clone().add(1, 'hours').valueOf(), {
devicestatus: statuses
, treatments: [{eventType: 'OpenAPS Offline', mills: now.valueOf(), duration: 60}]
});
sbx.extendedSettings = { 'enableAlerts': 'TRUE' };
openaps.setProperties(sbx);
openaps.checkNotifications(sbx);
var highest = ctx.notifications.findHighestAlarm('OpenAPS');
should.not.exist(highest);
done();
});
it('should handle virtAsst requests', function (done) {
var ctx = {
settings: {
units: 'mg/dl'
}
, notifications: require('../lib/notifications')(env, top_ctx)
, language: language
};
var sbx = sandbox.clientInit(ctx, now.valueOf(), {devicestatus: statuses});
openaps.setProperties(sbx);
openaps.virtAsst.intentHandlers.length.should.equal(2);
openaps.virtAsst.intentHandlers[0].intentHandler(function next(title, response) {
title.should.equal('OpenAPS Forecast');
response.should.equal('The OpenAPS Eventual BG is 125');
openaps.virtAsst.intentHandlers[1].intentHandler(function next(title, response) {
title.should.equal('Last Loop');
response.should.equal('The last successful loop was 2 minutes ago');
done();
}, [], sbx);
}, [], sbx);
});
});