diff --git a/server/homebrew.api.spec.js b/server/homebrew.api.spec.js index 8bb3a0c0b..a6bae65eb 100644 --- a/server/homebrew.api.spec.js +++ b/server/homebrew.api.spec.js @@ -135,7 +135,6 @@ describe('Tests for api', ()=>{ expect(id).toEqual('abcdefghij'); }); }); - describe('getBrew', ()=>{ const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); const notFoundError = { HBErrorCode: '05', message: 'Brew not found', name: 'BrewLoad Error', status: 404, accessType: 'share', brewId: '1' }; @@ -313,7 +312,68 @@ describe('Tests for api', ()=>{ await expect(fn(req, null, next)).rejects.toEqual({ 'HBErrorCode': '51', 'brewId': '1', 'brewTitle': 'test brew', 'code': 404, 'message': 'brew locked' }); }); }); + describe('Get CSS', ()=>{ + it('should return brew style content as CSS text', async ()=>{ + const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n```\n\n' }; + const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); + api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); + model.get = jest.fn(()=>toBrewPromise(testBrew)); + + const fn = api.getBrew('share', true); + const req = { brew: {} }; + const next = jest.fn(); + await fn(req, null, next); + await api.getCSS(req, res); + + expect(req.brew).toEqual(testBrew); + expect(req.brew).toHaveProperty('style', '\nI Have a style!\n'); + expect(res.status).toHaveBeenCalledWith(200); + expect(res.send).toHaveBeenCalledWith('\nI Have a style!\n'); + expect(res.set).toHaveBeenCalledWith({ + 'Cache-Control' : 'no-cache', + 'Content-Type' : 'text/css' + }); + }); + + it('should return 404 when brew has no style content', async ()=>{ + const testBrew = { title: 'test brew', text: 'I don\'t have a style!' }; + + const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); + api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); + model.get = jest.fn(()=>toBrewPromise(testBrew)); + + const fn = api.getBrew('share', true); + const req = { brew: {} }; + const next = jest.fn(); + await fn(req, null, next); + await api.getCSS(req, res); + + expect(req.brew).toEqual(testBrew); + expect(req.brew).toHaveProperty('style'); + expect(res.status).toHaveBeenCalledWith(404); + expect(res.send).toHaveBeenCalledWith(''); + }); + + it('should return 404 when brew does not exist', async ()=>{ + const testBrew = { }; + + const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); + api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); + model.get = jest.fn(()=>toBrewPromise(testBrew)); + + const fn = api.getBrew('share', true); + const req = { brew: {} }; + const next = jest.fn(); + await fn(req, null, next); + await api.getCSS(req, res); + + expect(req.brew).toEqual(testBrew); + expect(req.brew).toHaveProperty('style'); + expect(res.status).toHaveBeenCalledWith(404); + expect(res.send).toHaveBeenCalledWith(''); + }); + }); describe('mergeBrewText', ()=>{ it('should set metadata and no style if it is not present', ()=>{ const result = api.mergeBrewText({ @@ -376,7 +436,6 @@ hello yes i am css brew`); }); }); - describe('exclusion methods', ()=>{ it('excludePropsFromUpdate removes the correct keys', ()=>{ const sent = Object.assign({}, googleBrew); @@ -414,7 +473,6 @@ brew`); expect(result.pageCount).toBe(1); }); }); - describe('beforeNewSave', ()=>{ it('sets the title if none', ()=>{ const brew = { @@ -456,7 +514,6 @@ brew`); expect(hbBrew.text).toEqual('merged'); }); }); - describe('newGoogleBrew', ()=>{ it('should call the correct methods', ()=>{ api.excludeGoogleProps = jest.fn(()=>'newBrew'); @@ -470,7 +527,6 @@ brew`); expect(google.newGoogleBrew).toHaveBeenCalledWith('client', 'newBrew'); }); }); - describe('newBrew', ()=>{ it('should set up a default brew via Homebrew model', async ()=>{ await api.newBrew({ body: { text: 'asdf' }, query: {}, account: { username: 'test user' } }, res); @@ -562,17 +618,6 @@ brew`); }); }); }); - - describe('deleteGoogleBrew', ()=>{ - it('should check auth and delete brew', async ()=>{ - const result = await api.deleteGoogleBrew({ username: 'test user' }, 'id', 'editId', res); - - expect(result).toBe(true); - expect(google.authCheck).toHaveBeenCalledWith({ username: 'test user' }, expect.objectContaining({})); - expect(google.deleteGoogleBrew).toHaveBeenCalledWith('client', 'id', 'editId'); - }); - }); - describe('Theme bundle', ()=>{ it('should return Theme Bundle for a User Theme', async ()=>{ const brews = { @@ -716,7 +761,95 @@ brew`); status : 422 }); }); }); + describe('deleteBrewAuthor', ()=>{ + it('should handle case where fetching the brew returns an error', async ()=>{ + api.getBrew = jest.fn(()=>async ()=>{ throw { message: 'err', HBErrorCode: '02' }; }); + api.getId = jest.fn(()=>({ id: '1', googleId: '2' })); + model.deleteOne = jest.fn(async ()=>{}); + const next = jest.fn(()=>{}); + await api.deleteBrew(null, null, next); + + expect(next).toHaveBeenCalled(); + expect(model.deleteOne).toHaveBeenCalledWith({ editId: '1' }); + }); + + it('should remove one author', async ()=>{ + const brew = { + ...hbBrew, + authors : ['test', 'test2'] + }; + api.getBrew = jest.fn(()=>async (req)=>{ + req.brew = brew; + }); + model.findOne = jest.fn(async ()=>modelBrew(brew)); + model.deleteOne = jest.fn(async ()=>{}); + const req = { account: { username: 'test' } }; + + await api.deleteBrew(req, res); + + expect(api.getBrew).toHaveBeenCalled(); + expect(markModifiedFunc).toHaveBeenCalled(); + expect(model.findOne).toHaveBeenCalled(); + expect(model.deleteOne).not.toHaveBeenCalled(); + expect(saveFunc).toHaveBeenCalled(); + expect(saved.authors).toEqual(['test2']); + }); + + it('should delete google brew', async ()=>{ + const brew = { + ...googleBrew, + authors : ['test'] + }; + api.getBrew = jest.fn(()=>async (req)=>{ + req.brew = brew; + }); + model.findOne = jest.fn(async ()=>modelBrew(brew)); + model.deleteOne = jest.fn(async ()=>{}); + api.deleteGoogleBrew = jest.fn(async ()=>true); + const req = { account: { username: 'test' } }; + + await api.deleteBrew(req, res); + + expect(api.getBrew).toHaveBeenCalled(); + expect(model.findOne).toHaveBeenCalled(); + expect(model.deleteOne).toHaveBeenCalled(); + expect(api.deleteGoogleBrew).toHaveBeenCalled(); + }); + + it('should retain google brew and update stub when multiple authors and extra author requests deletion', async ()=>{ + const brew = { + ...googleBrew, + authors : ['test', 'test2'] + }; + api.getBrew = jest.fn(()=>async (req)=>{ + req.brew = brew; + }); + model.findOne = jest.fn(async ()=>modelBrew(brew)); + model.deleteOne = jest.fn(async ()=>{}); + api.deleteGoogleBrew = jest.fn(async ()=>true); + const req = { account: { username: 'test2' } }; + + await api.deleteBrew(req, res); + + expect(api.getBrew).toHaveBeenCalled(); + expect(model.findOne).toHaveBeenCalled(); + expect(model.deleteOne).not.toHaveBeenCalled(); + expect(api.deleteGoogleBrew).not.toHaveBeenCalled(); + expect(saveFunc).toHaveBeenCalled(); + expect(saved.authors).toEqual(['test']); + expect(saved.googleId).toEqual(brew.googleId); + }); + }); + describe('deleteGoogleBrew', ()=>{ + it('should check auth and delete brew', async ()=>{ + const result = await api.deleteGoogleBrew({ username: 'test user' }, 'id', 'editId', res); + + expect(result).toBe(true); + expect(google.authCheck).toHaveBeenCalledWith({ username: 'test user' }, expect.objectContaining({})); + expect(google.deleteGoogleBrew).toHaveBeenCalledWith('client', 'id', 'editId'); + }); + }); describe('deleteBrew', ()=>{ it('should handle case where fetching the brew returns an error', async ()=>{ api.getBrew = jest.fn(()=>async ()=>{ throw { message: 'err', HBErrorCode: '02' }; }); @@ -937,68 +1070,7 @@ brew`); expect(saved.googleId).toEqual(brew.googleId); }); }); - describe('Get CSS', ()=>{ - it('should return brew style content as CSS text', async ()=>{ - const testBrew = { title: 'test brew', text: '```css\n\nI Have a style!\n```\n\n' }; - const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); - api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); - model.get = jest.fn(()=>toBrewPromise(testBrew)); - - const fn = api.getBrew('share', true); - const req = { brew: {} }; - const next = jest.fn(); - await fn(req, null, next); - await api.getCSS(req, res); - - expect(req.brew).toEqual(testBrew); - expect(req.brew).toHaveProperty('style', '\nI Have a style!\n'); - expect(res.status).toHaveBeenCalledWith(200); - expect(res.send).toHaveBeenCalledWith('\nI Have a style!\n'); - expect(res.set).toHaveBeenCalledWith({ - 'Cache-Control' : 'no-cache', - 'Content-Type' : 'text/css' - }); - }); - - it('should return 404 when brew has no style content', async ()=>{ - const testBrew = { title: 'test brew', text: 'I don\'t have a style!' }; - - const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); - api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); - model.get = jest.fn(()=>toBrewPromise(testBrew)); - - const fn = api.getBrew('share', true); - const req = { brew: {} }; - const next = jest.fn(); - await fn(req, null, next); - await api.getCSS(req, res); - - expect(req.brew).toEqual(testBrew); - expect(req.brew).toHaveProperty('style'); - expect(res.status).toHaveBeenCalledWith(404); - expect(res.send).toHaveBeenCalledWith(''); - }); - - it('should return 404 when brew does not exist', async ()=>{ - const testBrew = { }; - - const toBrewPromise = (brew)=>new Promise((res)=>res({ toObject: ()=>brew })); - api.getId = jest.fn(()=>({ id: '1', googleId: undefined })); - model.get = jest.fn(()=>toBrewPromise(testBrew)); - - const fn = api.getBrew('share', true); - const req = { brew: {} }; - const next = jest.fn(); - await fn(req, null, next); - await api.getCSS(req, res); - - expect(req.brew).toEqual(testBrew); - expect(req.brew).toHaveProperty('style'); - expect(res.status).toHaveBeenCalledWith(404); - expect(res.send).toHaveBeenCalledWith(''); - }); - }); describe('Split Text, Style, and Metadata', ()=>{ it('basic splitting', async ()=>{