UserSessionsManagerTests.js 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817
  1. /* eslint-disable
  2. handle-callback-err,
  3. max-len,
  4. no-return-assign,
  5. no-unused-vars,
  6. */
  7. // TODO: This file was created by bulk-decaffeinate.
  8. // Fix any style issues and re-enable lint.
  9. /*
  10. * decaffeinate suggestions:
  11. * DS102: Remove unnecessary code created because of implicit returns
  12. * Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
  13. */
  14. const sinon = require('sinon')
  15. const chai = require('chai')
  16. const should = chai.should()
  17. const { expect } = chai
  18. const modulePath = '../../../../app/src/Features/User/UserSessionsManager.js'
  19. const SandboxedModule = require('sandboxed-module')
  20. const Async = require('async')
  21. describe('UserSessionsManager', function() {
  22. beforeEach(function() {
  23. this.user = {
  24. _id: 'abcd',
  25. email: 'user@example.com'
  26. }
  27. this.sessionId = 'some_session_id'
  28. this.rclient = {
  29. multi: sinon.stub(),
  30. exec: sinon.stub(),
  31. get: sinon.stub(),
  32. del: sinon.stub(),
  33. sadd: sinon.stub(),
  34. srem: sinon.stub(),
  35. smembers: sinon.stub(),
  36. mget: sinon.stub(),
  37. pexpire: sinon.stub()
  38. }
  39. this.rclient.multi.returns(this.rclient)
  40. this.rclient.get.returns(this.rclient)
  41. this.rclient.del.returns(this.rclient)
  42. this.rclient.sadd.returns(this.rclient)
  43. this.rclient.srem.returns(this.rclient)
  44. this.rclient.smembers.returns(this.rclient)
  45. this.rclient.pexpire.returns(this.rclient)
  46. this.rclient.exec.callsArgWith(0, null)
  47. this.UserSessionsRedis = {
  48. client: () => this.rclient,
  49. sessionSetKey: user => `UserSessions:{${user._id}}`
  50. }
  51. this.logger = {
  52. err: sinon.stub(),
  53. error: sinon.stub(),
  54. warn: sinon.stub(),
  55. log: sinon.stub()
  56. }
  57. this.settings = {
  58. redis: {
  59. web: {}
  60. }
  61. }
  62. return (this.UserSessionsManager = SandboxedModule.require(modulePath, {
  63. globals: {
  64. console: console
  65. },
  66. requires: {
  67. 'logger-sharelatex': this.logger,
  68. 'settings-sharelatex': this.settings,
  69. './UserSessionsRedis': this.UserSessionsRedis,
  70. async: Async
  71. }
  72. }))
  73. })
  74. describe('_sessionKey', function() {
  75. it('should build the correct key', function() {
  76. const result = this.UserSessionsManager._sessionKey(this.sessionId)
  77. return result.should.equal('sess:some_session_id')
  78. })
  79. })
  80. describe('trackSession', function() {
  81. beforeEach(function() {
  82. this.call = callback => {
  83. return this.UserSessionsManager.trackSession(
  84. this.user,
  85. this.sessionId,
  86. callback
  87. )
  88. }
  89. this.rclient.exec.callsArgWith(0, null)
  90. return (this._checkSessions = sinon
  91. .stub(this.UserSessionsManager, '_checkSessions')
  92. .returns(null))
  93. })
  94. afterEach(function() {
  95. return this._checkSessions.restore()
  96. })
  97. it('should not produce an error', function(done) {
  98. return this.call(err => {
  99. expect(err).to.not.be.instanceof(Error)
  100. return done()
  101. })
  102. })
  103. it('should call the appropriate redis methods', function(done) {
  104. return this.call(err => {
  105. this.rclient.multi.callCount.should.equal(1)
  106. this.rclient.sadd.callCount.should.equal(1)
  107. this.rclient.pexpire.callCount.should.equal(1)
  108. this.rclient.exec.callCount.should.equal(1)
  109. return done()
  110. })
  111. })
  112. it('should call _checkSessions', function(done) {
  113. return this.call(err => {
  114. this._checkSessions.callCount.should.equal(1)
  115. return done()
  116. })
  117. })
  118. describe('when rclient produces an error', function() {
  119. beforeEach(function() {
  120. return this.rclient.exec.callsArgWith(0, new Error('woops'))
  121. })
  122. it('should produce an error', function(done) {
  123. return this.call(err => {
  124. expect(err).to.be.instanceof(Error)
  125. return done()
  126. })
  127. })
  128. it('should not call _checkSessions', function(done) {
  129. return this.call(err => {
  130. this._checkSessions.callCount.should.equal(0)
  131. return done()
  132. })
  133. })
  134. })
  135. describe('when no user is supplied', function() {
  136. beforeEach(function() {
  137. return (this.call = callback => {
  138. return this.UserSessionsManager.trackSession(
  139. null,
  140. this.sessionId,
  141. callback
  142. )
  143. })
  144. })
  145. it('should not produce an error', function(done) {
  146. return this.call(err => {
  147. expect(err).to.not.be.instanceof(Error)
  148. expect(err).to.equal(null)
  149. return done()
  150. })
  151. })
  152. it('should not call the appropriate redis methods', function(done) {
  153. return this.call(err => {
  154. this.rclient.multi.callCount.should.equal(0)
  155. this.rclient.sadd.callCount.should.equal(0)
  156. this.rclient.pexpire.callCount.should.equal(0)
  157. this.rclient.exec.callCount.should.equal(0)
  158. return done()
  159. })
  160. })
  161. it('should not call _checkSessions', function(done) {
  162. return this.call(err => {
  163. this._checkSessions.callCount.should.equal(0)
  164. return done()
  165. })
  166. })
  167. })
  168. describe('when no sessionId is supplied', function() {
  169. beforeEach(function() {
  170. return (this.call = callback => {
  171. return this.UserSessionsManager.trackSession(
  172. this.user,
  173. null,
  174. callback
  175. )
  176. })
  177. })
  178. it('should not produce an error', function(done) {
  179. return this.call(err => {
  180. expect(err).to.not.be.instanceof(Error)
  181. expect(err).to.equal(null)
  182. return done()
  183. })
  184. })
  185. it('should not call the appropriate redis methods', function(done) {
  186. return this.call(err => {
  187. this.rclient.multi.callCount.should.equal(0)
  188. this.rclient.sadd.callCount.should.equal(0)
  189. this.rclient.pexpire.callCount.should.equal(0)
  190. this.rclient.exec.callCount.should.equal(0)
  191. return done()
  192. })
  193. })
  194. it('should not call _checkSessions', function(done) {
  195. return this.call(err => {
  196. this._checkSessions.callCount.should.equal(0)
  197. return done()
  198. })
  199. })
  200. })
  201. })
  202. describe('untrackSession', function() {
  203. beforeEach(function() {
  204. this.call = callback => {
  205. return this.UserSessionsManager.untrackSession(
  206. this.user,
  207. this.sessionId,
  208. callback
  209. )
  210. }
  211. this.rclient.exec.callsArgWith(0, null)
  212. return (this._checkSessions = sinon
  213. .stub(this.UserSessionsManager, '_checkSessions')
  214. .returns(null))
  215. })
  216. afterEach(function() {
  217. return this._checkSessions.restore()
  218. })
  219. it('should not produce an error', function(done) {
  220. return this.call(err => {
  221. expect(err).to.not.be.instanceof(Error)
  222. expect(err).to.equal(undefined)
  223. return done()
  224. })
  225. })
  226. it('should call the appropriate redis methods', function(done) {
  227. return this.call(err => {
  228. this.rclient.multi.callCount.should.equal(1)
  229. this.rclient.srem.callCount.should.equal(1)
  230. this.rclient.pexpire.callCount.should.equal(1)
  231. this.rclient.exec.callCount.should.equal(1)
  232. return done()
  233. })
  234. })
  235. it('should call _checkSessions', function(done) {
  236. return this.call(err => {
  237. this._checkSessions.callCount.should.equal(1)
  238. return done()
  239. })
  240. })
  241. describe('when rclient produces an error', function() {
  242. beforeEach(function() {
  243. return this.rclient.exec.callsArgWith(0, new Error('woops'))
  244. })
  245. it('should produce an error', function(done) {
  246. return this.call(err => {
  247. expect(err).to.be.instanceof(Error)
  248. return done()
  249. })
  250. })
  251. it('should not call _checkSessions', function(done) {
  252. return this.call(err => {
  253. this._checkSessions.callCount.should.equal(0)
  254. return done()
  255. })
  256. })
  257. })
  258. describe('when no user is supplied', function() {
  259. beforeEach(function() {
  260. return (this.call = callback => {
  261. return this.UserSessionsManager.untrackSession(
  262. null,
  263. this.sessionId,
  264. callback
  265. )
  266. })
  267. })
  268. it('should not produce an error', function(done) {
  269. return this.call(err => {
  270. expect(err).to.not.be.instanceof(Error)
  271. expect(err).to.equal(null)
  272. return done()
  273. })
  274. })
  275. it('should not call the appropriate redis methods', function(done) {
  276. return this.call(err => {
  277. this.rclient.multi.callCount.should.equal(0)
  278. this.rclient.srem.callCount.should.equal(0)
  279. this.rclient.pexpire.callCount.should.equal(0)
  280. this.rclient.exec.callCount.should.equal(0)
  281. return done()
  282. })
  283. })
  284. it('should not call _checkSessions', function(done) {
  285. return this.call(err => {
  286. this._checkSessions.callCount.should.equal(0)
  287. return done()
  288. })
  289. })
  290. })
  291. describe('when no sessionId is supplied', function() {
  292. beforeEach(function() {
  293. return (this.call = callback => {
  294. return this.UserSessionsManager.untrackSession(
  295. this.user,
  296. null,
  297. callback
  298. )
  299. })
  300. })
  301. it('should not produce an error', function(done) {
  302. return this.call(err => {
  303. expect(err).to.not.be.instanceof(Error)
  304. expect(err).to.equal(null)
  305. return done()
  306. })
  307. })
  308. it('should not call the appropriate redis methods', function(done) {
  309. return this.call(err => {
  310. this.rclient.multi.callCount.should.equal(0)
  311. this.rclient.srem.callCount.should.equal(0)
  312. this.rclient.pexpire.callCount.should.equal(0)
  313. this.rclient.exec.callCount.should.equal(0)
  314. return done()
  315. })
  316. })
  317. it('should not call _checkSessions', function(done) {
  318. return this.call(err => {
  319. this._checkSessions.callCount.should.equal(0)
  320. return done()
  321. })
  322. })
  323. })
  324. })
  325. describe('revokeAllUserSessions', function() {
  326. beforeEach(function() {
  327. this.sessionKeys = ['sess:one', 'sess:two']
  328. this.retain = []
  329. this.rclient.smembers.callsArgWith(1, null, this.sessionKeys)
  330. this.rclient.del = sinon.stub().callsArgWith(1, null)
  331. this.rclient.srem = sinon.stub().callsArgWith(2, null)
  332. return (this.call = callback => {
  333. return this.UserSessionsManager.revokeAllUserSessions(
  334. this.user,
  335. this.retain,
  336. callback
  337. )
  338. })
  339. })
  340. it('should not produce an error', function(done) {
  341. return this.call(err => {
  342. expect(err).to.not.be.instanceof(Error)
  343. expect(err).to.equal(null)
  344. return done()
  345. })
  346. })
  347. it('should call the appropriate redis methods', function(done) {
  348. return this.call(err => {
  349. this.rclient.smembers.callCount.should.equal(1)
  350. this.rclient.del.callCount.should.equal(2)
  351. expect(this.rclient.del.firstCall.args[0]).to.deep.equal(
  352. this.sessionKeys[0]
  353. )
  354. expect(this.rclient.del.secondCall.args[0]).to.deep.equal(
  355. this.sessionKeys[1]
  356. )
  357. this.rclient.srem.callCount.should.equal(1)
  358. expect(this.rclient.srem.firstCall.args[1]).to.deep.equal(
  359. this.sessionKeys
  360. )
  361. return done()
  362. })
  363. })
  364. describe('when a session is retained', function() {
  365. beforeEach(function() {
  366. this.sessionKeys = ['sess:one', 'sess:two', 'sess:three', 'sess:four']
  367. this.retain = ['two']
  368. this.rclient.smembers.callsArgWith(1, null, this.sessionKeys)
  369. this.rclient.del = sinon.stub().callsArgWith(1, null)
  370. return (this.call = callback => {
  371. return this.UserSessionsManager.revokeAllUserSessions(
  372. this.user,
  373. this.retain,
  374. callback
  375. )
  376. })
  377. })
  378. it('should not produce an error', function(done) {
  379. return this.call(err => {
  380. expect(err).to.not.be.instanceof(Error)
  381. expect(err).to.equal(null)
  382. return done()
  383. })
  384. })
  385. it('should call the appropriate redis methods', function(done) {
  386. return this.call(err => {
  387. this.rclient.smembers.callCount.should.equal(1)
  388. this.rclient.del.callCount.should.equal(this.sessionKeys.length - 1)
  389. this.rclient.srem.callCount.should.equal(1)
  390. return done()
  391. })
  392. })
  393. it('should remove all sessions except for the retained one', function(done) {
  394. return this.call(err => {
  395. expect(this.rclient.del.firstCall.args[0]).to.deep.equal('sess:one')
  396. expect(this.rclient.del.secondCall.args[0]).to.deep.equal(
  397. 'sess:three'
  398. )
  399. expect(this.rclient.del.thirdCall.args[0]).to.deep.equal('sess:four')
  400. expect(this.rclient.srem.firstCall.args[1]).to.deep.equal([
  401. 'sess:one',
  402. 'sess:three',
  403. 'sess:four'
  404. ])
  405. return done()
  406. })
  407. })
  408. })
  409. describe('when rclient produces an error', function() {
  410. beforeEach(function() {
  411. return (this.rclient.del = sinon
  412. .stub()
  413. .callsArgWith(1, new Error('woops')))
  414. })
  415. it('should produce an error', function(done) {
  416. return this.call(err => {
  417. expect(err).to.be.instanceof(Error)
  418. return done()
  419. })
  420. })
  421. it('should not call rclient.srem', function(done) {
  422. return this.call(err => {
  423. this.rclient.srem.callCount.should.equal(0)
  424. return done()
  425. })
  426. })
  427. })
  428. describe('when no user is supplied', function() {
  429. beforeEach(function() {
  430. return (this.call = callback => {
  431. return this.UserSessionsManager.revokeAllUserSessions(
  432. null,
  433. this.retain,
  434. callback
  435. )
  436. })
  437. })
  438. it('should not produce an error', function(done) {
  439. return this.call(err => {
  440. expect(err).to.not.be.instanceof(Error)
  441. expect(err).to.equal(null)
  442. return done()
  443. })
  444. })
  445. it('should not call the appropriate redis methods', function(done) {
  446. return this.call(err => {
  447. this.rclient.smembers.callCount.should.equal(0)
  448. this.rclient.del.callCount.should.equal(0)
  449. this.rclient.srem.callCount.should.equal(0)
  450. return done()
  451. })
  452. })
  453. })
  454. describe('when there are no keys to delete', function() {
  455. beforeEach(function() {
  456. return this.rclient.smembers.callsArgWith(1, null, [])
  457. })
  458. it('should not produce an error', function(done) {
  459. return this.call(err => {
  460. expect(err).to.not.be.instanceof(Error)
  461. expect(err).to.equal(null)
  462. return done()
  463. })
  464. })
  465. it('should not do the delete operation', function(done) {
  466. return this.call(err => {
  467. this.rclient.smembers.callCount.should.equal(1)
  468. this.rclient.del.callCount.should.equal(0)
  469. this.rclient.srem.callCount.should.equal(0)
  470. return done()
  471. })
  472. })
  473. })
  474. })
  475. describe('touch', function() {
  476. beforeEach(function() {
  477. this.rclient.pexpire.callsArgWith(2, null)
  478. return (this.call = callback => {
  479. return this.UserSessionsManager.touch(this.user, callback)
  480. })
  481. })
  482. it('should not produce an error', function(done) {
  483. return this.call(err => {
  484. expect(err).to.not.be.instanceof(Error)
  485. expect(err).to.equal(null)
  486. return done()
  487. })
  488. })
  489. it('should call rclient.pexpire', function(done) {
  490. return this.call(err => {
  491. this.rclient.pexpire.callCount.should.equal(1)
  492. return done()
  493. })
  494. })
  495. describe('when rclient produces an error', function() {
  496. beforeEach(function() {
  497. return this.rclient.pexpire.callsArgWith(2, new Error('woops'))
  498. })
  499. it('should produce an error', function(done) {
  500. return this.call(err => {
  501. expect(err).to.be.instanceof(Error)
  502. return done()
  503. })
  504. })
  505. })
  506. describe('when no user is supplied', function() {
  507. beforeEach(function() {
  508. return (this.call = callback => {
  509. return this.UserSessionsManager.touch(null, callback)
  510. })
  511. })
  512. it('should not produce an error', function(done) {
  513. return this.call(err => {
  514. expect(err).to.not.be.instanceof(Error)
  515. expect(err).to.equal(null)
  516. return done()
  517. })
  518. })
  519. it('should not call pexpire', function(done) {
  520. return this.call(err => {
  521. this.rclient.pexpire.callCount.should.equal(0)
  522. return done()
  523. })
  524. })
  525. })
  526. })
  527. describe('getAllUserSessions', function() {
  528. beforeEach(function() {
  529. this.sessionKeys = ['sess:one', 'sess:two', 'sess:three']
  530. this.sessions = [
  531. '{"user": {"ip_address": "a", "session_created": "b"}}',
  532. '{"passport": {"user": {"ip_address": "c", "session_created": "d"}}}'
  533. ]
  534. this.exclude = ['two']
  535. this.rclient.smembers.callsArgWith(1, null, this.sessionKeys)
  536. this.rclient.get = sinon.stub()
  537. this.rclient.get.onCall(0).callsArgWith(1, null, this.sessions[0])
  538. this.rclient.get.onCall(1).callsArgWith(1, null, this.sessions[1])
  539. return (this.call = callback => {
  540. return this.UserSessionsManager.getAllUserSessions(
  541. this.user,
  542. this.exclude,
  543. callback
  544. )
  545. })
  546. })
  547. it('should not produce an error', function(done) {
  548. return this.call((err, sessions) => {
  549. expect(err).to.equal(null)
  550. return done()
  551. })
  552. })
  553. it('should get sessions', function(done) {
  554. return this.call((err, sessions) => {
  555. expect(sessions).to.deep.equal([
  556. { ip_address: 'a', session_created: 'b' },
  557. { ip_address: 'c', session_created: 'd' }
  558. ])
  559. return done()
  560. })
  561. })
  562. it('should have called rclient.smembers', function(done) {
  563. return this.call((err, sessions) => {
  564. this.rclient.smembers.callCount.should.equal(1)
  565. return done()
  566. })
  567. })
  568. it('should have called rclient.get', function(done) {
  569. return this.call((err, sessions) => {
  570. this.rclient.get.callCount.should.equal(this.sessionKeys.length - 1)
  571. return done()
  572. })
  573. })
  574. describe('when there are no other sessions', function() {
  575. beforeEach(function() {
  576. this.sessionKeys = ['sess:two']
  577. return this.rclient.smembers.callsArgWith(1, null, this.sessionKeys)
  578. })
  579. it('should not produce an error', function(done) {
  580. return this.call((err, sessions) => {
  581. expect(err).to.equal(null)
  582. return done()
  583. })
  584. })
  585. it('should produce an empty list of sessions', function(done) {
  586. return this.call((err, sessions) => {
  587. expect(sessions).to.deep.equal([])
  588. return done()
  589. })
  590. })
  591. it('should have called rclient.smembers', function(done) {
  592. return this.call((err, sessions) => {
  593. this.rclient.smembers.callCount.should.equal(1)
  594. return done()
  595. })
  596. })
  597. it('should not have called rclient.mget', function(done) {
  598. return this.call((err, sessions) => {
  599. this.rclient.mget.callCount.should.equal(0)
  600. return done()
  601. })
  602. })
  603. })
  604. describe('when smembers produces an error', function() {
  605. beforeEach(function() {
  606. return this.rclient.smembers.callsArgWith(1, new Error('woops'))
  607. })
  608. it('should produce an error', function(done) {
  609. return this.call((err, sessions) => {
  610. expect(err).to.not.equal(null)
  611. expect(err).to.be.instanceof(Error)
  612. return done()
  613. })
  614. })
  615. it('should not have called rclient.mget', function(done) {
  616. return this.call((err, sessions) => {
  617. this.rclient.mget.callCount.should.equal(0)
  618. return done()
  619. })
  620. })
  621. })
  622. describe('when get produces an error', function() {
  623. beforeEach(function() {
  624. return (this.rclient.get = sinon
  625. .stub()
  626. .callsArgWith(1, new Error('woops')))
  627. })
  628. it('should produce an error', function(done) {
  629. return this.call((err, sessions) => {
  630. expect(err).to.not.equal(null)
  631. expect(err).to.be.instanceof(Error)
  632. return done()
  633. })
  634. })
  635. })
  636. })
  637. describe('_checkSessions', function() {
  638. beforeEach(function() {
  639. this.call = callback => {
  640. return this.UserSessionsManager._checkSessions(this.user, callback)
  641. }
  642. this.sessionKeys = ['one', 'two']
  643. this.rclient.smembers.callsArgWith(1, null, this.sessionKeys)
  644. this.rclient.get.callsArgWith(1, null, 'some-value')
  645. return this.rclient.srem.callsArgWith(2, null, {})
  646. })
  647. it('should not produce an error', function(done) {
  648. return this.call(err => {
  649. expect(err).to.not.be.instanceof(Error)
  650. expect(err).to.equal(undefined)
  651. return done()
  652. })
  653. })
  654. it('should call the appropriate redis methods', function(done) {
  655. return this.call(err => {
  656. this.rclient.smembers.callCount.should.equal(1)
  657. this.rclient.get.callCount.should.equal(2)
  658. this.rclient.srem.callCount.should.equal(0)
  659. return done()
  660. })
  661. })
  662. describe('when one of the keys is not present in redis', function() {
  663. beforeEach(function() {
  664. this.rclient.get.onCall(0).callsArgWith(1, null, 'some-val')
  665. return this.rclient.get.onCall(1).callsArgWith(1, null, null)
  666. })
  667. it('should not produce an error', function(done) {
  668. return this.call(err => {
  669. expect(err).to.not.be.instanceof(Error)
  670. expect(err).to.equal(undefined)
  671. return done()
  672. })
  673. })
  674. it('should remove that key from the set', function(done) {
  675. return this.call(err => {
  676. this.rclient.smembers.callCount.should.equal(1)
  677. this.rclient.get.callCount.should.equal(2)
  678. this.rclient.srem.callCount.should.equal(1)
  679. this.rclient.srem.firstCall.args[1].should.equal('two')
  680. return done()
  681. })
  682. })
  683. })
  684. describe('when no user is supplied', function() {
  685. beforeEach(function() {
  686. return (this.call = callback => {
  687. return this.UserSessionsManager._checkSessions(null, callback)
  688. })
  689. })
  690. it('should not produce an error', function(done) {
  691. return this.call(err => {
  692. expect(err).to.not.be.instanceof(Error)
  693. expect(err).to.equal(null)
  694. return done()
  695. })
  696. })
  697. it('should not call redis methods', function(done) {
  698. return this.call(err => {
  699. this.rclient.smembers.callCount.should.equal(0)
  700. this.rclient.get.callCount.should.equal(0)
  701. return done()
  702. })
  703. })
  704. })
  705. describe('when one of the get operations produces an error', function() {
  706. beforeEach(function() {
  707. this.rclient.get.onCall(0).callsArgWith(1, new Error('woops'), null)
  708. return this.rclient.get.onCall(1).callsArgWith(1, null, null)
  709. })
  710. it('should produce an error', function(done) {
  711. return this.call(err => {
  712. expect(err).to.be.instanceof(Error)
  713. return done()
  714. })
  715. })
  716. it('should call the right redis methods, bailing out early', function(done) {
  717. return this.call(err => {
  718. this.rclient.smembers.callCount.should.equal(1)
  719. this.rclient.get.callCount.should.equal(1)
  720. this.rclient.srem.callCount.should.equal(0)
  721. return done()
  722. })
  723. })
  724. })
  725. })
  726. })