From ba822834e80226dcdbd2d9680cb864e3cf301f07 Mon Sep 17 00:00:00 2001 From: Camilo Aguilar Date: Wed, 22 Feb 2012 18:17:50 -0500 Subject: [PATCH] Adds Usage API along with tests and bumps version. --- configuration/lib/swarm.js | 2 +- configuration/lib/usage.js | 98 ++++++++++++++++ configuration/package.json | 5 +- configuration/specs/usage.spec.js | 186 ++++++++++++++++++++++++++++++ participation/package.json | 2 +- 5 files changed, 289 insertions(+), 4 deletions(-) create mode 100644 configuration/lib/usage.js create mode 100644 configuration/specs/usage.spec.js diff --git a/configuration/lib/swarm.js b/configuration/lib/swarm.js index 625d921..84bbd32 100644 --- a/configuration/lib/swarm.js +++ b/configuration/lib/swarm.js @@ -2,7 +2,7 @@ var request = require('superagent'); var config = require('../config'); var Swarm = function(key) { - if (!key || !key.length) { + if (!key || !key.length) { throw new TypeError('You must provide an API Key to ' + 'create an instance of this class.'); } diff --git a/configuration/lib/usage.js b/configuration/lib/usage.js new file mode 100644 index 0000000..f8e85ae --- /dev/null +++ b/configuration/lib/usage.js @@ -0,0 +1,98 @@ +var request = require('superagent'); +var config = require('../config'); + +var Usage = function(key) { + if (!key || !key.length) { + throw new TypeError('You must provide an API Key to ' + + 'create an instance of this class.'); + } + this.apikey = key; + this.url = config.baseurl + '/usage'; +}; + +(function() { + var apikeyHeader = config.apikey_header; + + /** + * Returns detailed or totalized information + * about sent and received messages. + * @param {Object} filter An optinal filter object. + * @param {Function} callback The callback function. + * + * The filter object should have the following properties: + * { + * from: A String with an ISO8601 Date, indicating the initial + * date from where you want to make the query. + * to: A String with an ISO8601 Date indicating the end + * date. + * resource_id: A String with a resource id. + * swarm_id: A String with a swarm id. + * totalized: A Boolean indicating whether you want to get the + * total usage or not. + * page: A Number with the result page you want to get. + * count: The number of results you would like to get. + * orderby: A string with the name of the field by which you would like to sort the result. + * sort: A string with 'asc' or desc' that determines the order +of the result. + * + * } + * + * @public + **/ + this.get = function() { + var filter, callback; + var arglen = arguments.length; + + if (arglen > 2 || arglen < 1) { + var arglen = arguments.length; + throw new TypeError('Wrong number of arguments. ' + + 'In order to invoke this function you need ' + + 'to provide one or two arguments.'); + } + + if (arglen == 1) { + callback = arguments[0]; + if (typeof callback !== 'function') { + throw new TypeError('When invoking with one ' + + 'argument, a callback function is expected.'); + + } + } else if (arglen == 2) { + filter = arguments[0]; + callback = arguments[1]; + + if (typeof filter !== 'object' || + typeof callback !== 'function') { + throw new TypeError('When invoking with two ' + + 'arguments, an object is expected as the first ' + + 'argument and a callback function as the second argument.'); + } + + /** + * Workaround for superagent given that it + * doesn't handle boolean values properly when + * sending data through the query string. + **/ + filter.totalized = filter.totalized ? 'true' : 'false'; + } + + var url = this.url; + + request + .get(url + '/messages') + .send(filter) + .set(apikeyHeader, this.apikey) + .end(function(res) { + var err; + if (res.status == 200) { + callback(err, res.body); + } else { + err = res.body || res.text; + callback(err); + } + }); + } +}).call(Usage.prototype); + +module.exports = Usage; + diff --git a/configuration/package.json b/configuration/package.json index 117e371..e90a00f 100644 --- a/configuration/package.json +++ b/configuration/package.json @@ -1,7 +1,7 @@ { "name": "bugswarm-cfg", "description": "[Configuration] BUGswarm is platform that allows you to share and access your hardware sensor data easily and effortlessly.", - "version": "0.2.0", + "version": "0.2.1", "keywords" : [ "m2m", "IoT", "realtime", "messaging", "sensor", "hardware", "socket", "configuration"], "homepage": "http://developer.bugswarm.net", "author": "BugLabs Inc.", @@ -11,7 +11,8 @@ }, "devDependencies": { "should": "0.5.1", - "mocha": "0.10.0" + "mocha": "0.10.0", + "bugswarm-prt": "0.2.0" }, "dependencies": { "superagent": "0.3.0" diff --git a/configuration/specs/usage.spec.js b/configuration/specs/usage.spec.js new file mode 100644 index 0000000..af33d16 --- /dev/null +++ b/configuration/specs/usage.spec.js @@ -0,0 +1,186 @@ +var SwarmService = require('../lib/swarm'); +var ResourceService = require('../lib/resource'); +var ApiKeyService = require('../lib/apikey'); +var UsageService = require('../lib/usage'); + +var bugswarmprt = require('bugswarm-prt'); +var Prosumer = bugswarmprt.Swarm; + +describe('Usage service', function() { + var swarmId; + var prosumerId; + var cfgKey; + var prtKey; + + var lastRecord = {}; + + var apikeyService; + var swarmService; + var resourceService; + var usageService; + + before(function(done) { + apikeyService = new ApiKeyService('librarytest', 'test123'); + apikeyService.generate(function(err, keys) { + for(var i in keys) { + if(keys[i].type == 'configuration') { + cfgKey = keys[i].key; + } else { + prtKey = keys[i].key; + } + } + swarmService = new SwarmService(cfgKey); + resourceService = new ResourceService(cfgKey); + usageService = new UsageService(cfgKey); + done(); + }); + }); + + it('should prepare the environment for this test suite', function(done) { + var data = { + name: 'my swarm', + public: false, + description: 'my swarm description' + }; + + //creates swarm + swarmService.create(data, + function(err, swarm) { + swarmId = swarm.id; + + var data = { + name: 'my resource', + description: 'my description', + machine_type: 'bug' + }; + + //creates resource + resourceService.create(data, function(err, resource) { + var options = { + swarm_id: swarmId, + resource_id: resource.id, + resource_type: 'consumer' + }; + + prosumerId = resource.id; + //adds resource as consumer + swarmService.addResource(options, function(err) { + options.resource_type = 'producer'; + //adds resource as producer + swarmService.addResource(options, function(err) { + done(); + }); + }); + }); + }); + }); + + it('should generate some messages', function(done) { + var options = { + apikey: prtKey, + resource: prosumerId, + swarms: swarmId + }; + + var prosumer = new Prosumer(options); + prosumer.on('error', function(err) { + assert.isUndefined(err); + prosumer.disconnect(); + }); + + prosumer.on('presence', function(presence) { + if (presence.from.swarm) { + presence.from.swarm.should.equal(swarmId); + for (var i = 0; i < 3; i++) { + prosumer.send('hey!'); + } + } + }); + + var j = 1; + prosumer.on('message', function(message) { + if (j == 3) { + prosumer.disconnect(); + } + j++; + }); + + prosumer.on('disconnect', function() { + done(); + }); + + prosumer.connect(); + }); + + it('should return the total of sent and received messages between a given period of time.', function(done) { + var from = new Date(); + from.setMinutes(0); + from.setSeconds(0); + from.setMilliseconds(0); + from = from.toISOString(); + + var to = new Date(); + to.setMinutes(59); + to.setSeconds(59); + to = to.toISOString(); + + + var filter = { + totalized: true, + resource_id: prosumerId, + from: from, + to: to + }; + + usageService.get(filter, function(error, data) { + Array.isArray(data).should.be.false; + Object.keys(data).should.not.be.empty; + data.should.have.property('messages'); + data.messages.should.have.property('sent', 3); + data.messages.should.have.property('received', 0); + done(); + }); + }); + + it('should return the user\'s usage detail', function(done) { + usageService.get(function(error, data) { + Array.isArray(data).should.be.true; + data.length.should.be.above(0); + for(var i in data) { + data[i].user_id.should.eql('librarytest'); + } + + ['resource_id', 'swarm_id', + 'timestamp', 'user_id', + 'bytes', 'messages'].forEach(function(p) { + data[0].should.have.property(p); + }); + + done(); + }); + }); + + it('should return detailed information of the current month if no dates are provided', function(done) { + usageService.get(function(error, data) { + Array.isArray(data).should.be.true; + data.length.should.be.above(0); + + var now = new Date(); + var cyear = now.getFullYear(); + var cmonth = now.getMonth(); + var cday = now.getDate(); + var chour = now.getHours(); + + var currentMonth = new Date(cyear, cmonth).getTime(); + + for(var i in data) { + var timestamp = new Date(data[i].timestamp); + var mtime = new Date(timestamp.getFullYear(), + timestamp.getMonth()).getTime(); + + currentMonth.should.eql(mtime); + } + done(); + }); + }); +}); diff --git a/participation/package.json b/participation/package.json index 927e836..af2decc 100644 --- a/participation/package.json +++ b/participation/package.json @@ -1,7 +1,7 @@ { "name": "bugswarm-prt", "description": "[Participation] BUGswarm is platform that allows you to share and access your hardware sensor data easily and effortlessly.", - "version": "0.2.0", + "version": "0.2.1", "keywords" : [ "m2m", "IoT", "realtime", "messaging", "sensor", "hardware", "socket", "configuration"], "homepage": "http://developer.bugswarm.net", "author": "BugLabs Inc.",