LearnedWordsManagerTests.js 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. const sinon = require('sinon')
  2. const chai = require('chai')
  3. const { expect } = chai
  4. const SandboxedModule = require('sandboxed-module')
  5. const modulePath = require('path').join(
  6. __dirname,
  7. '../../../app/js/LearnedWordsManager'
  8. )
  9. const { assert } = require('chai')
  10. describe('LearnedWordsManager', function() {
  11. beforeEach(function() {
  12. this.token = 'a6b3cd919ge'
  13. this.callback = sinon.stub()
  14. this.db = {
  15. spellingPreferences: {
  16. update: sinon.stub().yields()
  17. }
  18. }
  19. this.cache = {
  20. get: sinon.stub(),
  21. set: sinon.stub(),
  22. del: sinon.stub()
  23. }
  24. this.LearnedWordsManager = SandboxedModule.require(modulePath, {
  25. requires: {
  26. './DB': this.db,
  27. './MongoCache': this.cache,
  28. 'logger-sharelatex': {
  29. log() {},
  30. err() {},
  31. info() {}
  32. },
  33. 'metrics-sharelatex': {
  34. timeAsyncMethod: sinon.stub(),
  35. inc: sinon.stub()
  36. }
  37. }
  38. })
  39. })
  40. describe('learnWord', function() {
  41. beforeEach(function() {
  42. this.word = 'instanton'
  43. this.LearnedWordsManager.learnWord(this.token, this.word, this.callback)
  44. })
  45. it('should insert the word in the word list in the database', function() {
  46. expect(
  47. this.db.spellingPreferences.update.calledWith(
  48. {
  49. token: this.token
  50. },
  51. {
  52. $push: { learnedWords: this.word }
  53. },
  54. {
  55. upsert: true
  56. }
  57. )
  58. ).to.equal(true)
  59. })
  60. it('should call the callback', function() {
  61. expect(this.callback.called).to.equal(true)
  62. })
  63. })
  64. describe('unlearnWord', function() {
  65. beforeEach(function() {
  66. this.word = 'instanton'
  67. this.LearnedWordsManager.unlearnWord(this.token, this.word, this.callback)
  68. })
  69. it('should remove the word from the word list in the database', function() {
  70. expect(
  71. this.db.spellingPreferences.update.calledWith(
  72. {
  73. token: this.token
  74. },
  75. {
  76. $pull: { learnedWords: this.word }
  77. }
  78. )
  79. ).to.equal(true)
  80. })
  81. it('should call the callback', function() {
  82. expect(this.callback.called).to.equal(true)
  83. })
  84. })
  85. describe('getLearnedWords', function() {
  86. beforeEach(function() {
  87. this.wordList = ['apples', 'bananas', 'pears']
  88. this.db.spellingPreferences.findOne = (conditions, callback) => {
  89. callback(null, { learnedWords: this.wordList })
  90. }
  91. sinon.spy(this.db.spellingPreferences, 'findOne')
  92. this.LearnedWordsManager.getLearnedWords(this.token, this.callback)
  93. })
  94. it('should get the word list for the given user', function() {
  95. expect(
  96. this.db.spellingPreferences.findOne.calledWith({ token: this.token })
  97. ).to.equal(true)
  98. })
  99. it('should return the word list in the callback', function() {
  100. expect(this.callback.calledWith(null, this.wordList)).to.equal(true)
  101. })
  102. })
  103. describe('caching the result', function() {
  104. it('should use the cache first if it is primed', function(done) {
  105. this.wordList = ['apples', 'bananas', 'pears']
  106. this.cache.get.returns(this.wordList)
  107. this.db.spellingPreferences.findOne = sinon.stub()
  108. this.LearnedWordsManager.getLearnedWords(this.token, (err, spellings) => {
  109. expect(err).not.to.exist
  110. this.db.spellingPreferences.findOne.called.should.equal(false)
  111. assert.deepEqual(this.wordList, spellings)
  112. done()
  113. })
  114. })
  115. it('should set the cache after hitting the db', function(done) {
  116. this.wordList = ['apples', 'bananas', 'pears']
  117. this.db.spellingPreferences.findOne = sinon
  118. .stub()
  119. .callsArgWith(1, null, { learnedWords: this.wordList })
  120. this.LearnedWordsManager.getLearnedWords(this.token, () => {
  121. this.cache.set.calledWith(this.token, this.wordList).should.equal(true)
  122. done()
  123. })
  124. })
  125. it('should break cache when update is called', function(done) {
  126. this.word = 'instanton'
  127. this.LearnedWordsManager.learnWord(this.token, this.word, () => {
  128. this.cache.del.calledWith(this.token).should.equal(true)
  129. done()
  130. })
  131. })
  132. })
  133. describe('deleteUsersLearnedWords', function() {
  134. beforeEach(function() {
  135. this.db.spellingPreferences.remove = sinon.stub().callsArgWith(1)
  136. })
  137. it('should get the word list for the given user', function(done) {
  138. this.LearnedWordsManager.deleteUsersLearnedWords(this.token, () => {
  139. this.db.spellingPreferences.remove
  140. .calledWith({ token: this.token })
  141. .should.equal(true)
  142. done()
  143. })
  144. })
  145. })
  146. })