mirror of
https://github.com/thewesker/bug-em.git
synced 2025-12-22 04:51:05 -05:00
lol
This commit is contained in:
646
node_modules/twit/tests/streaming.js
generated
vendored
Normal file
646
node_modules/twit/tests/streaming.js
generated
vendored
Normal file
@@ -0,0 +1,646 @@
|
||||
var assert = require('assert')
|
||||
, http = require('http')
|
||||
, EventEmitter = require('events').EventEmitter
|
||||
, rewire = require('rewire')
|
||||
, sinon = require('sinon')
|
||||
, Twit = require('../lib/twitter')
|
||||
, config1 = require('../config1')
|
||||
, config2 = require('../config2')
|
||||
, colors = require('colors')
|
||||
, helpers = require('./helpers')
|
||||
, util = require('util')
|
||||
, zlib = require('zlib')
|
||||
, async = require('async')
|
||||
, restTest = require('./rest');
|
||||
|
||||
/**
|
||||
* Stop the stream and check the tweet we got back.
|
||||
* Call @done on completion.
|
||||
*
|
||||
* @param {object} stream object returned by twit.stream()
|
||||
* @param {Function} done completion callback
|
||||
*/
|
||||
exports.checkStream = function (stream, done) {
|
||||
stream.on('connected', function () {
|
||||
console.log('\nconnected'.grey)
|
||||
});
|
||||
|
||||
stream.once('tweet', function (tweet) {
|
||||
stream.stop()
|
||||
assert.ok(tweet)
|
||||
assert.equal('string', typeof tweet.text)
|
||||
assert.equal('string', typeof tweet.id_str)
|
||||
|
||||
console.log(('\ntweet: '+tweet.text).grey)
|
||||
|
||||
done()
|
||||
});
|
||||
|
||||
stream.on('reconnecting', function (req, res, connectInterval) {
|
||||
console.log('Got disconnected. Scheduling reconnect! statusCode:', res.statusCode, 'connectInterval', connectInterval)
|
||||
});
|
||||
|
||||
stream.on('error', function (err) {
|
||||
console.log('Stream emitted an error', err)
|
||||
return done(err)
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* Check the stream state is correctly set for a stopped stream.
|
||||
*
|
||||
* @param {object} stream object returned by twit.stream()
|
||||
*/
|
||||
exports.checkStreamStopState = function (stream) {
|
||||
assert.strictEqual(stream._connectInterval, 0)
|
||||
assert.strictEqual(stream._usedFirstReconnect, false)
|
||||
assert.strictEqual(stream._scheduledReconnect, undefined)
|
||||
assert.strictEqual(stream._stallAbortTimeout, undefined)
|
||||
}
|
||||
|
||||
describe('Streaming API', function () {
|
||||
|
||||
it('statuses/sample', function (done) {
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('statuses/sample')
|
||||
|
||||
exports.checkStream(stream, done)
|
||||
})
|
||||
|
||||
it('statuses/filter using `track`', function (done) {
|
||||
this.timeout(120000)
|
||||
var twit = new Twit(config2);
|
||||
var stream = twit.stream('statuses/filter', { track: 'fun' })
|
||||
|
||||
exports.checkStream(stream, done)
|
||||
})
|
||||
|
||||
it('statuses/filter using `locations` string', function (done) {
|
||||
var twit = new Twit(config1);
|
||||
var world = '-180,-90,180,90';
|
||||
var stream = twit.stream('statuses/filter', { locations: world })
|
||||
|
||||
exports.checkStream(stream, done)
|
||||
})
|
||||
|
||||
it('statuses/filter using `locations` array for San Francisco and New York', function (done) {
|
||||
var twit = new Twit(config2);
|
||||
var params = {
|
||||
locations: [ '-122.75', '36.8', '121.75', '37.8', '-74', '40', '73', '41' ]
|
||||
}
|
||||
|
||||
var stream = twit.stream('statuses/filter', params)
|
||||
|
||||
exports.checkStream(stream, done)
|
||||
})
|
||||
|
||||
it('statuses/filter using `track` array', function (done) {
|
||||
var twit = new Twit(config1);
|
||||
var params = {
|
||||
track: [ 'twitter', ':)', 'fun' ]
|
||||
}
|
||||
|
||||
var stream = twit.stream('statuses/filter', params)
|
||||
|
||||
exports.checkStream(stream, done)
|
||||
})
|
||||
|
||||
it('statuses/filter using `track` and `language`', function (done) {
|
||||
var twit = new Twit(config1);
|
||||
var params = {
|
||||
track: [ 'twitter', '#apple', 'google', 'twitter', 'facebook', 'happy', 'party', ':)' ],
|
||||
language: 'en'
|
||||
}
|
||||
|
||||
var stream = twit.stream('statuses/filter', params)
|
||||
|
||||
exports.checkStream(stream, done)
|
||||
})
|
||||
|
||||
it('stopping & restarting the stream works', function (done) {
|
||||
var twit = new Twit(config2);
|
||||
var stream = twit.stream('statuses/sample')
|
||||
|
||||
//stop the stream after 2 seconds
|
||||
setTimeout(function () {
|
||||
stream.stop()
|
||||
|
||||
exports.checkStreamStopState(stream)
|
||||
|
||||
console.log('\nstopped stream')
|
||||
}, 2000)
|
||||
|
||||
//after 3 seconds, start the stream, and stop after 'connect'
|
||||
setTimeout(function () {
|
||||
stream.once('connected', function (req) {
|
||||
console.log('\nrestarted stream')
|
||||
stream.stop()
|
||||
|
||||
exports.checkStreamStopState(stream)
|
||||
|
||||
console.log('\nstopped stream')
|
||||
done()
|
||||
})
|
||||
|
||||
//restart the stream
|
||||
stream.start()
|
||||
}, 3000)
|
||||
})
|
||||
|
||||
it('stopping & restarting stream emits to previously assigned callbacks', function (done) {
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('statuses/sample')
|
||||
|
||||
var started = false
|
||||
var numTweets = 0
|
||||
stream.on('tweet', function (tweet) {
|
||||
process.stdout.write('.')
|
||||
if (!started) {
|
||||
started = true
|
||||
numTweets++
|
||||
console.log('received tweet', numTweets)
|
||||
|
||||
console.log('stopping stream')
|
||||
stream.stop()
|
||||
|
||||
exports.checkStreamStopState(stream)
|
||||
|
||||
// we've successfully received a new tweet after restarting, test successful
|
||||
if (numTweets === 2) {
|
||||
done()
|
||||
} else {
|
||||
started = false
|
||||
console.log('restarting stream')
|
||||
|
||||
setTimeout(function () {
|
||||
stream.start()
|
||||
}, 1000)
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
stream.on('limit', function (limitMsg) {
|
||||
console.log('limit', limitMsg)
|
||||
})
|
||||
|
||||
stream.on('disconnect', function (disconnMsg) {
|
||||
console.log('disconnect', disconnMsg)
|
||||
})
|
||||
|
||||
stream.on('reconnect', function (req, res, ival) {
|
||||
console.log('reconnect. statusCode:', res.statusCode, 'interval:', ival)
|
||||
})
|
||||
|
||||
stream.on('connect', function (req) {
|
||||
console.log('connect')
|
||||
})
|
||||
|
||||
})
|
||||
})
|
||||
|
||||
describe('streaming API direct message events', function () {
|
||||
var senderScreenName;
|
||||
var receiverScreenName;
|
||||
var twitSender;
|
||||
var twitReceiver;
|
||||
|
||||
// before we send direct messages the user receiving the DM
|
||||
// has to follow the sender. Make this so.
|
||||
before(function (done) {
|
||||
twitSender = new Twit(config1);
|
||||
twitReceiver = new Twit(config2);
|
||||
|
||||
// get sender/receiver names in parallel, then make the receiver follow the sender
|
||||
async.parallel({
|
||||
// get sender screen name and set it for tests to use
|
||||
getSenderScreenName: function (parNext) {
|
||||
console.log('getting sender user screen_name')
|
||||
|
||||
twitSender.get('account/verify_credentials', { twit_options: { retry: true } }, function (err, reply) {
|
||||
assert(!err, err)
|
||||
|
||||
assert(reply)
|
||||
assert(reply.screen_name)
|
||||
|
||||
senderScreenName = reply.screen_name
|
||||
|
||||
return parNext()
|
||||
})
|
||||
},
|
||||
// get receiver screen name and set it for tests to use
|
||||
getReceiverScreenName: function (parNext) {
|
||||
console.log('getting receiver user screen_name')
|
||||
twitReceiver.get('account/verify_credentials', { twit_options: { retry: true } }, function (err, reply) {
|
||||
assert(!err, err)
|
||||
|
||||
assert(reply)
|
||||
assert(reply.screen_name)
|
||||
|
||||
receiverScreenName = reply.screen_name
|
||||
|
||||
return parNext()
|
||||
})
|
||||
}
|
||||
}, function (err) {
|
||||
assert(!err, err)
|
||||
|
||||
var followParams = { screen_name: senderScreenName }
|
||||
console.log('making receiver user follow the sender user')
|
||||
// make receiver follow sender
|
||||
twitReceiver.post('friendships/create', followParams, function (err, reply) {
|
||||
assert(!err, err)
|
||||
assert(reply.following)
|
||||
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
it('user_stream `direct_message` event', function (done) {
|
||||
// User A follows User B
|
||||
// User A connects to their user stream
|
||||
// User B posts a DM to User A
|
||||
// User A receives it in their user stream
|
||||
this.timeout(0);
|
||||
|
||||
// build out DM params
|
||||
function makeDmParams () {
|
||||
return {
|
||||
screen_name: receiverScreenName,
|
||||
text: helpers.generateRandomString(10) + ' direct message streaming event test! :-) ' + helpers.generateRandomString(20),
|
||||
twit_options: {
|
||||
retry: true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var dmIdsReceived = []
|
||||
var dmIdsSent = []
|
||||
var sentDmFound = false
|
||||
|
||||
// start listening for user stream events
|
||||
var receiverStream = twitReceiver.stream('user')
|
||||
|
||||
console.log('\nlistening for DMs')
|
||||
// listen for direct_message event and check DM once it's received
|
||||
receiverStream.on('direct_message', function (directMsg) {
|
||||
if (sentDmFound) {
|
||||
// don't call `done` more than once
|
||||
return
|
||||
}
|
||||
|
||||
console.log('got DM event. id:', directMsg.direct_message.id_str)
|
||||
restTest.checkDm(directMsg.direct_message)
|
||||
dmIdsReceived.push(directMsg.direct_message.id_str)
|
||||
|
||||
// make sure one of the DMs sent was found
|
||||
// (we can send multiple DMs if our stream has to reconnect)
|
||||
sentDmFound = dmIdsSent.some(function (dmId) {
|
||||
return dmId == directMsg.direct_message.id_str
|
||||
})
|
||||
|
||||
if (!sentDmFound) {
|
||||
console.log('this DM doesnt match our test DMs - still waiting for a matching one.')
|
||||
console.log('dmIdsSent', dmIdsSent)
|
||||
return
|
||||
}
|
||||
|
||||
receiverStream.stop()
|
||||
return done()
|
||||
})
|
||||
|
||||
var lastTimeSent = 0
|
||||
var msToWait = 0
|
||||
var postDmInterval = null
|
||||
|
||||
receiverStream.on('connected', function () {
|
||||
var dmParams = makeDmParams()
|
||||
|
||||
console.log('sending a new DM:', dmParams.text)
|
||||
twitSender.post('direct_messages/new', dmParams, function (err, reply) {
|
||||
assert(!err, err)
|
||||
assert(reply)
|
||||
restTest.checkDm(reply)
|
||||
assert(reply.id_str)
|
||||
// we will check this dm against the reply recieved in the message event
|
||||
dmIdsSent.push(reply.id_str)
|
||||
|
||||
console.log('successfully posted DM:', reply.text, reply.id_str)
|
||||
if (dmIdsReceived.indexOf(reply.id_str) !== -1) {
|
||||
// our response to the DM posting lost the race against the direct_message
|
||||
// listener (we already got the event). So we can finish the test.
|
||||
done()
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
after(function (done) {
|
||||
console.log('cleaning up DMs:', dmIdsSent)
|
||||
// delete the DMs we posted
|
||||
var deleteDms = dmIdsSent.map(function (dmId) {
|
||||
return function (next) {
|
||||
assert.equal(typeof dmId, 'string')
|
||||
console.log('\ndeleting DM', dmId)
|
||||
var params = { id: dmId, twit_options: { retry: true } }
|
||||
twitSender.post('direct_messages/destroy', params, function (err, reply) {
|
||||
assert(!err, err)
|
||||
restTest.checkDm(reply)
|
||||
assert.equal(reply.id, dmId)
|
||||
return next()
|
||||
})
|
||||
}
|
||||
})
|
||||
async.parallel(deleteDms, done)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('streaming API friends preamble', function () {
|
||||
it('returns an array of strings if stringify_friend_ids is true', function (done) {
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('user', { stringify_friend_ids: true });
|
||||
stream.on('friends', function (friendsObj) {
|
||||
assert(friendsObj)
|
||||
assert(friendsObj.friends_str)
|
||||
if (friendsObj.friends_str.length) {
|
||||
assert.equal(typeof friendsObj.friends_str[0], 'string')
|
||||
} else {
|
||||
console.log('\nEmpty friends preamble:', friendsObj, '. Make some friends on Twitter! ^_^')
|
||||
}
|
||||
done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('streaming API bad request', function (done) {
|
||||
it('emits an error for a 401 response', function (done) {
|
||||
var badCredentials = {
|
||||
consumer_key: 'a'
|
||||
, consumer_secret: 'b'
|
||||
, access_token: 'c'
|
||||
, access_token_secret: 'd'
|
||||
}
|
||||
|
||||
var twit = new Twit(badCredentials);
|
||||
|
||||
var stream = twit.stream('statuses/filter', { track : ['foo'] });
|
||||
|
||||
stream.on('parser-error', function (err) {
|
||||
assert.equal(err.statusCode, 401)
|
||||
assert(err.twitterReply)
|
||||
|
||||
return done()
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('streaming API `messages` event', function (done) {
|
||||
var request = require('request');
|
||||
var originalPost = request.post;
|
||||
var RewiredTwit = rewire('../lib/twitter');
|
||||
var RewiredStreamingApiConnection = rewire('../lib/streaming-api-connection');
|
||||
var revertParser, revertTwit;
|
||||
|
||||
var MockParser = function () {
|
||||
var self = this;
|
||||
EventEmitter.call(self);
|
||||
process.nextTick(function () {
|
||||
self.emit('element', {scrub_geo: 'bar'})
|
||||
self.emit('element', {limit: 'buzz'})
|
||||
});
|
||||
}
|
||||
util.inherits(MockParser, EventEmitter);
|
||||
|
||||
before(function () {
|
||||
revertTwit = RewiredTwit.__set__('StreamingAPIConnection', RewiredStreamingApiConnection);
|
||||
revertParser = RewiredStreamingApiConnection.__set__('Parser', MockParser);
|
||||
|
||||
request.post = function () { return new helpers.FakeRequest() }
|
||||
})
|
||||
|
||||
after(function () {
|
||||
request.post = originalPost;
|
||||
revertTwit();
|
||||
revertParser();
|
||||
})
|
||||
|
||||
it('is returned for 2 different event types', function (done) {
|
||||
var twit = new RewiredTwit(config1);
|
||||
var stream = twit.stream('statuses/sample');
|
||||
var gotScrubGeo = false;
|
||||
var gotLimit = false;
|
||||
var numMessages = 0;
|
||||
|
||||
var maybeDone = function () {
|
||||
if (gotScrubGeo && gotLimit && numMessages == 2) {
|
||||
done()
|
||||
}
|
||||
}
|
||||
|
||||
stream.on('limit', function () {
|
||||
gotLimit = true;
|
||||
maybeDone();
|
||||
});
|
||||
stream.on('scrub_geo', function () {
|
||||
gotScrubGeo = true;
|
||||
maybeDone();
|
||||
})
|
||||
|
||||
stream.on('message', function (msg) {
|
||||
numMessages++;
|
||||
maybeDone();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('streaming reconnect', function (done) {
|
||||
it('correctly implements connection closing backoff', function (done) {
|
||||
var stubPost = function () {
|
||||
var fakeRequest = new helpers.FakeRequest()
|
||||
process.nextTick(function () {
|
||||
fakeRequest.emit('close')
|
||||
})
|
||||
return fakeRequest
|
||||
}
|
||||
|
||||
var request = require('request')
|
||||
var stubPost = sinon.stub(request, 'post', stubPost)
|
||||
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('statuses/filter', { track: [ 'fun', 'yolo']});
|
||||
|
||||
var reconnects = [0, 250, 500, 750]
|
||||
var reconnectCount = -1
|
||||
|
||||
var testDone = false
|
||||
|
||||
stream.on('reconnect', function () {
|
||||
if (testDone) {
|
||||
return
|
||||
}
|
||||
reconnectCount += 1
|
||||
var expectedInterval = reconnects[reconnectCount]
|
||||
|
||||
// make sure our connect interval is correct
|
||||
assert.equal(stream._connectInterval, expectedInterval);
|
||||
|
||||
// simulate immediate reconnect by forcing a new connection (`self._connectInterval` parameter unchanged)
|
||||
stream._startPersistentConnection();
|
||||
|
||||
if (reconnectCount === reconnects.length -1) {
|
||||
// restore request.post
|
||||
stubPost.restore()
|
||||
testDone = true
|
||||
return done();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
it('correctly implements 420 backoff', function (done) {
|
||||
var stubPost = function () {
|
||||
var fakeRequest = new helpers.FakeRequest()
|
||||
process.nextTick(function () {
|
||||
var fakeResponse = new helpers.FakeResponse(420)
|
||||
fakeRequest.emit('response', fakeResponse)
|
||||
fakeRequest.emit('close')
|
||||
})
|
||||
return fakeRequest
|
||||
}
|
||||
|
||||
var request = require('request')
|
||||
var stubPost = sinon.stub(request, 'post', stubPost)
|
||||
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('statuses/filter', { track: [ 'fun', 'yolo']});
|
||||
|
||||
var reconnects = [60000, 120000, 240000, 480000]
|
||||
var reconnectCount = -1
|
||||
var testComplete = false
|
||||
|
||||
stream.on('reconnect', function (req, res, connectInterval) {
|
||||
if (testComplete) {
|
||||
// prevent race between last connection attempt firing a reconnect and us validating the final
|
||||
// reconnect value in `reconnects`
|
||||
return
|
||||
}
|
||||
|
||||
reconnectCount += 1
|
||||
var expectedInterval = reconnects[reconnectCount]
|
||||
|
||||
// make sure our connect interval is correct
|
||||
assert.equal(stream._connectInterval, connectInterval);
|
||||
assert.equal(stream._connectInterval, expectedInterval);
|
||||
// simulate immediate reconnect by forcing a new connection (`self._connectInterval` parameter unchanged)
|
||||
stream._startPersistentConnection();
|
||||
|
||||
if (reconnectCount === reconnects.length -1) {
|
||||
// restore request.post
|
||||
stubPost.restore()
|
||||
testComplete = true
|
||||
return done();
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('Streaming API disconnect message', function (done) {
|
||||
it('results in stopping the stream', function (done) {
|
||||
var stubPost = function () {
|
||||
var fakeRequest = new helpers.FakeRequest()
|
||||
process.nextTick(function () {
|
||||
var body = zlib.gzipSync(JSON.stringify({disconnect: true}) + '\r\n')
|
||||
var fakeResponse = new helpers.FakeResponse(200, body)
|
||||
fakeRequest.emit('response', fakeResponse);
|
||||
fakeResponse.emit('close')
|
||||
});
|
||||
return fakeRequest
|
||||
}
|
||||
|
||||
var request = require('request')
|
||||
var origRequest = request.post
|
||||
var stubs = sinon.collection
|
||||
stubs.stub(request, 'post', stubPost)
|
||||
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('statuses/filter', { track: ['fun']});
|
||||
|
||||
stream.on('disconnect', function (disconnMsg) {
|
||||
stream.stop();
|
||||
// restore stub
|
||||
request.post = origRequest
|
||||
done();
|
||||
})
|
||||
})
|
||||
});
|
||||
|
||||
describe('Streaming API Connection limit exceeded message', function (done) {
|
||||
it('results in an `error` event containing the message', function (done) {
|
||||
var errMsg = 'Exceeded connection limit for user';
|
||||
|
||||
var stubPost = function () {
|
||||
var fakeRequest = new helpers.FakeRequest();
|
||||
process.nextTick(function () {
|
||||
var body = zlib.gzipSync(errMsg + '\r\n');
|
||||
var fakeResponse = new helpers.FakeResponse(200, body);
|
||||
fakeRequest.emit('response', fakeResponse);
|
||||
fakeResponse.emit('close');
|
||||
});
|
||||
return fakeRequest
|
||||
}
|
||||
|
||||
var request = require('request');
|
||||
var origRequest = request.post;
|
||||
var stubs = sinon.collection;
|
||||
stubs.stub(request, 'post', stubPost);
|
||||
|
||||
var twit = new Twit(config1);
|
||||
var stream = twit.stream('statuses/filter');
|
||||
|
||||
stream.on('error', function (err) {
|
||||
assert(err.toString().indexOf(errMsg) !== -1, 'Unexpected error msg:' + errMsg + '.');;
|
||||
stream.stop();
|
||||
// restore stub
|
||||
request.post = origRequest;
|
||||
done();
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
describe('Streaming API connection management', function () {
|
||||
it('.stop() works in all states', function (done) {
|
||||
var stubPost = function () {
|
||||
var fakeRequest = new helpers.FakeRequest();
|
||||
process.nextTick(function () {
|
||||
var body = zlib.gzipSync('Foobar\r\n');
|
||||
var fakeResponse = new helpers.FakeResponse(200, body);
|
||||
fakeRequest.emit('response', fakeResponse);
|
||||
});
|
||||
return fakeRequest
|
||||
}
|
||||
|
||||
var request = require('request');
|
||||
var origRequest = request.post;
|
||||
var stubs = sinon.collection;
|
||||
stubs.stub(request, 'post', stubPost);
|
||||
|
||||
var twit = new Twit(config1);
|
||||
|
||||
var stream = twit.stream('statuses/sample');
|
||||
stream.stop();
|
||||
console.log('\nStopped. Restarting..');
|
||||
stream.start();
|
||||
stream.once('connect', function(request) {
|
||||
console.log('Stream emitted `connect`. Stopping & starting stream..')
|
||||
stream.stop();
|
||||
|
||||
stream.once('connected', function () {
|
||||
console.log('Stream emitted `connected`. Stopping stream.');
|
||||
stream.stop();
|
||||
|
||||
stubs.restore();
|
||||
done();
|
||||
});
|
||||
stream.start();
|
||||
});
|
||||
})
|
||||
})
|
||||
Reference in New Issue
Block a user