UserSessionsManagerTests.js 23 KB

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