exports.__setup = function (test){ ctrl.seq([ curry([db],model.clean) , curry([platforms.concat(tests)],db.save,db) , curry([db], model.rollout) , test.done ]).go() }
const f = (base, path, options) => { if (typeof(base) === 'object' && !base.etagCaching) { const fetchFn = base.globalFetch ? fetch : isofetch return fetchFn(url.resolve(base.base, path), options) .then(curry(intercept)(base.base, path, options)) } return eFetch(url.resolve(base, path), options) .then(curry(intercept)(base, path, options)) }
exports ['can curry a function'] = function (){ var cx = curry([1],x) beF(cx) assert.deepEqual(cx(),[1,undefined,undefined]) var xc = curry(x,[1]) //if you don't pass in any args is does matter if it's left or right curried. beF(xc) assert.deepEqual(xc(),[1,undefined,undefined]) }
Situation.prototype.mark = function markSituation(){ var self = this; var mark = curry(['marked'], self._set, self); var mark_name; var additional_properties = {}; var callback = function(){}; switch(arguments.length){ case 1 : mark_name = arguments[0]; break; case 2 : mark_name = arguments[0]; callback = arguments[1]; break; case 3 : mark_name = arguments[0]; additional_properties = arguments[1]; callback = arguments[2]; break; } additional_properties.summary = "Marked '"+ mark_name.replace('_', ' ') +"'"; return mark.apply(self, [ mark_name, (new Date()).getTime(), additional_properties, callback ]); }
Situation.prototype.unmark = function unmarkSituation(){ var self = this; var unmark = curry(['marked'], self._unset, self); var mark_name; var additional_properties = {}; var callback = function(){}; switch(arguments.length){ case 1 : mark_name = arguments[0]; break; case 2 : mark_name = arguments[0]; callback = arguments[1]; break; case 3 : mark_name = arguments[0]; additional_properties = arguments[1]; callback = arguments[2]; break; } additional_properties.summary = [ "Removed mark '", mark_name.replace('_', ' '), "'" ].join(''); return unmark.apply(self, [ mark_name, additional_properties, callback ]); }
SimpleExecutor.prototype.executeNonRegQueryOnRemoteCall = function(queryId, configuration, origin) { var that = this; var callSenderPrototype = curry(function(origin, err, data) { var messageB = messageBuilderBuilder.QueryMessageBuilder().setQueryId(queryId).setSimpleType() .setOrigin(origin).setPayloadTypeData(); utilities.sendDataMessage(origin, messageB, data, that.storageApis); }); var callSender = callSenderPrototype(origin); utilities.getschema(configuration.namespace, this.storageApis, function(err, schema) { if (err) { logging.logRemoteErrorOnMissingschema(that.statisticHolder, configuration.namespace, queryId); } else { that.statisticHolder.emitEvent(constants.NEW_QUERY); that.runningData[queryId] = {}; that.queryConfigurations[queryId] = _buildMemoryForRemote(configuration, callSender, constants.STORE); that.queryConfigurations[queryId].primaryKey = schema.primaryKey; that.queryConfigurations[queryId].local = false; utilities.produceUnmarshallerDataFunction(schema, configuration.aggregations, function(unmarshaller) { that.queryConfigurations[queryId].unmarshaller = unmarshaller; that.queryConfigurations[queryId].configuration.timeoutValue = utilities.setTimeouts(queryId, callSender, -1, configuration.timeoutValue / 5.0, that); that.updateWithLocalMatch(queryId); }); } }); };
function run (test,adapter,done){ var opts = exports.callbacks , result = [] , remaps opts.adapter = adapters[adapter] if('object' == typeof test){ var _test = test test = Object.keys(_test)[0] remaps = _test[test] } //oldDone = opts.onSuiteDone opts.onSuiteDone = function (status,report) { result[0] = [status, report, false, remaps] log('report',result.length) suiteDone(status, report, false, remaps) } opts.onExit = curry(result,done) child.runFile ( require.resolve(test), opts, remaps) }
Situation.prototype.untag = function untagSituation(){ var self = this; var removeTag = curry(['tags'], self._remove, self); var tag_name; var additional_properties = {}; var callback = function(){}; switch(arguments.length){ case 1 : tag_name = arguments[0]; break; case 2 : tag_name = arguments[0]; callback = arguments[1]; break; case 3 : tag_name = arguments[0]; additional_properties = arguments[1]; callback = arguments[2]; break; } additional_properties.summary = "Removed tag '"+ tag_name +"'"; return removeTag.apply(self, [ tag_name, additional_properties, callback ]); }
StatisticHolder.prototype.informListeners = function(tag, data) { var runningQueries = curry(function(numberOfQueries, emitter) { emitter.emit(constants.RUNNING_QUERIES, numberOfQueries); }); var performance = curry(function(everageRunTime, emitter) { emitter.emit(constants.QUERY_PERF, everageRunTime); }); var log = curry(function(logLevel, text, emitter) { emitter.emit(logLevel, text); }); var execute = function() { }; var emitIt = true; switch (tag) { case constants.NEW_QUERY: execute = runningQueries(this.numberOfQueries); break; case constants.FIN_QUERY: execute = runningQueries(this.numberOfQueries); break; case constants.QUERY_PERF: var performanceL = this.averageRunningTime(); execute = performance(performanceL); break; case constants.LOG_INFO: execute = log(constants.LOG_INFO, data); break; case constants.LOG_FINE: execute = log(constants.LOG_FINE, data); if (this.logLevel === 0) emitIt = false; break; case constants.LOG_FINER: execute = log(constants.LOG_FINER, data); if (this.logLevel !== 2) emitIt = false; break; } if (emitIt) { this.listeners.forEach(execute); } };
before(function () { // create patient return auth.createTestUser(undefined, true).then(curry(common.createOtherPatient)({}, user)).then(function (p) { patient = p; // share patient return Q.nbind(patient.share, patient)(user.email, "default", "anyone"); }); });
exports ['math'] = function () { assert.equal( curry([3], function (x,y) { return x * 2 + y })(4), 3 * 2 + 4 ); }
describe("Show Single Medication (GET /patients/:patientid/medications/:medicationid)", function () { // given a patient ID, medication ID and access token, try and show the medication var show = module.exports.show = function (medicationId, patientId, accessToken) { var url = util.format("http://localhost:5000/v1/patients/%d/medications/%d", patientId, medicationId); return chakram.get(url, auth.genAuthHeaders(accessToken)); }; var showMedication = function (patient, medication) { return show(medication._id, patient._id, patient.user.accessToken); }; patients.itRequiresAuthentication(curry(show)(1)); patients.itRequiresValidPatientId(curry(show)(1)); common.itRequiresReadAuthorization(showMedication); it("lets me view medications referencing pharmacies and doctors", function () { // we validate the child pharmacy and doctor schema return patients.testMyPatient({}).then(function (patient) { var createPharmacy = Q.nbind(patient.createPharmacy, patient); var createDoctor = Q.nbind(patient.createDoctor, patient); var createMedication = Q.nbind(patient.createMedication, patient); var ep = createPharmacy({ name: "test pharmacy" }).then(function () { return createDoctor({ name: "test doctor" }); }).then(function () { return createMedication({ name: "loratadine", pharmacy_id: patient.pharmacies[0]._id, doctor_id: patient.doctors[0]._id }); }).then(function (medication) { return show(medication._id, patient._id, patient.user.accessToken); }); return expect(ep).to.be.a.medication.viewSuccess; }); }); });
exports ['right curry'] = function (){ function callback() { // assert.finish() } var fn = curry(x,['callback:',callback]) , list = [1,2,3,4,5] , r = fn(list) assert.deepEqual(r,[list,'callback:',callback]) assert.deepEqual(r[2],callback) r[2]() }
exports ['can curry a function, this passed in'] = function (){ var s = {helo: 'asdfvnurowfn249r00jy4'} var ys = curry(y,s) var cys = curry([1],y,s) var ycs = curry(y,[2],s) var cycs = curry([1],y,[2],s) beF(ys) assert.deepEqual(ys('X'),{self: s, args: ['X',undefined,undefined]}) assert.deepEqual(cys('X'),{self: s, args: [1,'X',undefined]}) assert.deepEqual(ycs('X'),{self: s, args: ['X',2,undefined]}) assert.deepEqual(cycs('X'),{self: s, args: [1,'X',2]}) /* that was easy! */ }
before(function () { // setup user and medication // setup current user and two patients for them, both with a medication return auth.createTestUser() .then(curry(patients.createMyPatient)({})) .then(function (p) { patient = p; }) .then(function () { var med1 = Q.nbind(patient.createMedication, patient)({ name: "foobar" }); var med2 = Q.nbind(patient.createMedication, patient)({ name: "foobar" }); return med1.then(med2); }); });
Situation.prototype.alias = function changeSituationAlias(){ var self = this; var fn_args = arguments; var changeAlias = curry(['alias'], self._change, self); var alias; var callback = function(){}; var additional_properties = {}; switch(arguments.length){ case 1 : alias = arguments[0]; break; case 2 : alias = arguments[0]; callback = arguments[1]; break; case 3 : alias = arguments[0]; additional_properties = arguments[1]; callback = arguments[2]; break; } Situation.identify(alias, function(id_error, id){ if (id_error){ if (id_error.error == 'not_found'){ return changeAlias.apply(self, fn_args); } return callback(id_error, null); } var situation = new Situation(id); situation.readField('alias', function(read_error, situation_alias){ if (read_error){ return callback(read_error, null); } if (situation_alias != alias){ return changeAlias.apply(self, fn_args); } var error = { error: "taken", message: "Already being used by another situation." } return callback(error, null); }); }); }
var updateUser = function (data, modifications) { var updateWithMods = curry(update)(modifications); // also store access token so we can check if it's revoked later // and user so we can try authentication return fixtures.create("User", data).then(function (u) { user = u; credentials = { email: user.email, password: user.rawPassword }; return user; }).then(auth.genAccessToken).then(function (t) { token = t; return token; }).then(updateWithMods); };
client.on('message', function (channel, message) { //console.log('MESSAGE:',message); try { data = JSON.parse(message); } catch (e) { console.error(did + 'subsystem error with redis result: '+ e, message); throw new Error('invalid JSON data received from redis subsystem queue '+e); } if ((!data.verb) || (!data.actor) || (!data.actor.platform)) { throw new Error(did + 'data object on subsystem channel not valid '+JSON.stringify(data)); } if (data.actor.platform === platform) { // skip your own messages console.debug(did + 'skipping own message'); } else if ((typeof data.status !== 'undefined') && (data.status)) { if (data.target[0].platform !== platform) { // skip ping responses not address to us console.debug(did + 'skipping ping response not addressed to this platform'); } else { // this is a ping response. console.info(did + 'received response to a ping from '+data.actor.platform); events.emit('ping-response', data); } } else if ((!data.target) || (data.target.length === 0) || (data.target[0].platform === platform)) { // we received a ping initiation. so we respond. responseCallbackCalled = false; console.log('emitting ping and ping-with-callback, target:', data.target); events.emit('ping', data); events.emit('ping-with-callback', data, curry(['ping',data.actor.platform], responseCallback)); setTimeout(function () { if (responseCallbackCalled) { return; } console.warn(did + 'callback never executed, responding to ping directly'); responseCallback('ping', data.actor.platform); }, 1000); } });
describe("Create New Patient (POST /patients)", function () { // simple endpoint var create = function (data, accessToken) { return chakram.post("http://*****:*****@address.com" }, user.accessToken).then(function (response) { expect(response).to.be.a.patient.createSuccess; expect(response.body.creator).to.equal(user.email); }); }); }); // access levels it("lets me set the 'anyone' access level to a valid value", function () { return expect(createPatient({ access_anyone: "read" })).to.be.a.patient.createSuccess; }); it("doesn't let me set the 'anyone' access level to null", function () { return expect(createPatient({ access_anyone: null })).to.be.an.api.error(400, "invalid_access_anyone"); }); it("doesn't let me set the 'anyone' access level to blank", function () { return expect(createPatient({ access_anyone: "" })).to.be.an.api.error(400, "invalid_access_anyone"); }); it("doesn't let me set the 'anyone' access level to an invalid value", function () { return expect(createPatient({ access_anyone: "foo" })).to.be.an.api.error(400, "invalid_access_anyone"); }); it("lets me set the 'family' access level to a valid value", function () { return expect(createPatient({ access_family: "read" })).to.be.a.patient.createSuccess; }); it("doesn't let me set the 'family' access level to null", function () { return expect(createPatient({ access_family: null })).to.be.an.api.error(400, "invalid_access_family"); }); it("doesn't let me set the 'family' access level to blank", function () { return expect(createPatient({ access_family: "" })).to.be.an.api.error(400, "invalid_access_family"); }); it("doesn't let me set the 'family' access level to an invalid value", function () { return expect(createPatient({ access_family: "foo" })).to.be.an.api.error(400, "invalid_access_family"); }); it("lets me set the 'prime' access level to a valid value", function () { return expect(createPatient({ access_prime: "read" })).to.be.a.patient.createSuccess; }); it("doesn't let me set the 'prime' access level to null", function () { return expect(createPatient({ access_prime: null })).to.be.an.api.error(400, "invalid_access_prime"); }); it("doesn't let me set the 'prime' access level to blank", function () { return expect(createPatient({ access_prime: "" })).to.be.an.api.error(400, "invalid_access_prime"); }); it("doesn't let me set the 'prime' access level to an invalid value", function () { return expect(createPatient({ access_prime: "foo" })).to.be.an.api.error(400, "invalid_access_prime"); }); });
return prePattern + (urlPattern ? urlPattern.replace(/\/$/, '') + postPattern : ''); } var registerRoute = curry(function(securityLevel, category, method, name, urlPattern, handler, parameters, description) { var enforcedPattern = applyPatternSettings(urlPattern); var routeKey = method + ':' + enforcedPattern; var isSecured = securityLevel === SECURED; var route = { "secured": isSecured , "category": category , "method": method , "name": name , "pattern": enforcedPattern , "handler": isSecured ? authenticationHandlers.concat([handler]) : [handler] , "parameters": parameters , "description": description }; if (routes[routeKey]) { registeredRouteError.emit('registrationError', route); return; } routes[routeKey] = route; registeredRoute.emit('registeredSuccessfully', route); }); const registerPublicRoute = registerRoute(PUBLIC, null); const registerAuthenticatedRoute = registerRoute(SECURED, null);
connection.on("message", function (message) { errorSent = false; //console.debug(' [dispacher] shutdown:'+Dispatcher.inShutdown); if (Dispatcher.inShutdown) { // shutdown in progress console.debug(' [dispatcher:' + sessionId + '] shutdown in progress,' + ' cannot receive new messages'); } else if (message.type === 'utf8') { // incoming message to handle console.info(' [dispatcher:' + sessionId + '] received message'); var obj = false; try { obj = JSON.parse(message.utf8Data); } catch (e) { console.error(' [dispatcher:' + sessionId + '] invalid JSON!'); sendError(undefined, undefined, undefined, 'invalid JSON received'); return false; } var m = []; // list of incomming requests if (typeof obj[0] === 'object') { // list of requests m = obj; } else { // single request m[0] = obj; } for (var i = 0, numObjs = m.length; i < numObjs; i = i + 1) { var rid = m[i].rid, platform = m[i].platform, verb = m[i].verb, o = m[i]; if ((typeof rid !== 'string') && (typeof rid !== 'number')) { sendError(undefined, undefined, 'confirm', 'no rid (request ID) specified'); } else if (typeof platform !== 'string') { sendError(rid, undefined, 'confirm', 'no platform specified'); } else if (typeof verb !== 'string') { sendError(rid, platform, 'confirm', 'no verb (action) specified'); } else if (typeof _this.proto.platforms[platform] !== 'object') { sendError(rid, platform, 'confirm', 'unknown platform received: ' + platform); } else if (typeof _this.proto.platforms[platform].verbs[verb] !== 'object') { sendError(rid, platform, 'confirm', 'unknown verb received: ' + verb); } else if (typeof m[i].sessionId !== 'undefined') { sendError(rid, platform, 'confirm', 'cannot use name sessionId, reserved property'); } else if ((!session.isRegistered()) && (o.verb !== 'register')) { sendError(rid, platform, 'confirm', 'session not registered, cannot process verb'); } if (errorSent) { return false; } var jsv = _this.JSVlib.createEnvironment(); var report = jsv.validate(o, _this.proto.verbs[verb].schema); var onError = curry([rid, platform, verb], sendError); var onMessage = curry([rid, platform, verb], sendMessage); var responseHandler = initResponseHandler(onError, onMessage); if (report.errors.length === 0) { // incoming json validated o.sessionId = ""+sessionId; // add sessionId to sendConfirm(rid); // confirm request is valid and will be processed if (typeof _this.proto.platforms[platform].verbs[verb].func === 'function') { _this.proto.platforms[platform].verbs[verb].func(o, session, responseHandler); } else { var channel = 'sockethub:'+_this.sockethubId+':listener:' + platform + ':incoming'; console.info(' [dispatcher:'+sessionId+'] sending verb "' + verb + '" to channel ' + channel); var json_o = JSON.stringify(o); _this.util.redis.set('lpush', channel, json_o); } } else { // errors validating incoming json onError('unable to validate json against schema'); console.error(' [dispatcher:'+sessionId+'] JSV validation error: '+JSON.stringify(report.errors)); } } } else if (message.type === 'binary') { // we don't do anything with this at the moment console.info(' ['+protoName+'] received binary message of ' + message.binaryData.length + ' bytes'); connection.sendBytes(message.binaryData); } });
describe("Update Single Patient (PUT /patients/:patientid)", function () { // simple endpoint var edit = function (data, patientId, accessToken) { var headers = auth.genAuthHeaders(accessToken); return chakram.put("http://*****:*****@creator.com" }).then(function (response) { expect(response).to.be.a.patient.success; expect(response.body.creator).to.not.equal("*****@*****.**"); }); }); it("doesn't let the owner change their group", function () { return expect(editAPatient({}, { group: "prime" })).to.be.an.api.error(400, "is_owner"); }); it("doesn't let the owner change their access level to read-only", function () { return expect(editAPatient({}, { access: "read" })).to.be.an.api.error(400, "is_owner"); }); it("doesn't let the owner remove their access", function () { return expect(editAPatient({}, { access: "none" })).to.be.an.api.error(400, "is_owner"); }); describe("with a patient shared with me with write access", function () { var patient; beforeEach(function () { // create a patient return Q.all([auth.createTestUser(), auth.createTestUser()]) .spread(common.createOtherPatient({})) .then(function (p) { patient = p; // share the patient // prime defaults to write ability return Q.nbind(patient.share, patient)(patient.user.email, "write", "prime"); }); }); it("lets me change their group to prime", function () { return expect(editPatient({ group: "prime" }, patient)).to.be.a.patient.success; }); it("lets me change their group to family", function () { return expect(editPatient({ group: "family" }, patient)).to.be.a.patient.success; }); it("lets me change their group to anyone", function () { return expect(editPatient({ group: "anyone" }, patient)).to.be.a.patient.success; }); it("doesn't let me change their group to owner", function () { return expect(editPatient({ group: "owner" }, patient)).to.be.an.api.error(400, "invalid_group"); }); it("doesn't let me change their group an invalid group", function () { return expect(editPatient({ group: "foo" }, patient)).to.be.an.api.error(400, "invalid_group"); }); it("doesn't let me change their group to blank", function () { return expect(editPatient({ group: "" }, patient)).to.be.an.api.error(400, "invalid_group"); }); it("doesn't let me change their group to null", function () { return expect(editPatient({ group: null }, patient)).to.be.an.api.error(400, "invalid_group"); }); it("lets me explicitly set their access level to read", function () { return editPatient({ access: "read" }, patient).then(function (response) { expect(response).to.be.a.patient.success; expect(response.body.access).to.equal("read"); // should have read access now but not write access expect(view.showPatient(patient)).to.be.a.patient.success; expect(editPatient({}, patient)).to.be.an.api.error(403, "unauthorized"); return chakram.wait(); }); }); it("lets me explicitly set their access level to write", function () { return editPatient({ access: "write" }, patient).then(function (response) { expect(response).to.be.a.patient.success; expect(response.body.access).to.equal("write"); // should have read and write access still expect(view.showPatient(patient)).to.be.a.patient.success; expect(editPatient({}, patient)).to.be.a.patient.success; return chakram.wait(); }); }); it("lets me explicitly set their access level to none", function () { return editPatient({ access: "none" }, patient).then(function (response) { expect(response).to.be.a.patient.success; expect(response.body.access).to.equal("none"); // should no longer have read or write access expect(view.showPatient(patient)).to.be.an.api.error(403, "unauthorized"); expect(editPatient({}, patient)).to.be.an.api.error(403, "unauthorized"); return chakram.wait(); }); }); it("lets me explicitly set their access level to default", function () { return editPatient({ access: "default" }, patient).then(function (response) { expect(response).to.be.a.patient.success; // bubbling up to patient permissions: prime = write expect(response.body.access).to.equal("write"); // should have read and write access still expect(view.showPatient(patient)).to.be.a.patient.success; expect(editPatient({}, patient)).to.be.a.patient.success; return chakram.wait(); }); }); it("doesn't let me change their access level to an invalid value", function () { return expect(editPatient({ access: "foo" }, patient)).to.be.an.api.error(400, "invalid_access"); }); it("doesn't let me change their access level to blank", function () { return expect(editPatient({ access: "" }, patient)).to.be.an.api.error(400, "invalid_access"); }); it("doesn't let me change their access level to null", function () { return expect(editPatient({ access: null }, patient)).to.be.an.api.error(400, "invalid_access"); }); }); // patient-wide access levels it("lets me set the 'anyone' access level to a valid value", function () { return expect(editAPatient({}, { access_anyone: "read" })).to.be.a.patient.success; }); it("doesn't let me set the 'anyone' access level to null", function () { return expect(editAPatient({}, { access_anyone: null })).to.be.an.api.error(400, "invalid_access_anyone"); }); it("doesn't let me set the 'anyone' access level to blank", function () { return expect(editAPatient({}, { access_anyone: "" })).to.be.an.api.error(400, "invalid_access_anyone"); }); it("doesn't let me set the 'anyone' access level to an invalid value", function () { return expect(editAPatient({}, { access_anyone: "foo" })).to.be.an.api.error(400, "invalid_access_anyone"); }); it("lets me set the 'family' access level to a valid value", function () { return expect(editAPatient({}, { access_family: "read" })).to.be.a.patient.success; }); it("doesn't let me set the 'family' access level to null", function () { return expect(editAPatient({}, { access_family: null })).to.be.an.api.error(400, "invalid_access_family"); }); it("doesn't let me set the 'family' access level to blank", function () { return expect(editAPatient({}, { access_family: "" })).to.be.an.api.error(400, "invalid_access_family"); }); it("doesn't let me set the 'family' access level to an invalid value", function () { return expect(editAPatient({}, { access_family: "foo" })).to.be.an.api.error(400, "invalid_access_family"); }); it("lets me set the 'prime' access level to a valid value", function () { return expect(editAPatient({}, { access_prime: "read" })).to.be.a.patient.success; }); it("doesn't let me set the 'prime' access level to null", function () { return expect(editAPatient({}, { access_prime: null })).to.be.an.api.error(400, "invalid_access_prime"); }); it("doesn't let me set the 'prime' access level to blank", function () { return expect(editAPatient({}, { access_prime: "" })).to.be.an.api.error(400, "invalid_access_prime"); }); it("doesn't let me set the 'prime' access level to an invalid value", function () { return expect(editAPatient({}, { access_prime: "foo" })).to.be.an.api.error(400, "invalid_access_prime"); }); });
var editAPatient = function (data, modifications) { return common.testMyPatient(data).then(curry(editPatient)(modifications)); };
describe("Share Patient with User (POST /patients/:patientid/shares)", function () { // share the passed patient with a user (user specified in data) var share = function (data, patientId, accessToken) { var url = util.format("http://*****:*****@bar.com" })).to.be.a.share.createSuccess; }); // check a valid group is required it("requires a group", function () { return expect(shareAPatientWithExisting({ group: undefined })).to.be.an.api.error(400, "invalid_group"); }); it("rejects a null group", function () { return expect(shareAPatientWithExisting({ group: null })).to.be.an.api.error(400, "invalid_group"); }); it("rejects a blank group", function () { return expect(shareAPatientWithExisting({ group: "" })).to.be.an.api.error(400, "invalid_group"); }); it("rejects an invalid group", function () { return expect(shareAPatientWithExisting({ group: "foo" })).to.be.an.api.error(400, "invalid_group"); }); it("rejects group being owner", function () { return expect(shareAPatientWithExisting({ group: "owner" })).to.be.an.api.error(400, "invalid_group"); }); it("accepts a valid group", function () { return expect(shareAPatientWithExisting({ group: "anyone" })).to.be.a.share.createSuccess; }); // check a valid access level (read/write/default is required) it("requires an access level", function () { return expect(shareAPatientWithExisting({ access: undefined })).to.be.an.api.error(400, "invalid_access"); }); it("rejects a null access level", function () { return expect(shareAPatientWithExisting({ access: null })).to.be.an.api.error(400, "invalid_access"); }); it("rejects a blank access level", function () { return expect(shareAPatientWithExisting({ access: "" })).to.be.an.api.error(400, "invalid_access"); }); it("rejects an invalid access level", function () { return expect(shareAPatientWithExisting({ access: "foo" })).to.be.an.api.error(400, "invalid_access"); }); it("accepts a valid access level", function () { return expect(shareAPatientWithExisting({ access: "read" })).to.be.a.share.createSuccess; }); it("accepts a valid default access level", function () { return expect(shareAPatientWithExisting({ access: "default" })).to.be.a.share.createSuccess; }); it("lets me share with an existing user", function () { return shareAPatientWithExisting().then(function (response) { expect(response).to.be.a.share.createSuccess; expect(response.body.is_user).to.be.true; }); }); describe("sharing with a user who doesn't exist yet", function () { var patient, shareId; it("lets me share with them initially", function () { return patients.testMyPatient({}).then(function (p) { patient = p; return sharePatient({ email: "*****@*****.**" }, patient); }).then(function (response) { expect(response).to.be.a.share.createSuccess; expect(response.body.is_user).to.be.false; shareId = response.body.id; }); }); describe("after the user is created", function () { // create user before(function () { return fixtures.create("User", { email: "*****@*****.**" }); }); it("shows that the user now exists", function () { // no view endpoint, so we hackishly use the edit one var url = util.format("http://localhost:5000/v1/patients/%d/shares/%d", patient._id, shareId); var headers = auth.genAuthHeaders(patient.user.accessToken); return chakram.put(url, {}, headers).then(function (response) { expect(response).to.be.a.share.success; expect(response.body.is_user).to.be.true; }); }); }); }); });
exports.createHTML = function(html, whitelist, callback) { var filter, filterWithWhitelist, parser, walker, handler, htmlparser = require("htmlparser2"), entities = require("entities"), curry = require("curry"), //needed to make $.createStyle available to this function (which must be invoked with .call) $ = this; filter = curry(function(whitelist, html, callback) { var filterhtml = require("filterhtml"), result, textFilter; try { textFilter = function(text, stack) { //stack length greater than zero means text is in a whitelisted tag if (stack.length > 0) { return text; } //disgard tag and contents if not whitelisted. Returning null or undefined will bomb out filterhtml return ''; }; //filterhtml.filter_html ti-htmlcontract is (html text, white list json, allowed url schemas, text replacement function) result = filterhtml.filter_html(html, whitelist, ['http', 'https'], textFilter); callback(null, result); } catch(ex) { callback(ex); } }); filterWithWhitelist = filter(whitelist); walker = function(dom, outerFont) { var tree = [], tiObjects = [], objects = [], createLabel, getTableRowItems, getLabels, getImages, counter = 1; /* * Helper functions */ getImages = function(item) { var images = [], obj = {}; item = item || { attribs : { } }; try { obj.src = item.attribs.src; if (item.attribs.height && item.attribs.width) { obj.height = item.attribs.height; obj.width = item.attribs.width; } else { obj.height = Ti.UI.SIZE; obj.width = Ti.UI.SIZE; } obj.type = "imageView"; images.push(obj); } catch(ex) { console.error(ex); } finally { return images; } }; getLabels = function(item) { var obj = { links : [], texts : [] }, txt = "", childLabels = [], images = [], key, innerFont = {}; try { obj.type = "label"; obj.class = item.name; //shallow clone of outerFont for (key in outerFont) { if (outerFont.hasOwnProperty(key)) { innerFont[key] = outerFont[key]; } } //record if it has come from a ul or ol if (item && item.parent && item.parent.name && (['ul', 'ol'].indexOf(item.parent.name) !== -1)) { obj.parent = item.parent.name; } if (item.children && item.children.length > 0) { //TODO refactor as cyclomatic complexity is too high (use a platform switch style function) item.children.map(function(child) { if (child.type === "text" && child.data) { txt = entities.decodeHTML(child.data); obj.texts.push(txt); //add attributed strings if (item.name === 'em' || item.name === 'i') { innerFont.fontStyle = 'italic'; innerFont.fontWeight = 'normal'; obj.links.push({ text : item.attribs.title || txt, type : Ti.UI.ATTRIBUTE_FONT, value : innerFont }); } if (item.name === 'strong' || item.name === 'b') { innerFont.fontStyle = 'normal'; innerFont.fontWeight = 'bold'; obj.links.push({ text : item.attribs.title || txt, type : Ti.UI.ATTRIBUTE_FONT, value : innerFont }); } if (item.name === 'u') { obj.links.push({ text : item.attribs.title || txt, type : Ti.UI.ATTRIBUTE_UNDERLINES_STYLE, value : Ti.UI.ATTRIBUTE_UNDERLINE_STYLE_SINGLE }); } if (item.name === 'strike' || item.name === 's' || item.name === 'del') { obj.links.push({ text : item.attribs.title || txt, type : Ti.UI.ATTRIBUTE_STRIKETHROUGH_STYLE, value : Ti.UI.ATTRIBUTE_UNDERLINE_STYLE_SINGLE }); } if (item.name === 'a' && item.attribs.href) { obj.links.push({ value : item.attribs.href, text : item.attribs.title || txt, type : Titanium.UI.ATTRIBUTE_LINK }); } } else if (child.type === "tag") { //just push paragraph embedded images straight into objects array for assembly into a ti object if (child.name === "img") { images = getImages(child); images.map(function(image) { objects.push(image); }); } else { //recurse childLabels = getLabels(child); childLabels.map(function(lbl) { lbl.texts.map(function(txt) { obj.texts.push(txt); }); lbl.links.map(function(link) { obj.links.push(link); }); }); } } }); } } catch(ex) { console.error(ex); } finally { return [obj]; } }; getTableRowItems = function(data) { var kids = []; try { data.map(function(item) { var obj = {}; obj.type = "tableViewRow"; obj.attribs = item.attribs; //should not be anything else, but just in case if (item.type === "tag" && item.children) { var txt = ''; item.children.map(function(child) { if (child.type === "text" && child.data) { obj.text = entities.decodeHTML(child.data); } else if (child.type === "tag") { //if its a header we will make it a tableViewSection if (child.name === "th") { obj.type = "tableViewSection"; } else { obj.type = "tableViewRow"; } if (child.children) { child.children.map(function(kid) { if (kid.type === "text" && kid.data) { txt = txt + " " + kid.data; } }); obj.text = txt; } } }); } kids.push(obj); }); } catch(ex) { console.error(ex); } finally { return kids; } }; createLabel = function(obj, style) { var lbl, attr, attributes = [], useAS = false, text; try { obj = obj || {}; text = obj.text; //ul if (obj.parent === "ul") { text = "\u2022 " + text; } //ol if (obj.parent === "ol") { text = "" + counter + " " + text; counter++; } else { //reset the counter if another tag is encountered counter = 1; } if (obj.links && obj.links.length > 0) { useAS = true; obj.links.map(function(link) { attributes.push({ type : link.type, value : link.value, range : [text.indexOf(link.text), (link.text).length] }); }); } if (useAS) { attr = Ti.UI.createAttributedString({ text : text, attributes : attributes }); lbl = Ti.UI.createLabel({ attributedString : attr }); lbl.addEventListener('link', function(e) { var intent; if (Ti.Platform.osname !== "android") { Ti.Platform.openURL(e.url); } else { intent = Ti.Android.createIntent({ action : Ti.Android.ACTION_VIEW, data : e.url }); Ti.Android.currentActivity.startActivity(intent); } }); } else { lbl = Ti.UI.createLabel({ text : text }); } lbl.applyProperties(style); } catch(ex) { console.error(ex); } finally { return lbl; } }; try { if (dom) { if (dom.slice) { tree = dom.slice(); } tree.map(function(item) { var obj = {}, images = [], labels = [], specialTags = ['img', 'table', 'td', 'th', 'tr', 'ol', 'ul', 'li']; if (item.children) { walker(item.children, outerFont); } if (item.type === "tag") { if (item.name === "hr") { obj.type = "hr"; obj.class = "hr"; objects.push(obj); } else if (specialTags.indexOf(item.name) === -1) { //reinitialise labels array as getLabels is recursive labels = getLabels(item); labels.map(function(label) { label.text = label.texts.join(""); delete label.texts; objects.push(label); }); } else if (item.name === "img") { images = getImages(item); images.map(function(image) { objects.push(image); }); } else { obj.type = item.name; obj.attribs = item.attribs; if (item.children && item.children.length > 0) { if (item.name === 'ol' || item.name === 'ul') { item.children.map(function(child) { labels = getLabels(child); labels.map(function(label) { label.text = label.texts.join(""); delete label.texts; objects.push(label); }); }); } else if (item.name === 'table') { obj.type = "tableView"; obj.class = "tableViewRow"; obj.children = getTableRowItems(item.children); objects.push(obj); } } } } }); } //create the titanium objects objects.map(function(obj) { var lbl, klass, style, iv, vw; obj = obj || {}; if (obj.class) { klass = obj.class; } else { klass = obj.type; } //note that you need to to use .call($) to bind createStyle to your page style = $.createStyle({ classes : klass, apiName : 'Label' }); if (obj.type === "label" && obj.text) { obj.apiName = 'Label'; lbl = createLabel(obj, style); if (lbl) { tiObjects.push(lbl); } } if (obj.type === "hr") { style = $.createStyle({ classes : "hr", apiName : 'View' }); vw = Ti.UI.createView(); vw.applyProperties(style); tiObjects.push(vw); } if ((obj.type === "tableView") ) { //use a counter for <ol> elements obj.children.map(function(child) { var txt = child.text; if (child.class) { klass = child.class; } else { klass = child.type; } if (child.type === "tableViewSection" && child.text) { style = $.createStyle({ classes : "tableViewHeader", apiName : 'Label' }); } else if ((child.type === "tableViewRow") && child.text) { style = $.createStyle({ classes : klass, apiName : 'Label' }); } child.text = txt; lbl = createLabel(child, style); if (lbl) { tiObjects.push(lbl); } }); } if (obj.type === "imageView" && obj.src && obj.height && obj.width) { iv = Ti.UI.createImageView({ "image" : obj.src, "height" : obj.height, "width" : obj.width }); style = $.createStyle({ classes : 'imageView', apiName : 'ImageView' }); iv.applyProperties(style); tiObjects.push(iv); } }); } catch(ex) { console.error(ex); } finally { objects = null; return tiObjects; } }; handler = new htmlparser.DomHandler(function(error, dom) { //we pass some default font attributes for use by AS styling var font = { fontSize : 12 }; try { if (error) { callback(error); } else { callback(null, walker(dom, font)); } } catch(ex) { callback(ex); } }); parser = new htmlparser.Parser(handler); // jshint ignore:line //remove whitespace and line breaks from markup html = require('htmlclean')(html); //filter the supplied HTML and fire the callback filterWithWhitelist(html, function(error, data) { if (error) { callback(error); } else { //note that the handler function fires the success callback parser.parseComplete(data); } }); };
var shareAPatientWithExisting = function (data) { return patients.testMyPatient({}).then(curry(sharePatientWithExisting)(data)); };
Situation.prototype.title = function changeSituationTitle(){ var self = this; var changeTitle = curry(['title'], self._change, self); return changeTitle.apply(self, arguments); }
Situation.prototype.description = function changeSituationDescription(){ var self = this; var changeDescription = curry(['description'], self._change, self); return changeDescription.apply(self, arguments); }
Situation.prototype.location = function changeSituationLocation(){ var self = this; var changeLocation = curry(['location'], self._change, self); return changeLocation.apply(self, arguments); }
Situation.prototype.period = function changeSituationPeriod(){ var self = this; var changePeriod = curry(['period'], self._change, self); return changePeriod.apply(self, arguments); }