node is set to true Coverage

Coverage

95%
120
115
5

/home/thierry/workspace/stream-js/src/getstream.js

100%
8
8
0
LineHitsSource
1
2// GetStream client library for node and the browser
3// Author: Thierry Schellenbach
4// BSD License
5
61var StreamClient = require('./lib/client');
71var errors = require('./lib/errors');
81var request = require('request');
9
101function connect(apiKey, apiSecret, siteId) {
1123 return new StreamClient(apiKey, apiSecret, siteId);
12}
13
141module.exports.connect = connect;
151module.exports.errors = errors;
161module.exports.request = request;
17

/home/thierry/workspace/stream-js/src/lib/client.js

95%
45
43
2
LineHitsSource
11var request = require('request');
21var StreamFeed = require('./feed');
31var signing = require('./signing');
41var errors = require('./errors');
51var crypto = require('crypto');
6
71var StreamClient = function () {
823 this.initialize.apply(this, arguments);
9};
10
111StreamClient.prototype = {
12 baseUrl: 'https://getstream.io',
13
14 initialize: function (key, secret, siteId, fayeUrl) {
15 /*
16 * API key and secret
17 * Secret is optional
18 */
1923 this.key = key;
2023 this.secret = secret;
2123 this.siteId = siteId;
2223 this.fayeUrl = fayeUrl ? fayeUrl : 'https://getstream.io/faye';
23 },
24
25 feed: function(feedId, token, siteId) {
26 /*
27 * Returns a feed object for the given feed id and token
28 * Example:
29 *
30 * client.feed('user1', 'token2');
31 */
3246 var match = feedId.match(/\:/g);
3346 if (match === null || match.length != 1) {
341 throw new errors.FeedError('Wrong feed format ' + feedId + ' correct format is flat:1');
35 }
36
3745 if (crypto.createHash && this.secret && !token) {
38 // we are server side, have a secret but no feed signature
3944 token = signing.sign(this.secret, feedId.replace(':', ''));
40 }
41
4245 if (!token) {
430 throw new errors.FeedError('Missing token, in client side mode please provide a feed secret');
44 }
45
4645 var feed = new StreamFeed(this, feedId, token, siteId);
4745 return feed;
48 },
49
50 enrichUrl: function(relativeUrl) {
5120 var url = this.baseUrl + relativeUrl;
5220 if (url.indexOf('?') != -1) {
530 url += '&api_key=' + this.key;
54 } else {
5520 url += '?api_key=' + this.key;
56 }
5720 return url;
58 },
59
60 enrichKwargs: function(kwargs) {
6120 kwargs.url = this.enrichUrl(kwargs.url);
6220 kwargs.json = true;
6320 var secret = kwargs.secret || this.secret;
6420 kwargs.headers = {};
6520 kwargs.headers.Authorization = secret;
6620 return kwargs;
67 },
68 /*
69 * Shortcuts for post, get and delete HTTP methods
70 */
71 dummyCallback: function(error, response, body) {
72
73 },
74 get: function(kwargs, cb) {
757 cb = cb || this.dummyCallback;
767 kwargs = this.enrichKwargs(kwargs);
777 kwargs.method = 'GET';
787 return request.get(kwargs, cb);
79 },
80 post: function(kwargs, cb) {
8111 cb = cb || this.dummyCallback;
8211 kwargs = this.enrichKwargs(kwargs);
8311 kwargs.method = 'POST';
8411 return request(kwargs, cb);
85 },
86 delete: function(kwargs, cb) {
872 cb = cb || this.dummyCallback;
882 kwargs = this.enrichKwargs(kwargs);
892 kwargs.method = 'DELETE';
902 return request(kwargs, cb);
91 }
92};
93
941module.exports = StreamClient;
95

/home/thierry/workspace/stream-js/src/lib/errors.js

84%
19
16
3
LineHitsSource
11var errors = module.exports;
2
31var canCapture = (typeof Error.captureStackTrace === 'function');
41var canStack = !!(new Error()).stack;
5
61function ErrorAbstract(msg, constructor) {
74 this.message = msg;
8
94 Error.call(this, this.message);
10
114 if (canCapture) {
124 Error.captureStackTrace(this, constructor);
13 }
140 else if (canStack) {
150 this.stack = (new Error()).stack;
16 }
17 else {
180 this.stack = '';
19 }
20}
211errors._Abstract = ErrorAbstract;
221ErrorAbstract.prototype = new Error();
23
24/**
25 * FeedError
26 * @param {String} [msg] - An error message that will probably end up in a log.
27 */
281errors.FeedError = function FeedError(msg) {
291 ErrorAbstract.call(this, msg);
30};
311errors.FeedError.prototype = new ErrorAbstract();
32
33
341errors.SiteError = function SiteError(msg) {
351 ErrorAbstract.call(this, msg);
36};
371errors.SiteError.prototype = new ErrorAbstract();
38
39

/home/thierry/workspace/stream-js/src/lib/feed.js

100%
38
38
0
LineHitsSource
1
21var StreamFeed = function () {
345 this.initialize.apply(this, arguments);
4};
5
61StreamFeed.prototype = {
7 /*
8 * The feed object contains convenience functions such add activity
9 * remove activity etc
10 *
11 */
12 initialize: function(client, feed, token) {
1345 this.client = client;
1445 this.feed = feed;
1545 this.token = token;
1645 this.feedUrl = feed.replace(':', '/');
1745 this.feedTogether = feed.replace(':', '');
1845 this.feedToken = this.feedTogether + ' ' + this.token;
1945 this.fayeClient = null;
2045 this.notificationChannel = 'site-' + this.client.siteId + '-feed-' + this.feedTogether;
21 },
22 addActivity: function(activity, callback) {
23 /*
24 * Adds the given activity to the feed and
25 * calls the specified callback
26 */
279 var xhr = this.client.post({
28 'url': '/api/feed/'+ this.feedUrl + '/',
29 'body': activity,
30 'secret': this.feedToken
31 }, callback);
329 return xhr;
33 },
34 removeActivity: function(activityId, callback) {
351 var xhr = this.client.delete({
36 'url': '/api/feed/'+ this.feedUrl + '/' + activityId + '/',
37 'secret': this.feedToken
38 }, callback);
391 return xhr;
40 },
41 follow: function(target, callback) {
422 var xhr = this.client.post({
43 'url': '/api/feed/'+ this.feedUrl + '/follows/',
44 'body': {'target': target},
45 'secret': this.feedToken
46 }, callback);
472 return xhr;
48 },
49 unfollow: function(target, callback) {
501 var xhr = this.client.delete({
51 'url': '/api/feed/'+ this.feedUrl + '/follows/' + target + '/',
52 'secret': this.feedToken
53 }, callback);
541 return xhr;
55 },
56 get: function(argumentHash, callback) {
577 var xhr = this.client.get({
58 'url': '/api/feed/'+ this.feedUrl + '/',
59 'qs': argumentHash,
60 'secret': this.feedToken
61 }, callback);
627 return xhr;
63 },
64
65 getFayeAuthorization: function(){
662 var api_key = this.client.key;
672 var user_id = this.notificationChannel;
682 var signature = this.token;
692 return {
70 incoming: function(message, callback) {
713 callback(message);
72 },
73 outgoing: function(message, callback) {
743 message.ext = {'user_id': user_id, 'api_key':api_key, 'signature': signature};
753 callback(message);
76 }
77 };
78 },
79
80 getFayeClient: function(){
813 var Faye = require('faye');
823 if (this.fayeClient === null){
832 this.fayeClient = new Faye.Client(this.client.fayeUrl);
842 var authExtension = this.getFayeAuthorization();
852 this.fayeClient.addExtension(authExtension);
86 }
873 return this.fayeClient;
88 },
89
90 subscribe: function(callback){
912 if (!this.client.siteId) {
921 throw new errors.SiteError('Missing site id, which is needed to subscribe, use var client = stream.connect(key, secret, siteId);');
93 }
941 return this.getFayeClient().subscribe('/'+this.notificationChannel, callback);
95 }
96};
97
98
991module.exports = StreamFeed;

/home/thierry/workspace/stream-js/src/lib/signing.js

100%
10
10
0
LineHitsSource
1
21var crypto = require('crypto');
3
4
51function urlsafe_b64_encode(s) {
644 var escaped = s.replace('+', '-').replace('/', '_');
744 return escaped.replace(/^=+/, '').replace(/=+$/, '');
8}
9
10
111exports.sign = function(secret, value) {
12 /*
13 * Setup sha1 based on the secret
14 * Get the digest of the value
15 * Base64 encode the result
16 *
17 * Also see
18 * https://github.com/tbarbugli/stream-ruby/blob/master/lib/stream/signer.rb
19 * https://github.com/tschellenbach/stream-python/blob/master/stream/signing.py
20 *
21 * Steps
22 * secret: tfq2sdqpj9g446sbv653x3aqmgn33hsn8uzdc9jpskaw8mj6vsnhzswuwptuj9su
23 * value: flat1
24 * digest: Q\xb6\xd5+\x82\xd58\xdeu\x80\xc5\xe3\xb8\xa5bL1\xf1\xa3\xdb
25 * result: UbbVK4LVON51gMXjuKViTDHxo9s
26 */
2744 var key = new crypto.createHash('sha1').update(secret).digest();
2844 var hmac = crypto.createHmac('sha1', key);
2944 var signature = hmac.update(value).digest('base64');
3044 var urlsafe = urlsafe_b64_encode(signature);
3144 return urlsafe;
32};