2019-07-03 08:41:01 -04:00
|
|
|
const sinon = require('sinon')
|
2021-03-19 16:04:30 -04:00
|
|
|
const { assert, expect } = require('chai')
|
2019-07-03 08:41:01 -04:00
|
|
|
const SandboxedModule = require('sandboxed-module')
|
|
|
|
const modulePath = require('path').join(
|
|
|
|
__dirname,
|
|
|
|
'../../../app/js/LearnedWordsManager'
|
|
|
|
)
|
2021-03-19 16:04:30 -04:00
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
describe('LearnedWordsManager', function () {
|
|
|
|
beforeEach(function () {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.token = 'a6b3cd919ge'
|
|
|
|
this.callback = sinon.stub()
|
|
|
|
this.db = {
|
|
|
|
spellingPreferences: {
|
2021-07-13 07:04:47 -04:00
|
|
|
updateOne: sinon.stub().yields(),
|
|
|
|
},
|
2019-07-03 08:41:01 -04:00
|
|
|
}
|
|
|
|
this.cache = {
|
|
|
|
get: sinon.stub(),
|
|
|
|
set: sinon.stub(),
|
2021-07-13 07:04:47 -04:00
|
|
|
del: sinon.stub(),
|
2019-07-03 08:41:01 -04:00
|
|
|
}
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager = SandboxedModule.require(modulePath, {
|
2019-07-03 08:41:01 -04:00
|
|
|
requires: {
|
2020-09-03 12:05:13 -04:00
|
|
|
'./mongodb': { db: this.db },
|
2019-07-03 08:41:01 -04:00
|
|
|
'./MongoCache': this.cache,
|
2020-11-25 06:57:24 -05:00
|
|
|
'@overleaf/metrics': {
|
2019-07-03 08:41:01 -04:00
|
|
|
timeAsyncMethod: sinon.stub(),
|
2021-07-13 07:04:47 -04:00
|
|
|
inc: sinon.stub(),
|
|
|
|
},
|
|
|
|
},
|
2019-07-22 07:14:30 -04:00
|
|
|
})
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
describe('learnWord', function () {
|
|
|
|
beforeEach(function () {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.word = 'instanton'
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.learnWord(this.token, this.word, this.callback)
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should insert the word in the word list in the database', function () {
|
2019-07-22 07:14:30 -04:00
|
|
|
expect(
|
2020-09-03 12:05:13 -04:00
|
|
|
this.db.spellingPreferences.updateOne.calledWith(
|
2019-07-03 08:41:01 -04:00
|
|
|
{
|
2021-07-13 07:04:47 -04:00
|
|
|
token: this.token,
|
2019-07-03 08:41:01 -04:00
|
|
|
},
|
|
|
|
{
|
2021-07-13 07:04:47 -04:00
|
|
|
$addToSet: { learnedWords: this.word },
|
2019-07-03 08:41:01 -04:00
|
|
|
},
|
|
|
|
{
|
2021-07-13 07:04:47 -04:00
|
|
|
upsert: true,
|
2019-07-03 08:41:01 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
).to.equal(true)
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should call the callback', function () {
|
2019-07-22 07:14:30 -04:00
|
|
|
expect(this.callback.called).to.equal(true)
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
describe('unlearnWord', function () {
|
|
|
|
beforeEach(function () {
|
2019-07-20 09:04:08 -04:00
|
|
|
this.word = 'instanton'
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.unlearnWord(this.token, this.word, this.callback)
|
2019-07-20 09:04:08 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should remove the word from the word list in the database', function () {
|
2019-07-22 07:14:30 -04:00
|
|
|
expect(
|
2020-09-03 12:05:13 -04:00
|
|
|
this.db.spellingPreferences.updateOne.calledWith(
|
2019-07-20 09:04:08 -04:00
|
|
|
{
|
2021-07-13 07:04:47 -04:00
|
|
|
token: this.token,
|
2019-07-20 09:04:08 -04:00
|
|
|
},
|
|
|
|
{
|
2021-07-13 07:04:47 -04:00
|
|
|
$pull: { learnedWords: this.word },
|
2019-07-20 09:04:08 -04:00
|
|
|
}
|
|
|
|
)
|
|
|
|
).to.equal(true)
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should call the callback', function () {
|
2019-07-22 07:14:30 -04:00
|
|
|
expect(this.callback.called).to.equal(true)
|
2019-07-20 09:04:08 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
describe('getLearnedWords', function () {
|
|
|
|
beforeEach(function () {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.wordList = ['apples', 'bananas', 'pears']
|
2020-02-18 10:58:03 -05:00
|
|
|
this.wordListWithDuplicates = this.wordList.slice()
|
|
|
|
this.wordListWithDuplicates.push('bananas')
|
2019-07-03 08:41:01 -04:00
|
|
|
this.db.spellingPreferences.findOne = (conditions, callback) => {
|
2020-02-18 10:58:03 -05:00
|
|
|
callback(null, { learnedWords: this.wordListWithDuplicates })
|
2019-07-03 08:41:01 -04:00
|
|
|
}
|
|
|
|
sinon.spy(this.db.spellingPreferences, 'findOne')
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.getLearnedWords(this.token, this.callback)
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should get the word list for the given user', function () {
|
2019-07-22 07:14:30 -04:00
|
|
|
expect(
|
2019-07-03 08:41:01 -04:00
|
|
|
this.db.spellingPreferences.findOne.calledWith({ token: this.token })
|
|
|
|
).to.equal(true)
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should return the word list in the callback without duplicates', function () {
|
2019-07-22 07:14:30 -04:00
|
|
|
expect(this.callback.calledWith(null, this.wordList)).to.equal(true)
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
describe('caching the result', function () {
|
|
|
|
it('should use the cache first if it is primed', function (done) {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.wordList = ['apples', 'bananas', 'pears']
|
|
|
|
this.cache.get.returns(this.wordList)
|
|
|
|
this.db.spellingPreferences.findOne = sinon.stub()
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.getLearnedWords(this.token, (err, spellings) => {
|
|
|
|
expect(err).not.to.exist
|
|
|
|
this.db.spellingPreferences.findOne.called.should.equal(false)
|
|
|
|
assert.deepEqual(this.wordList, spellings)
|
|
|
|
done()
|
|
|
|
})
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should set the cache after hitting the db', function (done) {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.wordList = ['apples', 'bananas', 'pears']
|
|
|
|
this.db.spellingPreferences.findOne = sinon
|
|
|
|
.stub()
|
|
|
|
.callsArgWith(1, null, { learnedWords: this.wordList })
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.getLearnedWords(this.token, () => {
|
|
|
|
this.cache.set.calledWith(this.token, this.wordList).should.equal(true)
|
|
|
|
done()
|
|
|
|
})
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should break cache when update is called', function (done) {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.word = 'instanton'
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.learnWord(this.token, this.word, () => {
|
2019-07-03 08:41:01 -04:00
|
|
|
this.cache.del.calledWith(this.token).should.equal(true)
|
2019-07-22 07:14:30 -04:00
|
|
|
done()
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
describe('deleteUsersLearnedWords', function () {
|
|
|
|
beforeEach(function () {
|
2020-09-03 12:05:13 -04:00
|
|
|
this.db.spellingPreferences.deleteOne = sinon.stub().callsArgWith(1)
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
|
2020-08-10 12:23:15 -04:00
|
|
|
it('should get the word list for the given user', function (done) {
|
2019-07-22 07:14:30 -04:00
|
|
|
this.LearnedWordsManager.deleteUsersLearnedWords(this.token, () => {
|
2020-09-03 12:05:13 -04:00
|
|
|
this.db.spellingPreferences.deleteOne
|
2019-07-22 07:14:30 -04:00
|
|
|
.calledWith({ token: this.token })
|
|
|
|
.should.equal(true)
|
|
|
|
done()
|
|
|
|
})
|
2019-07-03 08:41:01 -04:00
|
|
|
})
|
|
|
|
})
|
|
|
|
})
|