mirror of
https://github.com/overleaf/overleaf.git
synced 2024-11-21 20:47:08 -05:00
Merge pull request #6690 from overleaf/ta-max-dictionary-size
Add Dictionary Size Limit GitOrigin-RevId: f3b8be11de5a1480c8bc1a7fe26e9d67bd047757
This commit is contained in:
parent
01f63e810a
commit
1b4d675b0a
3 changed files with 95 additions and 32 deletions
|
@ -3,21 +3,32 @@ const logger = require('@overleaf/logger')
|
|||
const metrics = require('@overleaf/metrics')
|
||||
const { promisify } = require('util')
|
||||
const OError = require('@overleaf/o-error')
|
||||
const Settings = require('@overleaf/settings')
|
||||
const { InvalidError } = require('../Errors/Errors')
|
||||
|
||||
const LearnedWordsManager = {
|
||||
learnWord(userToken, word, callback) {
|
||||
return db.spellingPreferences.updateOne(
|
||||
{
|
||||
token: userToken,
|
||||
},
|
||||
{
|
||||
$addToSet: { learnedWords: word },
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
},
|
||||
callback
|
||||
)
|
||||
LearnedWordsManager.getLearnedWordsSize(userToken, (error, wordsSize) => {
|
||||
if (error != null) {
|
||||
return callback(OError.tag(error))
|
||||
}
|
||||
const wordSize = Buffer.from(word).length
|
||||
if (wordsSize + wordSize > Settings.maxDictionarySize) {
|
||||
return callback(new InvalidError('Max dictionary size reached'))
|
||||
}
|
||||
db.spellingPreferences.updateOne(
|
||||
{
|
||||
token: userToken,
|
||||
},
|
||||
{
|
||||
$addToSet: { learnedWords: word },
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
},
|
||||
callback
|
||||
)
|
||||
})
|
||||
},
|
||||
|
||||
unlearnWord(userToken, word, callback) {
|
||||
|
@ -52,6 +63,20 @@ const LearnedWordsManager = {
|
|||
)
|
||||
},
|
||||
|
||||
getLearnedWordsSize(userToken, callback) {
|
||||
db.spellingPreferences.findOne(
|
||||
{ token: userToken },
|
||||
function (error, preferences) {
|
||||
if (error != null) {
|
||||
return callback(OError.tag(error))
|
||||
}
|
||||
const words = (preferences && preferences.learnedWords) || []
|
||||
const wordsSize = Buffer.from(JSON.stringify(words)).length
|
||||
callback(null, wordsSize)
|
||||
}
|
||||
)
|
||||
},
|
||||
|
||||
deleteUsersLearnedWords(userToken, callback) {
|
||||
db.spellingPreferences.deleteOne({ token: userToken }, callback)
|
||||
},
|
||||
|
|
|
@ -423,6 +423,8 @@ module.exports = {
|
|||
'zh-CN': '简体中文',
|
||||
},
|
||||
|
||||
maxDictionarySize: 1024 * 1024, // 1 MB
|
||||
|
||||
// Password Settings
|
||||
// -----------
|
||||
// These restrict the passwords users can use when registering
|
||||
|
|
|
@ -5,6 +5,7 @@ const modulePath = require('path').join(
|
|||
__dirname,
|
||||
'/../../../../app/src/Features/Spelling/LearnedWordsManager'
|
||||
)
|
||||
const { InvalidError } = require('../../../../app/src/Features/Errors/Errors')
|
||||
|
||||
describe('LearnedWordsManager', function () {
|
||||
beforeEach(function () {
|
||||
|
@ -13,6 +14,7 @@ describe('LearnedWordsManager', function () {
|
|||
this.db = {
|
||||
spellingPreferences: {
|
||||
updateOne: sinon.stub().yields(),
|
||||
findOne: sinon.stub().yields(null, ['pear']),
|
||||
},
|
||||
}
|
||||
this.LearnedWordsManager = SandboxedModule.require(modulePath, {
|
||||
|
@ -22,34 +24,56 @@ describe('LearnedWordsManager', function () {
|
|||
timeAsyncMethod: sinon.stub(),
|
||||
inc: sinon.stub(),
|
||||
},
|
||||
'@overleaf/settings': {
|
||||
maxDictionarySize: 20,
|
||||
},
|
||||
},
|
||||
})
|
||||
})
|
||||
|
||||
describe('learnWord', function () {
|
||||
beforeEach(function () {
|
||||
this.word = 'instanton'
|
||||
this.LearnedWordsManager.learnWord(this.token, this.word, this.callback)
|
||||
describe('under size limit', function () {
|
||||
beforeEach(function () {
|
||||
this.word = 'instanton'
|
||||
this.LearnedWordsManager.learnWord(this.token, this.word, this.callback)
|
||||
})
|
||||
|
||||
it('should insert the word in the word list in the database', function () {
|
||||
expect(
|
||||
this.db.spellingPreferences.updateOne.calledWith(
|
||||
{
|
||||
token: this.token,
|
||||
},
|
||||
{
|
||||
$addToSet: { learnedWords: this.word },
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
}
|
||||
)
|
||||
).to.equal(true)
|
||||
})
|
||||
|
||||
it('should call the callback without error', function () {
|
||||
sinon.assert.called(this.callback)
|
||||
expect(this.callback.lastCall.args.length).to.equal(0)
|
||||
})
|
||||
})
|
||||
|
||||
it('should insert the word in the word list in the database', function () {
|
||||
expect(
|
||||
this.db.spellingPreferences.updateOne.calledWith(
|
||||
{
|
||||
token: this.token,
|
||||
},
|
||||
{
|
||||
$addToSet: { learnedWords: this.word },
|
||||
},
|
||||
{
|
||||
upsert: true,
|
||||
}
|
||||
)
|
||||
).to.equal(true)
|
||||
})
|
||||
describe('over size limit', function () {
|
||||
beforeEach(function () {
|
||||
this.word = 'superlongwordthatwillgobeyondthelimit'
|
||||
this.LearnedWordsManager.learnWord(this.token, this.word, this.callback)
|
||||
})
|
||||
|
||||
it('should call the callback', function () {
|
||||
expect(this.callback.called).to.equal(true)
|
||||
it('should not insert the word in the word list in the database', function () {
|
||||
expect(this.db.spellingPreferences.updateOne.notCalled).to.equal(true)
|
||||
})
|
||||
|
||||
it('should call the callback with error', function () {
|
||||
sinon.assert.called(this.callback)
|
||||
expect(this.callback.lastCall.args[0]).to.be.instanceof(InvalidError)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
|
@ -100,6 +124,18 @@ describe('LearnedWordsManager', function () {
|
|||
})
|
||||
})
|
||||
|
||||
describe('getLearnedWordsSize', function () {
|
||||
it('should return the word list size in the callback', function () {
|
||||
this.db.spellingPreferences.findOne = (conditions, callback) => {
|
||||
callback(null, {
|
||||
learnedWords: ['apples', 'bananas', 'pears', 'bananas'],
|
||||
})
|
||||
}
|
||||
this.LearnedWordsManager.getLearnedWordsSize(this.token, this.callback)
|
||||
sinon.assert.calledWith(this.callback, null, 38)
|
||||
})
|
||||
})
|
||||
|
||||
describe('deleteUsersLearnedWords', function () {
|
||||
beforeEach(function () {
|
||||
this.db.spellingPreferences.deleteOne = sinon.stub().callsArgWith(1)
|
||||
|
|
Loading…
Reference in a new issue