added stuff

This commit is contained in:
David Baldwynn 2015-09-18 09:32:17 -07:00
parent 4d20c36540
commit 90e00a98ba
9 changed files with 384 additions and 185 deletions

View File

@ -14,11 +14,13 @@ var mongoose = require('mongoose'),
util = require('util');
//Mongoose Models
var FieldSchema = require('./form_field.server.model.js');
var Field = mongoose.model('Field');
var FormSubmissionSchema = require('./form_submission.server.model.js'),
FieldSchema = require('./form_field.server.model.js'),
Field = mongoose.model('Field', FieldSchema),
FormSubmission = mongoose.model('FormSubmission', FormSubmissionSchema);
var ButtonSchema = new Schema({
url: {
type: String,
@ -64,10 +66,9 @@ var FormSchema = new Schema({
type: String,
default: '',
},
form_fields: [Field],
//form_fields: {
// type: [FieldSchema],
//},
form_fields: [{
type: Schema.Types.Mixed
}],
submissions: [{
type: Schema.Types.ObjectId,
@ -163,11 +164,9 @@ var FormSchema = new Schema({
auth: {
user: {
type: String,
required: true,
},
pass: {
type: String,
required: true,
}
}
}
@ -189,16 +188,15 @@ var _original;
//Set _original
FormSchema.pre('save', function (next) {
// console.log(this.constructor.model);
// console.log(FormModel);
this.constructor // ≈ mongoose.model('…', FieldSchema).findById
this.constructor
.findOne({_id: this._id}).exec(function(err, original){
if(err) {
console.log(err);
next(err);
} else {
_original = original;
// console.log('_original');
//console.log('_original');
// console.log(_original);
next();
}
@ -291,7 +289,6 @@ FormSchema.pre('save', function (next) {
callback( new Error('Generated formfields is empty'), null);
}
// console.log(_form_fields);
//Map PDF field names to FormField field names
for(var i = 0; i < _form_fields.length; i++){
var field = _form_fields[i];

View File

@ -4,12 +4,20 @@
* Module dependencies.
*/
var mongoose = require('mongoose'),
relationship = require('mongoose-relationship'),
_ = require('lodash'),
Schema = mongoose.Schema;
/**
* Question Schema
*/
var FormFieldSchema = new Schema({
// formSubmission: {
// type: Schema.ObjectId,
// ref: 'FormSubmission',
// childPath: 'form_fields'
// },
created: {
type: Date,
default: Date.now
@ -20,7 +28,6 @@ var FormFieldSchema = new Schema({
},
title: {
type: String,
default: '',
trim: true,
required: 'Field title cannot be blank'
},
@ -29,9 +36,10 @@ var FormFieldSchema = new Schema({
default: '',
},
logicJumps: [{
type: String,
}],
logicJump: {
type: Schema.Types.ObjectId,
ref: 'LogicJump'
},
//DAVID: TODO: SEMI-URGENT: Need to come up with a schema for field options
fieldOptions: [{
@ -58,6 +66,8 @@ var FormFieldSchema = new Schema({
fieldValue: Schema.Types.Mixed
});
// FormFieldSchema.plugin(relationship, { relationshipPathName:'formSubmission' });
FormFieldSchema.static('validTypes', function(){
return [
'textfield',
@ -114,4 +124,8 @@ function validateFormFieldType(value) {
return false;
};
module.exports = FormFieldSchema;
var cloneFieldSchema = _.cloneDeep(FormFieldSchema);
mongoose.model('Field', FormFieldSchema);
module.exports = cloneFieldSchema;

View File

@ -13,6 +13,7 @@ var mongoose = require('mongoose'),
fs = require('fs-extra'),
Field = mongoose.model('Field'),
soap = require('soap'),
FieldSchema = require('./form_field.server.model.js'),
OscarSecurity = require('../../scripts/oscarhost/OscarSecurity');
var newDemoTemplate = {
@ -60,7 +61,7 @@ var FormSubmissionSchema = new Schema({
ref: 'User',
required: true
},
form_fields: [Field],
form_fields: [FieldSchema],
form: {
type:Schema.Types.ObjectId,
ref:'Form',
@ -112,10 +113,10 @@ FormSubmissionSchema.post('save', function (next) {
}
//Generate demographics from hashmap
var generateDemo = function(formFields, conversionMap, templateDemo){
var generateDemo = function(formFields, conversionMap, demographicsTemplate){
var _generatedDemo = {};
for(var field in formFields){
if(templateDemo.hasOwnProperty(conversionMap[field._id])){
if(demographicsTemplate.hasOwnProperty(conversionMap[field._id])){
var propertyName = conversionMap[field._id];
if(propertyName === "unparsedDOB"){
@ -132,7 +133,7 @@ FormSubmissionSchema.post('save', function (next) {
return _generatedDemo;
}
var submissionDemographic = generateDemo(this.form_fields, this.form.plugin.oscarhost.settings.fieldMap);
var submissionDemographic = generateDemo(this.form_fields, this.form.plugin.oscarhost.settings.fieldMap, newDemoTemplate);
async.waterfall([
function (callback) {
@ -146,7 +147,7 @@ FormSubmissionSchema.post('save', function (next) {
},
function (security_obj, callback) {
//Force Add
//Force Add Demographic
if(this.plugins.oscarhost.settings.updateType === 'force_add'){
soap.createClient(url_demo, options, function(err, client) {
client.setSecurity(new OscarSecurity(security_obj.securityId, security_obj.securityTokenKey) );

View File

@ -7,6 +7,7 @@ var should = require('should'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
Form = mongoose.model('Form'),
Field = mongoose.model('Field'),
_ = require('lodash'),
config = require('../../config/config'),
FormSubmission = mongoose.model('FormSubmission');
@ -58,6 +59,11 @@ var user, myForm, mySubmission;
* Unit tests
*/
describe('Form Model Unit Tests:', function() {
beforeEach(function(done) {
Form.remove().exec(function() {
User.remove().exec(done);
});
});
beforeEach(function(done) {
user = new User({
firstName: 'Full',
@ -73,10 +79,12 @@ describe('Form Model Unit Tests:', function() {
title: 'Form Title',
admin: user,
language: 'english',
form_fields: [
{'fieldType':'textfield', 'title':'First Name', 'fieldValue': ''},
{'fieldType':'checkbox', 'title':'nascar', 'fieldValue': ''},
{'fieldType':'checkbox', 'title':'hockey', 'fieldValue': ''}
]
});
myForm.form_fields.push({fieldType:'textfield', title:'First Name'});
myForm.form_fields.push({fieldType:'checkbox', title:'nascar'});
myForm.form_fields.push({fieldType:'checkbox', title:'hockey'});
done();
});
@ -117,141 +125,7 @@ describe('Form Model Unit Tests:', function() {
});
});
});
describe('Test FormField and Submission Logic', function() {
var new_form_fields_add1, new_form_fields_del, submission_fields, old_fields, form;
before(function(){
new_form_fields_add1 = _.clone(myForm.toObject().form_fields);
new_form_fields_add1.push(
{'fieldType':'textfield', 'title':'Last Name', 'fieldValue': ''}
);
new_form_fields_del = _.clone(myForm.toObject().form_fields);
new_form_fields_del.splice(0, 1);
submission_fields = _.clone(myForm.toObject().form_fields);
submission_fields[0].fieldValue = 'David';
submission_fields[1].fieldValue = true;
submission_fields[2].fieldValue = true;
mySubmission = new FormSubmission({
form_fields: submission_fields,
admin: user,
form: myForm,
timeElapsed: 17.55
});
});
beforeEach(function(done){
myForm.save(function(){
mySubmission.save(function(){
done();
});
});
});
afterEach(function(done){
mySubmission.remove(function(){
done();
});
});
// it('should preserve deleted form_fields that have submissions without any problems', function(done) {
// old_fields = myForm.toObject().form_fields;
// // console.log(old_fields);
// // var expected_fields = old_fields.slice(1,3).concat(old_fields.slice(0,1));
// myForm.form_fields = new_form_fields_del;
// myForm.save(function(err, _form) {
// should.not.exist(err);
// should.exist(_form);
// // var actual_fields = _.map(_form.toObject().form_fields, function(o){ _.omit(o, '_id')});
// // old_fields = _.map(old_fields, function(o){ _.omit(o, '_id')});
// // console.log(old_fields);
// should.deepEqual(JSON.stringify(_form.toObject().form_fields), JSON.stringify(old_fields), 'old form_fields not equal to newly saved form_fields');
// done();
// });
// });
// it('should delete \'preserved\' form_fields whose submissions have been removed without any problems', function(done) {
// myForm.form_fields = new_form_fields_del;
// myForm.save(function(err, form
// should.not.exist(err);
// (form.form_fields).should.be.eql(old_fields, 'old form_fields not equal to newly saved form_fields');
// //Remove submission
// mySubmission.remove(function(err){
// myForm.submissions.should.have.length(0);
// myForm.form_fields.should.not.containDeep(old_fields[0]);
// });
// });
// });
});
describe('Submission of Form should add Patient to OscarHost', function() {
var mySubmission;
before(function(done){
myForm.form_fields = [
new Field({'fieldType':'textfield', 'title':'What\'s your first name', 'fieldValue': ''}),
new Field({'fieldType':'textfield', 'title':'And your last name', 'fieldValue': ''}),
new Field({'fieldType':'radio', 'title':'And your sex', 'fieldOptions': [{ 'option_id': 0, 'option_title': 'Male', 'option_value': 'M' }, { 'option_id': 1, 'option_title': 'Female', 'option_value': 'F' }], 'fieldValue': ''}),
new Field({'fieldType':'date', 'title':'When were you born?', 'fieldValue': ''}),
new Field({'fieldType':'number', 'title':'What\'s your phone #?', 'fieldValue': ''}),
];
var myFieldMap = {};
myFieldMap[myForm.form_fields[0]._id] = 'firstName';
myFieldMap[myForm.form_fields[1]._id] = 'lastName';
myFieldMap[myForm.form_fields[2]._id] = 'sex';
myFieldMap[myForm.form_fields[3]._id] = 'unparsedDOB';
myFieldMap[myForm.form_fields[4]._id] = 'phone';
myForm.plugins.oscarhost = {
baseUrl: config.oscarhost.baseUrl,
settings: {
lookupField: '',
updateType: 'force_add',
fieldMap: myFieldMap,
},
auth: config.oscarhost.auth,
};
myForm.save(function(err, form){
if(err) done(err);
var submission_fields = _.clone(myForm.toObject().form_fields);
submission_fields[0].fieldValue = 'David';
submission_fields[1].fieldValue = 'Baldwynn'+Date.now();
submission_fields[2].fieldValue = 'M';
submission_fields[3].fieldValue = Date.now();
submission_fields[4].fieldValue = 6043158008;
mySubmission = new FormSubmission({
form_fields: submission_fields,
admin: form.admin,
form: form,
timeElapsed: 17.55
});
done();
});
});
it('should be able to submit a valid form without problems', function(done) {
mySubmission.save(function(err, submission) {
should.not.exist(err);
should.exist(submission.oscarDemoNum);
done();
});
});
});
afterEach(function(done) {
Form.remove().exec(function() {
User.remove().exec(done);

View File

@ -0,0 +1,269 @@
'use strict';
/**
* Module dependencies.
*/
var should = require('should'),
mongoose = require('mongoose'),
User = mongoose.model('User'),
Form = mongoose.model('Form'),
Field = mongoose.model('Field'),
_ = require('lodash'),
config = require('../../config/config'),
FormSubmission = mongoose.model('FormSubmission');
var exampleDemo = {
activeCount: 1,
unparsedDOB: '',
address: '880-9650 Velit. St.',
chartNo: '',
city: '',
dateJoined: Date.now(),
dateOfBirth: '10',
displayName: 'LITTLE, URIAH',
email: '',
familyDoctor: '<rdohip></rdohip><rd></rd>',
firstName: 'Uriah F.',
hcType: 'BC',
hin: '',
hsAlertCount: 0,
lastName: 'Little',
lastUpdateDate: Date.now(),
lastUpdateUser: '',
links: '',
monthOfBirth: '05',
officialLanguage: 'English',
patientStatus: 'AC',
patientStatusDate: Date.now(),
phone: '250-',
phone2: '',
postal: "S4M 7T8",
providerNo: '4',
province: 'BC',
rosterStatus: '',
sex: 'M',
sexDesc: 'Female',
sin: '',
spokenLanguage: 'English',
title: 'MS.',
yearOfBirth: '2015'
}
/**
* Globals
*/
var user, myForm, mySubmission;
/**
* Unit tests
*/
describe('FormSubmission Model Unit Tests:', function() {
beforeEach(function(done) {
user = new User({
firstName: 'Full',
lastName: 'Name',
displayName: 'Full Name',
email: 'test1@test.com',
username: 'test1@test.com',
password: 'password'
});
user.save(function(err, _user) {
if(err) done(err);
myForm = new Form({
title: 'Form Title',
admin: _user,
language: 'english',
form_fields: [
{'fieldType':'textfield', 'title':'What\'s your first name', 'fieldValue': ''},
{'fieldType':'textfield', 'title':'And your last name', 'fieldValue': ''},
{'fieldType':'radio', 'title':'And your sex', 'fieldOptions': [{ 'option_id': 0, 'option_title': 'Male', 'option_value': 'M' }, { 'option_id': 1, 'option_title': 'Female', 'option_value': 'F' }], 'fieldValue': ''},
{'fieldType':'date', 'title':'When were you born?', 'fieldValue': ''},
{'fieldType':'number', 'title':'What\'s your phone #?', 'fieldValue': ''},
],
plugins: {
oscarhost: {
baseUrl: config.oscarhost.baseUrl,
settings: {
lookupField: '',
updateType: 'force_add',
},
auth: config.oscarhost.auth,
}
}
});
done();
});
});
describe('Method Save', function() {
var myFieldMap = {};
beforeEach(function(done){
myFieldMap[myForm.form_fields[0]._id+''] = 'firstName';
myFieldMap[myForm.form_fields[1]._id+''] = 'lastName';
myFieldMap[myForm.form_fields[2]._id+''] = 'sex';
myFieldMap[myForm.form_fields[3]._id+''] = 'unparsedDOB';
myFieldMap[myForm.form_fields[4]._id+''] = 'phone';
myForm.plugins.oscarhost.settings.fieldMap = myFieldMap;
myForm.save(function(err, form){
if(err) done(err);
// var submission_fields = _.cloneDeep(form.toObject().form_fields);
// var submission_fields = [
// {'fieldType':'textfield', 'title':'What\'s your first name', 'fieldValue': ''},
// {'fieldType':'textfield', 'title':'And your last name', 'fieldValue': ''},
// {'fieldType':'radio', 'title':'And your sex', 'fieldOptions': [{ 'option_id': 0, 'option_title': 'Male', 'option_value': 'M' }, { 'option_id': 1, 'option_title': 'Female', 'option_value': 'F' }], 'fieldValue': ''},
// {'fieldType':'date', 'title':'When were you born?', 'fieldValue': ''},
// {'fieldType':'number', 'title':'What\'s your phone #?', 'fieldValue': ''}
// ];
submission_fields[0].fieldValue = 'David';
submission_fields[1].fieldValue = 'Baldwynn'+Date.now();
submission_fields[2].fieldValue = 'M';
submission_fields[3].fieldValue = Date.now();
submission_fields[4].fieldValue = 6043158008;
mySubmission = new FormSubmission({
admin: user,
form: form,
timeElapsed: 17.55
});
// for(var i=0; i<submission_fields.length; i++){
// mySubmission.form_fields.create(submission_fields[i]);
// }
done();
});
});
it('should be able to save a FormSubmission without problems', function(done) {
return mySubmission.save(function(err, submission) {
should.not.exist(err);
should.exist(submission.oscarDemoNum);
done();
});
});
it('should add Patient to OscarHost EMR after save');
});
// describe('Method Find', function(){
// beforeEach(function(done){
// myForm.save(function(err) {
// done();
// });
// });
// // it('should be able to findOne my form without problems', function(done) {
// // return Form.findOne({_id: myForm._id}, function(err,form) {
// // should.not.exist(err);
// // should.exist(form);
// // should.deepEqual(form.toObject(), myForm.toObject());
// // done();
// // });
// // });
// });
// describe('Test FormField and Submission Logic', function() {
// var new_form_fields_add1, new_form_fields_del, submission_fields, old_fields, form;
// before(function(){
// new_form_fields_add1 = _.clone(myForm.toObject().form_fields);
// new_form_fields_add1.push(
// {'fieldType':'textfield', 'title':'Last Name', 'fieldValue': ''}
// );
// new_form_fields_del = _.clone(myForm.toObject().form_fields);
// new_form_fields_del.splice(0, 1);
// //Create Submission
// submission_fields = _.clone(myForm.toObject().form_fields);
// for(var i=0; i<submission_fields.length; i++){
// submission_fields[i] = new Field(submission_fields[i]);
// }
// submission_fields[0].fieldValue = 'David';
// submission_fields[1].fieldValue = true;
// submission_fields[2].fieldValue = true;
// mySubmission = new FormSubmission({
// form_fields: [],
// admin: user,
// form: myForm,
// timeElapsed: 17.55
// });
// for(var i=0; i<submission_fields.length; i++){
// mySubmission.form_fields.push(submission_fields[i]);
// }
// });
// beforeEach(function(done){
// myForm.save(function(){
// console.log(mySubmission);
// mySubmission.save(function(err){
// if(err) done(err);
// done();
// });
// });
// });
// afterEach(function(done){
// mySubmission.remove(function(){
// done();
// });
// });
// it('something', function(done){
// done();
// });
// // it('should preserve deleted form_fields that have submissions without any problems', function(done) {
// // old_fields = myForm.toObject().form_fields;
// // // var expected_fields = old_fields.slice(1,3).concat(old_fields.slice(0,1));
// // myForm.form_fields = new_form_fields_del;
// // myForm.save(function(err, form) {
// // should.not.exist(err);
// // should.exist(_form);
// // // var actual_fields = _.map(_form.toObject().form_fields, function(o){ _.omit(o, '_id')});
// // // old_fields = _.map(old_fields, function(o){ _.omit(o, '_id')});
// // // console.log(old_fields);
// // should.deepEqual(JSON.stringify(_form.toObject().form_fields), JSON.stringify(old_fields), 'old form_fields not equal to newly saved form_fields');
// // done();
// // });
// // });
// // it('should delete \'preserved\' form_fields whose submissions have been removed without any problems', function(done) {
// // myForm.form_fields = new_form_fields_del;
// // myForm.save(function(err, form
// // should.not.exist(err);
// // (form.form_fields).should.be.eql(old_fields, 'old form_fields not equal to newly saved form_fields');
// // //Remove submission
// // mySubmission.remove(function(err){
// // myForm.submissions.should.have.length(0);
// // myForm.form_fields.should.not.containDeep(old_fields[0]);
// // });
// // });
// // });
// });
afterEach(function(done) {
Form.remove().exec(function() {
User.remove().exec(done);
});
});
});

View File

@ -51,9 +51,10 @@
// };
// });
// // describe('Create, Verify and Activate a User', function() {
// describe('Create, Verify and Activate a User', function() {
// var username = 'testActiveAccount.be1e58fb@mailosaur.in';
// var link, _tmpUser, activateToken = '';
// var link, _tmpUser, activateToken;
// this.timeout(15000);
// it('should be able to create a temporary (non-activated) User', function(done) {
// _User.email = _User.username = username;
@ -101,35 +102,50 @@
// // // });
// // // mailbox.getEmails(function(err, _emails) {
// // // if(err) done(err);
// // mailbox.getEmails(function(err, _emails) {
// // if(err) done(err);
// // // var emails = _emails;
// // var emails = _emails;
// // // console.log('mailbox.getEmails:');
// // // console.log(emails[0].text.links);
// // console.log('mailbox.getEmails:');
// // console.log(emails[0].text.links);
// // // var link = emails[0].text.links[0].href;
// // // activateToken = _(url.parse(link).hash.split('/')).reverse().value()[0];
// // // console.log('actual activateToken: '+ activateToken);
// // // console.log('expected activateToken: ' + user.GENERATED_VERIFYING_URL);
// // // (activateToken).should.equal(user.GENERATED_VERIFYING_URL);
// // var link = emails[0].text.links[0].href;
// // activateToken = _(url.parse(link).hash.split('/')).reverse().value()[0];
// // console.log('actual activateToken: '+ activateToken);
// // console.log('expected activateToken: ' + user.GENERATED_VERIFYING_URL);
// // (activateToken).should.equal(user.GENERATED_VERIFYING_URL);
// // // done();
// // // });
// // done();
// // });
// // });
// });
// });
// it('shold have created User Account', function(done){
// tmpUser.findOne({username: _User.username}, function (err, user) {
// should.not.exist(err);
// should.exist(user);
// _tmpUser = user;
// // it('should be able to verify a User Account', function(done) {
// // userSession.get('/auth/verify/'+activateToken)
// // .expect(200)
// // .end(function(VerifyErr, VerifyRes) {
// // should.not.exist(VerifyErr);
// // (VerifyRes.text).should.equal('User successfully verified');
// // done();
// // });
// // });
// _User.username.should.equal(user.username);
// _User.firstName.should.equal(user.firstName);
// _User.lastName.should.equal(user.lastName)
// activateToken = user.GENERATED_VERIFYING_URL;
// done();
// });
// });
// it('should be able to verify a User Account', function(done) {
// userSession.get('/auth/verify/'+activateToken)
// .expect(200)
// .end(function(VerifyErr, VerifyRes) {
// should.not.exist(VerifyErr);
// (VerifyRes.text).should.equal('User successfully verified');
// done();
// });
// });
// // it('should receive confirmation email after verifying a User Account', function(done) {
// // mailbox.getEmails(function(err, _emails) {
@ -142,7 +158,7 @@
// // done();
// // });
// // });
// // });
// });
// // it('should be able to login and logout a User', function (done) {
// // var username = 'testActiveAccount.be1e58fb@mailosaur.in';

View File

@ -0,0 +1,7 @@
##Goals/Tasks for Week of Sep 13
1.Get OscarHost demographics update/create to work
2. Add testing for user verification/reset password
3. Fix bugs in GUI (user login and form creation)
4. Start creating E2E tests for user login/signup
5. Start testing GUI on different browsers/resolutions

View File

@ -0,0 +1,7 @@
###User Stories
1. A new patient walks up to kiosk, fills out new patient form, is detected to be new user, is added to OscarHost EMR and then completes form.
2. A patient walks up to kiosk, fills out new patient form, is detected to be current user, updates OscarHost EMR profile, and then completes form.
3. Manager wants to update or create form, so he logs into system, updates form and then changes are reflected in kiosk at front of clinic.

View File

@ -0,0 +1,14 @@
KioskForm Requirements
======================
##MVP
-Must be webform accessible online
-Can create new/update current OscarHost patient from webform
-Forms must be editable by admin
-Forms questions must be showed/not showed by logic statement
-Must have basic input types (Phone, Legal Signature, Email, Phone, Name, Dropdown, etc)
###Optional
-Must be secure and encrypted ()