LaunchpadControllerTests.js 33 KB

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