LaunchpadControllerTests.js 33 KB

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