From b2a59ee9dc66e6360c3342066a6c1657ceee171c Mon Sep 17 00:00:00 2001 From: Ben West Date: Wed, 18 Oct 2023 10:38:10 -0700 Subject: [PATCH 1/3] create next dev area post release --- package-lock.json | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package-lock.json b/package-lock.json index 53146c954f6..6a55fe2b8a4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "15.0.0", + "version": "15.0.1", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/package.json b/package.json index 9c192b7de8a..a2a3d183e54 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "nightscout", - "version": "15.0.0", + "version": "15.0.1", "description": "Nightscout acts as a web-based CGM (Continuous Glucose Montinor) to allow multiple caregivers to remotely view a patients glucose data in realtime.", "license": "AGPL-3.0", "author": "Nightscout Team", From 2e65b1dd9b9fc8bdfafa2aebf8cff137d0fde2a8 Mon Sep 17 00:00:00 2001 From: Ben West Date: Thu, 19 Oct 2023 13:03:38 -0700 Subject: [PATCH 2/3] Revert "Merge pull request #8026 from nightscout/less_frequent_db_updates" This reverts commit 2757fe585d51dbf6972f26a89291593bee476df3, reversing changes made to 4a461e58901e05a0346295091983641f7f7246ca. --- lib/api/activity/index.js | 2 +- lib/api/food/index.js | 2 +- lib/api/profile/index.js | 2 +- lib/api3/storage/mongoCollection/modify.js | 4 +- lib/api3/storage/mongoCollection/utils.js | 6 +- lib/authorization/storage.js | 21 +-- lib/client/index.js | 2 +- lib/server/activity.js | 4 +- lib/server/bootevent.js | 20 ++- lib/server/devicestatus.js | 19 +- lib/server/entries.js | 16 +- lib/server/food.js | 4 +- lib/server/profile.js | 4 +- lib/server/query.js | 2 +- lib/server/treatments.js | 24 +-- lib/server/websocket.js | 12 +- lib/storage/mongo-storage.js | 7 +- lib/storage/openaps-storage.js | 191 +++++++++++++++++++++ package-lock.json | 186 ++++++++++---------- package.json | 4 +- tests/XX_clean.test.js | 4 +- tests/api.entries.test.js | 6 +- tests/api.treatments.test.js | 10 +- tests/api.unauthorized.test.js | 4 +- tests/openaps-storage.test.js | 115 +++++++++++++ 25 files changed, 477 insertions(+), 194 deletions(-) create mode 100644 lib/storage/openaps-storage.js create mode 100644 tests/openaps-storage.test.js diff --git a/lib/api/activity/index.js b/lib/api/activity/index.js index ca1f7572ca6..7d67926b4d0 100644 --- a/lib/api/activity/index.js +++ b/lib/api/activity/index.js @@ -88,7 +88,7 @@ function configure(app, wares, ctx) { api.post('/activity/', ctx.authorization.isPermitted('api:activity:create'), post_response); api.delete('/activity/:_id', ctx.authorization.isPermitted('api:activity:delete'), function(req, res) { - ctx.activity.deleteOne(req.params._id, function() { + ctx.activity.remove(req.params._id, function() { res.json({}); }); }); diff --git a/lib/api/food/index.js b/lib/api/food/index.js index fbd56ceefd8..5db962db403 100644 --- a/lib/api/food/index.js +++ b/lib/api/food/index.js @@ -71,7 +71,7 @@ function configure (app, wares, ctx) { }); // delete record api.delete('/food/:_id', ctx.authorization.isPermitted('api:food:delete'), function(req, res) { - ctx.food.deleteOne(req.params._id, function ( ) { + ctx.food.remove(req.params._id, function ( ) { res.json({ }); }); }); diff --git a/lib/api/profile/index.js b/lib/api/profile/index.js index 9b6e1960a1a..57cce59e69a 100644 --- a/lib/api/profile/index.js +++ b/lib/api/profile/index.js @@ -92,7 +92,7 @@ function configure (app, wares, ctx) { }); api.delete('/profile/:_id', ctx.authorization.isPermitted('api:profile:delete'), function(req, res) { - ctx.profile.deleteOne(req.params._id, function ( ) { + ctx.profile.remove(req.params._id, function ( ) { res.json({ }); }); }); diff --git a/lib/api3/storage/mongoCollection/modify.js b/lib/api3/storage/mongoCollection/modify.js index 20b4013d206..7183f1c971a 100644 --- a/lib/api3/storage/mongoCollection/modify.js +++ b/lib/api3/storage/mongoCollection/modify.js @@ -69,7 +69,7 @@ function updateOne (col, identifier, setFields) { if (err) { reject(err); } else { - resolve({ updated: result.modifiedCount }); + resolve({ updated: result.result.nModified }); } }); }); @@ -91,7 +91,7 @@ function deleteOne (col, identifier) { if (err) { reject(err); } else { - resolve({ deleted: result.deletedCount }); + resolve({ deleted: result.result.n }); } }); }); diff --git a/lib/api3/storage/mongoCollection/utils.js b/lib/api3/storage/mongoCollection/utils.js index 094d663ca24..a2f7b16520c 100644 --- a/lib/api3/storage/mongoCollection/utils.js +++ b/lib/api3/storage/mongoCollection/utils.js @@ -2,7 +2,7 @@ const _ = require('lodash') , checkForHexRegExp = new RegExp("^[0-9a-fA-F]{24}$") - , ObjectID = require('mongodb-legacy').ObjectId + , ObjectID = require('mongodb').ObjectID ; @@ -112,7 +112,7 @@ function filterForOne (identifier) { // fallback to "identifier = _id" if (checkForHexRegExp.test(identifier)) { - filterOpts.push({ _id: new ObjectID(identifier) }); + filterOpts.push({ _id: ObjectID(identifier) }); } return { $or: filterOpts }; @@ -137,7 +137,7 @@ function identifyingFilter (identifier, doc, dedupFallbackFields) { // fallback to "identifier = _id" (APIv1) if (checkForHexRegExp.test(identifier)) { - filterItems.push({ identifier: { $exists: false }, _id: new ObjectID(identifier) }); + filterItems.push({ identifier: { $exists: false }, _id: ObjectID(identifier) }); } } diff --git a/lib/authorization/storage.js b/lib/authorization/storage.js index c119cd7e1cd..614f8c78051 100644 --- a/lib/authorization/storage.js +++ b/lib/authorization/storage.js @@ -3,7 +3,7 @@ var _ = require('lodash'); var crypto = require('crypto'); var shiroTrie = require('shiro-trie'); -var ObjectID = require('mongodb-legacy').ObjectId; +var ObjectID = require('mongodb').ObjectID; var find_options = require('../server/query'); @@ -27,14 +27,14 @@ function init (env, ctx) { if (!Object.prototype.hasOwnProperty.call(obj, 'created_at')) { obj.created_at = (new Date()).toISOString(); } - collection.insertOne(obj, function (err, doc) { + collection.insert(obj, function (err, doc) { if (err != null && err.message) { console.log('Data insertion error', err.message); fn(err.message, null); return; } storage.reload(function loaded() { - fn(null, obj); + fn(null, doc.ops); }); }); } @@ -42,7 +42,7 @@ function init (env, ctx) { } function list (collection) { - function doList(opts, fn) { + function doList(opts, fn) { // these functions, find, sort, and limit, are used to // dynamically configure the request, based on the options we've // been given @@ -65,8 +65,6 @@ function init (env, ctx) { fn(err, entries); } - console.log('Loading',opts); - // now just stitch them all together limit.call(collection .find(query_for(opts)) @@ -79,7 +77,7 @@ function init (env, ctx) { function remove (collection) { function doRemove (_id, callback) { - collection.deleteOne({ '_id': new ObjectID(_id) }, function (err) { + collection.remove({ '_id': new ObjectID(_id) }, function (err) { storage.reload(function loaded() { callback(err, null); }); @@ -94,7 +92,7 @@ function init (env, ctx) { if (!obj.created_at) { obj.created_at = (new Date()).toISOString(); } - collection.insertOne(obj, function (err) { + collection.save(obj, function (err) { //id should be added for new docs storage.reload(function loaded() { callback(err, obj); @@ -137,14 +135,8 @@ function init (env, ctx) { storage.reload = function reload (callback) { - console.log('Reloading auth data'); - storage.listRoles({sort: {name: 1}}, function listResults (err, results) { - - console.log('Roles listed'); - if (err) { - console.log('Problem listing roles', err); return callback && callback(err); } @@ -160,7 +152,6 @@ function init (env, ctx) { storage.listSubjects({sort: {name: 1}}, function listResults (err, results) { if (err) { - console.log('Problem listing subjects', err); return callback && callback(err); } diff --git a/lib/client/index.js b/lib/client/index.js index 5d08e34616e..0f0d17b7d64 100644 --- a/lib/client/index.js +++ b/lib/client/index.js @@ -68,7 +68,7 @@ client.init = function init (callback) { }).done(function success (serverSettings) { if (serverSettings.runtimeState !== 'loaded') { console.log('Server is still loading data'); - $('#loadingMessageText').html('Nightscout is still starting and should be available within about 15 seconds.'); + $('#loadingMessageText').html('Server is starting and still loading data, retrying load in 5 seconds'); window.setTimeout(window.Nightscout.client.init, 5000); return; } diff --git a/lib/server/activity.js b/lib/server/activity.js index 7be7d3d1581..45b77e60587 100644 --- a/lib/server/activity.js +++ b/lib/server/activity.js @@ -4,7 +4,7 @@ var find_options = require('./query'); function storage (env, ctx) { - var ObjectID = require('mongodb-legacy').ObjectId; + var ObjectID = require('mongodb').ObjectID; function create (obj, fn) { obj.created_at = (new Date( )).toISOString( ); @@ -62,7 +62,7 @@ function storage (env, ctx) { function remove (_id, fn) { var objId = new ObjectID(_id); - return api( ).deleteOne({ '_id': objId }, fn); + return api( ).remove({ '_id': objId }, fn); } function api ( ) { diff --git a/lib/server/bootevent.js b/lib/server/bootevent.js index 61a6149a43d..b377abcce98 100644 --- a/lib/server/bootevent.js +++ b/lib/server/bootevent.js @@ -1,15 +1,13 @@ 'use strict'; const _ = require('lodash'); -const UPDATE_THROTTLE = 15000; +const UPDATE_THROTTLE = 5000; function boot (env, language) { function startBoot(ctx, next) { - console.log('++++++++++++++++++++++++++++++'); - console.log('Nightscout Executing startBoot'); - console.log('++++++++++++++++++++++++++++++'); + console.log('Executing startBoot'); ctx.bootErrors = [ ]; ctx.moment = require('moment-timezone'); @@ -40,7 +38,7 @@ function boot (env, language) { const isLTS = process.release.lts ? true : false; - if (isLTS || (semver.satisfies(nodeVersion, '^20.0.0') || semver.satisfies(nodeVersion, '^18.0.0') || semver.satisfies(nodeVersion, '^16.0.0') || semver.satisfies(nodeVersion, '^14.0.0'))) { + if (isLTS && (semver.satisfies(nodeVersion, '^20.0.0') || semver.satisfies(nodeVersion, '^18.0.0') || semver.satisfies(nodeVersion, '^16.0.0') || semver.satisfies(nodeVersion, '^14.0.0'))) { //Latest Node 14 LTS and Node 16 LTS are recommended and supported. //Require at least Node 14 without known security issues console.debug('Node LTS version ' + nodeVersion + ' is supported'); @@ -150,6 +148,16 @@ function boot (env, language) { } try { + if (_.startsWith(env.storageURI, 'openaps://')) { + require('../storage/openaps-storage')(env, function ready (err, store) { + if (err) { + throw err; + } + ctx.store = store; + console.log('OpenAPS Storage system ready'); + next(); + }); + } else { //TODO assume mongo for now, when there are more storage options add a lookup require('../storage/mongo-storage')(env, function ready(err, store) { // FIXME, error is always null, if there is an error, the index.js will throw an exception @@ -162,6 +170,7 @@ function boot (env, language) { ctx.store = store; next(); }); + } } catch (err) { console.info('ERROR CONNECTING TO MONGO', err); ctx.bootErrors = ctx.bootErrors || [ ]; @@ -286,7 +295,6 @@ function boot (env, language) { ctx.bus.on('data-received', function forceReloadData ( ) { console.info('got data-received event, requesting reload'); - ctx.bus.emit('data-loaded'); // Since we update local sandbox instantly, process data-loaded right away in case this gets debounced updateData(); }); diff --git a/lib/server/devicestatus.js b/lib/server/devicestatus.js index 0bde778a6a6..bf71437d646 100644 --- a/lib/server/devicestatus.js +++ b/lib/server/devicestatus.js @@ -24,16 +24,16 @@ function storage (collection, ctx) { obj.utcOffset = d.utcOffset(); api().insertOne(obj, function(err, results) { - - if (err) { + if (err !== null && err.message) { console.log('Error inserting the device status object', err.message); errorOccurred = true; fn(err.message, null); return; } - if (results) { - if (!obj._id) obj._id = results.insertedId; + if (!err) { + + if (!obj._id) obj._id = results.insertedIds[0]._id; r.push(obj); ctx.bus.emit('data-update', { @@ -47,11 +47,6 @@ function storage (collection, ctx) { fn(null, r); ctx.bus.emit('data-received'); } - } else { - console.log('Error inserting the device status object', err.message); - errorOccurred = true; - fn(err.message, null); - return; } }); }; @@ -105,19 +100,17 @@ function storage (collection, ctx) { function removed (err, stat) { - console.log('removed', err, stat); - ctx.bus.emit('data-update', { type: 'devicestatus' , op: 'remove' - , count: stat.deletedCount + , count: stat.result.n , changes: opts.find._id }); fn(err, stat); } - return api().deleteMany( + return api().remove( query_for(opts), removed); } diff --git a/lib/server/entries.js b/lib/server/entries.js index 0fbe46acca4..7e6ac90d35f 100644 --- a/lib/server/entries.js +++ b/lib/server/entries.js @@ -2,7 +2,7 @@ var es = require('event-stream'); var find_options = require('./query'); -var ObjectId = require('mongodb-legacy').ObjectId; +var ObjectID = require('mongodb').ObjectID; var moment = require('moment'); /**********\ @@ -46,12 +46,12 @@ function storage (env, ctx) { } function remove (opts, fn) { - api().deleteMany(query_for(opts), function(err, stat) { + api().remove(query_for(opts), function(err, stat) { ctx.bus.emit('data-update', { type: 'entries' , op: 'remove' - , count: stat.deletedCount + , count: stat.result.n , changes: opts.find._id }); @@ -110,12 +110,12 @@ function storage (env, ctx) { if (doc.dateString) doc.dateString = doc.sysTime; var query = (doc.sysTime && doc.type) ? { sysTime: doc.sysTime, type: doc.type } : doc; - api().replaceOne(query, doc, { upsert: true }, function(err, updateResults) { + api().update(query, doc, { upsert: true }, function(err, updateResults) { firstErr = firstErr || err; - if (updateResults) { - if (updateResults.upsertedCount == 1) { - doc._id = updateResults.upsertedId + if (!err) { + if (updateResults.result.upserted) { + doc._id = updateResults.result.upserted[0]._id } ctx.bus.emit('data-update', { @@ -135,7 +135,7 @@ function storage (env, ctx) { } function getEntry (id, fn) { - api().findOne({ "_id": new ObjectId(id) }, function(err, entry) { + api().findOne({ _id: ObjectID(id) }, function(err, entry) { if (err) { fn(err); } else { diff --git a/lib/server/food.js b/lib/server/food.js index 8076ad5aa7a..92c41843f7b 100644 --- a/lib/server/food.js +++ b/lib/server/food.js @@ -1,7 +1,7 @@ 'use strict'; function storage (env, ctx) { - var ObjectID = require('mongodb-legacy').ObjectId; + var ObjectID = require('mongodb').ObjectID; function create (obj, fn) { obj.created_at = (new Date( )).toISOString( ); @@ -42,7 +42,7 @@ function storage (env, ctx) { function remove (_id, fn) { var objId = new ObjectID(_id); - return api( ).deleteOne({ '_id': objId }, fn); + return api( ).remove({ '_id': objId }, fn); } diff --git a/lib/server/profile.js b/lib/server/profile.js index 6f5b2b96194..e49e366d15a 100644 --- a/lib/server/profile.js +++ b/lib/server/profile.js @@ -4,7 +4,7 @@ var find_options = require('./query'); var consts = require('../constants'); function storage (collection, ctx) { - var ObjectID = require('mongodb-legacy').ObjectId; + var ObjectID = require('mongodb').ObjectID; function create (obj, fn) { obj.created_at = (new Date( )).toISOString( ); @@ -79,7 +79,7 @@ function storage (collection, ctx) { function remove (_id, fn) { var objId = new ObjectID(_id); - api( ).deleteOne({ '_id': objId }, fn); + api( ).remove({ '_id': objId }, fn); ctx.bus.emit('data-received'); } diff --git a/lib/server/query.js b/lib/server/query.js index 0e9750ad562..8279d5ad1e8 100644 --- a/lib/server/query.js +++ b/lib/server/query.js @@ -1,7 +1,7 @@ 'use strict'; const traverse = require('traverse'); -const ObjectID = require('mongodb-legacy').ObjectId; +const ObjectID = require('mongodb').ObjectID; const moment = require('moment'); const TWO_DAYS = 172800000; diff --git a/lib/server/treatments.js b/lib/server/treatments.js index 687d7cfd914..a9107ea99b2 100644 --- a/lib/server/treatments.js +++ b/lib/server/treatments.js @@ -6,7 +6,7 @@ var moment = require('moment'); var find_options = require('./query'); function storage (env, ctx) { - var ObjectID = require('mongodb-legacy').ObjectId; + var ObjectID = require('mongodb').ObjectID; function create (objOrArray, fn) { @@ -46,18 +46,18 @@ function storage (env, ctx) { , eventType: obj.eventType }; - api( ).replaceOne(query, obj, {upsert: true}, function complete (err, updateResults) { + api( ).update(query, obj, {upsert: true}, function complete (err, updateResults) { if (err) console.error('Problem upserting treatment', err); - if (updateResults) { - if (updateResults.upsertedCount == 1) { - obj._id = updateResults.upsertedId + if (!err) { + if (updateResults.result.upserted) { + obj._id = updateResults.result.upserted[0]._id } } // TODO document this feature - if (updateResults && obj.preBolus) { + if (!err && obj.preBolus) { //create a new object to insert copying only the needed fields var pbTreat = { created_at: (new Date(new Date(results.created_at).getTime() + (obj.preBolus * 60000))).toISOString(), @@ -70,11 +70,11 @@ function storage (env, ctx) { } query.created_at = pbTreat.created_at; - api( ).replaceOne(query, pbTreat, {upsert: true}, function pbComplete (err, updateResults) { + api( ).update(query, pbTreat, {upsert: true}, function pbComplete (err, updateResults) { - if (updateResults) { - if (updateResults.upsertedCount == 1) { - pbTreat._id = updateResults.upsertedId + if (!err) { + if (updateResults.result.upserted) { + pbTreat._id = updateResults.result.upserted[0]._id } } @@ -122,14 +122,14 @@ function storage (env, ctx) { } function remove (opts, fn) { - return api( ).deleteMany(query_for(opts), {}, function (err, stat) { + return api( ).remove(query_for(opts), function (err, stat) { //TODO: this is triggering a read from Mongo, we can do better //console.log('Treatment removed', opts); // , stat); ctx.bus.emit('data-update', { type: 'treatments', op: 'remove', - count: stat.deletedCount, + count: stat.result.n, changes: opts.find._id }); diff --git a/lib/server/websocket.js b/lib/server/websocket.js index b3ad9df59af..2924db0554d 100644 --- a/lib/server/websocket.js +++ b/lib/server/websocket.js @@ -2,7 +2,7 @@ var times = require('../times'); var calcData = require('../data/calcdelta'); -var ObjectID = require('mongodb-legacy').ObjectId; +var ObjectID = require('mongodb').ObjectID; const forwarded = require('forwarded-for'); function getRemoteIP (req) { @@ -220,7 +220,7 @@ function init (env, ctx, server) { id = new ObjectID(); } - ctx.store.collection(collection).updateOne({ '_id': id } + ctx.store.collection(collection).update({ '_id': id } , { $set: data.data } , function(err, results) { @@ -268,7 +268,7 @@ function init (env, ctx, server) { } var objId = new ObjectID(data._id); - ctx.store.collection(collection).updateOne({ '_id': objId }, { $unset: data.data } + ctx.store.collection(collection).update({ '_id': objId }, { $unset: data.data } , function(err, results) { if (!err) { @@ -394,7 +394,7 @@ function init (env, ctx, server) { console.log(LOG_DEDUP + 'Found similiar', array[0]); array[0].created_at = data.data.created_at; var objId = new ObjectID(array[0]._id); - ctx.store.collection(collection).updateOne({ '_id': objId }, { $set: { created_at: data.data.created_at } }); + ctx.store.collection(collection).update({ '_id': objId }, { $set: { created_at: data.data.created_at } }); if (callback) { callback([array[0]]); } @@ -506,14 +506,14 @@ function init (env, ctx, server) { } var objId = new ObjectID(data._id); - ctx.store.collection(collection).deleteOne({ '_id': objId } + ctx.store.collection(collection).remove({ '_id': objId } , function(err, stat) { if (!err) { ctx.bus.emit('data-update', { type: data.collection , op: 'remove' - , count: stat.deletedCount + , count: stat.result.n , changes: data._id }); diff --git a/lib/storage/mongo-storage.js b/lib/storage/mongo-storage.js index 1175cb0d81a..987e41ef67d 100644 --- a/lib/storage/mongo-storage.js +++ b/lib/storage/mongo-storage.js @@ -1,6 +1,6 @@ 'use strict'; -const MongoClient = require('mongodb-legacy').MongoClient; +const MongoClient = require('mongodb').MongoClient; const mongo = { client: null, @@ -82,11 +82,10 @@ function init(env, cb, forceNewConnection) { mongo.ensureIndexes = function ensureIndexes(collection, fields) { fields.forEach(function (field) { - const name = collection.collectionName + "." + field; - console.info('ensuring index for: ' + name); + console.info('ensuring index for: ' + field); collection.createIndex(field, { 'background': true }, function (err) { if (err) { - console.error('unable to ensureIndex for: ' + name + ' - ' + err); + console.error('unable to ensureIndex for: ' + field + ' - ' + err); } }); }); diff --git a/lib/storage/openaps-storage.js b/lib/storage/openaps-storage.js new file mode 100644 index 00000000000..0c9c238015e --- /dev/null +++ b/lib/storage/openaps-storage.js @@ -0,0 +1,191 @@ +'use strict'; + +var _ = require('lodash'); +var fs = require('fs'); +var crypto = require('crypto'); +var MongoMock = require('mongomock'); + +var config = { + collections: {} +}; + +function init (env, callback) { + + if (!env.storageURI || !_.isString(env.storageURI)) { + throw new Error('openaps config uri is missing or invalid'); + } + + var configPath = env.storageURI.split('openaps://').pop(); + + function addId (data) { + var shasum = crypto.createHash('sha1'); + shasum.update(JSON.stringify(data)); + data._id = shasum.digest('hex'); + } + + function loadData (path) { + + if (!path || !_.isString(path)) { + return [ ]; + } + + try { + purgeCache(path); + var inputData = require(path); + if (_.isArray(inputData)) { + //console.info('>>>input is an array', path); + _.forEach(inputData, addId); + } else if (!_.isEmpty(inputData) && _.isObject(inputData)) { + //console.info('>>>input is an object', path); + inputData.created_at = new Date(fs.statSync(path).mtime).toISOString(); + addId(inputData); + inputData = [ inputData ]; + } else { + //console.info('>>>input is something else', path, inputData); + inputData = [ ]; + } + + return inputData; + } catch (err) { + console.error('unable to find input data for', path, err); + return [ ]; + } + + } + + function reportAsCollection (name) { + var data = { }; + var input = _.get(config, 'collections.' + name + '.input'); + + if (_.isArray(input)) { + //console.info('>>>input is an array', input); + data[name] = _.flatten(_.map(input, loadData)); + } else { + data[name] = loadData(input); + } + + var mock = new MongoMock(data); + + var collection = mock.collection(name); + + var wrapper = { + findQuery: null + , sortQuery: null + , limitCount: null + , find: function find (query) { + query = _.cloneDeepWith(query, function booleanize (value) { + //TODO: for some reason we're getting {$exists: NaN} instead of true/false + if (value && _.isObject(value) && '$exists' in value) { + return {$exists: true}; + } + }); + wrapper.findQuery = query; + return wrapper; + } + , limit: function limit (count) { + wrapper.limitCount = count; + return wrapper; + } + , sort: function sort (query) { + wrapper.sortQuery = query; + return wrapper; + } + , toArray: function toArray(callback) { + collection.find(wrapper.findQuery).toArray(function intercept (err, results) { + if (err) { + return callback(err, results); + } + + if (wrapper.sortQuery) { + var field = _.keys(wrapper.sortQuery).pop(); + //console.info('>>>sortField', field); + if (field) { + results = _.sortBy(results, field); + if (-1 === wrapper.sortQuery[field]) { + //console.info('>>>sort reverse'); + results = _.reverse(results); + } + } + } + + if (wrapper.limitCount !== null && _.isNumber(wrapper.limitCount)) { + //console.info('>>>limit count', wrapper.limitCount); + results = _.take(results, wrapper.limitCount); + } + + //console.info('>>>toArray', name, wrapper.findQuery, wrapper.sortQuery, wrapper.limitCount, results.length); + + callback(null, results); + }); + return wrapper; + } + }; + + return wrapper; + + } + + try { + var customConfig = require(configPath); + + config = _.merge({}, customConfig, config); + + callback(null, { + collection: reportAsCollection + , ensureIndexes: _.noop + }); + } catch (err) { + callback(err); + } +} + +/** + * Removes a module from the cache + * + * see http://stackoverflow.com/a/14801711 + */ +function purgeCache(moduleName) { + // Traverse the cache looking for the files + // loaded by the specified module name + searchCache(moduleName, function (mod) { + delete require.cache[mod.id]; + }); + + // Remove cached paths to the module. + // Thanks to @bentael for pointing this out. + Object.keys(module.constructor._pathCache).forEach(function(cacheKey) { + if (cacheKey.indexOf(moduleName)>0) { + delete module.constructor._pathCache[cacheKey]; + } + }); +} + +/** + * Traverses the cache to search for all the cached + * files of the specified module name + * + * see http://stackoverflow.com/a/14801711 + */ +function searchCache(moduleName, callback) { + // Resolve the module identified by the specified name + var mod = require.resolve(moduleName); + + // Check if the module has been resolved and found within + // the cache + if (mod && ((mod = require.cache[mod]) !== undefined)) { + // Recursively go over the results + (function traverse(mod) { + // Go over each of the module's children and + // traverse them + mod.children.forEach(function (child) { + traverse(child); + }); + + // Call the specified callback providing the + // found cached module + callback(mod); + }(mod)); + } +} + +module.exports = init; diff --git a/package-lock.json b/package-lock.json index 6a55fe2b8a4..4ea121996b3 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1223,20 +1223,6 @@ "integrity": "sha512-Q5vtl1W5ue16D+nIaW8JWebSSraJVlK+EthKn7e7UcD4KWsaSJ8BqGPXNaPghgtcn/fhvrN17Tv8ksUsQpiplw==", "dev": true }, - "@types/webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-xTE1E+YF4aWPJJeUzaZI5DRntlkY3+BCVJi0axFptnjGmAoWxkyREIh/XMrfxVLejwQxMCfDXdICo0VLxThrog==" - }, - "@types/whatwg-url": { - "version": "8.2.2", - "resolved": "https://registry.npmjs.org/@types/whatwg-url/-/whatwg-url-8.2.2.tgz", - "integrity": "sha512-FtQu10RWgn3D9U4aazdwIE2yzphmTJREDqNdODHrbrZmmMqI0vMheC/6NE/J1Yveaj8H+ela+YwWTjq5PGmuhA==", - "requires": { - "@types/node": "*", - "@types/webidl-conversions": "*" - } - }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -1737,6 +1723,53 @@ "integrity": "sha512-jDctJ/IVQbZoJykoeHbhXpOlNBqGNcwXJKJog42E5HDPUwQTSdjCHdihjj0DlnheQ7blbT6dHOafNAiS8ooQKA==", "dev": true }, + "bl": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/bl/-/bl-2.2.1.tgz", + "integrity": "sha512-6Pesp1w0DEX1N550i/uGV/TqucVL4AM/pgThFSN/Qq9si1/DF9aIHs1BxD8V/QU0HoeHO6cQRTAuYnLPKq1e4g==", + "requires": { + "readable-stream": "^2.3.5", + "safe-buffer": "^5.1.1" + }, + "dependencies": { + "readable-stream": { + "version": "2.3.7", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", + "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "requires": { + "safe-buffer": "~5.1.0" + }, + "dependencies": { + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" + } + } + } + } + }, "bn.js": { "version": "5.2.1", "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-5.2.1.tgz", @@ -1887,9 +1920,9 @@ } }, "bson": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/bson/-/bson-5.3.0.tgz", - "integrity": "sha512-ukmCZMneMlaC5ebPHXIkP8YJzNl5DC41N5MAIvKDqLggdao342t4McltoJBQfQya/nHBWAcSsYRqlXPoQkTJag==" + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/bson/-/bson-1.1.6.tgz", + "integrity": "sha512-EvVNVeGo4tHxwi8L6bPj3y3itEvStdwvvlojVxxbyYfoaxJ6keLgrTuKdyfEAszFK+H3olzBuafE0yoh0D1gdg==" }, "buffer": { "version": "6.0.3", @@ -2743,6 +2776,11 @@ "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", "integrity": "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==" }, + "denque": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/denque/-/denque-1.5.1.tgz", + "integrity": "sha512-XwE+iZ4D6ZUB7mfYRMb5wByE8L74HCn30FBN7sWnXksWc1LO1bPDl67pBR9o/kC4z/xSNAwkMYcGgqDV3BE3Hw==" + }, "depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -4174,11 +4212,6 @@ "resolved": "https://registry.npmjs.org/interpret/-/interpret-2.2.0.tgz", "integrity": "sha512-Ju0Bz/cEia55xDwUWEa8+olFpCiQoypjnQySseKtmjNrnps3P+xfpUmGr90T7yjlVJmOtybRvPXhKMbHr+fWnw==" }, - "ip": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.0.tgz", - "integrity": "sha512-WKa+XuLG1A1R0UWhl2+1XQSi+fZWMsYKffMZTTYsiZaUD8k2yDAj5atimTUD2TZkyCkNEeYE5NhFZmupOGtjYQ==" - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -4260,8 +4293,7 @@ "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==", - "dev": true + "integrity": "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ==" }, "isexe": { "version": "2.0.0", @@ -5075,11 +5107,6 @@ "tough-cookie": "^4.0.0" }, "dependencies": { - "@types/tough-cookie": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@types/tough-cookie/-/tough-cookie-4.0.1.tgz", - "integrity": "sha512-Y0K95ThC3esLEYD6ZuqNek29lNX2EM1qxV8y2FTLUB0ff5wWrk7az+mLrnNFUnaXcgKye22+sFBRXOgpPILZNg==" - }, "@ungap/promise-all-settled": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/@ungap/promise-all-settled/-/promise-all-settled-1.1.2.tgz", @@ -6281,55 +6308,16 @@ "integrity": "sha512-mv0RXncyzNt+gtnKOjD3YJK4I6+r9jk3aU5psa8/E8zvpN03AsQ0DkLJPBs5vPAzCfMs4T8gA2UQgaFx3QANHw==" }, "mongodb": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.5.0.tgz", - "integrity": "sha512-XgrkUgAAdfnZKQfk5AsYL8j7O99WHd4YXPxYxnh8dZxD+ekYWFRA3JktUsBnfg+455Smf75/+asoU/YLwNGoQQ==", - "requires": { - "bson": "^5.3.0", - "mongodb-connection-string-url": "^2.6.0", - "saslprep": "^1.0.3", - "socks": "^2.7.1" - } - }, - "mongodb-connection-string-url": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mongodb-connection-string-url/-/mongodb-connection-string-url-2.6.0.tgz", - "integrity": "sha512-WvTZlI9ab0QYtTYnuMLgobULWhokRjtC7db9LtcVfJ+Hsnyr5eo6ZtNAt3Ly24XZScGMelOcGtm7lSn0332tPQ==", - "requires": { - "@types/whatwg-url": "^8.2.1", - "whatwg-url": "^11.0.0" - }, - "dependencies": { - "tr46": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-3.0.0.tgz", - "integrity": "sha512-l7FvfAHlcmulp8kr+flpQZmVwtu7nfRV7NZujtN0OqES8EL4O4e0qqzL0DC5gAvx/ZC/9lk6rhcUwYvkBnBnYA==", - "requires": { - "punycode": "^2.1.1" - } - }, - "webidl-conversions": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz", - "integrity": "sha512-VwddBukDzu71offAQR975unBIGqfKZpM+8ZX6ySk8nYhVoo5CYaZyzt3YBvYtRtO+aoGlqxPg/B87NGVZ/fu6g==" - }, - "whatwg-url": { - "version": "11.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-11.0.0.tgz", - "integrity": "sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==", - "requires": { - "tr46": "^3.0.0", - "webidl-conversions": "^7.0.0" - } - } - } - }, - "mongodb-legacy": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/mongodb-legacy/-/mongodb-legacy-5.0.0.tgz", - "integrity": "sha512-q2G+MRwde6114bCAF/EZLmMXSsebIKMHmzsfOJq6M/Tj4gr3wLT50+rJsJNkiR0e0kjFx3dllWjqwRR1n11Zsw==", - "requires": { - "mongodb": "^5.0.0" + "version": "3.7.3", + "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-3.7.3.tgz", + "integrity": "sha512-Psm+g3/wHXhjBEktkxXsFMZvd3nemI0r3IPsE0bU+4//PnvNWKkzhZcEsbPcYiWqe8XqXJJEg4Tgtr7Raw67Yw==", + "requires": { + "bl": "^2.2.1", + "bson": "^1.1.4", + "denque": "^1.4.1", + "optional-require": "^1.1.8", + "safe-buffer": "^5.1.2", + "saslprep": "^1.0.0" } }, "mongomock": { @@ -6379,9 +6367,9 @@ "dev": true }, "nightscout-connect": { - "version": "0.0.12", - "resolved": "https://registry.npmjs.org/nightscout-connect/-/nightscout-connect-0.0.12.tgz", - "integrity": "sha512-y4Dc+shzkmGQqJG2w2zNp1Jnu4Yzc4VtSCoBiinrssjy+7ksjmOenxVDyh0Xw2UCWMkqr4A4o+iJ28KvrHWcvw==", + "version": "0.0.11", + "resolved": "https://registry.npmjs.org/nightscout-connect/-/nightscout-connect-0.0.11.tgz", + "integrity": "sha512-O7wMMG6BgW7Wxm0hr4Fj9SO1IH/7f29obKSnN8V9I2Ko4v5XxL5FqoONpmvlgI6So0MwksoMCcedSCiCL6Lj4A==", "requires": { "axios": "^1.3.4", "axios-cookiejar-support": "^4.0.6", @@ -6392,9 +6380,9 @@ }, "dependencies": { "axios": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", - "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", + "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", @@ -6855,6 +6843,14 @@ "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", "dev": true }, + "optional-require": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/optional-require/-/optional-require-1.1.8.tgz", + "integrity": "sha512-jq83qaUb0wNg9Krv1c5OQ+58EK+vHde6aBPzLvPPqJm89UQWsvSuFy9X/OSNJnFeSOKo7btE0n8Nl2+nE+z5nA==", + "requires": { + "require-at": "^1.0.6" + } + }, "optionator": { "version": "0.8.3", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.3.tgz", @@ -7125,8 +7121,7 @@ "process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", - "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", - "dev": true + "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "progress": { "version": "2.0.3", @@ -7467,6 +7462,11 @@ "tough-cookie": "^2.3.3" } }, + "require-at": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/require-at/-/require-at-1.0.6.tgz", + "integrity": "sha512-7i1auJbMUrXEAZCOQ0VNJgmcT2VOKPRl2YGJwgpHpC9CE91Mv4/4UYIUm4chGJaI381ZDq1JUicFii64Hapd8g==" + }, "require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -8846,11 +8846,6 @@ } } }, - "smart-buffer": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-4.2.0.tgz", - "integrity": "sha512-94hK0Hh8rPqQl2xXc3HsaBoOXKV20MToPkcXvwbISWLEs+64sBq5kFgn2kJDHb1Pry9yrP0dxrCI9RRci7RXKg==" - }, "socket.io": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/socket.io/-/socket.io-4.5.4.tgz", @@ -8889,15 +8884,6 @@ "debug": "~4.3.1" } }, - "socks": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/socks/-/socks-2.7.1.tgz", - "integrity": "sha512-7maUZy1N7uo6+WVEX6psASxtNlKaNVMlGQKkG/63nEDdLOWNbiUMoLK7X4uYoLhQstau72mLgfEWcXcwsaHbYQ==", - "requires": { - "ip": "^2.0.0", - "smart-buffer": "^4.2.0" - } - }, "source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", diff --git a/package.json b/package.json index a2a3d183e54..2b9abcf8fc3 100644 --- a/package.json +++ b/package.json @@ -114,9 +114,9 @@ "moment-timezone": "^0.5.31", "moment-timezone-data-webpack-plugin": "^1.5.0", "mongo-url-parser": "^1.0.2", - "mongodb-legacy": "^5.0.0", + "mongodb": "^3.6.0", "mongomock": "^0.1.2", - "nightscout-connect": "^0.0.12", + "nightscout-connect": "^0.0.11", "node-cache": "^4.2.1", "parse-duration": "^0.1.3", "process": "^0.11.10", diff --git a/tests/XX_clean.test.js b/tests/XX_clean.test.js index 3549baa4ba9..9b921a01721 100644 --- a/tests/XX_clean.test.js +++ b/tests/XX_clean.test.js @@ -25,13 +25,13 @@ describe('Clean MONGO after tests', function ( ) { }); it('wipe treatment data', function (done) { - self.ctx.treatments().deleteMany({ }, function ( ) { + self.ctx.treatments().remove({ }, function ( ) { done(); }); }); it('wipe entries data', function (done) { - self.ctx.entries().deleteMany({ }, function ( ) { + self.ctx.entries().remove({ }, function ( ) { done(); }); }); diff --git a/tests/api.entries.test.js b/tests/api.entries.test.js index c4cbf90c948..07fe0cc4aeb 100644 --- a/tests/api.entries.test.js +++ b/tests/api.entries.test.js @@ -63,11 +63,11 @@ describe('Entries REST api', function ( ) { }); afterEach(function (done) { - self.archive( ).deleteMany({ }, done); + self.archive( ).remove({ }, done); }); after(function (done) { - self.archive( ).deleteMany({ }, done); + self.archive( ).remove({ }, done); }); // keep this test pinned at or near the top in order to validate all @@ -238,7 +238,7 @@ describe('Entries REST api', function ( ) { it('/entries/:id', function (done) { var app = self.app; - self.archive.list({count: 10}, function(err, records) { + self.archive.list({count: 1}, function(err, records) { var currentId = records.pop()._id.toString(); request(app) .get('/entries/'+currentId+'.json') diff --git a/tests/api.treatments.test.js b/tests/api.treatments.test.js index 17241643a43..40e2d052de7 100644 --- a/tests/api.treatments.test.js +++ b/tests/api.treatments.test.js @@ -35,7 +35,7 @@ describe('Treatment API', function ( ) { it('post single treatments', function (done) { - self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { + self.ctx.treatments().remove({ }, function ( ) { var now = (new Date()).toISOString(); request(self.app) .post('/api/treatments/') @@ -88,8 +88,8 @@ describe('Treatment API', function ( ) { var current_time = Date.now(); console.log('Testing date with local format: ', _moment(current_time).format("YYYY-MM-DDTHH:mm:ss.SSSZZ")); - - self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { + + self.ctx.treatments().remove({ }, function ( ) { request(self.app) .post('/api/treatments/') .set('api-secret', api_secret_hash || '') @@ -122,7 +122,7 @@ describe('Treatment API', function ( ) { it('post a treatment array', function (done) { - self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { + self.ctx.treatments().remove({ }, function ( ) { var now = (new Date()).toISOString(); request(self.app) .post('/api/treatments/') @@ -149,7 +149,7 @@ describe('Treatment API', function ( ) { }); it('post a treatment array and dedupe', function (done) { - self.ctx.treatments.remove({ find: { created_at: { '$gte': '1999-01-01T00:00:00.000Z' } } }, function ( ) { + self.ctx.treatments().remove({ }, function ( ) { var now = (new Date()).toISOString(); request(self.app) .post('/api/treatments/') diff --git a/tests/api.unauthorized.test.js b/tests/api.unauthorized.test.js index 594e2dc6bf7..e1cfae62ac8 100644 --- a/tests/api.unauthorized.test.js +++ b/tests/api.unauthorized.test.js @@ -39,11 +39,11 @@ describe('authed REST api', function ( ) { }); afterEach(function (done) { - this.archive( ).deleteMany({ }, done); + this.archive( ).remove({ }, done); }); after(function (done) { - this.archive( ).deleteMany({ }, done); + this.archive( ).remove({ }, done); }); it('disallow unauthorized POST', function (done) { diff --git a/tests/openaps-storage.test.js b/tests/openaps-storage.test.js new file mode 100644 index 00000000000..36714181a40 --- /dev/null +++ b/tests/openaps-storage.test.js @@ -0,0 +1,115 @@ +'use strict'; + +var should = require('should'); + +describe('openaps storage', function () { + + var env = require('../lib/server/env')(); + + + before(function (done) { + delete env.api_secret; + env.storageURI = 'openaps://../../tests/fixtures/openaps-storage/config'; + done(); + }); + + it('The module class should be OK.', function (done) { + require('../lib/storage/openaps-storage')(env, function callback (err, storage) { + should.not.exist(err); + should.exist(storage.collection); + should.exist(storage.ensureIndexes); + done(); + }); + }); + + it('find sgv entries', function (done) { + require('../lib/storage/openaps-storage')(env, function callback (err, storage) { + should.not.exist(err); + should.exist(storage.collection); + + storage.collection('entries').find({type: 'sgv'}).toArray(function callback (err, results) { + should.not.exist(err); + should.exist(results); + + results.length.should.equal(4); + results[0].sgv.should.equal(102); + + done(); + }); + }); + }); + + it('find cal entries', function (done) { + require('../lib/storage/openaps-storage')(env, function callback (err, storage) { + should.not.exist(err); + should.exist(storage.collection); + + storage.collection('entries').find({type: 'cal'}).toArray(function callback (err, results) { + should.not.exist(err); + should.exist(results); + + results.length.should.equal(1); + results[0].slope.should.equal(841.6474113376482); + + done(); + }); + }); + }); + + it('find devicestatus entries', function (done) { + require('../lib/storage/openaps-storage')(env, function callback (err, storage) { + should.not.exist(err); + should.exist(storage.collection); + + storage.collection('devicestatus').find({}).toArray(function callback (err, results) { + should.not.exist(err); + should.exist(results); + + results.length.should.equal(1); + results[0].openaps.enacted.eventualBG.should.equal(82); + + done(); + }); + }); + }); + + it('find treatments', function (done) { + require('../lib/storage/openaps-storage')(env, function callback (err, storage) { + should.not.exist(err); + should.exist(storage.collection); + + storage.collection('treatments').find({}).toArray(function callback (err, results) { + should.not.exist(err); + should.exist(results); + + results.length.should.equal(2); + results[0].eventType.should.equal('Temp Basal'); + + done(); + }); + }); + }); + + it('When no connection-string is given the storage-class should throw an error.', function (done) { + delete env.storageURI; + should.not.exist(env.storageURI); + + (function () { + return require('../lib/storage/openaps-storage')(env); + }).should.throw('openaps config uri is missing or invalid'); + + done(); + }); + + it('An invalid connection-string should throw an error.', function (done) { + env.storageURI = 'This is not an openaps config path'; + + (function () { + return require('../lib/storage/openaps-storage')(env); + }).should.throw(Error); + + done(); + }); + +}); + From 89354e53983368ca98bd33f86eb4a2c189a5ecdd Mon Sep 17 00:00:00 2001 From: Ben West Date: Thu, 19 Oct 2023 20:30:52 -0700 Subject: [PATCH 3/3] bump nightscout-connect version --- package-lock.json | 12 ++++++------ package.json | 2 +- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/package-lock.json b/package-lock.json index 4ea121996b3..6aa3a366cb4 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6367,9 +6367,9 @@ "dev": true }, "nightscout-connect": { - "version": "0.0.11", - "resolved": "https://registry.npmjs.org/nightscout-connect/-/nightscout-connect-0.0.11.tgz", - "integrity": "sha512-O7wMMG6BgW7Wxm0hr4Fj9SO1IH/7f29obKSnN8V9I2Ko4v5XxL5FqoONpmvlgI6So0MwksoMCcedSCiCL6Lj4A==", + "version": "0.0.12", + "resolved": "https://registry.npmjs.org/nightscout-connect/-/nightscout-connect-0.0.12.tgz", + "integrity": "sha512-y4Dc+shzkmGQqJG2w2zNp1Jnu4Yzc4VtSCoBiinrssjy+7ksjmOenxVDyh0Xw2UCWMkqr4A4o+iJ28KvrHWcvw==", "requires": { "axios": "^1.3.4", "axios-cookiejar-support": "^4.0.6", @@ -6380,9 +6380,9 @@ }, "dependencies": { "axios": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.4.0.tgz", - "integrity": "sha512-S4XCWMEmzvo64T9GfvQDOXgYRDJ/wsSZc7Jvdgx5u1sd0JwsuPLqb3SYmusag+edF6ziyMensPVqLTSc1PiSEA==", + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/axios/-/axios-1.5.1.tgz", + "integrity": "sha512-Q28iYCWzNHjAm+yEAot5QaAMxhMghWLFVf7rRdwhUI+c2jix2DUXjAHXVi+s1ibs3mjPO/cCgbA++3BjD0vP/A==", "requires": { "follow-redirects": "^1.15.0", "form-data": "^4.0.0", diff --git a/package.json b/package.json index 2b9abcf8fc3..b4742fc05f3 100644 --- a/package.json +++ b/package.json @@ -116,7 +116,7 @@ "mongo-url-parser": "^1.0.2", "mongodb": "^3.6.0", "mongomock": "^0.1.2", - "nightscout-connect": "^0.0.11", + "nightscout-connect": "^0.0.12", "node-cache": "^4.2.1", "parse-duration": "^0.1.3", "process": "^0.11.10",