diff --git a/lib/oauth.js b/lib/oauth.js index 61a8bd1..10d3e7a 100644 --- a/lib/oauth.js +++ b/lib/oauth.js @@ -264,7 +264,7 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke } } - if( method == "POST" && ( post_body == null && extra_params != null) ) { + if( (method == "POST" || method == "PUT") && ( post_body == null && extra_params != null) ) { post_body= querystring.stringify(extra_params); } @@ -295,13 +295,14 @@ exports.OAuth.prototype._performSecureRequest= function( oauth_token, oauth_toke }); request.socket.addListener("error",callback); - if( method == "POST" && post_body != null && post_body != "" ) { + + if( (method == "POST" || method =="PUT") && post_body != null && post_body != "" ) { request.write(post_body); } request.end(); } else { - if( method == "POST" && post_body != null && post_body != "" ) { + if( (method == "POST" || method =="PUT") && post_body != null && post_body != "" ) { request.write(post_body); } return request; @@ -336,11 +337,15 @@ exports.OAuth.prototype.getProtectedResource= function(url, method, oauth_token, this._performSecureRequest( oauth_token, oauth_token_secret, method, url, null, "", null, callback ); } +exports.OAuth.prototype.delete= function(url, oauth_token, oauth_token_secret, callback) { + return this._performSecureRequest( oauth_token, oauth_token_secret, "DELETE", url, null, "", null, callback ); +} + exports.OAuth.prototype.get= function(url, oauth_token, oauth_token_secret, callback) { return this._performSecureRequest( oauth_token, oauth_token_secret, "GET", url, null, "", null, callback ); } -exports.OAuth.prototype.post= function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback) { +exports.OAuth.prototype._putOrPost= function(method, url, oauth_token, oauth_token_secret, post_body, post_content_type, callback) { var extra_params= null; if( typeof post_content_type == "function" ) { callback= post_content_type; @@ -351,9 +356,18 @@ exports.OAuth.prototype.post= function(url, oauth_token, oauth_token_secret, pos extra_params= post_body; post_body= null; } - return this._performSecureRequest( oauth_token, oauth_token_secret, "POST", url, extra_params, post_body, post_content_type, callback ); + return this._performSecureRequest( oauth_token, oauth_token_secret, method, url, extra_params, post_body, post_content_type, callback ); } + +exports.OAuth.prototype.put= function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback) { + return this._putOrPost("PUT", url, oauth_token, oauth_token_secret, post_body, post_content_type, callback); +} + +exports.OAuth.prototype.post= function(url, oauth_token, oauth_token_secret, post_body, post_content_type, callback) { + return this._putOrPost("POST", url, oauth_token, oauth_token_secret, post_body, post_content_type, callback); +} + exports.OAuth.prototype.getOAuthRequestToken= function(extraParams, callback) { if( typeof extraParams == "function" ){ callback = extraParams; diff --git a/tests/oauth.js b/tests/oauth.js index c58fac6..219a472 100644 --- a/tests/oauth.js +++ b/tests/oauth.js @@ -377,7 +377,173 @@ vows.describe('OAuth').addBatch({ oa._createClient= op; } } + } + }, + 'PUT' : { + 'if no callback is passed' : { + 'it should return a request object': function(oa) { + var request= oa.put("http://foo.com/blah", "token", "token_secret", "BLAH", "text/plain") + assert.isObject(request); + assert.equal(request.method, "PUT"); + request.end(); + } }, + 'if a callback is passed' : { + "it should call the internal request's end method and return nothing": function(oa) { + var callbackCalled= false; + var op= oa._createClient; + try { + oa._createClient= function() { + return { + request: function(method, path, headers) { + return { + write: function(){}, + socket: {addListener: function(){}}, + addListener: function() {}, + end: function() { + callbackCalled= true; + } + } + } + } + } + var request= oa.put("http://foo.com/blah", "token", "token_secret", "BLAH", "text/plain", function(e,d){}) + assert.equal(callbackCalled, true); + assert.isUndefined(request); + } + finally { + oa._createClient= op; + } + } + }, + 'if the post_body is not a string' : { + "It should be url encoded and the content type set to be x-www-form-urlencoded" : function(oa) { + var op= oa._createClient; + try { + var callbackCalled= false; + oa._createClient= function() { + return { + request: function(method, path, headers) { + assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded") + return { + socket: {addListener: function(){}}, + write: function(data) { + callbackCalled= true; + assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2"); + }, + addListener: function() {}, + end: function() {} + } + } + } + } + var request= oa.put("http://foo.com/blah", "token", "token_secret", {"foo":"1,2,3", "bar":"1+2"}) + assert.equal(callbackCalled, true); + } + finally { + oa._createClient= op; + } + } + }, + 'if the post_body is a string' : { + "and no post_content_type is specified" : { + "It should be written as is, with a content length specified, and the encoding should be set to be x-www-form-urlencoded" : function(oa) { + var op= oa._createClient; + try { + var callbackCalled= false; + oa._createClient= function() { + return { + request: function(method, path, headers) { + assert.equal(headers["Content-Type"], "application/x-www-form-urlencoded"); + assert.equal(headers["Content-length"], 23); + return { + socket: {addListener: function(){}}, + write: function(data) { + callbackCalled= true; + assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2"); + }, + addListener: function() {}, + end: function() {} + } + } + } + } + var request= oa.put("http://foo.com/blah", "token", "token_secret", "foo=1%2C2%2C3&bar=1%2B2") + assert.equal(callbackCalled, true); + } + finally { + oa._createClient= op; + } + } + }, + "and a post_content_type is specified" : { + "It should be written as is, with a content length specified, and the encoding should be set to be as specified" : function(oa) { + var op= oa._createClient; + try { + var callbackCalled= false; + oa._createClient= function() { + return { + request: function(method, path, headers) { + assert.equal(headers["Content-Type"], "unicorn/encoded"); + assert.equal(headers["Content-length"], 23); + return { + socket: {addListener: function(){}}, + write: function(data) { + callbackCalled= true; + assert.equal(data, "foo=1%2C2%2C3&bar=1%2B2"); + }, + addListener: function() {}, + end: function() {} + } + } + } + } + var request= oa.put("http://foo.com/blah", "token", "token_secret", "foo=1%2C2%2C3&bar=1%2B2", "unicorn/encoded") + assert.equal(callbackCalled, true); + } + finally { + oa._createClient= op; + } + } + } + } + }, + 'DELETE' : { + 'if no callback is passed' : { + 'it should return a request object': function(oa) { + var request= oa.delete("http://foo.com/blah", "token", "token_secret") + assert.isObject(request); + assert.equal(request.method, "DELETE"); + request.end(); + } + }, + 'if a callback is passed' : { + "it should call the internal request's end method and return nothing": function(oa) { + var callbackCalled= false; + var op= oa._createClient; + try { + oa._createClient= function() { + return { + request: function(method, path, headers) { + return { + socket: {addListener: function(){}}, + addListener: function() {}, + end: function() { + callbackCalled= true; + } + } + } + } + } + var request= oa.delete("http://foo.com/blah", "token", "token_secret", function(e,d) {}) + assert.equal(callbackCalled, true); + assert.isUndefined(request); + } + finally { + oa._createClient= op; + } + } + } } } }).export(module);