Migrating reference settings to mongo and exposing them through code … (#31726)

* Migrating reference settings to mongo and exposing them through code mirror context

* removing undefined optional for reference manager type settings

* allowing partial updates to user settings objects, and remove repeated cypress intercepts

* Zod schema parsing for user reference manager settings

* Splitting ref provider mongoose schema into const

* Persisting local storage reference settings to mongo and deleting from local

* Enforcing ref provider group id to always be type string

* Fixing test and format errors

* Migrated flag for settings to only migrate once

* fixing cypress tests adding migrated flag

* persisting local storage to allow for easy rollback

GitOrigin-RevId: f59522bdee6f0e56efb7d98b9d9373a743619ec8
This commit is contained in:
l-obrien-overleaf
2026-03-26 09:07:40 +00:00
committed by Copybot
parent 03c30a9d1b
commit 27e5044d30
9 changed files with 368 additions and 0 deletions
@@ -565,6 +565,126 @@ describe('UserController', function () {
})
})
it('should set zotero settings object', function (ctx) {
return new Promise(resolve => {
ctx.req.body = {
zotero: {
enabled: false,
groups: [{ id: '123' }],
disablePersonalLibrary: true,
},
}
ctx.res.sendStatus = code => {
ctx.user.ace.zotero.enabled.should.equal(false)
ctx.user.ace.zotero.groups.should.deep.equal([{ id: '123' }])
ctx.user.ace.zotero.disablePersonalLibrary.should.equal(true)
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should set zotero settings with partial update', function (ctx) {
return new Promise(resolve => {
ctx.user.ace.zotero = {
enabled: true,
groups: [{ id: 'existing' }],
disablePersonalLibrary: false,
}
ctx.req.body = {
zotero: { enabled: false },
}
ctx.res.sendStatus = code => {
ctx.user.ace.zotero.enabled.should.equal(false)
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should set mendeley settings object', function (ctx) {
return new Promise(resolve => {
ctx.req.body = {
mendeley: {
enabled: false,
groups: [{ id: 'group-456' }],
disablePersonalLibrary: true,
},
}
ctx.res.sendStatus = code => {
ctx.user.ace.mendeley.enabled.should.equal(false)
ctx.user.ace.mendeley.groups.should.deep.equal([{ id: 'group-456' }])
ctx.user.ace.mendeley.disablePersonalLibrary.should.equal(true)
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should set mendeley with multiple groups', function (ctx) {
return new Promise(resolve => {
ctx.req.body = {
mendeley: {
enabled: true,
groups: [{ id: 'group-1' }, { id: 'group-2' }, { id: 'group-3' }],
disablePersonalLibrary: false,
},
}
ctx.res.sendStatus = code => {
ctx.user.ace.mendeley.groups.should.have.length(3)
ctx.user.ace.mendeley.groups[0].id.should.equal('group-1')
ctx.user.ace.mendeley.groups[1].id.should.equal('group-2')
ctx.user.ace.mendeley.groups[2].id.should.equal('group-3')
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should set papers settings object', function (ctx) {
return new Promise(resolve => {
ctx.req.body = {
papers: {
enabled: true,
groups: [],
disablePersonalLibrary: false,
},
}
ctx.res.sendStatus = code => {
ctx.user.ace.papers.enabled.should.equal(true)
ctx.user.ace.papers.groups.should.deep.equal([])
ctx.user.ace.papers.disablePersonalLibrary.should.equal(false)
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should allow setting only papers disablePersonalLibrary', function (ctx) {
return new Promise(resolve => {
ctx.req.body = {
papers: { disablePersonalLibrary: true },
}
ctx.res.sendStatus = code => {
ctx.user.ace.papers.disablePersonalLibrary.should.equal(true)
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should handle undefined mendeley by not setting it', function (ctx) {
return new Promise(resolve => {
ctx.user.ace.mendeley = { enabled: true, groups: [] }
ctx.req.body = { mendeley: undefined }
ctx.res.sendStatus = code => {
ctx.user.ace.mendeley.enabled.should.equal(true)
resolve()
}
ctx.UserController.updateUserSettings(ctx.req, ctx.res)
})
})
it('should send an error if the email is 0 len', function (ctx) {
return new Promise(resolve => {
ctx.req.body.email = ''