Files
cgm-remote-monitor/tests/boluswizardpreview.test.js
T
Ben WestandCopilot 358941bba2 fix(tests): use fixed timestamp in BWP test for determinism
Replace Date.now() with the pre-captured 'now' variable in the
'set a pill to BWP with infos' test. This prevents timing drift
between when test data timestamps are set and when the sandbox
is initialized, eliminating flaky failures in CI environments.

Refs: BWP-TIME-001, GAP-TEST-001

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-03-17 13:28:12 -07:00

312 lines
9.4 KiB
JavaScript

var should = require('should');
var Stream = require('stream');
const helper = require('./inithelper')();
describe('boluswizardpreview', function ( ) {
var env = require('../lib/server/env')();
env.testMode = true;
var ctx = helper.getctx();
ctx.ddata = require('../lib/data/ddata')();
ctx.notifications = require('../lib/notifications')(env, ctx);
var boluswizardpreview = require('../lib/plugins/boluswizardpreview')(ctx);
var ar2 = require('../lib/plugins/ar2')(ctx);
var iob = require('../lib/plugins/iob')(ctx);
var bgnow = require('../lib/plugins/bgnow')(ctx);
function prepareSandbox ( ) {
var sbx = require('../lib/sandbox')().serverInit(env, ctx);
bgnow.setProperties(sbx);
ar2.setProperties(sbx);
iob.setProperties(sbx);
boluswizardpreview.setProperties(sbx);
sbx.offerProperty('direction', function setFakeDirection() {
return {value: 'FortyFiveUp', label: '↗', entity: '&#8599;'};
});
return sbx;
}
var now = Date.now();
var before = now - (5 * 60 * 1000);
var profile = {
dia: 3
, sens: 90
, target_high: 120
, target_low: 100
};
it('should calculate IOB results correctly with 0 IOB', function (done) {
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 100}, {mills: now, mgdl: 100}];
ctx.ddata.treatments = [];
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
var results = boluswizardpreview.calc(sbx);
results.effect.should.equal(0);
results.effectDisplay.should.equal(0);
results.outcome.should.equal(100);
results.outcomeDisplay.should.equal(100);
results.bolusEstimate.should.equal(0);
results.displayLine.should.equal('BWP: 0U');
done();
});
it('should calculate IOB results correctly with 1.0 U IOB', function (done) {
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 100}, {mills: now, mgdl: 100}];
ctx.ddata.treatments = [{mills: now, insulin: '1.0'}];
var profile = {
dia: 3
, sens: 50
, target_high: 100
, target_low: 50
};
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
var results = boluswizardpreview.calc(sbx);
Math.round(results.effect).should.equal(50);
results.effectDisplay.should.equal(50);
Math.round(results.outcome).should.equal(50);
results.outcomeDisplay.should.equal(50);
results.bolusEstimate.should.equal(0);
results.displayLine.should.equal('BWP: 0U');
done();
});
it('should calculate IOB results correctly with 1.0 U IOB resulting in going low', function (done) {
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 100}, {mills: now, mgdl: 100}];
ctx.ddata.treatments = [{mills: now, insulin: '1.0'}];
var profile = {
dia: 3
, sens: 50
, target_high: 200
, target_low: 100
, basal: 1
};
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
var results = boluswizardpreview.calc(sbx);
Math.round(results.effect).should.equal(50);
results.effectDisplay.should.equal(50);
Math.round(results.outcome).should.equal(50);
results.outcomeDisplay.should.equal(50);
Math.round(results.bolusEstimate).should.equal(-1);
results.displayLine.should.equal('BWP: -1.00U');
results.tempBasalAdjustment.thirtymin.should.equal(-100);
results.tempBasalAdjustment.onehour.should.equal(0);
done();
});
it('should calculate IOB results correctly with 1.0 U IOB resulting in going low in MMOL', function (done) {
// boilerplate for client sandbox running in mmol
var profileData = {
dia: 3
, units: 'mmol'
, sens: 10
, target_high: 10
, target_low: 5.6
, basal: 1
};
var sandbox = require('../lib/sandbox')();
var ctx = {
settings: {
units: 'mmol'
}
, pluginBase: {}
, moment: helper.ctx.moment
};
ctx.language = require('../lib/language')();
var data = {sgvs: [{mills: before, mgdl: 100}, {mills: now, mgdl: 100}]};
data.treatments = [{mills: now, insulin: '1.0'}];
data.devicestatus = [];
data.profile = require('../lib/profilefunctions')([profileData], ctx);
var sbx = sandbox.clientInit(ctx, Date.now(), data);
sbx.properties.iob = iob.calcTotal(data.treatments, data.devicestatus, data.profile, now);
var results = boluswizardpreview.calc(sbx);
results.effect.should.equal(10);
results.outcome.should.equal(-4.4);
results.bolusEstimate.should.equal(-1);
results.displayLine.should.equal('BWP: -1.00U');
results.tempBasalAdjustment.thirtymin.should.equal(-100);
results.tempBasalAdjustment.onehour.should.equal(0);
done();
});
it('should calculate IOB results correctly with 0.45 U IOB resulting in going low in MMOL', function (done) {
// boilerplate for client sandbox running in mmol
var profileData = {
dia: 3
, units: 'mmol'
, sens: 9
, target_high: 6
, target_low: 5
, basal: 0.125
};
var sandbox = require('../lib/sandbox')();
var ctx = {
settings: {
units: 'mmol'
}
, pluginBase: {}
, moment: helper.ctx.moment
};
ctx.language = require('../lib/language')();
var data = {sgvs: [{mills: before, mgdl: 175}, {mills: now, mgdl: 153}]};
data.treatments = [{mills: now, insulin: '0.45'}];
data.devicestatus = [];
data.profile = require('../lib/profilefunctions')([profileData], ctx);
var sbx = sandbox.clientInit(ctx, Date.now(), data);
sbx.properties.iob = iob.calcTotal(data.treatments, data.devicestatus, data.profile, now);
var results = boluswizardpreview.calc(sbx);
results.effect.should.equal(4.05);
results.outcome.should.equal(4.45);
Math.round(results.bolusEstimate*100).should.equal(-6);
results.displayLine.should.equal('BWP: -0.07U');
results.tempBasalAdjustment.thirtymin.should.equal(2);
results.tempBasalAdjustment.onehour.should.equal(51);
done();
});
it('Not trigger an alarm when in range', function (done) {
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 95}, {mills: now, mgdl: 100}];
ctx.ddata.treatments = [];
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
boluswizardpreview.checkNotifications(sbx);
should.not.exist(ctx.notifications.findHighestAlarm());
done();
});
it('trigger a warning when going out of range', function (done) {
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 175}, {mills: now, mgdl: 180}];
ctx.ddata.treatments = [];
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
boluswizardpreview.checkNotifications(sbx);
var highest = ctx.notifications.findHighestAlarm();
highest.level.should.equal(ctx.levels.WARN);
highest.title.should.equal('Warning, Check BG, time to bolus?');
highest.message.should.equal('BG Now: 180 +5 ↗ mg/dl\nBG 15m: 187 mg/dl\nBWP: 0.66U');
done();
});
it('trigger an urgent alarms when going too high', function (done) {
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 295}, {mills: now, mgdl: 300}];
ctx.ddata.treatments = [];
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
boluswizardpreview.checkNotifications(sbx);
ctx.notifications.findHighestAlarm().level.should.equal(ctx.levels.URGENT);
done();
});
it('request a snooze when there is enough IOB', function (done) {
ctx.notifications.resetStateForTests();
ctx.notifications.initRequests();
ctx.ddata.sgvs = [{mills: before, mgdl: 295}, {mills: now, mgdl: 300}];
ctx.ddata.treatments = [{mills: before, insulin: '5.0'}];
ctx.ddata.profiles = [profile];
var sbx = prepareSandbox();
//start fresh to we don't pick up other notifications
ctx.bus = new Stream;
//if notification doesn't get called test will time out
ctx.bus.on('notification', function callback (notify) {
notify.clear.should.equal(true);
if (notify.clear) {
done();
}
});
ar2.checkNotifications(sbx);
boluswizardpreview.checkNotifications(sbx);
ctx.notifications.process();
});
it('set a pill to the BWP with infos', function (done) {
// BWP-TIME-001: Use fixed timestamp for deterministic IOB calculation
// Using `now` instead of `Date.now()` prevents timing drift between
// when data timestamps are set and when sandbox is initialized
var ctx = {
settings: {}
, pluginBase: {
updatePillText: function mockedUpdatePillText(plugin, options) {
options.label.should.equal('BWP');
options.value.should.equal('0.50U');
done();
}
}
, moment: helper.ctx.moment
};
ctx.language = require('../lib/language')();
var loadedProfile = require('../lib/profilefunctions')(null, ctx);
loadedProfile.loadData([profile]);
var data = {
sgvs: [{mills: before, mgdl: 295}, {mills: now, mgdl: 300}]
, treatments: [{mills: before, insulin: '1.5'}]
, devicestatus: []
, profile: loadedProfile
};
// Use `now` (same as data timestamps) instead of Date.now() for determinism
var sbx = require('../lib/sandbox')().clientInit(ctx, now, data);
iob.setProperties(sbx);
boluswizardpreview.setProperties(sbx);
boluswizardpreview.updateVisualisation(sbx);
});
});