mirror of
https://github.com/bckelley/cgm-remote-monitor.git
synced 2026-08-24 03:14:12 -05:00
First describe block was missing its closing }); Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
518 lines
15 KiB
JavaScript
518 lines
15 KiB
JavaScript
'use strict';
|
|
|
|
/**
|
|
* UUID_HANDLING Feature Flag Tests
|
|
*
|
|
* Tests for GET/DELETE by UUID using the `identifier` field lookup.
|
|
*
|
|
* @see docs/backlogs/uuid-identifier-lookup.md
|
|
* @see lib/server/env.js (env.uuidHandling)
|
|
* @see lib/server/query.js (updateIdQuery UUID detection)
|
|
*/
|
|
|
|
var request = require('supertest');
|
|
var should = require('should');
|
|
var language = require('../lib/language')();
|
|
var api = require('../lib/api/');
|
|
|
|
var api_secret_hash = 'b723e97aa97846eb92d5264f084b2823f57c4aa1';
|
|
|
|
// Test UUIDs
|
|
var TEST_UUID = '550e8400-e29b-41d4-a716-446655440000';
|
|
var TEST_UUID_2 = '6ba7b810-9dad-11d1-80b4-00c04fd430c8';
|
|
|
|
/**
|
|
* Clear module caches to allow env reloading
|
|
*/
|
|
function clearModuleCache() {
|
|
var modulesToClear = [
|
|
'../lib/server/env',
|
|
'../lib/server/query',
|
|
'../lib/server/treatments',
|
|
'../lib/server/entries',
|
|
'../lib/api/entries/',
|
|
'../lib/api/',
|
|
'../lib/middleware/',
|
|
'../lib/server/bootevent'
|
|
];
|
|
|
|
modulesToClear.forEach(function(mod) {
|
|
try {
|
|
delete require.cache[require.resolve(mod)];
|
|
} catch (e) {
|
|
// Module not yet loaded
|
|
}
|
|
});
|
|
}
|
|
|
|
describe('UUID_HANDLING=false (explicit)', function() {
|
|
var self = this;
|
|
this.timeout(10000);
|
|
|
|
before(function(done) {
|
|
// Explicitly set UUID_HANDLING OFF (default changed to true in 15.0.7)
|
|
process.env.UUID_HANDLING = 'false';
|
|
clearModuleCache();
|
|
|
|
process.env.API_SECRET = 'this is my long pass phrase';
|
|
self.env = require('../lib/server/env')();
|
|
self.env.settings.authDefaultRoles = 'readable';
|
|
self.env.settings.enable = ['careportal', 'api'];
|
|
|
|
// Verify flag is off
|
|
self.env.uuidHandling.should.equal(false);
|
|
|
|
self.wares = require('../lib/middleware/')(self.env);
|
|
self.app = require('express')();
|
|
self.app.enable('api');
|
|
|
|
require('../lib/server/bootevent')(self.env, language).boot(function booted(ctx) {
|
|
self.ctx = ctx;
|
|
self.ctx.ddata = require('../lib/data/ddata')();
|
|
self.ctx.ddata.lastUpdated = Date.now();
|
|
self.app.use('/api', api(self.env, ctx));
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function(done) {
|
|
self.ctx.treatments.remove({ find: {} }, done);
|
|
});
|
|
|
|
it('UUID-OFF-001: GET by UUID returns empty (no crash)', function(done) {
|
|
// Insert treatment with identifier
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Test note',
|
|
identifier: TEST_UUID,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// GET by UUID _id - should return empty since flag is off
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + TEST_UUID)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-OFF-002: DELETE by UUID deletes nothing (no crash)', function(done) {
|
|
// Insert treatment
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Test for delete',
|
|
identifier: TEST_UUID,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// DELETE by UUID - should not crash, delete nothing
|
|
request(self.app)
|
|
.delete('/api/treatments/' + TEST_UUID)
|
|
.set('api-secret', api_secret_hash)
|
|
.expect(200)
|
|
.end(function(err) {
|
|
should.not.exist(err);
|
|
|
|
// Verify treatment still exists
|
|
self.ctx.treatments.list({}, function(err, results) {
|
|
should.not.exist(err);
|
|
results.length.should.equal(1);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-OFF-003: POST with UUID _id strips UUID, does not copy to identifier', function(done) {
|
|
// When UUID_HANDLING=false, UUID in _id is stripped but NOT preserved as identifier
|
|
self.ctx.treatments.create([{
|
|
_id: TEST_UUID,
|
|
eventType: 'Note',
|
|
notes: 'UUID stripped write test',
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
// Treatment was created (no crash), but UUID was not preserved as identifier
|
|
self.ctx.treatments.list({}, function(err, results) {
|
|
should.not.exist(err);
|
|
results.length.should.equal(1);
|
|
// identifier should NOT be set from the UUID _id when flag is false
|
|
should.not.exist(results[0].identifier);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
describe('UUID_HANDLING=true', function() {
|
|
var self = this;
|
|
this.timeout(10000);
|
|
|
|
before(function(done) {
|
|
// Enable UUID_HANDLING
|
|
process.env.UUID_HANDLING = 'true';
|
|
clearModuleCache();
|
|
|
|
process.env.API_SECRET = 'this is my long pass phrase';
|
|
self.env = require('../lib/server/env')();
|
|
self.env.settings.authDefaultRoles = 'readable';
|
|
self.env.settings.enable = ['careportal', 'api'];
|
|
|
|
// Verify flag is on
|
|
self.env.uuidHandling.should.equal(true);
|
|
|
|
self.wares = require('../lib/middleware/')(self.env);
|
|
self.app = require('express')();
|
|
self.app.enable('api');
|
|
|
|
require('../lib/server/bootevent')(self.env, language).boot(function booted(ctx) {
|
|
self.ctx = ctx;
|
|
self.ctx.ddata = require('../lib/data/ddata')();
|
|
self.ctx.ddata.lastUpdated = Date.now();
|
|
self.app.use('/api', api(self.env, ctx));
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function(done) {
|
|
self.ctx.treatments.remove({ find: {} }, done);
|
|
});
|
|
|
|
after(function() {
|
|
delete process.env.UUID_HANDLING;
|
|
});
|
|
|
|
it('UUID-ON-001: GET by UUID finds treatment via identifier', function(done) {
|
|
// Insert treatment with identifier field
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Found by UUID',
|
|
identifier: TEST_UUID,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// GET by UUID _id - should redirect to identifier search
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + TEST_UUID)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(1);
|
|
res.body[0].notes.should.equal('Found by UUID');
|
|
res.body[0].identifier.should.equal(TEST_UUID);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-ON-002: DELETE by UUID removes treatment via identifier', function(done) {
|
|
// Insert treatment
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Will be deleted',
|
|
identifier: TEST_UUID,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// DELETE by UUID
|
|
request(self.app)
|
|
.delete('/api/treatments/' + TEST_UUID)
|
|
.set('api-secret', api_secret_hash)
|
|
.expect(200)
|
|
.end(function(err) {
|
|
should.not.exist(err);
|
|
|
|
// Verify treatment is gone
|
|
self.ctx.treatments.list({}, function(err, results) {
|
|
should.not.exist(err);
|
|
results.length.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-ON-003: ObjectId still works normally', function(done) {
|
|
var ObjectID = require('mongodb').ObjectId;
|
|
var testId = new ObjectID();
|
|
|
|
// Insert treatment with ObjectId
|
|
self.ctx.treatments.create([{
|
|
_id: testId,
|
|
eventType: 'Note',
|
|
notes: 'ObjectId test',
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// GET by ObjectId - should work normally
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + testId.toString())
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(1);
|
|
res.body[0].notes.should.equal('ObjectId test');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-ON-004: Non-matching UUID returns empty', function(done) {
|
|
// Insert with different identifier
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Different UUID',
|
|
identifier: TEST_UUID_2,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// Search for non-existing UUID
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + TEST_UUID)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-ON-005: POST with UUID _id extracts UUID to identifier', function(done) {
|
|
// When UUID_HANDLING=true, UUID in _id is extracted to identifier
|
|
self.ctx.treatments.create([{
|
|
_id: TEST_UUID,
|
|
eventType: 'Note',
|
|
notes: 'UUID write test',
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
// UUID should have been moved to identifier
|
|
self.ctx.treatments.list({}, function(err, results) {
|
|
should.not.exist(err);
|
|
results.length.should.equal(1);
|
|
// identifier should be set from the UUID _id
|
|
results[0].identifier.should.equal(TEST_UUID);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
// ============================================
|
|
|
|
// ============================================
|
|
// UUID Edge Case Tests
|
|
// ============================================
|
|
|
|
describe('UUID Edge Cases', function() {
|
|
var self = this;
|
|
this.timeout(10000);
|
|
|
|
before(function(done) {
|
|
process.env.UUID_HANDLING = 'true';
|
|
clearModuleCache();
|
|
|
|
process.env.API_SECRET = 'this is my long pass phrase';
|
|
self.env = require('../lib/server/env')();
|
|
self.env.settings.authDefaultRoles = 'readable';
|
|
self.env.settings.enable = ['careportal', 'api'];
|
|
|
|
self.wares = require('../lib/middleware/')(self.env);
|
|
self.app = require('express')();
|
|
self.app.enable('api');
|
|
|
|
require('../lib/server/bootevent')(self.env, language).boot(function booted(ctx) {
|
|
self.ctx = ctx;
|
|
self.ctx.ddata = require('../lib/data/ddata')();
|
|
self.ctx.ddata.lastUpdated = Date.now();
|
|
self.app.use('/api', api(self.env, ctx));
|
|
done();
|
|
});
|
|
});
|
|
|
|
afterEach(function(done) {
|
|
self.ctx.treatments.remove({ find: {} }, done);
|
|
});
|
|
|
|
after(function() {
|
|
delete process.env.UUID_HANDLING;
|
|
});
|
|
|
|
it('UUID-EDGE-001: 23-char hex (invalid ObjectId) returns empty', function(done) {
|
|
// 23 chars - one short of valid ObjectId
|
|
var invalidId = '507f1f77bcf86cd79943901';
|
|
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + invalidId)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('UUID-EDGE-002: 25-char hex (too long) returns empty', function(done) {
|
|
// 25 chars - one more than valid ObjectId
|
|
var invalidId = '507f1f77bcf86cd7994390112';
|
|
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + invalidId)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
|
|
it('UUID-EDGE-003: UUID without hyphens not recognized as UUID', function(done) {
|
|
// UUID without hyphens (32 hex chars)
|
|
var noHyphenUUID = '550e8400e29b41d4a716446655440000';
|
|
|
|
// Insert treatment with hyphenated UUID
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Hyphenated UUID',
|
|
identifier: TEST_UUID,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// Search with non-hyphenated version - should not match
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + noHyphenUUID)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(0);
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-EDGE-004: Empty _id query returns all with date filter', function(done) {
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Test note',
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// Empty _id - should not crash, returns based on other filters
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=')
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
// May return results based on date filter
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-EDGE-005: Multiple treatments same identifier - documents upsert behavior', function(done) {
|
|
// treatments.create uses upsert by identifier, so duplicates are merged
|
|
// This test documents the expected behavior
|
|
var now = new Date();
|
|
var later = new Date(now.getTime() + 1000);
|
|
|
|
self.ctx.treatments.create([
|
|
{ eventType: 'Note', notes: 'First', identifier: TEST_UUID, created_at: now.toISOString() }
|
|
], function(err) {
|
|
should.not.exist(err);
|
|
|
|
self.ctx.treatments.create([
|
|
{ eventType: 'Note', notes: 'Second', identifier: TEST_UUID, created_at: later.toISOString() }
|
|
], function(err2) {
|
|
should.not.exist(err2);
|
|
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + TEST_UUID)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
// Due to upsert by identifier, only 1 treatment exists (updated)
|
|
res.body.length.should.equal(1);
|
|
// The second create updates the first
|
|
res.body[0].notes.should.equal('Second');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-EDGE-006: Uppercase UUID matches case-insensitively', function(done) {
|
|
var lowerUUID = TEST_UUID.toLowerCase();
|
|
var upperUUID = TEST_UUID.toUpperCase();
|
|
|
|
// Insert with lowercase
|
|
self.ctx.treatments.create([{
|
|
eventType: 'Note',
|
|
notes: 'Lowercase UUID',
|
|
identifier: lowerUUID,
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
// Query with uppercase - UUID regex is case insensitive
|
|
// but identifier field match depends on stored value
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + upperUUID)
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
// Documents current behavior - uppercase query searches by identifier
|
|
// which is case-sensitive in MongoDB
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
|
|
it('UUID-EDGE-007: Valid ObjectId still works normally', function(done) {
|
|
var ObjectID = require('mongodb').ObjectId;
|
|
var testId = new ObjectID();
|
|
|
|
self.ctx.treatments.create([{
|
|
_id: testId,
|
|
eventType: 'Note',
|
|
notes: 'ObjectId test',
|
|
created_at: new Date().toISOString()
|
|
}], function(err) {
|
|
should.not.exist(err);
|
|
|
|
request(self.app)
|
|
.get('/api/treatments?find[_id]=' + testId.toString())
|
|
.expect(200)
|
|
.end(function(err, res) {
|
|
should.not.exist(err);
|
|
res.body.should.be.Array();
|
|
res.body.length.should.equal(1);
|
|
res.body[0].notes.should.equal('ObjectId test');
|
|
done();
|
|
});
|
|
});
|
|
});
|
|
});
|