Skip to content

Commit f120d3b

Browse files
committed
Merge pull request #37 from hbeeken/swarm-tests
Adding Swarm in and query node tests
2 parents d7953ed + 398c33a commit f120d3b

File tree

2 files changed

+304
-2
lines changed

2 files changed

+304
-2
lines changed

swarm/swarm.js

+3-2
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,8 @@ module.exports = function(RED) {
8686

8787
}
8888
}
89+
90+
RED.nodes.registerType("swarm in", SwarmInNode);
8991

9092
/**
9193
* Swarm query node - will return the most recent check-in since
@@ -140,6 +142,7 @@ module.exports = function(RED) {
140142
} else {
141143
if (result.response.checkins.items.length !== 0) {
142144
var latest = result.response.checkins.items[0];
145+
msg.payload = {};
143146
msg.payload = latest;
144147
callback(msg);
145148
}
@@ -148,8 +151,6 @@ module.exports = function(RED) {
148151
});
149152
}
150153

151-
RED.nodes.registerType("swarm in", SwarmInNode);
152-
153154
RED.httpAdmin.get('/swarm-credentials/auth', function(req, res){
154155
if (!req.query.clientid || !req.query.clientsecret || !req.query.id || !req.query.callback) {
155156
return res.status(400).send('ERROR: request does not contain the required parameters');

test/swarm/swarm_spec.js

+301
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,301 @@
1+
/**
2+
* Copyright 2014 IBM Corp.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
**/
16+
17+
var should = require("should");
18+
var swarmNode = require("../../swarm/swarm.js");
19+
var helper = require('../helper.js');
20+
var sinon = require('sinon');
21+
var nock = helper.nock;
22+
23+
describe('swarm nodes', function() {
24+
25+
before(function(done) {
26+
helper.startServer(done);
27+
});
28+
29+
afterEach(function() {
30+
helper.unload();
31+
});
32+
33+
describe('query node', function() {
34+
35+
if (nock) {
36+
37+
it('can do oauth dance', function(done) {
38+
helper.load(swarmNode,
39+
[ {id:"n1", type:"helper", wires:[["n2"]]},
40+
{id:"n4", type:"swarm-credentials"},
41+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
42+
{id:"n3", type:"helper"}],
43+
function() {
44+
45+
var scope = nock('https://foursquare.com:443')
46+
.filteringRequestBody(/redirect_uri=[^&]*/g, 'redirect_uri=XXX')
47+
.post('/oauth2/access_token', "redirect_uri=XXX&" +
48+
"grant_type=authorization_code&client_id=abcdefg&client_secret=mnopqrs&code=123456")
49+
.reply(200, {"access_token":"2468abc"});
50+
51+
var apiscope = nock('https://api.foursquare.com:443')
52+
.get('/v2/users/self?oauth_token=2468abc&v=20141016')
53+
.reply(200, {"meta":{"code":200},"response":{"user":{"id":"987654321","firstName":"John","lastName":"Smith"}}});
54+
55+
helper.request()
56+
.get('/swarm-credentials/auth?id=n4&clientid=abcdefg&clientsecret=mnopqrs&response_type=code&callback=http://localhost:1880:/swarm-credentials')
57+
.expect(302)
58+
.end(function(err, res) {
59+
if (err) return done(err);
60+
var state = res.text.split("state=n4%253A");
61+
helper.request()
62+
.get('/swarm-credentials/auth/callback?code=123456&state=n4:'+state[1])
63+
.expect(200)
64+
.end(function(err, res) {
65+
if (err) return done(err);
66+
helper.credentials.get("n4")
67+
.should.have.property('displayname',
68+
'John Smith');
69+
done();
70+
});
71+
});
72+
});
73+
});
74+
75+
it(' fails oauth dance if request is missing required parameter', function(done) {
76+
helper.load(swarmNode,
77+
[ {id:"n1", type:"helper", wires:[["n2"]]},
78+
{id:"n4", type:"swarm-credentials"},
79+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
80+
{id:"n3", type:"helper"}],
81+
function() {
82+
helper.request()
83+
.get('/swarm-credentials/auth?id=n4&clientsecret=mnopqrs&response_type=code&callback=http://localhost:1880:/swarm-credentials')
84+
.expect(400, 'ERROR: request does not contain the required parameters')
85+
.end(function(err, res) {
86+
done();
87+
});
88+
});
89+
});
90+
91+
92+
it('fails oauth dance if client id is invalid', function(done) {
93+
helper.load(swarmNode,
94+
[ {id:"n1", type:"helper", wires:[["n2"]]},
95+
{id:"n4", type:"swarm-credentials"},
96+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
97+
{id:"n3", type:"helper"}],
98+
function() {
99+
var scope = nock('https://foursquare.com:443')
100+
.post('/oauth/access_token')
101+
.reply(401, '{"errors":[{"errorType":"oauth","fieldName":"oauth_consumer_key","message":"Cause of error: Value abcdefg is invalid for consumer key"}],"success":false}');
102+
helper.request()
103+
.get('/swarm-credentials/auth?id=n4&clientid=abcdefg&clientsecret=mnopqrs&response_type=code&callback=http://localhost:1880:/swarm-credentials')
104+
.expect(302)
105+
.end(function(err, res) {
106+
if (err) return done(err);
107+
var state = res.text.split("state=n4%253A");
108+
helper.request()
109+
.get('/swarm-credentials/auth/callback?code=123456&state=n4:'+state[1])
110+
.expect(200)
111+
.end(function(err, res) {
112+
if (err) return done(err);
113+
res.text.should.containEql('Oh no');
114+
done();
115+
});
116+
});
117+
});
118+
});
119+
120+
it(' fails if profile can\'t be retrieved', function(done) {
121+
helper.load(swarmNode,
122+
[ {id:"n1", type:"helper", wires:[["n2"]]},
123+
{id:"n4", type:"swarm-credentials"},
124+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
125+
{id:"n3", type:"helper"}],
126+
function() {
127+
128+
var scope = nock('https://foursquare.com:443')
129+
.filteringRequestBody(/redirect_uri=[^&]*/g, 'redirect_uri=XXX')
130+
.post('/oauth2/access_token', "redirect_uri=XXX&" +
131+
"grant_type=authorization_code&client_id=abcdefg&client_secret=mnopqrs&code=123456")
132+
.reply(200, {"access_token":"2468abc"});
133+
134+
var apiscope = nock('https://api.foursquare.com:443')
135+
.get('/v2/users/self?oauth_token=2468abc&v=20141016')
136+
.reply(401, '{"meta":[{"code":"401"}]}');
137+
138+
helper.request()
139+
.get('/swarm-credentials/auth?id=n4&clientid=abcdefg&clientsecret=mnopqrs&response_type=code&callback=http://localhost:1880:/swarm-credentials')
140+
.expect(302)
141+
.end(function(err, res) {
142+
if (err) return done(err);
143+
var state = res.text.split("state=n4%253A");
144+
helper.request()
145+
.get('/swarm-credentials/auth/callback?code=123456&state=n4:'+state[1])
146+
.expect(200)
147+
.end(function(err, res) {
148+
if (err) return done(err);
149+
res.text.should.containEql('Http return code');
150+
done();
151+
});
152+
});
153+
});
154+
});
155+
156+
it(' fails if CSRF token mismatch', function(done) {
157+
helper.load(swarmNode,
158+
[ {id:"n1", type:"helper", wires:[["n2"]]},
159+
{id:"n4", type:"swarm-credentials"},
160+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
161+
{id:"n3", type:"helper"}],
162+
function() {
163+
164+
var scope = nock('https://foursquare.com:443')
165+
.filteringRequestBody(/redirect_uri=[^&]*/g, 'redirect_uri=XXX')
166+
.post('/oauth2/access_token', "redirect_uri=XXX&" +
167+
"grant_type=authorization_code&client_id=abcdefg&client_secret=mnopqrs&code=123456")
168+
.reply(200, {"access_token":"2468abc"});
169+
170+
helper.request()
171+
.get('/swarm-credentials/auth?id=n4&clientid=abcdefg&clientsecret=mnopqrs&response_type=code&callback=http://localhost:1880:/swarm-credentials')
172+
.expect(302)
173+
.end(function(err, res) {
174+
if (err) return done(err);
175+
helper.request()
176+
.get('/swarm-credentials/auth/callback?code=123456&state=n4:13579')
177+
.expect(401)
178+
.end(function(err, res) {
179+
if (err) return done(err);
180+
res.text.should.containEql('CSRF token mismatch, possible cross-site request forgery attempt');
181+
done();
182+
});
183+
});
184+
});
185+
});
186+
187+
it(' can fetch check-in information', function(done) {
188+
helper.load(swarmNode,
189+
[ {id:"n1", type:"helper", wires:[["n2"]]},
190+
{id:"n4", type:"swarm-credentials"},
191+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
192+
{id:"n3", type:"helper"}],
193+
{
194+
"n4": {
195+
displayname : "John",
196+
clientid: "987654321",
197+
clientsecret:"123456789",
198+
accesstoken:"abcd1234",
199+
},
200+
},
201+
function() {
202+
var scope = nock('https://api.foursquare.com:443')
203+
.filteringPath(/afterTimestamp=[^&]*/g, 'afterTimestamp=foo')
204+
.get('/v2/users/self/checkins?oauth_token=abcd1234&v=20141016&afterTimestamp=foo&sort=newestfirst')
205+
.reply(200, {"meta":{"code":200},"response":{"checkins":{"count":1, "items":[{"id":"b695edf5ewc2","createdAt":1412861751,"type":"checkin","timeZoneOffset":60,"venue":{"id":"49a8b774","name":"Bobs House"}}]}}});
206+
207+
var n1 = helper.getNode("n1");
208+
var n2 = helper.getNode("n2");
209+
var n3 = helper.getNode("n3");
210+
n2.should.have.property('id','n2');
211+
n1.send({payload:"foo"});
212+
n3.on('input', function(msg){
213+
var venue = msg.payload.venue;
214+
venue.should.have.property('name', "Bobs House");
215+
done();
216+
});
217+
218+
});
219+
});
220+
221+
it(' fails if error fetching check-in information', function(done) {
222+
helper.load(swarmNode,
223+
[ {id:"n1", type:"helper", wires:[["n2"]]},
224+
{id:"n4", type:"swarm-credentials"},
225+
{id:"n2", type:"swarm", swarm: "n4", wires:[["n3"]]},
226+
{id:"n3", type:"helper"}],
227+
{
228+
"n4": {
229+
displayname : "John",
230+
clientid: "987654321",
231+
clientsecret:"123456789",
232+
accesstoken:"abcd1234",
233+
},
234+
},
235+
function() {
236+
var scope = nock('https://api.foursquare.com:443')
237+
.filteringPath(/afterTimestamp=[^&]*/g, 'afterTimestamp=foo')
238+
.get('/v2/users/self/checkins?oauth_token=abcd1234&v=20141016&afterTimestamp=foo&sort=newestfirst')
239+
.reply(200, {"meta":{"code":400, "errorDetail":'test forced failure'}});
240+
241+
var n1 = helper.getNode("n1");
242+
var n2 = helper.getNode("n2");
243+
var n3 = helper.getNode("n3");
244+
n2.should.have.property('id','n2');
245+
246+
sinon.stub(n2, 'status', function(status){
247+
var expected = {fill:"red",shape:"ring",text:"failed"};
248+
should.deepEqual(status, expected);
249+
done();
250+
});
251+
252+
n1.send({payload:"foo"});
253+
});
254+
});
255+
256+
}}
257+
);
258+
259+
260+
describe('in node', function() {
261+
262+
if (nock) {
263+
264+
it(' can fetch check-in information', function(done) {
265+
helper.load(swarmNode,
266+
[ {id:"n1", type:"helper", wires:[["n2"]]},
267+
{id:"n4", type:"swarm-credentials"},
268+
{id:"n2", type:"swarm in", swarm: "n4", wires:[["n3"]]},
269+
{id:"n3", type:"helper"}],
270+
{
271+
"n4": {
272+
displayname : "John",
273+
clientid: "987654321",
274+
clientsecret:"123456789",
275+
accesstoken:"abcd1234",
276+
},
277+
},
278+
function() {
279+
var scope = nock('https://api.foursquare.com:443')
280+
.filteringPath(/afterTimestamp=[^&]*/g, 'afterTimestamp=foo')
281+
.get('/v2/users/self/checkins?oauth_token=abcd1234&v=20141016&afterTimestamp=foo&sort=newestfirst')
282+
.reply(200, {"meta":{"code":200},"response":{"checkins":{"count":1, "items":[{"id":"b695edf5ewc2","createdAt":1412861751,"type":"checkin","timeZoneOffset":60,"venue":{"id":"49a8b774","name":"Bobs House"}}]}}});
283+
284+
var n1 = helper.getNode("n1");
285+
var n2 = helper.getNode("n2");
286+
var n3 = helper.getNode("n3");
287+
n2.should.have.property('id','n2');
288+
n2.emit("input", {});
289+
n3.on('input', function(msg){
290+
var venue = msg.payload.venue;
291+
venue.should.have.property('name', "Bobs House");
292+
done();
293+
});
294+
});
295+
});
296+
297+
}
298+
299+
});
300+
301+
});

0 commit comments

Comments
 (0)