LaunchpadControllerTests.js 33 KB

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