diff --git a/scripts/genbrews.js b/scripts/genbrews.js index 0005304..e6dac10 100644 --- a/scripts/genbrews.js +++ b/scripts/genbrews.js @@ -47,5 +47,6 @@ return Promise.resolve() }) .then(() => { console.log(`\n Added ${randomBrews.length + specificBrews.length} brews.`); + return DB.close(); }) .catch(console.error); diff --git a/server/brew.data.js b/server/brew.data.js index b6a5a85..c6e92ee 100644 --- a/server/brew.data.js +++ b/server/brew.data.js @@ -93,63 +93,8 @@ const BrewData = { getByEdit : (editId) => { return BrewData.get({ editId }); }, - - - //TODO: Add a 'core search' which just takes a search object - //TODO: extend the core search with a user search and a term search - //TODO: break these functions off into a 'brew.search.js' file - //TODO: pagniation, sorting and full access should be an 'opts' param - - search : (searchTerms, pagination, sorting, fullAccess = true) => { - let query = {}; - if(searchTerms){ - query = {$text: { - //Wrap terms in quots to perform an AND operator - $search: _.map(searchTerms.split(' '), (term)=>{ - return `\"${term}\"`; - }).join(' '), - $caseSensitive : false - }}; - } - - pagination = _.defaults(pagination, { - limit : 25, - page : 0 - }); - sorting = _.defaults(sorting, { - 'views' : 1 - }); - let filter = { - //editId : 0, - text : 0 - }; - - - if(!fullAccess){ - filter.editId = 0; - query.published = false; - } - - const searchQuery = Brew - .find(query) - .sort(sorting) - .select(filter) - .limit(pagination.limit) - .skip(pagination.page * pagination.limit) - .exec(); - - const countQuery = Brew.count(query).exec(); - - return Promise.all([searchQuery, countQuery]) - .then((result) => { - return { - brews : result[0], - total : result[1] - } - }); - }, - - }; -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..99e993e --- /dev/null +++ b/server/brew.search.js @@ -0,0 +1,59 @@ +const _ = require('lodash'); + +module.exports = (Brew) => { + const cmds = { + termSearch : (terms='', opts, fullAccess) => { + const 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, opts, fullAccess) => { + const query = { + authors : username + }; + + return cmds.search(query, opts, fullAccess); + }, + + search : (queryObj={}, opts={}, fullAccess = true) => { + const pagination = _.defaults(opts.pagination, { + limit : 25, + page : 0 + }); + const sorting = _.defaults(opts.sorting, { + 'views' : 1 + }); + let filter = { + text : 0 + }; + if(!fullAccess){ + filter.editId = 0; + queryObj.published = false; + } + + const searchQuery = Brew + .find(queryObj) + .sort(sorting) + .select(filter) + .limit(pagination.limit) + .skip(pagination.page * pagination.limit) + .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 6cb0986..d0756bf 100644 --- a/server/db.js +++ b/server/db.js @@ -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/test/api.test.js b/test/api.test.js index 822683c..31330e5 100644 --- a/test/api.test.js +++ b/test/api.test.js @@ -111,4 +111,28 @@ describe('Brew API', () => { }); }); + describe('Search', () => { + it.skip('should be able to search for brews with given terms', ()=>{ + + }); + it.skip('should exclude unpublished brews and have no editIdsh', ()=>{ + + }); + it.skip('should sort the search', ()=>{ + + }); + it.skip('should use pagniation on the search', ()=>{ + + }); + }); + + describe('User', () => { + it.skip('should be able to query brews for a specific user', ()=>{ + + }); + it.skip('should return full access to brews if loggedin user is queried user', ()=>{ + + }); + }); + }); \ No newline at end of file diff --git a/test/search.test.js b/test/search.test.js index 56352dd..5efdd1f 100644 --- a/test/search.test.js +++ b/test/search.test.js @@ -11,11 +11,13 @@ const ids = (brewIds) => { }); } + +//TODO: Move this brew generator to test.init const brews = { BrewA : { title : 'BrewA', description : 'fancy', - authors : [], + authors : ['userA'], systems : [], views : 12, published : false @@ -23,7 +25,7 @@ const brews = { BrewB : { title : 'BrewB', description : 'very fancy', - authors : [], + authors : ['userA'], systems : [], views : 7, published : true @@ -31,7 +33,7 @@ const brews = { BrewC : { title : 'BrewC', description : 'test', - authors : [], + authors : ['userA', 'userB'], systems : [], views : 0, published : false @@ -39,7 +41,7 @@ const brews = { BrewD : { title : 'BrewD', description : 'test super amazing brew for 5e. Geared for Rangers.', - authors : [], + authors : ['userC'], systems : [], views : 1, published : true @@ -58,6 +60,10 @@ describe('Brew Search', () => { describe('Searching', ()=>{ + it.skip('should return a total and a brew array', ()=>{ + + }); + it('should be able to search for all brews', ()=>{ return BrewData.search() .then((result) => { @@ -65,52 +71,34 @@ describe('Brew Search', () => { result.brews.length.should.be.equal(_.size(brews)); }) }); - it('should search brews based on title', () => { - return BrewData.search('BrewC') - .then((result) => { - result.total.should.be.equal(1); - result.brews.should.containSubset(ids(['BrewC'])); - }) - }); + }); - it('should search brews based on description', () => { - return BrewData.search('fancy') - .then((result) => { - result.total.should.be.equal(2); - result.brews.should.containSubset(ids(['BrewA', 'BrewB'])); - }) - }); - - it('should search brews based on multiple terms', () => { - return BrewData.search('ranger 5e') - .then((result) => { - result.total.should.be.equal(1); - result.brews.should.containSubset(ids(['BrewD'])); - }) - }); - - it('should perform an AND operation on the provided terms', () => { - return BrewData.search('BrewD GARBAGE') - .then((result) => { - result.total.should.be.equal(0); - }); - }); - - it('should search brews based on a combination of both', () => { - return BrewData.search('BrewB fancy') - .then((result) => { - result.total.should.be.equal(1); - result.brews.should.containSubset(ids(['BrewB'])); - }); - }); - - it.skip('should be able to search for a specific system', ()=>{ + describe('Pagniation', () => { + it.skip('should return the exact number of brews based on limit', () => { }); - it.skip('should be able to search for a specifc user', ()=>{ + + it.skip('should return the correct pages when specified', () => { }); - }) + + it.skip('should return a partial list if on the last page', () => { + + }); + + }); + + describe('Sorting', ()=>{ + it.skip('should sort ASC', () => { + + }); + it.skip('should sort DESC', () => { + + }); + it.skip('should sort based on multiple fields', () => { + + }); + }); describe('Permissions', () => { it.skip('should only fetch published brews', () => { @@ -127,16 +115,62 @@ describe('Brew Search', () => { }); }); - describe('Pagniation', () => { - it.skip('should return the exact number of brews based on limit', () => { + + describe('Term Search', ()=>{ + it('should search brews based on title', () => { + return BrewData.termSearch('BrewC') + .then((result) => { + result.total.should.be.equal(1); + result.brews.should.containSubset(ids(['BrewC'])); + }) }); + it('should search brews based on description', () => { + return BrewData.termSearch('fancy') + .then((result) => { + result.total.should.be.equal(2); + result.brews.should.containSubset(ids(['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.containSubset(ids(['BrewD'])); + }) + }); + + it('should perform an AND operation on the provided terms', () => { + return BrewData.termSearch('BrewD GARBAGE') + .then((result) => { + result.total.should.be.equal(0); + }); + }); + + it('should search brews based on a combination of both', () => { + return BrewData.termSearch('BrewB fancy') + .then((result) => { + result.total.should.be.equal(1); + result.brews.should.containSubset(ids(['BrewB'])); + }); + }); }); - describe('Sorting', ()=>{ - + 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.containSubset(ids(['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