diff --git a/lib/client.js b/lib/client.js index 04ac63c6..56a3b061 100644 --- a/lib/client.js +++ b/lib/client.js @@ -34,19 +34,28 @@ var p = Client.prototype; p.connect = function() { var self = this; var con = this.connection; + con.connect(this.port, this.host); + + con.on('connect', function() { + con.startupMessage({ + user: self.user, + database: self.database + }); + }); + con.on('authenticationCleartextPassword', function() { con.passwordMessage(self.password); }); con.on('authenticationMD5Password', function(msg) { - var inner = self.md5(self.password + self.user); - var outer = self.md5(inner + msg.salt.toString('binary')); + var inner = Client.md5(self.password + self.user); + var outer = Client.md5(inner + msg.salt.toString('binary')); var md5password = "md5" + outer; con.passwordMessage(md5password); }); }; -p.md5 = function(string) { +Client.md5 = function(string) { return crypto.createHash('md5').update(string).digest('hex'); }; diff --git a/lib/connection.js b/lib/connection.js index 1650f792..debbb037 100644 --- a/lib/connection.js +++ b/lib/connection.js @@ -22,11 +22,14 @@ sys.inherits(Connection, EventEmitter); var p = Connection.prototype; p.connect = function(port, host) { + if(this.stream.readyState === 'closed'){ this.stream.connect(port, host); - }else if(this.stream.readyState == 'open') { + } + else if(this.stream.readyState == 'open') { this.emit('connect'); } + var self = this; this.stream.on('connect', function() { diff --git a/test.js b/test.js index c7282ab1..db474ef4 100755 --- a/test.js +++ b/test.js @@ -9,4 +9,12 @@ var runDir = function(dir) { require(dir + file.split('.js') [0]); }); }; -runDir(__dirname+'/test/' + (process.argv[2] || "unit")+ '/'); +var arg = (process.argv[2] || "unit"); +if(arg == 'all') { + runDir(__dirname+'/test/unit/'); + runDir(__dirname+'/test/integration/'); +} +else { + runDir(__dirname+'/test/' + + '/'); +} + diff --git a/test/integration/simple-bound-query-tests.js b/test/integration/connection/bound-command-tests.js similarity index 89% rename from test/integration/simple-bound-query-tests.js rename to test/integration/connection/bound-command-tests.js index c91fa4a6..87ce5143 100644 --- a/test/integration/simple-bound-query-tests.js +++ b/test/integration/connection/bound-command-tests.js @@ -9,15 +9,17 @@ helper.connect(function(con) { con.flush(); con.once('parseComplete', function() { + console.log('parseComplete'); con.bind(); con.flush(); }); con.once('bindComplete', function() { + console.log('bindComplete'); con.execute(); con.flush(); }); - + con.on('dataRow', function(msg) { sys.debug("got row from pepared query"); }); @@ -25,7 +27,7 @@ helper.connect(function(con) { con.on('commandComplete', function() { con.sync(); }); - + con.on('readyForQuery', function() { con.end(); }); diff --git a/test/integration/connection/cleartext-password-tests.js b/test/integration/connection/cleartext-password-tests.js new file mode 100644 index 00000000..0996337b --- /dev/null +++ b/test/integration/connection/cleartext-password-tests.js @@ -0,0 +1,15 @@ +var helper = require(__dirname + '/test-helper'); + +helper.authConnect('user_pw', 'postgres', function(con) { + + con.once('authenticationCleartextPassword', function() { + con.passwordMessage('pass'); + }); + + con.once('readyForQuery', function() { + console.log('successfully connected with cleartext password'); + con.end(); + }); + +}); + diff --git a/test/integration/connection/md5-password-tests.js b/test/integration/connection/md5-password-tests.js new file mode 100644 index 00000000..a155132c --- /dev/null +++ b/test/integration/connection/md5-password-tests.js @@ -0,0 +1,16 @@ +var helper = require(__dirname + '/test-helper'); + +helper.authConnect('user_md5', 'postgres', function(con) { + + con.once('authenticationMD5Password', function(msg) { + var enc = Client.md5('ssap' + 'user_md5'); + enc = Client.md5(enc + msg.salt.toString('binary')); + con.passwordMessage('md5'+enc); + }); + + con.once('readyForQuery', function() { + console.log('successfully connected with md5 password'); + con.end(); + }); + +}); diff --git a/test/integration/connection/no-password-tests.js b/test/integration/connection/no-password-tests.js new file mode 100644 index 00000000..8d90b618 --- /dev/null +++ b/test/integration/connection/no-password-tests.js @@ -0,0 +1,7 @@ +var helper = require(__dirname+'/test-helper'); +helper.authConnect(function(con) { + con.once('readyForQuery', function() { + console.log("Succesfully connected without a password"); + con.end(); + }); +}); diff --git a/test/integration/simple-query-tests.js b/test/integration/connection/query-tests.js similarity index 84% rename from test/integration/simple-query-tests.js rename to test/integration/connection/query-tests.js index b82b11a8..a2666bc2 100644 --- a/test/integration/simple-query-tests.js +++ b/test/integration/connection/query-tests.js @@ -7,6 +7,7 @@ var rows = []; helper.connect(function(con) { con.query('select * from ids'); con.on('dataRow', function(msg) { + console.log("row: " + sys.inspect(msg.fields)); rows.push(msg.fields); }); con.once('readyForQuery', function() { @@ -17,8 +18,8 @@ helper.connect(function(con) { process.on('exit', function() { assert.equal(rows.length, 2); assert.equal(rows[0].length, 1); - assert.equal(rows[0] [0], 1); - assert.equal(rows[1] [0], 2); + assert.strictEqual(rows[0] [0], '1'); + assert.strictEqual(rows[1] [0], '2'); }); diff --git a/test/integration/connection/test-helper.js b/test/integration/connection/test-helper.js new file mode 100644 index 00000000..ae86a0ea --- /dev/null +++ b/test/integration/connection/test-helper.js @@ -0,0 +1,39 @@ +var net = require('net'); +require(__dirname+'/../test-helper'); + +var authConnect = function(username, database, callback) { + if(typeof username === 'function') { + callback = username; + username = 'brian'; + database = 'postgres'; + } + var connection = new Connection({stream: new net.Stream()}); + connection.connect('5432','localhost'); + connection.once('connect', function() { + connection.startupMessage({ + user: username, + database: database + }); + callback(connection); + }); +}; + +var connect = function(callback) { + authConnect(function(con) { + con.once('readyForQuery', function() { + con.query('create temp table ids(id integer)'); + }); + con.once('readyForQuery', function() { + con.query('insert into ids(id) values(1); insert into ids(id) values(2);'); + }); + con.once('readyForQuery', function() { + callback(con); + }); + + }); +}; + +module.exports = { + authConnect: authConnect, + connect: connect +}; diff --git a/test/integration/password-connection-tests.js b/test/integration/password-connection-tests.js deleted file mode 100644 index f1fd0dbe..00000000 --- a/test/integration/password-connection-tests.js +++ /dev/null @@ -1,35 +0,0 @@ -require(__dirname + '/test-helper'); - -var pwClient = new Client({ - database: 'postgres', - user: 'user_pw', - password: 'pass' -}); -pwClient.on('error', function(error) { - console.log(error); - throw error; -}); -pwClient.connect(); - -pwClient.on('readyForQuery', function(){ - sys.debug("Connected with clear text password"); - pwClient.end(); -}); - -var md5Client = new Client({ - database: 'postgres', - user: 'user_md5', - password: 'ssap' -}); - -md5Client.on('error', function(error) { - console.log(error); - throw error; -}); - -md5Client.connect(); - -md5Client.on('readyForQuery', function() { - sys.debug("Connected with md5 password"); - md5Client.end(); -}); diff --git a/test/integration/test-helper.js b/test/integration/test-helper.js index 5e1cce2c..2b2cca0c 100644 --- a/test/integration/test-helper.js +++ b/test/integration/test-helper.js @@ -1,24 +1,6 @@ -Client = require(__dirname+'/../../lib/client'); +var requireLib = function(lib) { + return require(__dirname + '/../../lib/' + lib); +}; +Client = requireLib('client'); +Connection = requireLib('connection'); sys = require('sys'); - -//creates a configured, connecting client -var connect = function(onReady) { - var con = new Client({ - database: 'postgres', - user: 'brian' - }); - con.connect(); - con.once('readyForQuery', function() { - con.query('create temporary table ids(id integer)'); - con.once('readyForQuery', function() { - con.query('insert into ids(id) values(1); insert into ids(id) values(2);'); - con.once('readyForQuery',function() { - onReady(con); - }); - }); - }); -}; - -module.exports = { - connect: connect -}; diff --git a/test/unit/client/md5-password-tests.js b/test/unit/client/md5-password-tests.js index 70d3a18f..649f06c2 100644 --- a/test/unit/client/md5-password-tests.js +++ b/test/unit/client/md5-password-tests.js @@ -8,8 +8,8 @@ test('md5 authentication', function() { test('responds', function() { assert.length(client.stream.packets, 1); test('should have correct encrypted data', function() { - var encrypted = client.md5(client.password + client.user); - encrypted = client.md5(encrypted + salt.toString('binary')); + var encrypted = Client.md5(client.password + client.user); + encrypted = Client.md5(encrypted + salt.toString('binary')); var password = "md5" + encrypted //how do we want to test this? assert.equalBuffers(client.stream.packets[0], new BufferList() diff --git a/test/unit/prepared-query-tests.js b/test/unit/prepared-query-tests.js new file mode 100644 index 00000000..e69de29b