From 362f5607d98eec6121f2044fbb26d3ef2e00a1b0 Mon Sep 17 00:00:00 2001 From: "Didier Villevalois (Ptitjes)" Date: Fri, 17 Nov 2017 22:20:53 +0100 Subject: [PATCH] test(urls): extract and enhance urls tests The authentication tests were mixed in with urls tests. Also, the url tests were enhanced to take in account use of urlParse and handling of db prefixes. (cf. #150 and #158) --- package.json | 4 +- test/test.authentication.js | 309 ++++++++++++++++++++++++++++++++++ test/test.js | 320 ------------------------------------ test/test.urls.js | 46 ++++++ 4 files changed, 357 insertions(+), 322 deletions(-) create mode 100644 test/test.authentication.js delete mode 100644 test/test.js create mode 100644 test/test.urls.js diff --git a/package.json b/package.json index 3f1ea74..4657404 100644 --- a/package.json +++ b/package.json @@ -19,8 +19,8 @@ "prepublishOnly": "npm run build", "build": "npm-run-all clean rollup minify", "lint": "eslint bin/ src/ tests/", - "dev": "npm run rollup-cjs && zuul --local 9000 --no-coverage --ui mocha-bdd test/test.js", - "test": "npm run rollup-cjs && zuul --phantom --ui mocha-bdd test/test.js", + "dev": "npm run rollup-cjs && zuul --local 9000 --no-coverage --ui mocha-bdd test/*", + "test": "npm run rollup-cjs && zuul --phantom --ui mocha-bdd test/*", "release": "standard-version" }, "keywords": [ diff --git a/test/test.authentication.js b/test/test.authentication.js new file mode 100644 index 0000000..55cbb5d --- /dev/null +++ b/test/test.authentication.js @@ -0,0 +1,309 @@ +'use strict'; + +var PouchDB = require('pouchdb-memory'); +var Authentication = require('../lib'); +PouchDB.plugin(Authentication); +var chai = require('chai'); +var should = chai.should(); +chai.use(require('chai-as-promised')); + +var users = ['batman', 'superman', 'green_lantern', 'robin', 'aquaman', 'spiderman']; + +describe('authentication', function () { + + var dbName = 'http://localhost:5984/testdb'; + + var db; + + beforeEach(function () { + db = new PouchDB(dbName); + return db; + }); + afterEach(function () { + return db.logout().then(function () { + return db.destroy().then(function () { + var usersUrl = db.getUsersDatabaseUrl(); + var usersDb = new PouchDB(usersUrl); + // remove the fake users, hopefully we're in the admin party + return usersDb.allDocs({ + include_docs: true, + keys: users.map(function (user) { + return 'org.couchdb.user:' + user; + }) + }).then(function (res) { + var rows = res.rows.filter(function (row) { + return row.doc; + }); + var docs = rows.map(function (row) { + row.doc._deleted = true; + return row.doc; + }); + return usersDb.bulkDocs({docs: docs}); + }); + }); + }); + }); + + it('Test signup', function () { + return db.signup('batman', 'brucewayne').then(function (res) { + res.ok.should.equal(true); + res.id.should.equal('org.couchdb.user:batman'); + }); + }); + + it('Test signup conflict', function () { + return db.signup('superman', 'clarkkent').then(function (res) { + res.ok.should.equal(true); + return db.signup('superman', 'notclarkkent').then(function (res) { + should.not.exist(res); + }).catch(function (err) { + err.name.should.equal('conflict'); + }); + }); + }); + + it('Test bad signup args', function () { + return db.signup().catch(function (err) { + should.exist(err); + }); + }); + + it('Test bad signup args 2', function () { + return db.signup('green_lantern').catch(function (err) { + should.exist(err); + }); + }); + + it('Test login/logout', function () { + return db.signup('aquaman', 'sleeps_with_fishes').then(function (res) { + return db.getSession(); + }).then(function (res) { + should.equal(res.userCtx.name, null); + return db.login('aquaman', 'sleeps_with_fishes'); + }).then(function (res) { + res.ok.should.equal(true); + return db.getSession(); + }).then(function (res) { + res.userCtx.name.should.equal('aquaman'); + return db.logout(); + }).then(function () { + return db.getSession(); + }).then(function (res) { + should.equal(res.userCtx.name, null); + }); + }); + + it('Test metadata', function () { + var metadata = {alias: 'boywonder', profession: 'acrobat'}; + var opts = {metadata: metadata}; + return db.signup('robin', 'dickgrayson', opts).then(function (res) { + res.ok.should.equal(true); + return db.login('robin', 'dickgrayson'); + }).then(function () { + return db.getUser('robin'); + }).then(function (user) { + user.name.should.equal('robin'); + user.alias.should.equal('boywonder'); + user.profession.should.equal('acrobat'); + }); + }); + + it('Test changing metadata', function () { + var metadata = {alias: 'boywonder', profession: 'acrobat'}; + var newMetadata = {alias: 'rednowyob', profession: 'taborca'}; + var opts = {metadata: metadata}; + return db.signup('robin', 'dickgrayson', opts).then(function (res) { + res.ok.should.equal(true); + return db.login('robin', 'dickgrayson'); + }).then(function () { + return db.getUser('robin'); + }).then(function (user) { + user.name.should.equal('robin'); + user.alias.should.equal('boywonder'); + user.profession.should.equal('acrobat'); + }).then(function () { + return db.putUser('robin', {metadata: newMetadata}); + }).then(function () { + return db.getUser('robin'); + }).then(function (user) { + user.name.should.equal('robin'); + user.alias.should.equal('rednowyob'); + user.profession.should.equal('taborca'); + }); + }); + + var reservedWords = [ + '_id', + '_rev', + 'name', + 'type', + 'roles', + 'password', + 'password_scheme', + 'iterations', + 'derived_key', + 'salt' + ]; + + reservedWords.forEach(function (key) { + it('Test changing metadata using reserved word "' + key + '"', function () { + return db.signup('robin', 'dickgrayson').then(function (res) { + res.ok.should.equal(true); + return db.login('robin', 'dickgrayson'); + }).then(function () { + return db.getUser('robin').then(function (user) { + var metadata = {}; + metadata[key] = 'test'; + return db.putUser('robin', {metadata: metadata}).then(function (res) { + res.ok.should.not.equal(true); + }).catch(function (err) { + should.exist(err); + err.status.should.equal(400); + err.name.should.equal('authentication_error'); + err.message.should.equal('cannot use reserved word in metadata: "' + key + '"'); + err.error.should.equal(true); + + if (key === 'password') { + return db.login('robin', 'dickgrayson').then(function (res) { + res.ok.should.equal(true); + }).catch(function (err) { + should.not.exist(err); + }); + } else { + return db.getUser('robin').then(function (changedUser) { + changedUser[key].should.deep.equal(user[key]); + }).catch(function (err) { + should.not.exist(err); + }); + } + }); + }); + }); + }); + }); + + it('Test changing metadata using non-reserved word "metadata"', function () { + var metadata = {test: 'test'}; + return db.signup('robin', 'dickgrayson').then(function (res) { + res.ok.should.equal(true); + return db.login('robin', 'dickgrayson'); + }).then(function () { + return db.putUser('robin', {metadata: {metadata: metadata}}); + }).then(function (res) { + res.ok.should.equal(true); + return db.getUser('robin'); + }).then(function (changedUser) { + changedUser.metadata.should.deep.equal(metadata); + }).catch(function (err) { + should.not.exist(err); + }); + }); + + it('Test that admin can change roles', function () { + var roles = ['sidekick']; + var newRoles = ['superhero', 'villain']; + return db.signup('robin', 'dickgrayson', {roles: roles}).then(function (res) { + res.ok.should.equal(true); + return db.getUser('robin'); + }).then(function (user) { + user.roles.should.deep.equal(roles); + }).then(function () { + return db.putUser('robin', {roles: newRoles}); + }).then(function (res) { + res.ok.should.equal(true); + return db.getUser('robin'); + }).then(function (user) { + user.roles.should.deep.equal(newRoles); + }).catch(function (err) { + should.not.exist(err); + }); + }); + + it('Test that user cannot change roles', function () { + var roles = ['sidekick']; + var newRoles = ['superhero', 'villain']; + // We can't test for initial roles as we are in admin party + // Let us have faith in CouchDB + return db.signup('robin', 'dickgrayson', {roles: roles}).then(function (res) { + res.ok.should.equal(true); + return db.login('robin', 'dickgrayson'); + }).then(function () { + return db.getUser('robin'); + }).then(function (user) { + user.roles.should.deep.equal(roles); + }).then(function () { + return db.putUser('robin', {roles: newRoles}); + }).then(function (res) { + res.ok.should.not.equal(true); + return db.getUser('robin').then(function (user) { + user.roles.should.deep.equal(roles); + }); + }).catch(function (err) { + should.exist(err); + }); + }); + + it('Test wrong user for getUser', function () { + return db.signup('robin', 'dickgrayson').then(function (res) { + return db.signup('aquaman', 'sleeps_with_fishes'); + }).then(function () { + return db.login('robin', 'dickgrayson'); + }).then(function () { + return db.getUser('robin'); + }).then(function (res) { + res.name.should.equal('robin'); + return db.getUser('aquaman').then(function (res) { + should.not.exist(res); + }).catch(function (err) { + should.exist(err); + return db.login('aquaman', 'sleeps_with_fishes').then(function () { + return db.getUser('aquaman').then(function (res) { + res.name.should.equal('aquaman'); + return db.getSession(); + }).then(function (res) { + res.userCtx.name.should.equal('aquaman'); + return db.getUser('robin').then(function (res) { + should.not.exist(res); + }).catch(function (err) { + should.exist(err); + }); + }); + }); + }); + }); + }); + + it('Test change password', function () { + return db.signup('spiderman', 'will-forget').then(function (res) { + return db.changePassword('spiderman', 'will-remember').then(function (res) { + res.ok.should.equal(true); + }).then(function () { + return db.login('spiderman', 'will-remember'); + }).then(function (res) { + res.ok.should.equal(true); + }); + }); + }); + + it('Test change username', function () { + return db.signup('spiderman', 'will-forget').then(function (res) { + return db.changeUsername('spiderman', 'batman').then(function () { + return db.login('batman', 'will-forget'); + }).then(function (res) { + res.ok.should.equal(true); + }); + }); + }); + + it('Shouldn\'t change username if new username already exists', function () { + return db.signup('spiderman', 'will-forget').then(function (res) { + return db.signup('batman', 'will-remember'); + }).then(function () { + return db.changeUsername('spiderman', 'batman'); + }).then(function () { + throw new Error('shouldn\'t have worked'); + }, function (err) { + should.exist(err); + }); + }); +}); diff --git a/test/test.js b/test/test.js deleted file mode 100644 index 577eb5a..0000000 --- a/test/test.js +++ /dev/null @@ -1,320 +0,0 @@ -'use strict'; - -var PouchDB = require('pouchdb-memory'); -var Authentication = require('../lib'); -PouchDB.plugin(Authentication); -var chai = require('chai'); -var should = chai.should(); -chai.use(require('chai-as-promised')); - -var users = ['batman', 'superman', 'green_lantern', 'robin', 'aquaman', 'spiderman']; - -var testCases = [ - 'normal', - 'trailing-slash' -]; - -testCases.forEach(function (testCase) { - - describe('authentication-' + testCase, function () { - - var dbName = testCase === 'normal' ? - 'http://localhost:5984/testdb' : - 'http://localhost:5984/testdb/'; // trailing slash - - var db; - - beforeEach(function () { - db = new PouchDB(dbName); - return db; - }); - afterEach(function () { - return db.logout().then(function () { - return db.destroy().then(function () { - var usersUrl = db.getUsersDatabaseUrl(); - var usersDb = new PouchDB(usersUrl); - // remove the fake users, hopefully we're in the admin party - return usersDb.allDocs({ - include_docs: true, - keys: users.map(function (user) { - return 'org.couchdb.user:' + user; - }) - }).then(function (res) { - var rows = res.rows.filter(function (row) { - return row.doc; - }); - var docs = rows.map(function (row) { - row.doc._deleted = true; - return row.doc; - }); - return usersDb.bulkDocs({docs: docs}); - }); - }); - }); - }); - - it('Test signup', function () { - return db.signup('batman', 'brucewayne').then(function (res) { - res.ok.should.equal(true); - res.id.should.equal('org.couchdb.user:batman'); - }); - }); - - it('Test signup conflict', function () { - return db.signup('superman', 'clarkkent').then(function (res) { - res.ok.should.equal(true); - return db.signup('superman', 'notclarkkent').then(function (res) { - should.not.exist(res); - }).catch(function (err) { - err.name.should.equal('conflict'); - }); - }); - }); - - it('Test bad signup args', function () { - return db.signup().catch(function (err) { - should.exist(err); - }); - }); - - it('Test bad signup args 2', function () { - return db.signup('green_lantern').catch(function (err) { - should.exist(err); - }); - }); - - it('Test login/logout', function () { - return db.signup('aquaman', 'sleeps_with_fishes').then(function (res) { - return db.getSession(); - }).then(function (res) { - should.equal(res.userCtx.name, null); - return db.login('aquaman', 'sleeps_with_fishes'); - }).then(function (res) { - res.ok.should.equal(true); - return db.getSession(); - }).then(function (res) { - res.userCtx.name.should.equal('aquaman'); - return db.logout(); - }).then(function () { - return db.getSession(); - }).then(function (res) { - should.equal(res.userCtx.name, null); - }); - }); - - it('Test metadata', function () { - var metadata = {alias: 'boywonder', profession: 'acrobat'}; - var opts = {metadata: metadata}; - return db.signup('robin', 'dickgrayson', opts).then(function (res) { - res.ok.should.equal(true); - return db.login('robin', 'dickgrayson'); - }).then(function () { - return db.getUser('robin'); - }).then(function (user) { - user.name.should.equal('robin'); - user.alias.should.equal('boywonder'); - user.profession.should.equal('acrobat'); - }); - }); - - it('Test changing metadata', function () { - var metadata = {alias: 'boywonder', profession: 'acrobat'}; - var newMetadata = {alias: 'rednowyob', profession: 'taborca'}; - var opts = {metadata: metadata}; - return db.signup('robin', 'dickgrayson', opts).then(function (res) { - res.ok.should.equal(true); - return db.login('robin', 'dickgrayson'); - }).then(function () { - return db.getUser('robin'); - }).then(function (user) { - user.name.should.equal('robin'); - user.alias.should.equal('boywonder'); - user.profession.should.equal('acrobat'); - }).then(function () { - return db.putUser('robin', {metadata: newMetadata}); - }).then(function () { - return db.getUser('robin'); - }).then(function (user) { - user.name.should.equal('robin'); - user.alias.should.equal('rednowyob'); - user.profession.should.equal('taborca'); - }); - }); - - var reservedWords = [ - '_id', - '_rev', - 'name', - 'type', - 'roles', - 'password', - 'password_scheme', - 'iterations', - 'derived_key', - 'salt' - ]; - - reservedWords.forEach(function (key) { - it('Test changing metadata using reserved word "' + key + '"', function () { - return db.signup('robin', 'dickgrayson').then(function (res) { - res.ok.should.equal(true); - return db.login('robin', 'dickgrayson'); - }).then(function () { - return db.getUser('robin').then(function (user) { - var metadata = {}; - metadata[key] = 'test'; - return db.putUser('robin', {metadata: metadata}).then(function (res) { - res.ok.should.not.equal(true); - }).catch(function (err) { - should.exist(err); - err.status.should.equal(400); - err.name.should.equal('authentication_error'); - err.message.should.equal('cannot use reserved word in metadata: "' + key + '"'); - err.error.should.equal(true); - - if (key === 'password') { - return db.login('robin', 'dickgrayson').then(function (res) { - res.ok.should.equal(true); - }).catch(function (err) { - should.not.exist(err); - }); - } else { - return db.getUser('robin').then(function (changedUser) { - changedUser[key].should.deep.equal(user[key]); - }).catch(function (err) { - should.not.exist(err); - }); - } - }); - }); - }); - }); - }); - - it('Test changing metadata using non-reserved word "metadata"', function () { - var metadata = {test: 'test'}; - return db.signup('robin', 'dickgrayson').then(function (res) { - res.ok.should.equal(true); - return db.login('robin', 'dickgrayson'); - }).then(function () { - return db.putUser('robin', {metadata: {metadata: metadata}}); - }).then(function (res) { - res.ok.should.equal(true); - return db.getUser('robin'); - }).then(function (changedUser) { - changedUser.metadata.should.deep.equal(metadata); - }).catch(function (err) { - should.not.exist(err); - }); - }); - - it('Test that admin can change roles', function () { - var roles = ['sidekick']; - var newRoles = ['superhero', 'villain']; - return db.signup('robin', 'dickgrayson', {roles: roles}).then(function (res) { - res.ok.should.equal(true); - return db.getUser('robin'); - }).then(function (user) { - user.roles.should.deep.equal(roles); - }).then(function () { - return db.putUser('robin', {roles: newRoles}); - }).then(function (res) { - res.ok.should.equal(true); - return db.getUser('robin'); - }).then(function (user) { - user.roles.should.deep.equal(newRoles); - }).catch(function (err) { - should.not.exist(err); - }); - }); - - it('Test that user cannot change roles', function () { - var roles = ['sidekick']; - var newRoles = ['superhero', 'villain']; - // We can't test for initial roles as we are in admin party - // Let us have faith in CouchDB - return db.signup('robin', 'dickgrayson', {roles: roles}).then(function (res) { - res.ok.should.equal(true); - return db.login('robin', 'dickgrayson'); - }).then(function () { - return db.getUser('robin'); - }).then(function (user) { - user.roles.should.deep.equal(roles); - }).then(function () { - return db.putUser('robin', {roles: newRoles}); - }).then(function (res) { - res.ok.should.not.equal(true); - return db.getUser('robin').then(function (user) { - user.roles.should.deep.equal(roles); - }); - }).catch(function (err) { - should.exist(err); - }); - }); - - it('Test wrong user for getUser', function () { - return db.signup('robin', 'dickgrayson').then(function (res) { - return db.signup('aquaman', 'sleeps_with_fishes'); - }).then(function () { - return db.login('robin', 'dickgrayson'); - }).then(function () { - return db.getUser('robin'); - }).then(function (res) { - res.name.should.equal('robin'); - return db.getUser('aquaman').then(function (res) { - should.not.exist(res); - }).catch(function (err) { - should.exist(err); - return db.login('aquaman', 'sleeps_with_fishes').then(function () { - return db.getUser('aquaman').then(function (res) { - res.name.should.equal('aquaman'); - return db.getSession(); - }).then(function (res) { - res.userCtx.name.should.equal('aquaman'); - return db.getUser('robin').then(function (res) { - should.not.exist(res); - }).catch(function (err) { - should.exist(err); - }); - }); - }); - }); - }); - }); - - it('Test change password', function () { - return db.signup('spiderman', 'will-forget').then(function (res) { - return db.changePassword('spiderman', 'will-remember').then(function (res) { - res.ok.should.equal(true); - }).then(function () { - return db.login('spiderman', 'will-remember'); - }).then(function (res) { - res.ok.should.equal(true); - }); - }); - }); - - it('Test change username', function () { - return db.signup('spiderman', 'will-forget').then(function (res) { - return db.changeUsername('spiderman', 'batman').then(function () { - return db.login('batman', 'will-forget'); - }).then(function (res) { - res.ok.should.equal(true); - }); - }); - }); - - it('Shouldn\'t change username if new username already exists', function () { - return db.signup('spiderman', 'will-forget').then(function (res) { - return db.signup('batman', 'will-remember'); - }).then(function () { - return db.changeUsername('spiderman', 'batman'); - }).then(function () { - throw new Error('shouldn\'t have worked'); - }, function (err) { - should.exist(err); - }); - }); - }); - -}); diff --git a/test/test.urls.js b/test/test.urls.js new file mode 100644 index 0000000..f689d75 --- /dev/null +++ b/test/test.urls.js @@ -0,0 +1,46 @@ +'use strict'; + +var PouchDB = require('pouchdb-memory'); +var Authentication = require('../lib'); +PouchDB.plugin(Authentication); +var chai = require('chai'); +var should = chai.should(); + +describe('urls', function () { + + var hostUrl = 'http://localhost:5984'; + var dbName = 'testdb' + var dbUrl = hostUrl + '/' + dbName; + + it('Correct users database url for database without trailing slash', function () { + var db = new PouchDB(dbUrl); + var usersUrl = db.getUsersDatabaseUrl(); + usersUrl.should.equal(hostUrl + '/_users'); + }); + + it('Correct users database url for database with trailing slash', function () { + var db = new PouchDB(dbUrl + '/'); + var usersUrl = db.getUsersDatabaseUrl(); + usersUrl.should.equal(hostUrl + '/_users'); + }); + + it('Correct users database url using prefix without trailing slash', function () { + var PouchWithPrefix = PouchDB.defaults({prefix: hostUrl}); + var db = new PouchWithPrefix(dbName); + var usersUrl = db.getUsersDatabaseUrl(); + usersUrl.should.equal(hostUrl + '/_users'); + }); + + it('Correct users database url using prefix with trailing slash', function () { + var PouchWithPrefix = PouchDB.defaults({prefix: hostUrl + '/'}); + var db = new PouchWithPrefix(dbName); + var usersUrl = db.getUsersDatabaseUrl(); + usersUrl.should.equal(hostUrl + '/_users'); + }); + + it('Correct users database url for cloudant-style database urls', function () { + var db = new PouchDB(hostUrl + '/'); + var usersUrl = db.getUsersDatabaseUrl(); + usersUrl.should.equal(hostUrl + '/_users'); + }); +});