Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse files

Singleton. Added tests. 0.1.0

  • Loading branch information...
commit 2ae9032101731e13ce3c56c9f9edae22f54cb274 1 parent 39aef70
@masylum authored
View
1  .gitignore
@@ -0,0 +1 @@
+node_modules
View
6 Makefile
@@ -0,0 +1,6 @@
+NODE = node
+
+test:
+ @$(NODE) tests/twitter_test.js
+
+.PHONY: test
View
34 Readme.md
@@ -2,32 +2,32 @@
Easy peasy twitter client for connect.
- npm install twitter-js
+``` bash
+npm install twitter-js
+```
## Usage
twitter-js has two methods.
-* getAccesToken(_req_, _res_, _callback_): Uses oAuth module to retrieve the access_token
-* apiCall(_http_method_, _path_, _params_, _callback_): Does a call to twitter API.
+* getAccesToken(req, res, callback): Uses oAuth module to retrieve the access_token
+* apiCall(http_method, path, params, callback): Does a call to twitter API.
Params must contain the token.
## Example using express.js
- var express = require('express'),
- connect = require('connect');
-
- var twitterClient = require('./../')('yourKey', 'yourPass'),
- app = express.createServer(
- connect.bodyParser(),
- connect.cookieParser(),
- connect.session({secret: 'yourSecret'})
+ var express = require('express');
+ , twitterClient = require('twitter-js')('yourKey', 'yourPass')
+ , app = express.createServer(
+ express.bodyParser()
+ , express.cookieParser()
+ , express.session({secret: 'yourSecret'})
);
app.get('/', function (req, res) {
twitterClient.getAccessToken(req, res, function (error, token) {
- res.render('client.jade', {locals: {token: token}});
+ res.render('client', {token: token});
});
});
@@ -45,10 +45,8 @@ Params must contain the token.
## Test
-To test and see this module working:
+linkdin is fully tested using [testosterone](https://github.com/masylum/testosterone)
- * copy the test folder
- * set up the keys and password of your app
- * run it _node test/client.js_
- * Add 127.0.0.1 twitter-js.com at your hosts file
- * Open your browser at localhost:3003
+``` bash
+make
+```
View
162 lib/twitter_client.js
@@ -1,84 +1,102 @@
-/*
- * This file is part of twitter-js
- *
- * Copyright (c) 2010 masylum <masylum@gmail.com>
- *
- * Licensed under the terms of MIT License. For the full copyright and license
- * information, please see the LICENSE file in the root folder.
- */
-
-var url = require("url"),
- http = require('http'),
- OAuth = require('oauth').OAuth,
- querystring = require("querystring");
-
-module.exports = function (api_key, api_secret) {
- var client = {version: '0.0.3'},
-
- // PRIVATE
- oAuth = new OAuth(
- 'https://twitter.com/oauth/request_token',
- 'https://twitter.com/oauth/access_token',
- api_key,
- api_secret,
- '1.0',
- false,
- 'HMAC-SHA1',
- null,
- {'Accept': '*/*', 'Connection': 'close', 'User-Agent': 'twitter-js ' + client.version}
- ),
- rest_base = 'https://api.twitter.com/1',
-
- requestCallback = function (callback) {
- return function (error, data, response) {
- if (error) {
- callback(error, null);
- } else {
- try {
- callback(null, JSON.parse(data));
- } catch (exc) {
- callback(exc, null);
- }
- }
- };
- },
-
- get = function (path, params, token, callback) {
- oAuth.get(rest_base + path + '?' + querystring.stringify(params), token.oauth_token, token.oauth_token_secret, requestCallback(callback));
- },
-
- post = function (path, params, token, callback) {
- oAuth.post(rest_base + path, token.oauth_token, token.oauth_token_secret, params, null, requestCallback(callback));
- };
-
- // PUBLIC
- client.apiCall = function (method, path, params, callback) {
+var url = require('url')
+ , http = require('http')
+ , OAuth = require('oauth').OAuth
+ , querystring = require('querystring')
+ , memoize = {};
+
+module.exports = function (key, secret) {
+ if (memoize[key + secret]) {
+ return memoize[key + secret];
+ }
+
+ var CLIENT = {
+ oauth: new OAuth(
+ 'https://twitter.com/oauth/request_token'
+ , 'https://twitter.com/oauth/access_token'
+ , key
+ , secret
+ , '1.0'
+ , false
+ , 'HMAC-SHA1'
+ , null
+ , {'Accept': '*/*', 'Connection': 'close'}
+ )
+ }
+
+ , _rest_base = 'https://api.twitter.com/1';
+
+ memoize[key + secret] = CLIENT;
+
+
+ /* Does an API call to twitter and callbacks
+ * when the result is available.
+ *
+ * @param {String} method
+ * @param {String} path
+ * @param {Object} params
+ * @param {Function} callback
+ * @return {Request}
+ */
+ CLIENT.apiCall = function (method, path, params, callback) {
var token = params.token;
delete params.token;
- if (method === 'GET') {
- get(path, params, token, callback);
- } else if (method === 'POST') {
- post(path, params, token, callback);
+ function requestCallback(callback) {
+ return function (error, data, response) {
+ if (error) {
+ callback(error, null);
+ } else {
+ try {
+ callback(null, JSON.parse(data));
+ } catch (exc) {
+ callback(exc, null);
+ }
+ }
+ };
}
- };
- client.getAccessToken = function (req, res, callback) {
+ if (method.toUpperCase() === 'GET') {
+ return CLIENT.oauth.get(
+ _rest_base + path + '?' + querystring.stringify(params)
+ , token.oauth_token
+ , token.oauth_token_secret
+ , requestCallback(callback)
+ );
+ } else if (method.toUpperCase() === 'POST') {
+ return CLIENT.oauth.post(
+ _rest_base + path
+ , token.oauth_token
+ , token.oauth_token_secret
+ , params
+ , 'application/json; charset=UTF-8'
+ , requestCallback(callback)
+ );
+ }
+ };
- var parsedUrl = url.parse(req.url, true),
- protocol = req.socket.encrypted ? 'https' : 'http',
- callbackUrl = protocol + '://' + req.headers.host + parsedUrl.pathname,
- has_token = parsedUrl.query && parsedUrl.query.oauth_token,
- has_secret = req.session.auth && req.session.auth.twitter_oauth_token_secret;
+ /* Redirects to twitter to retrieve the token
+ * or callbacks with the proper token
+ *
+ * @param {Request} req
+ * @param {Response} res
+ * @param {Function} callback
+ */
+ CLIENT.getAccessToken = function (req, res, callback) {
+
+ var parsed_url = url.parse(req.url, true)
+ , protocol = req.socket.encrypted ? 'https' : 'http'
+ , callback_url = protocol + '://' + req.headers.host + parsed_url.pathname
+ , has_token = parsed_url.query && parsed_url.query.oauth_token
+ , has_secret = req.session.auth && req.session.auth.twitter_oauth_token_secret;
// Acces token
if (has_token && has_secret) {
- oAuth.getOAuthAccessToken(
- parsedUrl.query.oauth_token,
+ CLIENT.oauth.getOAuthAccessToken(
+ parsed_url.query.oauth_token,
req.session.auth.twitter_oauth_token_secret,
- parsedUrl.query.oauth_verifier,
+ parsed_url.query.oauth_verifier,
function (error, oauth_token, oauth_token_secret, additionalParameters) {
if (error) {
callback(error, null);
@@ -91,8 +109,8 @@ module.exports = function (api_key, api_secret) {
// Request token
} else {
- oAuth.getOAuthRequestToken(
- { oauth_callback: callbackUrl },
+ CLIENT.oauth.getOAuthRequestToken(
+ { oauth_callback: callback_url },
function (error, oauth_token, oauth_token_secret, oauth_authorize_url, additionalParameters) {
if (!error) {
req.session.twitter_redirect_url = req.url;
@@ -108,5 +126,5 @@ module.exports = function (api_key, api_secret) {
}
};
- return client;
+ return CLIENT;
};
View
8 package.json
@@ -1,12 +1,16 @@
{
"name": "twitter-js",
"description": "easy peasy twitter client",
- "version": "0.0.7",
+ "version": "0.1.0",
"author": "Pau Ramon <masylum@gmail.com>",
"keywords": ["twitter"],
"main" : "lib/twitter_client.js",
"directories" : { "lib" : "./lib" },
- "dependencies": { "oauth": ">= 0.8.2" },
+ "dependencies": { "oauth": "0.9.0" },
+ "devDependencies": {
+ "testosterone": "1.2.0",
+ "gently": "0.9.1"
+ },
"repository" : {"type": "git" , "url": "http://github.com/masylum/twitter-js.git" },
"engines": { "node": ">=0.2.0 <0.5.0" }
}
View
12 test/client.jade
@@ -1,12 +0,0 @@
-h1 Test, twitter-js
-form(action: '/message', method: 'post')
- label token
- input(name: 'oauth_token', value: token && token.oauth_token)
- br
- label token secret
- input(name: 'oauth_token_secret', value: token && token.oauth_token_secret)
- br
- label message
- textarea(name: 'message')
- br
- input(type: 'submit') Post
View
51 test/client.js
@@ -1,51 +0,0 @@
-/**
- * IMPORTANT:
- * In order to make this test work add
- * 127.0.0.1 twitter-js to your /etc/hosts
- */
-
-var express = require('express'),
- connect = require('connect'),
- twitterClient = require('./../')(
- 'yourKey',
- 'yourPass'
- ),
- app = express.createServer(
- connect.bodyParser(),
- connect.cookieParser(),
- connect.session({ secret: 'yourSecret' })
- );
-
-app.set('views', __dirname);
-
-app.get('/', function (req, res) {
- twitterClient.getAccessToken(req, res, function (error, token) {
- res.render('client.jade', {
- layout: false,
- locals: {
- token: token
- }
- });
- });
-});
-
-app.post('/message', function (req, res) {
- twitterClient.apiCall(
- 'POST',
- '/statuses/update.json',
- {
- token: {
- oauth_token_secret: req.param('oauth_token_secret'),
- oauth_token: req.param('oauth_token'),
- status: req.param('message')
- }
- },
- function (error, result) {
- console.log(error);
- console.log(result);
- res.render('done.jade', {layout: false});
- }
- );
-});
-
-app.listen(3003);
View
2  test/done.jade
@@ -1,2 +0,0 @@
-h1 Message published succesfully
-a(href: '/') back
View
52 tests/twitter_test.js
@@ -0,0 +1,52 @@
+var testosterone = require('testosterone')({title: 'models/twitter'})
+ , assert = testosterone.assert
+ , querystring = require('querystring')
+ , gently = global.GENTLY = new (require('gently'))
+ , key = 'foo'
+ , secret = 'bar'
+ , redirect = 'http://google.com'
+ , token = {oauth_token: '123', oauth_token_secret: '456'}
+ , twitter_client = require('../')(key, secret, redirect)
+ ;
+
+testosterone
+
+ .add('`apiCall` GET', function (done) {
+ var callback;
+
+ gently.expect(twitter_client.oauth, 'get', function (_path, _token, _secret, _callback) {
+ assert.equal(_path, 'https://api.twitter.com/1/statuses/public_timeline.json?trim_user=true');
+ assert.equal(_token, token.oauth_token);
+ assert.equal(_secret, token.oauth_token_secret);
+ _callback(null, '{"foo": "bar"}');
+ });
+
+ callback = gently.expect(function (error, response, body) {
+ assert.deepEqual(response, {foo: 'bar'});
+ done();
+ });
+
+ twitter_client.apiCall('GET', '/statuses/public_timeline.json', {token: token, trim_user: true}, callback);
+ })
+
+ .add('`apiCall` POST', function (done) {
+ var callback;
+
+ gently.expect(twitter_client.oauth, 'post', function (_path, _token, _secret, _params, _accept_header, _callback) {
+ assert.equal(_path, 'https://api.twitter.com/1/statuses/update.json');
+ assert.equal(_token, token.oauth_token);
+ assert.equal(_secret, token.oauth_token_secret);
+ assert.deepEqual(_params, {status: 'Tweet!'});
+ assert.deepEqual(_accept_header, 'application/json; charset=UTF-8');
+ _callback(null, '{"foo": "bar"}');
+ });
+
+ callback = gently.expect(function (error, response, body) {
+ assert.deepEqual(response, {foo: 'bar'});
+ done();
+ });
+
+ twitter_client.apiCall('POST', '/statuses/update.json', {token: token, status: 'Tweet!'}, callback);
+ })
+
+ .run();
Please sign in to comment.
Something went wrong with that request. Please try again.