LaunchpadControllerTests.js 33 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019
  1. /* eslint-disable
  2. max-len,
  3. no-return-assign,
  4. no-unused-vars,
  5. */
  6. // TODO: This file was created by bulk-decaffeinate.
  7. // Fix any style issues and re-enable lint.
  8. /*
  9. * decaffeinate suggestions:
  10. * DS102: Remove unnecessary code created because of implicit returns
  11. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  12. */
  13. const SandboxedModule = require('sandboxed-module')
  14. const assert = require('assert')
  15. require('chai').should()
  16. const { expect } = require('chai')
  17. const sinon = require('sinon')
  18. const modulePath = require('path').join(
  19. __dirname,
  20. '../../../app/src/LaunchpadController.js'
  21. )
  22. describe('LaunchpadController', function() {
  23. beforeEach(function() {
  24. this.user = {
  25. _id: '323123',
  26. first_name: 'fn',
  27. last_name: 'ln',
  28. save: sinon.stub().callsArgWith(0)
  29. }
  30. this.User = {}
  31. this.LaunchpadController = SandboxedModule.require(modulePath, {
  32. globals: {
  33. console: console
  34. },
  35. requires: {
  36. 'settings-sharelatex': (this.Settings = {}),
  37. 'logger-sharelatex': (this.Logger = {
  38. log() {},
  39. warn() {},
  40. err() {},
  41. error() {}
  42. }),
  43. 'metrics-sharelatex': (this.Metrics = {}),
  44. '../../../../app/src/Features/User/UserRegistrationHandler': (this.UserRegistrationHandler = {}),
  45. '../../../../app/src/Features/Email/EmailHandler': (this.EmailHandler = {}),
  46. '../../../../app/src/Features/User/UserGetter': (this.UserGetter = {}),
  47. '../../../../app/src/models/User': { User: this.User },
  48. '../../../../app/src/Features/Authentication/AuthenticationController': (this.AuthenticationController = {})
  49. }
  50. })
  51. this.email = 'bob@smith.com'
  52. this.req = {
  53. query: {},
  54. body: {},
  55. session: {}
  56. }
  57. this.res = {
  58. render: sinon.stub(),
  59. redirect: sinon.stub(),
  60. send: sinon.stub(),
  61. sendStatus: sinon.stub()
  62. }
  63. return (this.next = sinon.stub())
  64. })
  65. describe('launchpadPage', function() {
  66. beforeEach(function() {
  67. this._atLeastOneAdminExists = sinon.stub(
  68. this.LaunchpadController,
  69. '_atLeastOneAdminExists'
  70. )
  71. return (this.AuthenticationController.setRedirectInSession = sinon.stub())
  72. })
  73. afterEach(function() {
  74. return this._atLeastOneAdminExists.restore()
  75. })
  76. describe('when the user is not logged in', function() {
  77. beforeEach(function() {
  78. this.AuthenticationController.getSessionUser = sinon
  79. .stub()
  80. .returns(null)
  81. return (this.res.render = sinon.stub())
  82. })
  83. describe('when there are no admins', function() {
  84. beforeEach(function() {
  85. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  86. return this.LaunchpadController.launchpadPage(
  87. this.req,
  88. this.res,
  89. this.next
  90. )
  91. })
  92. it('should render the launchpad page', function() {
  93. const viewPath = require('path').join(
  94. __dirname,
  95. '../../../app/views/launchpad'
  96. )
  97. this.res.render.callCount.should.equal(1)
  98. return this.res.render
  99. .calledWith(viewPath, {
  100. adminUserExists: false,
  101. authMethod: 'local'
  102. })
  103. .should.equal(true)
  104. })
  105. })
  106. describe('when there is at least one admin', function() {
  107. beforeEach(function() {
  108. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  109. return this.LaunchpadController.launchpadPage(
  110. this.req,
  111. this.res,
  112. this.next
  113. )
  114. })
  115. it('should redirect to login page', function() {
  116. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  117. 1
  118. )
  119. this.res.redirect.calledWith('/login').should.equal(true)
  120. })
  121. it('should not render the launchpad page', function() {
  122. return this.res.render.callCount.should.equal(0)
  123. })
  124. })
  125. })
  126. describe('when the user is logged in', function() {
  127. beforeEach(function() {
  128. this.user = {
  129. _id: 'abcd',
  130. email: 'abcd@example.com'
  131. }
  132. this.AuthenticationController.getSessionUser = sinon
  133. .stub()
  134. .returns(this.user)
  135. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  136. this.res.render = sinon.stub()
  137. return (this.res.redirect = sinon.stub())
  138. })
  139. describe('when the user is an admin', function() {
  140. beforeEach(function() {
  141. this.UserGetter.getUser = sinon
  142. .stub()
  143. .callsArgWith(2, null, { isAdmin: true })
  144. return this.LaunchpadController.launchpadPage(
  145. this.req,
  146. this.res,
  147. this.next
  148. )
  149. })
  150. it('should render the launchpad page', function() {
  151. const viewPath = require('path').join(
  152. __dirname,
  153. '../../../app/views/launchpad'
  154. )
  155. this.res.render.callCount.should.equal(1)
  156. return this.res.render
  157. .calledWith(viewPath, {
  158. wsUrl: undefined,
  159. adminUserExists: true,
  160. authMethod: 'local'
  161. })
  162. .should.equal(true)
  163. })
  164. })
  165. describe('when the user is not an admin', function() {
  166. beforeEach(function() {
  167. this.UserGetter.getUser = sinon
  168. .stub()
  169. .callsArgWith(2, null, { isAdmin: false })
  170. return this.LaunchpadController.launchpadPage(
  171. this.req,
  172. this.res,
  173. this.next
  174. )
  175. })
  176. it('should redirect to restricted page', function() {
  177. this.res.redirect.callCount.should.equal(1)
  178. return this.res.redirect.calledWith('/restricted').should.equal(true)
  179. })
  180. })
  181. })
  182. })
  183. describe('_atLeastOneAdminExists', function() {
  184. describe('when there are no admins', function() {
  185. beforeEach(function() {
  186. return (this.UserGetter.getUser = sinon
  187. .stub()
  188. .callsArgWith(2, null, null))
  189. })
  190. it('should callback with false', function(done) {
  191. return this.LaunchpadController._atLeastOneAdminExists(
  192. (err, exists) => {
  193. expect(err).to.equal(null)
  194. expect(exists).to.equal(false)
  195. return done()
  196. }
  197. )
  198. })
  199. })
  200. describe('when there are some admins', function() {
  201. beforeEach(function() {
  202. return (this.UserGetter.getUser = sinon
  203. .stub()
  204. .callsArgWith(2, null, { _id: 'abcd' }))
  205. })
  206. it('should callback with true', function(done) {
  207. return this.LaunchpadController._atLeastOneAdminExists(
  208. (err, exists) => {
  209. expect(err).to.equal(null)
  210. expect(exists).to.equal(true)
  211. return done()
  212. }
  213. )
  214. })
  215. })
  216. describe('when getUser produces an error', function() {
  217. beforeEach(function() {
  218. return (this.UserGetter.getUser = sinon
  219. .stub()
  220. .callsArgWith(2, new Error('woops')))
  221. })
  222. it('should produce an error', function(done) {
  223. return this.LaunchpadController._atLeastOneAdminExists(
  224. (err, exists) => {
  225. expect(err).to.not.equal(null)
  226. expect(err).to.be.instanceof(Error)
  227. expect(exists).to.equal(undefined)
  228. return done()
  229. }
  230. )
  231. })
  232. })
  233. })
  234. describe('sendTestEmail', function() {
  235. beforeEach(function() {
  236. this.EmailHandler.sendEmail = sinon.stub().callsArgWith(2, null)
  237. this.req.body.email = 'someone@example.com'
  238. this.res.sendStatus = sinon.stub()
  239. return (this.next = sinon.stub())
  240. })
  241. it('should produce a 201 response', function() {
  242. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  243. this.res.sendStatus.callCount.should.equal(1)
  244. return this.res.sendStatus.calledWith(201).should.equal(true)
  245. })
  246. it('should not call next with an error', function() {
  247. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  248. return this.next.callCount.should.equal(0)
  249. })
  250. it('should have called sendEmail', function() {
  251. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  252. this.EmailHandler.sendEmail.callCount.should.equal(1)
  253. return this.EmailHandler.sendEmail
  254. .calledWith('testEmail')
  255. .should.equal(true)
  256. })
  257. describe('when sendEmail produces an error', function() {
  258. beforeEach(function() {
  259. return (this.EmailHandler.sendEmail = sinon
  260. .stub()
  261. .callsArgWith(2, new Error('woops')))
  262. })
  263. it('should call next with an error', function() {
  264. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  265. this.next.callCount.should.equal(1)
  266. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  267. })
  268. })
  269. describe('when no email address is supplied', function() {
  270. beforeEach(function() {
  271. return (this.req.body.email = undefined)
  272. })
  273. it('should produce a 400 response', function() {
  274. this.LaunchpadController.sendTestEmail(this.req, this.res, this.next)
  275. this.res.sendStatus.callCount.should.equal(1)
  276. return this.res.sendStatus.calledWith(400).should.equal(true)
  277. })
  278. })
  279. })
  280. describe('registerAdmin', function() {
  281. beforeEach(function() {
  282. return (this._atLeastOneAdminExists = sinon.stub(
  283. this.LaunchpadController,
  284. '_atLeastOneAdminExists'
  285. ))
  286. })
  287. afterEach(function() {
  288. return this._atLeastOneAdminExists.restore()
  289. })
  290. describe('when all goes well', function() {
  291. beforeEach(function() {
  292. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  293. this.email = 'someone@example.com'
  294. this.password = 'a_really_bad_password'
  295. this.req.body.email = this.email
  296. this.req.body.password = this.password
  297. this.user = {
  298. _id: 'abcdef',
  299. email: this.email
  300. }
  301. this.UserRegistrationHandler.registerNewUser = sinon
  302. .stub()
  303. .callsArgWith(1, null, this.user)
  304. this.User.update = sinon.stub().callsArgWith(2, null)
  305. this.AuthenticationController.setRedirectInSession = sinon.stub()
  306. this.res.json = sinon.stub()
  307. this.next = sinon.stub()
  308. return this.LaunchpadController.registerAdmin(
  309. this.req,
  310. this.res,
  311. this.next
  312. )
  313. })
  314. it('should send back a json response', function() {
  315. this.res.json.callCount.should.equal(1)
  316. return expect(this.res.json.lastCall.args[0].email).to.equal(this.email)
  317. })
  318. it('should have checked for existing admins', function() {
  319. return this._atLeastOneAdminExists.callCount.should.equal(1)
  320. })
  321. it('should have called registerNewUser', function() {
  322. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  323. return this.UserRegistrationHandler.registerNewUser
  324. .calledWith({ email: this.email, password: this.password })
  325. .should.equal(true)
  326. })
  327. it('should have updated the user to make them an admin', function() {
  328. this.User.update.callCount.should.equal(1)
  329. return this.User.update
  330. .calledWithMatch(
  331. { _id: this.user._id },
  332. {
  333. $set: {
  334. isAdmin: true,
  335. emails: [{ email: this.user.email }]
  336. }
  337. }
  338. )
  339. .should.equal(true)
  340. })
  341. it('should have set a redirect in session', function() {
  342. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  343. 1
  344. )
  345. return this.AuthenticationController.setRedirectInSession
  346. .calledWith(this.req, '/launchpad')
  347. .should.equal(true)
  348. })
  349. })
  350. describe('when no email is supplied', function() {
  351. beforeEach(function() {
  352. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  353. this.email = undefined
  354. this.password = 'a_really_bad_password'
  355. this.req.body.email = this.email
  356. this.req.body.password = this.password
  357. this.user = {
  358. _id: 'abcdef',
  359. email: this.email
  360. }
  361. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  362. this.User.update = sinon.stub()
  363. this.AuthenticationController.setRedirectInSession = sinon.stub()
  364. this.res.sendStatus = sinon.stub()
  365. this.next = sinon.stub()
  366. return this.LaunchpadController.registerAdmin(
  367. this.req,
  368. this.res,
  369. this.next
  370. )
  371. })
  372. it('should send a 400 response', function() {
  373. this.res.sendStatus.callCount.should.equal(1)
  374. return this.res.sendStatus.calledWith(400).should.equal(true)
  375. })
  376. it('should not check for existing admins', function() {
  377. return this._atLeastOneAdminExists.callCount.should.equal(0)
  378. })
  379. it('should not call registerNewUser', function() {
  380. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  381. 0
  382. )
  383. })
  384. })
  385. describe('when no password is supplied', function() {
  386. beforeEach(function() {
  387. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  388. this.email = 'someone@example.com'
  389. this.password = undefined
  390. this.req.body.email = this.email
  391. this.req.body.password = this.password
  392. this.user = {
  393. _id: 'abcdef',
  394. email: this.email
  395. }
  396. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  397. this.User.update = sinon.stub()
  398. this.AuthenticationController.setRedirectInSession = sinon.stub()
  399. this.res.sendStatus = sinon.stub()
  400. this.next = sinon.stub()
  401. return this.LaunchpadController.registerAdmin(
  402. this.req,
  403. this.res,
  404. this.next
  405. )
  406. })
  407. it('should send a 400 response', function() {
  408. this.res.sendStatus.callCount.should.equal(1)
  409. return this.res.sendStatus.calledWith(400).should.equal(true)
  410. })
  411. it('should not check for existing admins', function() {
  412. return this._atLeastOneAdminExists.callCount.should.equal(0)
  413. })
  414. it('should not call registerNewUser', function() {
  415. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  416. 0
  417. )
  418. })
  419. })
  420. describe('when there are already existing admins', function() {
  421. beforeEach(function() {
  422. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  423. this.email = 'someone@example.com'
  424. this.password = 'a_really_bad_password'
  425. this.req.body.email = this.email
  426. this.req.body.password = this.password
  427. this.user = {
  428. _id: 'abcdef',
  429. email: this.email
  430. }
  431. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  432. this.User.update = sinon.stub()
  433. this.AuthenticationController.setRedirectInSession = sinon.stub()
  434. this.res.sendStatus = sinon.stub()
  435. this.next = sinon.stub()
  436. return this.LaunchpadController.registerAdmin(
  437. this.req,
  438. this.res,
  439. this.next
  440. )
  441. })
  442. it('should send a 403 response', function() {
  443. this.res.sendStatus.callCount.should.equal(1)
  444. return this.res.sendStatus.calledWith(403).should.equal(true)
  445. })
  446. it('should not call registerNewUser', function() {
  447. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  448. 0
  449. )
  450. })
  451. })
  452. describe('when checking admins produces an error', function() {
  453. beforeEach(function() {
  454. this._atLeastOneAdminExists.callsArgWith(0, new Error('woops'))
  455. this.email = 'someone@example.com'
  456. this.password = 'a_really_bad_password'
  457. this.req.body.email = this.email
  458. this.req.body.password = this.password
  459. this.user = {
  460. _id: 'abcdef',
  461. email: this.email
  462. }
  463. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  464. this.User.update = sinon.stub()
  465. this.AuthenticationController.setRedirectInSession = sinon.stub()
  466. this.res.sendStatus = sinon.stub()
  467. this.next = sinon.stub()
  468. return this.LaunchpadController.registerAdmin(
  469. this.req,
  470. this.res,
  471. this.next
  472. )
  473. })
  474. it('should call next with an error', function() {
  475. this.next.callCount.should.equal(1)
  476. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  477. })
  478. it('should have checked for existing admins', function() {
  479. return this._atLeastOneAdminExists.callCount.should.equal(1)
  480. })
  481. it('should not call registerNewUser', function() {
  482. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  483. 0
  484. )
  485. })
  486. })
  487. describe('when registerNewUser produces an error', function() {
  488. beforeEach(function() {
  489. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  490. this.email = 'someone@example.com'
  491. this.password = 'a_really_bad_password'
  492. this.req.body.email = this.email
  493. this.req.body.password = this.password
  494. this.user = {
  495. _id: 'abcdef',
  496. email: this.email
  497. }
  498. this.UserRegistrationHandler.registerNewUser = sinon
  499. .stub()
  500. .callsArgWith(1, new Error('woops'))
  501. this.User.update = sinon.stub()
  502. this.AuthenticationController.setRedirectInSession = sinon.stub()
  503. this.res.json = sinon.stub()
  504. this.next = sinon.stub()
  505. return this.LaunchpadController.registerAdmin(
  506. this.req,
  507. this.res,
  508. this.next
  509. )
  510. })
  511. it('should call next with an error', function() {
  512. this.next.callCount.should.equal(1)
  513. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  514. })
  515. it('should have checked for existing admins', function() {
  516. return this._atLeastOneAdminExists.callCount.should.equal(1)
  517. })
  518. it('should have called registerNewUser', function() {
  519. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  520. return this.UserRegistrationHandler.registerNewUser
  521. .calledWith({ email: this.email, password: this.password })
  522. .should.equal(true)
  523. })
  524. it('should not call update', function() {
  525. return this.User.update.callCount.should.equal(0)
  526. })
  527. })
  528. describe('when user update produces an error', function() {
  529. beforeEach(function() {
  530. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  531. this.email = 'someone@example.com'
  532. this.password = 'a_really_bad_password'
  533. this.req.body.email = this.email
  534. this.req.body.password = this.password
  535. this.user = {
  536. _id: 'abcdef',
  537. email: this.email
  538. }
  539. this.UserRegistrationHandler.registerNewUser = sinon
  540. .stub()
  541. .callsArgWith(1, null, this.user)
  542. this.User.update = sinon.stub().callsArgWith(2, new Error('woops'))
  543. this.AuthenticationController.setRedirectInSession = sinon.stub()
  544. this.res.json = sinon.stub()
  545. this.next = sinon.stub()
  546. return this.LaunchpadController.registerAdmin(
  547. this.req,
  548. this.res,
  549. this.next
  550. )
  551. })
  552. it('should call next with an error', function() {
  553. this.next.callCount.should.equal(1)
  554. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  555. })
  556. it('should have checked for existing admins', function() {
  557. return this._atLeastOneAdminExists.callCount.should.equal(1)
  558. })
  559. it('should have called registerNewUser', function() {
  560. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  561. return this.UserRegistrationHandler.registerNewUser
  562. .calledWith({ email: this.email, password: this.password })
  563. .should.equal(true)
  564. })
  565. })
  566. describe('when overleaf', function() {
  567. beforeEach(function() {
  568. this.Settings.overleaf = { one: 1 }
  569. this.Settings.createV1AccountOnLogin = true
  570. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  571. this.email = 'someone@example.com'
  572. this.password = 'a_really_bad_password'
  573. this.req.body.email = this.email
  574. this.req.body.password = this.password
  575. this.user = {
  576. _id: 'abcdef',
  577. email: this.email
  578. }
  579. this.UserRegistrationHandler.registerNewUser = sinon
  580. .stub()
  581. .callsArgWith(1, null, this.user)
  582. this.User.update = sinon.stub().callsArgWith(2, null)
  583. this.AuthenticationController.setRedirectInSession = sinon.stub()
  584. this.UserGetter.getUser = sinon
  585. .stub()
  586. .callsArgWith(1, null, { _id: '1234' })
  587. this.res.json = sinon.stub()
  588. this.next = sinon.stub()
  589. return this.LaunchpadController.registerAdmin(
  590. this.req,
  591. this.res,
  592. this.next
  593. )
  594. })
  595. it('should send back a json response', function() {
  596. this.res.json.callCount.should.equal(1)
  597. return expect(this.res.json.lastCall.args[0].email).to.equal(this.email)
  598. })
  599. it('should have checked for existing admins', function() {
  600. return this._atLeastOneAdminExists.callCount.should.equal(1)
  601. })
  602. it('should have called registerNewUser', function() {
  603. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  604. return this.UserRegistrationHandler.registerNewUser
  605. .calledWith({ email: this.email, password: this.password })
  606. .should.equal(true)
  607. })
  608. it('should have updated the user to make them an admin', function() {
  609. return this.User.update
  610. .calledWith(
  611. { _id: this.user._id },
  612. {
  613. $set: {
  614. isAdmin: true,
  615. emails: [{ email: this.user.email }]
  616. }
  617. }
  618. )
  619. .should.equal(true)
  620. })
  621. it('should have set a redirect in session', function() {
  622. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  623. 1
  624. )
  625. return this.AuthenticationController.setRedirectInSession
  626. .calledWith(this.req, '/launchpad')
  627. .should.equal(true)
  628. })
  629. })
  630. })
  631. describe('registerExternalAuthAdmin', function() {
  632. beforeEach(function() {
  633. this.Settings.ldap = { one: 1 }
  634. return (this._atLeastOneAdminExists = sinon.stub(
  635. this.LaunchpadController,
  636. '_atLeastOneAdminExists'
  637. ))
  638. })
  639. afterEach(function() {
  640. return this._atLeastOneAdminExists.restore()
  641. })
  642. describe('when all goes well', function() {
  643. beforeEach(function() {
  644. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  645. this.email = 'someone@example.com'
  646. this.req.body.email = this.email
  647. this.user = {
  648. _id: 'abcdef',
  649. email: this.email
  650. }
  651. this.UserRegistrationHandler.registerNewUser = sinon
  652. .stub()
  653. .callsArgWith(1, null, this.user)
  654. this.User.update = sinon.stub().callsArgWith(2, null)
  655. this.AuthenticationController.setRedirectInSession = sinon.stub()
  656. this.res.json = sinon.stub()
  657. this.next = sinon.stub()
  658. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  659. this.req,
  660. this.res,
  661. this.next
  662. )
  663. })
  664. it('should send back a json response', function() {
  665. this.res.json.callCount.should.equal(1)
  666. return expect(this.res.json.lastCall.args[0].email).to.equal(this.email)
  667. })
  668. it('should have checked for existing admins', function() {
  669. return this._atLeastOneAdminExists.callCount.should.equal(1)
  670. })
  671. it('should have called registerNewUser', function() {
  672. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  673. return this.UserRegistrationHandler.registerNewUser
  674. .calledWith({
  675. email: this.email,
  676. password: 'password_here',
  677. first_name: this.email,
  678. last_name: ''
  679. })
  680. .should.equal(true)
  681. })
  682. it('should have updated the user to make them an admin', function() {
  683. this.User.update.callCount.should.equal(1)
  684. return this.User.update
  685. .calledWith(
  686. { _id: this.user._id },
  687. {
  688. $set: { isAdmin: true },
  689. emails: [{ email: this.user.email }]
  690. }
  691. )
  692. .should.equal(true)
  693. })
  694. it('should have set a redirect in session', function() {
  695. this.AuthenticationController.setRedirectInSession.callCount.should.equal(
  696. 1
  697. )
  698. return this.AuthenticationController.setRedirectInSession
  699. .calledWith(this.req, '/launchpad')
  700. .should.equal(true)
  701. })
  702. })
  703. describe('when the authMethod is invalid', function() {
  704. beforeEach(function() {
  705. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  706. this.email = undefined
  707. this.req.body.email = this.email
  708. this.user = {
  709. _id: 'abcdef',
  710. email: this.email
  711. }
  712. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  713. this.User.update = sinon.stub()
  714. this.AuthenticationController.setRedirectInSession = sinon.stub()
  715. this.res.sendStatus = sinon.stub()
  716. this.next = sinon.stub()
  717. return this.LaunchpadController.registerExternalAuthAdmin(
  718. 'NOTAVALIDAUTHMETHOD'
  719. )(this.req, this.res, this.next)
  720. })
  721. it('should send a 403 response', function() {
  722. this.res.sendStatus.callCount.should.equal(1)
  723. return this.res.sendStatus.calledWith(403).should.equal(true)
  724. })
  725. it('should not check for existing admins', function() {
  726. return this._atLeastOneAdminExists.callCount.should.equal(0)
  727. })
  728. it('should not call registerNewUser', function() {
  729. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  730. 0
  731. )
  732. })
  733. })
  734. describe('when no email is supplied', function() {
  735. beforeEach(function() {
  736. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  737. this.email = undefined
  738. this.req.body.email = this.email
  739. this.user = {
  740. _id: 'abcdef',
  741. email: this.email
  742. }
  743. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  744. this.User.update = sinon.stub()
  745. this.AuthenticationController.setRedirectInSession = sinon.stub()
  746. this.res.sendStatus = sinon.stub()
  747. this.next = sinon.stub()
  748. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  749. this.req,
  750. this.res,
  751. this.next
  752. )
  753. })
  754. it('should send a 400 response', function() {
  755. this.res.sendStatus.callCount.should.equal(1)
  756. return this.res.sendStatus.calledWith(400).should.equal(true)
  757. })
  758. it('should not check for existing admins', function() {
  759. return this._atLeastOneAdminExists.callCount.should.equal(0)
  760. })
  761. it('should not call registerNewUser', function() {
  762. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  763. 0
  764. )
  765. })
  766. })
  767. describe('when there are already existing admins', function() {
  768. beforeEach(function() {
  769. this._atLeastOneAdminExists.callsArgWith(0, null, true)
  770. this.email = 'someone@example.com'
  771. this.req.body.email = this.email
  772. this.user = {
  773. _id: 'abcdef',
  774. email: this.email
  775. }
  776. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  777. this.User.update = sinon.stub()
  778. this.AuthenticationController.setRedirectInSession = sinon.stub()
  779. this.res.sendStatus = sinon.stub()
  780. this.next = sinon.stub()
  781. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  782. this.req,
  783. this.res,
  784. this.next
  785. )
  786. })
  787. it('should send a 403 response', function() {
  788. this.res.sendStatus.callCount.should.equal(1)
  789. return this.res.sendStatus.calledWith(403).should.equal(true)
  790. })
  791. it('should not call registerNewUser', function() {
  792. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  793. 0
  794. )
  795. })
  796. })
  797. describe('when checking admins produces an error', function() {
  798. beforeEach(function() {
  799. this._atLeastOneAdminExists.callsArgWith(0, new Error('woops'))
  800. this.email = 'someone@example.com'
  801. this.req.body.email = this.email
  802. this.user = {
  803. _id: 'abcdef',
  804. email: this.email
  805. }
  806. this.UserRegistrationHandler.registerNewUser = sinon.stub()
  807. this.User.update = sinon.stub()
  808. this.AuthenticationController.setRedirectInSession = sinon.stub()
  809. this.res.sendStatus = sinon.stub()
  810. this.next = sinon.stub()
  811. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  812. this.req,
  813. this.res,
  814. this.next
  815. )
  816. })
  817. it('should call next with an error', function() {
  818. this.next.callCount.should.equal(1)
  819. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  820. })
  821. it('should have checked for existing admins', function() {
  822. return this._atLeastOneAdminExists.callCount.should.equal(1)
  823. })
  824. it('should not call registerNewUser', function() {
  825. return this.UserRegistrationHandler.registerNewUser.callCount.should.equal(
  826. 0
  827. )
  828. })
  829. })
  830. describe('when registerNewUser produces an error', function() {
  831. beforeEach(function() {
  832. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  833. this.email = 'someone@example.com'
  834. this.req.body.email = this.email
  835. this.user = {
  836. _id: 'abcdef',
  837. email: this.email
  838. }
  839. this.UserRegistrationHandler.registerNewUser = sinon
  840. .stub()
  841. .callsArgWith(1, new Error('woops'))
  842. this.User.update = sinon.stub()
  843. this.AuthenticationController.setRedirectInSession = sinon.stub()
  844. this.res.json = sinon.stub()
  845. this.next = sinon.stub()
  846. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  847. this.req,
  848. this.res,
  849. this.next
  850. )
  851. })
  852. it('should call next with an error', function() {
  853. this.next.callCount.should.equal(1)
  854. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  855. })
  856. it('should have checked for existing admins', function() {
  857. return this._atLeastOneAdminExists.callCount.should.equal(1)
  858. })
  859. it('should have called registerNewUser', function() {
  860. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  861. return this.UserRegistrationHandler.registerNewUser
  862. .calledWith({
  863. email: this.email,
  864. password: 'password_here',
  865. first_name: this.email,
  866. last_name: ''
  867. })
  868. .should.equal(true)
  869. })
  870. it('should not call update', function() {
  871. return this.User.update.callCount.should.equal(0)
  872. })
  873. })
  874. describe('when user update produces an error', function() {
  875. beforeEach(function() {
  876. this._atLeastOneAdminExists.callsArgWith(0, null, false)
  877. this.email = 'someone@example.com'
  878. this.req.body.email = this.email
  879. this.user = {
  880. _id: 'abcdef',
  881. email: this.email
  882. }
  883. this.UserRegistrationHandler.registerNewUser = sinon
  884. .stub()
  885. .callsArgWith(1, null, this.user)
  886. this.User.update = sinon.stub().callsArgWith(2, new Error('woops'))
  887. this.AuthenticationController.setRedirectInSession = sinon.stub()
  888. this.res.json = sinon.stub()
  889. this.next = sinon.stub()
  890. return this.LaunchpadController.registerExternalAuthAdmin('ldap')(
  891. this.req,
  892. this.res,
  893. this.next
  894. )
  895. })
  896. it('should call next with an error', function() {
  897. this.next.callCount.should.equal(1)
  898. return expect(this.next.lastCall.args[0]).to.be.instanceof(Error)
  899. })
  900. it('should have checked for existing admins', function() {
  901. return this._atLeastOneAdminExists.callCount.should.equal(1)
  902. })
  903. it('should have called registerNewUser', function() {
  904. this.UserRegistrationHandler.registerNewUser.callCount.should.equal(1)
  905. return this.UserRegistrationHandler.registerNewUser
  906. .calledWith({
  907. email: this.email,
  908. password: 'password_here',
  909. first_name: this.email,
  910. last_name: ''
  911. })
  912. .should.equal(true)
  913. })
  914. })
  915. })
  916. })