diff --git a/client/admin/adminSearch/adminSearch.jsx b/client/admin/adminSearch/adminSearch.jsx index 1f95153..15d0972 100644 --- a/client/admin/adminSearch/adminSearch.jsx +++ b/client/admin/adminSearch/adminSearch.jsx @@ -11,7 +11,7 @@ const AdminSearch = React.createClass({ }, render: function(){ return
- AdminSearch Component Ready. +

Admin Search

} }); diff --git a/package.json b/package.json index e553ba5..02d5ab8 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,7 @@ "quick": "node scripts/quick.js", "build": "node scripts/build.js", "phb": "node scripts/phb.js", + "populate": "node scripts/populate.js", "prod": "set NODE_ENV=production&& npm run build", "postinstall": "npm run build", "start": "node server.js", @@ -43,6 +44,7 @@ "app-module-path": "^2.1.0", "chai": "^3.5.0", "chai-as-promised": "^6.0.0", + "chai-subset": "^1.4.0", "mocha": "^3.2.0", "supertest": "^2.0.1", "supertest-as-promised": "^4.0.2" diff --git a/scripts/populate.js b/scripts/populate.js new file mode 100644 index 0000000..7a392af --- /dev/null +++ b/scripts/populate.js @@ -0,0 +1,22 @@ +//Populates the DB with a bunch of brews for UI testing +const _ = require('lodash'); + +const DB = require('../server/db.js'); +const BrewData = require('../server/brew.data.js'); +const BrewGen = require('../test/brew.gen.js'); + +return Promise.resolve() + .then(DB.connect) + .then(BrewData.removeAll) + .then(() => { + console.log('Adding random brews...'); + return return BrewGen.populateDB(BrewGen.random(5)); + }) + .then(() => { + console.log('Adding specific brews...'); + return return BrewGen.populateDB(BrewGen.static()); + }) + .then(() => { + return DB.close(); + }) + .catch(console.error); diff --git a/server/brew.api.js b/server/brew.api.js index d7e30bf..d0565b4 100644 --- a/server/brew.api.js +++ b/server/brew.api.js @@ -6,10 +6,25 @@ const mw = require('./middleware.js'); //Search router.get('/api/brew', (req, res, next) => { + const opts = _.pick(req.query, ['limit', 'sort', 'page']); - //TODO + BrewData.termSearch(req.query.terms, opts, req.admin) + .then((result) => { + return res.status(200).json(result); + }) + .catch(next); +}); +//User +router.get('/api/user/:username', (req, res, next) => { + const fullAccess = req.admin || + !!(req.account && req.params.username == req.account.username); + BrewData.userSearch(req.params.username, fullAccess) + .then((result) => { + return res.status(200).json(result); + }) + .catch(next); }); //Get diff --git a/server/brew.data.js b/server/brew.data.js index 367d33b..c6e92ee 100644 --- a/server/brew.data.js +++ b/server/brew.data.js @@ -21,7 +21,8 @@ const BrewSchema = mongoose.Schema({ createdAt : { type: Date, default: Date.now }, updatedAt : { type: Date, default: Date.now}, lastViewed : { type: Date, default: Date.now}, - views : {type:Number, default:0} + views : {type:Number, default:0}, + version : {type: Number, default:1} }, { versionKey: false, toJSON : { @@ -32,6 +33,9 @@ const BrewSchema = mongoose.Schema({ } }); +//Index these fields for fast text searching +BrewSchema.index({ title: "text", description: "text" }); + BrewSchema.methods.increaseView = function(){ this.views = this.views + 1; return this.save(); @@ -39,9 +43,6 @@ BrewSchema.methods.increaseView = function(){ const Brew = mongoose.model('Brew', BrewSchema); - - - const BrewData = { schema : BrewSchema, model : Brew, @@ -92,15 +93,8 @@ const BrewData = { getByEdit : (editId) => { return BrewData.get({ editId }); }, - - search : (query, req={}) => { - //defaults with page and count - //returns a non-text version of brews - //assume sanatized ? - return Promise.resolve([]); - }, - - }; -module.exports = BrewData; \ No newline at end of file +const BrewSearch = require('./brew.search.js')(Brew); + +module.exports = _.merge(BrewData, BrewSearch); \ No newline at end of file diff --git a/server/brew.search.js b/server/brew.search.js new file mode 100644 index 0000000..a75b768 --- /dev/null +++ b/server/brew.search.js @@ -0,0 +1,66 @@ +const _ = require('lodash'); + +module.exports = (Brew) => { + const cmds = { + termSearch : (terms='', opts, fullAccess) => { + let query = {}; + if(terms){ + query = {$text: { + //Wrap terms in quotes to perform an AND operation + $search: _.map(terms.split(' '), (term)=>{ + return `\"${term}\"`; + }).join(' '), + $caseSensitive : false + }}; + } + return cmds.search(query, opts, fullAccess); + }, + + userSearch : (username, fullAccess) => { + const query = { + authors : username + }; + + return cmds.search(query, {}, fullAccess); + }, + + search : (queryObj={}, options={}, fullAccess = true) => { + const opts = _.merge({ + limit : 25, + page : 0, + sort : {} + }, options); + opts.limit = _.toNumber(opts.limit); + opts.page = _.toNumber(opts.page); + + let filter = { + text : 0 + }; + + if(!fullAccess){ + filter.editId = 0; + queryObj.published = true; + } + + const searchQuery = Brew + .find(queryObj) + .sort(opts.sort) + .select(filter) + .limit(opts.limit) + .skip(opts.page * opts.limit) + .lean() + .exec(); + + const countQuery = Brew.count(queryObj).exec(); + + return Promise.all([searchQuery, countQuery]) + .then((result) => { + return { + brews : result[0], + total : result[1] + } + }); + } + }; + return cmds; +}; \ No newline at end of file diff --git a/server/db.js b/server/db.js index a9c5400..d0756bf 100644 --- a/server/db.js +++ b/server/db.js @@ -8,14 +8,14 @@ module.exports = { connect : ()=>{ return new Promise((resolve, reject)=>{ if(mongoose.connection.readyState == 1){ - log.info('DB already connected'); + log.warn('DB already connected'); return resolve(); } mongoose.connect(dbPath, (err) => { if(err){ - log.info('Error : Could not connect to a Mongo Database.'); - log.info(' If you are running locally, make sure mongodb.exe is running.'); + log.error('Error : Could not connect to a Mongo Database.'); + log.error(' If you are running locally, make sure mongodb.exe is running.'); return reject(err); } log.info('DB connected.'); @@ -24,5 +24,13 @@ module.exports = { ); }); }, + close : ()=>{ + return new Promise((resolve, reject) => { + mongoose.connection.close(()=>{ + log.info('DB connection closed.'); + return resolve(); + }); + }); + }, instance : mongoose } \ No newline at end of file diff --git a/server/middleware.js b/server/middleware.js index cc2a535..fb4c424 100644 --- a/server/middleware.js +++ b/server/middleware.js @@ -16,7 +16,8 @@ const Middleware = { return next(); }, admin : (req, res, next) => { - if(req.query.admin_key === config.get('admin:key')){ + req.admin = false; + if(req.headers['x-homebrew-admin'] === config.get('admin:key')){ req.admin = true; } return next(); @@ -44,6 +45,7 @@ const Middleware = { }, + //TODO: REMOVE //Loaders loadBrew : (req, res, next) => { BrewData.getByEdit(req.params.editId) diff --git a/shared/homebrewery/brewEditor/metadataEditor/metadataEditor.less b/shared/homebrewery/brewEditor/metadataEditor/metadataEditor.less index c3141f0..2f9812d 100644 --- a/shared/homebrewery/brewEditor/metadataEditor/metadataEditor.less +++ b/shared/homebrewery/brewEditor/metadataEditor/metadataEditor.less @@ -76,4 +76,7 @@ font-size: 0.8em; line-height : 1.5em; } + .thumbnail.field{ + + } } \ No newline at end of file diff --git a/test/admin.test.js b/test/admin.test.js index 6d2ccce..b2590ca 100644 --- a/test/admin.test.js +++ b/test/admin.test.js @@ -15,6 +15,7 @@ let brewA = { authors : ['your_dm'] }; + describe('Admin API', ()=>{ before('Connect DB', DB.connect); @@ -35,7 +36,7 @@ describe('Admin API', ()=>{ it('looks up a brew based on the share id', () => { return request(app) .get(`/admin/lookup/${brewA.shareId}`) - .query({ admin_key : config.get('admin:key') }) + .set('x-homebrew-admin', config.get('admin:key')) .expect(200) .then((res) => { const brew = res.body; @@ -47,7 +48,7 @@ describe('Admin API', ()=>{ it('looks up a brew based on the edit id', () => { return request(app) .get(`/admin/lookup/${brewA.editId}`) - .query({ admin_key : config.get('admin:key') }) + .set('x-homebrew-admin', config.get('admin:key')) .expect(200) .then((res) => { const brew = res.body; @@ -60,7 +61,7 @@ describe('Admin API', ()=>{ const query = brewA.editId.substring(0, brewA.editId.length -2); return request(app) .get(`/admin/lookup/${query}`) - .query({ admin_key : config.get('admin:key') }) + .set('x-homebrew-admin', config.get('admin:key')) .expect(200) .then((res) => { const brew = res.body; @@ -72,7 +73,7 @@ describe('Admin API', ()=>{ it('throws an error if it can not find a brew', ()=>{ return request(app) .get(`/admin/lookup/BADID`) - .query({ admin_key : config.get('admin:key') }) + .set('x-homebrew-admin', config.get('admin:key')) .expect(404); }); }); diff --git a/test/api.test.js b/test/api.test.js index 822683c..0ba5fdb 100644 --- a/test/api.test.js +++ b/test/api.test.js @@ -1,112 +1,246 @@ -const testing = require('./test.init.js'); +const Test = require('./test.init.js'); +const _ = require('lodash'); const request = require('supertest-as-promised'); -const jwt = require('jwt-simple'); + const config = require('nconf'); const app = require('app.js'); const DB = require('db.js'); const BrewData = require('brew.data.js'); +const BrewGen = require('./brew.gen.js'); const Error = require('error.js'); -const apiPath = '/api/brew'; -let session_token; -const test_user = { - username : 'cool guy' -}; -let storedBrew = { - title : 'good title', - text : 'original text', - authors : ['your_dm'] -}; +const UserX = { username : 'userX' }; +const UserA = { username : 'userA' }; +let UserXToken, UserAToken; describe('Brew API', () => { - before('Connect DB', DB.connect); - before('Clear DB', BrewData.removeAll); before('Create session token', () => { - session_token = jwt.encode(test_user, config.get('jwt_secret')); - }); - before('Create brew', ()=>{ - return BrewData.create(storedBrew) - .then((brew)=>{ storedBrew = brew; }); + UserXToken = Test.getSessionToken(UserX); + UserAToken = Test.getSessionToken(UserA); }); + describe('CRUD', ()=>{ + before('Connect DB', DB.connect); + before('Clear DB', BrewData.removeAll); + before('Populate brews', ()=>{ + return BrewGen.populateDB(BrewGen.static()); + }); + describe('Create', () => { + it('creates a new brew', () => { + return request(app) + .post(`/api/brew`) + .send({ text : 'Brew Text' }) + .expect(200) + .then((res) => { + const brew = res.body; + brew.should.have.property('editId').that.is.a('string'); + brew.should.have.property('shareId').that.is.a('string'); + brew.should.have.property('text').equal('Brew Text'); + brew.should.not.have.property('_id'); + }); + }); - describe('Create', () => { - it('creates a new brew', () => { - return request(app) - .post(apiPath) - .send({ text : 'Brew Text' }) - .expect(200) - .then((res) => { - const brew = res.body; - brew.should.have.property('editId').that.is.a('string'); - brew.should.have.property('shareId').that.is.a('string'); - brew.should.have.property('text').equal('Brew Text'); - brew.should.not.have.property('_id'); - }); + it('creates a new brew with a session author', () => { + return request(app) + .post(`/api/brew`) + .set('Cookie', `nc_session=${UserXToken}`) + .send({ text : 'Brew Text' }) + .expect(200) + .then((res) => { + const brew = res.body; + brew.should.have.property('authors').include(UserX.username); + }); + }); }); - it('creates a new brew with a session author', () => { - return request(app) - .post(apiPath) - .set('Cookie', `nc_session=${session_token}`) - .send({ text : 'Brew Text' }) - .expect(200) - .then((res) => { - const brew = res.body; - brew.should.have.property('authors').include(test_user.username); - }); - }); - }); + describe('Update', () => { + it('updates an existing brew', () => { + const storedBrew = BrewGen.get('BrewA'); + return request(app) + .put(`/api/brew/${storedBrew.editId}`) + .send({ text : 'New Text' }) + .expect(200) + .then((res) => { + const brew = res.body; + brew.should.have.property('editId').equal(storedBrew.editId); + brew.should.have.property('text').equal('New Text'); + brew.should.have.property('authors').include(storedBrew.authors[0]); + brew.should.not.have.property('_id'); + }); + }); - describe('Update', () => { - it('updates an existing brew', () => { - return request(app) - .put(`${apiPath}/${storedBrew.editId}`) - .send({ text : 'New Text' }) - .expect(200) - .then((res) => { - const brew = res.body; - brew.should.have.property('editId').equal(storedBrew.editId); - brew.should.have.property('text').equal('New Text'); - brew.should.have.property('authors').include('your_dm'); - brew.should.not.have.property('_id'); - }); + it('adds the user as author', () => { + const storedBrew = BrewGen.get('BrewA'); + return request(app) + .put(`/api/brew/${storedBrew.editId}`) + .set('Cookie', `nc_session=${UserXToken}`) + .send({ text : 'New Text' }) + .expect(200) + .then((res) => { + const brew = res.body; + brew.should.have.property('authors').include(UserX.username); + brew.should.have.property('authors').include(storedBrew.authors[0]); + }); + }); + it('should throw error on bad edit id', ()=>{ + const storedBrew = BrewGen.get('BrewA'); + return request(app) + .put(`/api/brew/BADEDITID`) + .send({ text : 'New Text' }) + .expect(404) + }); }); - it('adds the user as author', () => { - return request(app) - .put(`${apiPath}/${storedBrew.editId}`) - .set('Cookie', `nc_session=${session_token}`) - .send({ text : 'New Text' }) - .expect(200) - .then((res) => { - const brew = res.body; - brew.should.have.property('authors').include(test_user.username); - brew.should.have.property('authors').include('your_dm'); - }); + describe('Remove', () => { + it('should removes a brew', ()=>{ + const storedBrew = BrewGen.get('BrewA'); + return request(app) + .del(`/api/brew/${storedBrew.editId}`) + .send() + .expect(200) + .then(() => { + BrewData.getByEdit(storedBrew.editId) + .then(() => { throw 'Brew found when one should not have been'; }) + .catch((err) => { + err.should.be.instanceof(Error.noBrew); + }) + }); + }); }); - it('should throw error on bad edit id', ()=>{ - return request(app) - .put(`${apiPath}/BADEDITID`) - .send({ text : 'New Text' }) - .expect(404) - }); - }); + }) - describe('Remove', () => { - it('should removes a brew', ()=>{ + + describe('Search', () => { + before('Connect DB', DB.connect); + before('Clear DB', BrewData.removeAll); + before('Populate brews', ()=>{ + return BrewGen.populateDB(BrewGen.static()); + }); + + it('should be able to search for all published brews', ()=>{ return request(app) - .del(`${apiPath}/${storedBrew.editId}`) + .get(`/api/brew`) + .query({}) .send() .expect(200) - .then(() => { - BrewData.getByEdit(storedBrew.editId) - .then(() => { throw 'Brew found when one should not have been'; }) - .catch((err) => { - err.should.be.instanceof(Error.noBrew); - }) + .then((res) => { + const result = res.body; + result.total.should.be.equal(2); + result.brews.should.have.brews('BrewB','BrewD'); + result.brews[0].should.not.have.property('editId'); + }); + }); + + it('should be able to search for brews with given terms', ()=>{ + return request(app) + .get(`/api/brew`) + .query({ + terms : '5e ranger' + }) + .send() + .expect(200) + .then((res) => { + const result = res.body; + result.total.should.be.equal(1); + result.brews.should.have.brews('BrewD'); + }); + }); + it('should be able to sort the search', ()=>{ + return request(app) + .get(`/api/brew`) + .query({ + sort : { views : 1} + }) + .send() + .expect(200) + .then((res) => { + const result = res.body; + result.total.should.be.equal(2); + result.brews[0].should.be.brew('BrewD'); + result.brews[1].should.be.brew('BrewB'); + }); + }); + it('should use pagniation on the search', ()=>{ + return request(app) + .get(`/api/brew`) + .query({ + limit : 1, + page : 1, + sort : { views : -1} + }) + .send() + .expect(200) + .then((res) => { + const result = res.body; + result.total.should.be.equal(2); + result.brews[0].should.be.brew('BrewD'); + }) + }); + it('should return all brews and editIds if admin', ()=>{ + return request(app) + .get(`/api/brew`) + .query({}) + .set('x-homebrew-admin', config.get('admin:key')) + .send() + .expect(200) + .then((res) => { + const result = res.body; + const brewCount = _.size(BrewGen.static()); + result.total.should.be.equal(brewCount); + result.brews.length.should.be.equal(brewCount); + result.brews[0].should.have.property('editId'); + }); + }); + }); + + describe('User', () => { + before('Connect DB', DB.connect); + before('Clear DB', BrewData.removeAll); + before('Populate brews', ()=>{ + return BrewGen.populateDB(BrewGen.static()); + }); + + it('should be able to query brews for a specific user', ()=>{ + return request(app) + .get(`/api/user/userA`) + .send() + .expect(200) + .then((res) => { + const result = res.body; + result.total.should.be.equal(1); + result.brews.length.should.be.equal(1); + result.brews.should.have.brews('BrewB'); + result.brews[0].should.not.have.property('editId'); + }); + }); + it('should have full access if loggedin user is queried user', ()=>{ + return request(app) + .get(`/api/user/userA`) + .set('Cookie', `nc_session=${UserAToken}`) + .send() + .expect(200) + .then((res) => { + const result = res.body; + result.total.should.be.equal(3); + result.brews.length.should.be.equal(3); + result.brews.should.have.brews('BrewA', 'BrewB', 'BrewC'); + result.brews[0].should.have.property('editId'); + }); + }); + it('should have full access if admin', ()=>{ + return request(app) + .get(`/api/user/userA`) + .set('x-homebrew-admin', config.get('admin:key')) + .send() + .expect(200) + .then((res) => { + const result = res.body; + result.total.should.be.equal(3); + result.brews.length.should.be.equal(3); + result.brews.should.have.brews('BrewA', 'BrewB', 'BrewC'); + result.brews[0].should.have.property('editId'); }); }); }); diff --git a/test/brew.gen.js b/test/brew.gen.js new file mode 100644 index 0000000..c7d59b3 --- /dev/null +++ b/test/brew.gen.js @@ -0,0 +1,111 @@ +const _ = require('lodash'); +const BrewData = require('../server/brew.data.js'); + +let PopulatedBrews = {}; + +module.exports = { + //TODO: Add in a generator for old brews to test the old rendering code + + random : (num = 20)=>{ + return _.times(num, ()=>{ + //TODO: Build better generator + return { + title : 'BrewA', + description : '', + text : '', + authors : _.sampleSize(['userA','userB','userC','userD'], _.random(0, 3)), + systems : _.sampleSize(['5e', '4e', '3.5e', 'Pathfinder'], _.random(0,2)), + views : _.random(0,1000), + published : !!_.random(0,1) + }; + }); + }, + static : () => { + return { + BrewA : { + title : 'Brew-Alpha', + description : 'fancy', + authors : ['userA'], + systems : [], + views : 12, + published : false + }, + BrewB : { + title : 'Brew-Beta', + description : 'very fancy', + authors : ['userA'], + systems : [], + views : 7, + published : true + }, + BrewC : { + title : 'Brew-Charlie', + description : 'test', + authors : ['userA', 'userB'], + systems : [], + views : 0, + published : false + }, + BrewD : { + title : 'Brew-Delta', + description : 'test super amazing brew for 5e. Geared for Rangers.', + authors : ['userC'], + systems : [], + views : 1, + published : true + } + }; + }, + + populateDB : (brewCollection)=>{ + PopulatedBrews = {}; + return Promise.all(_.map(brewCollection, (brewData, id) => { + return BrewData.create(brewData) + .then((brew)=>{ + PopulatedBrews[id] = brew; + }); + }) + ); + }, + + get : (brewId) => { + return PopulatedBrews[brewId] + }, + + chaiPlugin : (chai, utils) => { + chai.Assertion.addMethod('brews', function(...brewIds){ + new chai.Assertion(this._obj).to.be.instanceof(Array); + const valid = _.every(brewIds, (brewId) => { + const storedBrew = PopulatedBrews[brewId]; + if(!storedBrew) return false; + return _.some(this._obj, (brew)=>{ + return brew.shareId == storedBrew.shareId && + brew.title == storedBrew.title && + brew.views == storedBrew.views; + }); + }); + this.assert( + valid, + `expect #{this} to have brews ${brewIds.join(', ')}`, + `expect #{this} to not have brews ${brewIds.join(', ')}` + ) + }); + + chai.Assertion.addMethod('brew', function(brewId){ + new chai.Assertion(this._obj).to.be.instanceof(Object); + const brew = this._obj; + const storedBrew = PopulatedBrews[brewId]; + + const valid = storedBrew && + brew.shareId == storedBrew.shareId && + brew.title == storedBrew.title && + brew.views == storedBrew.views; + + this.assert( + valid, + `expect #{this} to be brew ${brewId}`, + `expect #{this} to not be brew ${brewId}` + ) + }); + } +}; \ No newline at end of file diff --git a/test/middleware.test.js b/test/middleware.test.js index 44c822d..c407516 100644 --- a/test/middleware.test.js +++ b/test/middleware.test.js @@ -15,8 +15,6 @@ const requestHandler = (req, res) => { }; -console.log(config.get('admin:key')); - const test_user = { username : 'cool guy' }; @@ -106,7 +104,7 @@ describe('Middleware', () => { app.use(mw.admin); app.use(requestHandler) return request(app).get('/') - .query({ admin_key : config.get('admin:key') }) + .set('x-homebrew-admin', config.get('admin:key')) .expect(200) .then((res) => { const req = res.body; @@ -119,7 +117,7 @@ describe('Middleware', () => { app.get(requestHandler); app.use(Error.expressHandler); return request(app).get('/') - .query({ admin_key : 'BADUSER' }) + .set('x-homebrew-admin', 'BADADMIN') .send() .expect(401); }); diff --git a/test/search.test.js b/test/search.test.js index e69de29..6649500 100644 --- a/test/search.test.js +++ b/test/search.test.js @@ -0,0 +1,186 @@ +const Test = require('./test.init.js'); +const _ = require('lodash'); + +const DB = require('db.js'); +const BrewData = require('brew.data.js'); +const BrewGen = require('./brew.gen.js'); +//const Error = require('error.js'); + + + +describe('Brew Search', () => { + before('Connect DB', DB.connect); + before('Clear DB', BrewData.removeAll); + before('Populate brews', ()=>{ + return BrewGen.populateDB(BrewGen.static()); + }); + + + describe('Searching', ()=>{ + it('should return a total and a brew array', ()=>{ + return BrewData.search() + .then((result) => { + result.total.should.be.a('number'); + result.brews.should.be.an('array'); + }) + }); + + it('should be able to search for all brews', ()=>{ + return BrewData.search() + .then((result) => { + const brewCount = _.size(BrewGen.static()); + result.total.should.be.equal(brewCount); + result.brews.length.should.be.equal(brewCount); + }) + }); + }); + + describe('Pagniation', () => { + it('should return the exact number of brews based on limit', () => { + return BrewData.search({}, { + limit : 2 + }) + .then((result) => { + result.total.should.be.equal(_.size(BrewGen.static())); + result.brews.length.should.be.equal(2); + }) + }); + + it('should return the correct pages when specified', () => { + return BrewData.search({}, { + limit : 2, + page : 1, + sort : { views : 1 } + }) + .then((result) => { + result.brews.should.have.brews('BrewA', 'BrewB'); + }) + }); + + it('should return a partial list if on the last page', () => { + return BrewData.search({}, { + limit : 3, + page : 1 + }) + .then((result) => { + result.brews.length.should.be.equal(1); + }); + }); + + }); + + describe('Sorting', ()=>{ + it('should sort ASC', () => { + return BrewData.search({}, { + sort : { views : 1 } + }) + .then((result) => { + result.brews[0].should.be.brew('BrewC'); + result.brews[1].should.be.brew('BrewD'); + result.brews[2].should.be.brew('BrewB'); + result.brews[3].should.be.brew('BrewA'); + }) + }); + it('should sort DESC', () => { + return BrewData.search({}, { + sort : { views : -1 } + }) + .then((result) => { + result.brews[0].should.be.brew('BrewA'); + result.brews[1].should.be.brew('BrewB'); + result.brews[2].should.be.brew('BrewD'); + result.brews[3].should.be.brew('BrewC'); + }) + }); + }); + + describe('Permissions', () => { + it('should only fetch published brews', () => { + return BrewData.search({}, {}, false) + .then((result) => { + result.total.should.be.equal(2); + result.brews.should.have.brews('BrewB', 'BrewD'); + }) + }); + it('fetched brews should not have text or editId', () => { + return BrewData.search({}, {}, false) + .then((result) => { + result.brews[0].should.not.have.property('text'); + result.brews[0].should.not.have.property('editId'); + }) + }); + it('if full access, brews should have editid, but no text', () => { + return BrewData.search({}, {}, true) + .then((result) => { + result.brews[0].should.not.have.property('text'); + result.brews[0].should.have.property('editId'); + }) + }); + }); + + + + describe('Term Search', ()=>{ + it('should search brews based on title', () => { + return BrewData.termSearch('Charlie') + .then((result) => { + result.total.should.be.equal(1); + result.brews.should.have.brews('BrewC'); + }) + }); + + it('should search brews based on description', () => { + return BrewData.termSearch('fancy') + .then((result) => { + result.total.should.be.equal(2); + result.brews.should.have.brews('BrewA', 'BrewB'); + }) + }); + + it('should search brews based on multiple terms', () => { + return BrewData.termSearch('ranger 5e') + .then((result) => { + result.total.should.be.equal(1); + result.brews.should.have.brews('BrewD'); + }) + }); + + it('should perform an AND operation on the provided terms', () => { + return BrewData.termSearch('Brew Delta GARBAGE') + .then((result) => { + result.total.should.be.equal(0); + }); + }); + + it('should search brews based on a combination of both', () => { + return BrewData.termSearch('Brew Beta fancy') + .then((result) => { + result.total.should.be.equal(1); + result.brews.should.have.brews('BrewB'); + }); + }); + it('should not worry about the case of the terms', () => { + return BrewData.termSearch('FANCY') + .then((result) => { + result.total.should.be.equal(2); + result.brews.should.have.brews('BrewA', 'BrewB'); + }); + }); + }); + + describe('User Search', ()=>{ + it('should return brews just for a single user', () => { + return BrewData.userSearch('userA') + .then((result) => { + result.total.should.be.equal(3); + result.brews.should.have.brews('BrewA', 'BrewB', 'BrewC'); + }); + }); + it('should return nothing if provided a non-exsistent user', () => { + return BrewData.userSearch('userXYZ') + .then((result) => { + result.total.should.be.equal(0); + }); + }); + }); +}); \ No newline at end of file diff --git a/test/test.init.js b/test/test.init.js index 7dda4f8..ab1567a 100644 --- a/test/test.init.js +++ b/test/test.init.js @@ -7,10 +7,18 @@ const config = require('nconf') .file('environment', { file: `config/${process.env.NODE_ENV}.json` }) .file('defaults', { file: 'config/default.json' }); -const should = require('chai').use(require('chai-as-promised')).should(); +const Chai = require('chai') + .use(require('chai-as-promised')) + .use(require('chai-subset')) + .use(require('./brew.gen.js').chaiPlugin); + const log = require('loglevel'); log.setLevel(config.get('log_level')); +const jwt = require('jwt-simple'); module.exports = { - should: should + should: Chai.should(), + getSessionToken : (userInfo) => { + return jwt.encode(userInfo, config.get('jwt_secret')); + } };