diff --git a/test/README.md b/test/README.md index ea5f0300..e65a4fd2 100644 --- a/test/README.md +++ b/test/README.md @@ -2,10 +2,6 @@ - [app](#app) - [app.model(Model)](#app-appmodelmodel) - [app.models()](#app-appmodels) - - [loopback](#loopback) - - [loopback.createDataSource(options)](#loopback-loopbackcreatedatasourceoptions) - - [loopback.remoteMethod(Model, fn, [options]);](#loopback-loopbackremotemethodmodel-fn-options) - - [loopback.memory([name])](#loopback-loopbackmemoryname) - [DataSource](#datasource) - [dataSource.createModel(name, properties, settings)](#datasource-datasourcecreatemodelname-properties-settings) - [dataSource.operations()](#datasource-datasourceoperations) @@ -13,6 +9,11 @@ - [geoPoint.distanceTo(geoPoint, options)](#geopoint-geopointdistancetogeopoint-options) - [GeoPoint.distanceBetween(a, b, options)](#geopoint-geopointdistancebetweena-b-options) - [GeoPoint()](#geopoint-geopoint) + - [loopback](#loopback) + - [loopback.createDataSource(options)](#loopback-loopbackcreatedatasourceoptions) + - [loopback.remoteMethod(Model, fn, [options]);](#loopback-loopbackremotemethodmodel-fn-options) + - [loopback.memory([name])](#loopback-loopbackmemoryname) + - [Memory Connector](#memory-connector) - [Model](#model) - [Model.validatesPresenceOf(properties...)](#model-modelvalidatespresenceofproperties) - [Model.validatesLengthOf(property, options)](#model-modelvalidateslengthofproperty-options) @@ -41,6 +42,7 @@ - [Model.properties](#model-modelproperties) - [Model.extend()](#model-modelextend) - [User](#user) + - [User.create](#user-usercreate) - [User.login](#user-userlogin) - [User.logout](#user-userlogout) - [user.hasPassword(plain, fn)](#user-userhaspasswordplain-fn) @@ -74,61 +76,6 @@ assert.equal(models.length, 1); assert.equal(models[0].modelName, 'color'); ``` - -# loopback - -## loopback.createDataSource(options) -Create a data source with a connector.. - -```js -var dataSource = loopback.createDataSource({ - connector: loopback.Memory -}); -assert(dataSource.connector()); -``` - - -## loopback.remoteMethod(Model, fn, [options]); -Setup a remote method.. - -```js -var Product = loopback.createModel('product', {price: Number}); - -Product.stats = function(fn) { - // ... -} - -loopback.remoteMethod( - Product.stats, - { - returns: {arg: 'stats', type: 'array'}, - http: {path: '/info', verb: 'get'} - } -); - -assert.equal(Product.stats.returns.arg, 'stats'); -assert.equal(Product.stats.returns.type, 'array'); -assert.equal(Product.stats.http.path, '/info'); -assert.equal(Product.stats.http.verb, 'get'); -assert.equal(Product.stats.shared, true); -``` - - -## loopback.memory([name]) -Get an in-memory data source. Use one if it already exists.. - -```js -var memory = loopback.memory(); -assertValidDataSource(memory); -var m1 = loopback.memory(); -var m2 = loopback.memory('m2'); -var alsoM2 = loopback.memory('m2'); - -assert(m1 === memory); -assert(m1 !== m2); -assert(alsoM2 === m2); -``` - # DataSource @@ -188,7 +135,6 @@ existsAndShared('save', true); existsAndShared('isNewRecord', false); existsAndShared('_adapter', false); existsAndShared('destroy', true); -existsAndShared('updateAttribute', true); existsAndShared('updateAttributes', true); existsAndShared('reload', true); @@ -224,7 +170,7 @@ assert.equal(GeoPoint.distanceBetween(here, there, {type: 'feet'}), 2568169.0388 ## GeoPoint() -Create from string.. +Create from string. ```js var point = new GeoPoint('1.234,5.678'); @@ -238,7 +184,7 @@ assert.equal(point3.lng, 1.333); assert.equal(point3.lat, 5.111); ``` -Serialize as string.. +Serialize as string. ```js var str = '1.234,5.678'; @@ -246,7 +192,7 @@ var point = new GeoPoint(str); assert.equal(point.toString(), str); ``` -Create from array.. +Create from array. ```js var point = new GeoPoint([5.555, 6.777]); @@ -270,6 +216,99 @@ assert.equal(m.geo.lng, 1.222); assert.equal(m.geo.lat, 3.444); ``` + +# loopback + +## loopback.createDataSource(options) +Create a data source with a connector. + +```js +var dataSource = loopback.createDataSource({ + connector: loopback.Memory +}); +assert(dataSource.connector()); +``` + + +## loopback.remoteMethod(Model, fn, [options]); +Setup a remote method.. + +```js +var Product = loopback.createModel('product', {price: Number}); + +Product.stats = function(fn) { + // ... +} + +loopback.remoteMethod( + Product.stats, + { + returns: {arg: 'stats', type: 'array'}, + http: {path: '/info', verb: 'get'} + } +); + +assert.equal(Product.stats.returns.arg, 'stats'); +assert.equal(Product.stats.returns.type, 'array'); +assert.equal(Product.stats.http.path, '/info'); +assert.equal(Product.stats.http.verb, 'get'); +assert.equal(Product.stats.shared, true); +``` + + +## loopback.memory([name]) +Get an in-memory data source. Use one if it already exists. + +```js +var memory = loopback.memory(); +assertValidDataSource(memory); +var m1 = loopback.memory(); +var m2 = loopback.memory('m2'); +var alsoM2 = loopback.memory('m2'); + +assert(m1 === memory); +assert(m1 !== m2); +assert(alsoM2 === m2); +``` + + +# Memory Connector +Create a model using the memory connector. + +```js +// use the built in memory function +// to create a memory data source +var memory = loopback.memory(); + +// or create it using the standard +// data source creation api +var memory = loopback.createDataSource({ + connector: loopback.Memory +}); + +// create a model using the +// memory data source +var properties = { + name: String, + price: Number +}; + +var Product = memory.createModel('product', properties); + +Product.create([ + {name: 'apple', price: 0.79}, + {name: 'pear', price: 1.29}, + {name: 'orange', price: 0.59}, +], count); + +function count() { + Product.count(function (err, count) { + assert.equal(count, 3); + done(); + }); +} +``` + # Model @@ -368,7 +407,7 @@ assert(valid === false); assert(user.errors.age, 'model should have age error'); ``` -Asynchronously validate the model.. +Asynchronously validate the model. ```js User.validatesNumericalityOf('age', {int: true}); @@ -555,7 +594,7 @@ request(app) ### Model.beforeRemote(name, fn) -Run a function before a remote method is called by a client.. +Run a function before a remote method is called by a client. ```js var hookCalled = false; @@ -580,7 +619,7 @@ request(app) ### Model.afterRemote(name, fn) -Run a function after a remote method is called by a client.. +Run a function after a remote method is called by a client. ```js var beforeCalled = false; @@ -706,7 +745,7 @@ Book.create({title: 'Into the Wild', author: 'Jon Krakauer'}, function(err, book ## Model.properties -Normalized properties passed in originally by loopback.createModel().. +Normalized properties passed in originally by loopback.createModel(). ```js var props = { @@ -740,7 +779,7 @@ Object.keys(MyModel.properties).forEach(function (key) { ## Model.extend() -Create a new model by extending an existing model.. +Create a new model by extending an existing model. ```js var User = loopback.Model.extend('test-user', { @@ -776,9 +815,64 @@ assert.equal(user.b, 'bar'); # User + +## User.create +Create a new user. + +```js +User.create({email: 'f@b.com'}, function (err, user) { + assert(!err); + assert(user.id); + assert(user.email); + done(); +}); +``` + +Requires a valid email. + +```js +User.create({}, function (err) { + assert(err); + User.create({email: 'foo@'}, function (err) { + assert(err); + done(); + }); +}); +``` + +Requires a unique email. + +```js +User.create({email: 'a@b.com'}, function () { + User.create({email: 'a@b.com'}, function (err) { + assert(err, 'should error because the email is not unique!'); + done(); + }); +}); +``` + +Requires a password to login with basic auth. + +```js +User.create({email: 'b@c.com'}, function (err) { + User.login({email: 'b@c.com'}, function (err, session) { + assert(!session, 'should not create a session without a valid password'); + assert(err, 'should not login without a password'); + done(); + }); +}); +``` + +Hashes the given password. + +```js +var u = new User({username: 'foo', password: 'bar'}); +assert(u.password !== 'bar'); +``` + ## User.login -Login a user by providing credentials.. +Login a user by providing credentials. ```js request(app) @@ -792,6 +886,7 @@ request(app) assert(session.uid); assert(session.id); + assert.equal((new Buffer(session.id, 'base64')).length, 64); done(); }); @@ -799,7 +894,21 @@ request(app) ## User.logout -Logout a user by providing the current session id.. +Logout a user by providing the current session id (using node). + +```js +login(logout); + +function login(fn) { + User.login({email: 'foo@bar.com', password: 'bar'}, fn); +} + +function logout(err, session) { + User.logout(session.id, verify(session.id, done)); +} +``` + +Logout a user by providing the current session id (over rest). ```js login(logout); @@ -826,33 +935,78 @@ function logout(err, sid) { .post('/users/logout') .expect(200) .send({sid: sid}) - .end(verify(sid)); + .end(verify(sid, done)); +} +``` + +Logout a user using the instance method. + +```js +login(logout); + +function login(fn) { + User.login({email: 'foo@bar.com', password: 'bar'}, fn); } -function verify(sid) { - return function (err) { - if(err) return done(err); - Session.findById(sid, function (err, session) { - assert(!session, 'session should not exist after logging out'); - done(err); - }); - } +function logout(err, session) { + User.findOne({email: 'foo@bar.com'}, function (err, user) { + user.logout(verify(session.id, done)); + }); } ``` ## user.hasPassword(plain, fn) -Determine if the password matches the stored password.. +Determine if the password matches the stored password. ```js var u = new User({username: 'foo', password: 'bar'}); - u.hasPassword('bar', function (err, isMatch) { assert(isMatch, 'password doesnt match'); done(); }); ``` +should match a password when saved. + +```js +var u = new User({username: 'a', password: 'b', email: 'z@z.net'}); + +u.save(function (err, user) { + User.findById(user.id, function (err, uu) { + uu.hasPassword('b', function (err, isMatch) { + assert(isMatch); + done(); + }); + }); +}); +``` + +should match a password after it is changed. + +```js +User.create({email: 'foo@baz.net', username: 'bat', password: 'baz'}, function (err, user) { + User.findById(user.id, function (err, foundUser) { + assert(foundUser); + foundUser.hasPassword('baz', function (err, isMatch) { + assert(isMatch); + foundUser.password = 'baz2'; + foundUser.save(function (err, updatedUser) { + updatedUser.hasPassword('baz2', function (err, isMatch) { + assert(isMatch); + User.findById(user.id, function (err, uu) { + uu.hasPassword('baz2', function (err, isMatch) { + assert(isMatch); + done(); + }); + }); + }); + }); + }); + }); +}); +``` + ## Verification @@ -888,7 +1042,7 @@ request(app) .post('/users') .expect('Content-Type', /json/) .expect(200) - .send({data: {email: 'bar@bat.com', password: 'bar'}}) + .send({email: 'bar@bat.com', password: 'bar'}) .end(function(err, res){ if(err) return done(err); }); @@ -929,7 +1083,7 @@ request(app) .post('/users') .expect('Content-Type', /json/) .expect(302) - .send({data: {email: 'bar@bat.com', password: 'bar'}}) + .send({email: 'bar@bat.com', password: 'bar'}) .end(function(err, res){ if(err) return done(err); }); diff --git a/test/geo-point.test.js b/test/geo-point.test.js index 223df816..469076f6 100644 --- a/test/geo-point.test.js +++ b/test/geo-point.test.js @@ -18,7 +18,7 @@ describe('GeoPoint', function() { }); describe('GeoPoint()', function(){ - it('Create from string.', function() { + it('Create from string', function() { var point = new GeoPoint('1.234,5.678'); assert.equal(point.lng, 1.234); assert.equal(point.lat, 5.678); @@ -29,12 +29,12 @@ describe('GeoPoint', function() { assert.equal(point3.lng, 1.333); assert.equal(point3.lat, 5.111); }); - it('Serialize as string.', function() { + it('Serialize as string', function() { var str = '1.234,5.678'; var point = new GeoPoint(str); assert.equal(point.toString(), str); }); - it('Create from array.', function() { + it('Create from array', function() { var point = new GeoPoint([5.555, 6.777]); assert.equal(point.lng, 5.555); assert.equal(point.lat, 6.777); diff --git a/test/loopback.test.js b/test/loopback.test.js index 0f52636b..21ec540e 100644 --- a/test/loopback.test.js +++ b/test/loopback.test.js @@ -1,6 +1,6 @@ describe('loopback', function() { describe('loopback.createDataSource(options)', function(){ - it('Create a data source with a connector.', function() { + it('Create a data source with a connector', function() { var dataSource = loopback.createDataSource({ connector: loopback.Memory }); @@ -33,7 +33,7 @@ describe('loopback', function() { }); describe('loopback.memory([name])', function(){ - it('Get an in-memory data source. Use one if it already exists.', function() { + it('Get an in-memory data source. Use one if it already exists', function() { var memory = loopback.memory(); assertValidDataSource(memory); var m1 = loopback.memory(); diff --git a/test/model.test.js b/test/model.test.js index 9e43c51f..30afa286 100644 --- a/test/model.test.js +++ b/test/model.test.js @@ -96,7 +96,7 @@ describe('Model', function() { assert(user.errors.age, 'model should have age error'); }); - it('Asynchronously validate the model.', function(done) { + it('Asynchronously validate the model', function(done) { User.validatesNumericalityOf('age', {int: true}); var user = new User({first: 'joe', age: 'flarg'}) user.isValid(function (valid) { @@ -285,7 +285,7 @@ describe('Model', function() { }); describe('Model.beforeRemote(name, fn)', function(){ - it('Run a function before a remote method is called by a client.', function(done) { + it('Run a function before a remote method is called by a client', function(done) { var hookCalled = false; User.beforeRemote('create', function(ctx, user, next) { @@ -308,7 +308,7 @@ describe('Model', function() { }); describe('Model.afterRemote(name, fn)', function(){ - it('Run a function after a remote method is called by a client.', function(done) { + it('Run a function after a remote method is called by a client', function(done) { var beforeCalled = false; var afterCalled = false; @@ -433,7 +433,7 @@ describe('Model', function() { }); describe('Model.properties', function(){ - it('Normalized properties passed in originally by loopback.createModel().', function() { + it('Normalized properties passed in originally by loopback.createModel()', function() { var props = { s: String, n: {type: 'Number'}, @@ -465,7 +465,7 @@ describe('Model', function() { }); describe('Model.extend()', function(){ - it('Create a new model by extending an existing model.', function() { + it('Create a new model by extending an existing model', function() { var User = loopback.Model.extend('test-user', { email: String }); @@ -545,7 +545,7 @@ describe('Model', function() { // }); // describe('Model.before(name, fn)', function(){ -// it('Run a function before a method is called.', function() { +// it('Run a function before a method is called', function() { // // User.before('save', function(user, next) { // // console.log('about to save', user); // // @@ -569,7 +569,7 @@ describe('Model', function() { // }); // // describe('Model.after(name, fn)', function(){ -// it('Run a function after a method is called.', function() { +// it('Run a function after a method is called', function() { // // throw new Error('not implemented'); // }); diff --git a/test/user.test.js b/test/user.test.js index 9ef24b42..cdc3194c 100644 --- a/test/user.test.js +++ b/test/user.test.js @@ -32,7 +32,7 @@ describe('User', function(){ }); describe('User.create', function(){ - it('Create a new user.', function(done) { + it('Create a new user', function(done) { User.create({email: 'f@b.com'}, function (err, user) { assert(!err); assert(user.id); @@ -41,7 +41,7 @@ describe('User', function(){ }); }); - it('Requires a valid email.', function(done) { + it('Requires a valid email', function(done) { User.create({}, function (err) { assert(err); User.create({email: 'foo@'}, function (err) { @@ -51,7 +51,7 @@ describe('User', function(){ }); }); - it('Requires a unique email.', function(done) { + it('Requires a unique email', function(done) { User.create({email: 'a@b.com'}, function () { User.create({email: 'a@b.com'}, function (err) { assert(err, 'should error because the email is not unique!'); @@ -60,7 +60,7 @@ describe('User', function(){ }); }); - it('Requires a password to login with basic auth.', function(done) { + it('Requires a password to login with basic auth', function(done) { User.create({email: 'b@c.com'}, function (err) { User.login({email: 'b@c.com'}, function (err, session) { assert(!session, 'should not create a session without a valid password'); @@ -70,14 +70,14 @@ describe('User', function(){ }); }); - it('Hashes the given password.', function() { + it('Hashes the given password', function() { var u = new User({username: 'foo', password: 'bar'}); assert(u.password !== 'bar'); }); }); describe('User.login', function() { - it('Login a user by providing credentials.', function(done) { + it('Login a user by providing credentials', function(done) { request(app) .post('/users/login') .expect('Content-Type', /json/) @@ -97,7 +97,7 @@ describe('User', function(){ }); describe('User.logout', function() { - it('Logout a user by providing the current session id (using node).', function(done) { + it('Logout a user by providing the current session id (using node)', function(done) { login(logout); function login(fn) { @@ -109,7 +109,7 @@ describe('User', function(){ } }); - it('Logout a user by providing the current session id (over rest).', function(done) { + it('Logout a user by providing the current session id (over rest)', function(done) { login(logout); function login(fn) { @@ -138,7 +138,7 @@ describe('User', function(){ } }); - it('Logout a user using the instance method.', function(done) { + it('Logout a user using the instance method', function(done) { login(logout); function login(fn) { @@ -167,7 +167,7 @@ describe('User', function(){ }); describe('user.hasPassword(plain, fn)', function(){ - it('Determine if the password matches the stored password.', function(done) { + it('Determine if the password matches the stored password', function(done) { var u = new User({username: 'foo', password: 'bar'}); u.hasPassword('bar', function (err, isMatch) { assert(isMatch, 'password doesnt match');