mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-13 21:53:43 +01:00
[document-updater] add track-changes support to setDoc (#35820)
GitOrigin-RevId: 5d39dd1945e710ec3f7068830fb2476e59f0f2a5
This commit is contained in:
@@ -282,6 +282,7 @@ describe('DocumentUpdaterHandler', function () {
|
||||
lines: ctx.lines,
|
||||
source: ctx.source,
|
||||
user_id: ctx.user_id,
|
||||
trackChanges: false,
|
||||
})
|
||||
.reply(204)
|
||||
})
|
||||
@@ -298,6 +299,31 @@ describe('DocumentUpdaterHandler', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('with track changes enabled', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.docUpdaterMock
|
||||
.post(`/project/${ctx.project_id}/doc/${ctx.doc_id}`, {
|
||||
lines: ctx.lines,
|
||||
source: ctx.source,
|
||||
user_id: ctx.user_id,
|
||||
trackChanges: true,
|
||||
})
|
||||
.reply(204)
|
||||
})
|
||||
|
||||
it('should forward the trackChanges flag', async function (ctx) {
|
||||
await ctx.handler.promises.setDocument(
|
||||
ctx.project_id,
|
||||
ctx.doc_id,
|
||||
ctx.user_id,
|
||||
ctx.lines,
|
||||
ctx.source,
|
||||
true
|
||||
)
|
||||
expect(ctx.docUpdaterMock.isDone()).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the document updater API returns an error', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.docUpdaterMock
|
||||
@@ -305,6 +331,7 @@ describe('DocumentUpdaterHandler', function () {
|
||||
lines: ctx.lines,
|
||||
source: ctx.source,
|
||||
user_id: ctx.user_id,
|
||||
trackChanges: false,
|
||||
})
|
||||
.replyWithError('boom')
|
||||
})
|
||||
@@ -329,6 +356,7 @@ describe('DocumentUpdaterHandler', function () {
|
||||
lines: ctx.lines,
|
||||
source: ctx.source,
|
||||
user_id: ctx.user_id,
|
||||
trackChanges: false,
|
||||
})
|
||||
.reply(500)
|
||||
})
|
||||
@@ -1603,6 +1631,7 @@ describe('DocumentUpdaterHandler', function () {
|
||||
lines: ctx.lines,
|
||||
source: ctx.source,
|
||||
user_id: ctx.user_id,
|
||||
trackChanges: false,
|
||||
})
|
||||
.reply(200)
|
||||
})
|
||||
@@ -1619,6 +1648,31 @@ describe('DocumentUpdaterHandler', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('with track changes enabled', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.docUpdaterMock
|
||||
.post(`/project/${ctx.project_id}/doc/${ctx.doc_id}/append`, {
|
||||
lines: ctx.lines,
|
||||
source: ctx.source,
|
||||
user_id: ctx.user_id,
|
||||
trackChanges: true,
|
||||
})
|
||||
.reply(200)
|
||||
})
|
||||
|
||||
it('should forward the trackChanges flag', async function (ctx) {
|
||||
await ctx.handler.promises.appendToDocument(
|
||||
ctx.project_id,
|
||||
ctx.doc_id,
|
||||
ctx.user_id,
|
||||
ctx.lines,
|
||||
ctx.source,
|
||||
true
|
||||
)
|
||||
expect(ctx.docUpdaterMock.isDone()).to.be.true
|
||||
})
|
||||
})
|
||||
|
||||
describe('when the document updater API returns an error', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.docUpdaterMock
|
||||
|
||||
@@ -112,6 +112,9 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
getProject: sinon.stub(),
|
||||
},
|
||||
}
|
||||
ctx.ProjectHelper = {
|
||||
isTrackChangesEnabledForUser: sinon.stub().returns(false),
|
||||
}
|
||||
ctx.ProjectLocator = {
|
||||
promises: {
|
||||
findElement: sinon.stub(),
|
||||
@@ -217,6 +220,10 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
default: ctx.ProjectGetter,
|
||||
}))
|
||||
|
||||
vi.doMock('../../../../app/src/Features/Project/ProjectHelper', () => ({
|
||||
default: ctx.ProjectHelper,
|
||||
}))
|
||||
|
||||
vi.doMock('../../../../app/src/Features/Project/ProjectLocator', () => ({
|
||||
default: ctx.ProjectLocator,
|
||||
}))
|
||||
@@ -838,6 +845,10 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
})
|
||||
|
||||
describe('upsertDoc', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.resolves(ctx.project)
|
||||
})
|
||||
|
||||
describe('upserting into an invalid folder', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.ProjectLocator.promises.findElement.resolves({ element: null })
|
||||
@@ -866,6 +877,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
describe('updating an existing doc', function () {
|
||||
let upsertDocResponse
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.project.track_changes = { 'some-user-id': true }
|
||||
ctx.existingDoc = { _id: docId, name: ctx.docName }
|
||||
ctx.existingFile = {
|
||||
_id: fileId,
|
||||
@@ -893,16 +905,32 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('gets the project with the track changes state', function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject
|
||||
.calledWith(projectId, {
|
||||
rootFolder: true,
|
||||
rootDoc_id: true,
|
||||
track_changes: true,
|
||||
})
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('tries to find the folder', function (ctx) {
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.calledWith({
|
||||
project_id: projectId,
|
||||
project: ctx.project,
|
||||
element_id: folderId,
|
||||
type: 'folder',
|
||||
})
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('resolves the track changes state for the user', function (ctx) {
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser
|
||||
.calledWith(ctx.project.track_changes, userId)
|
||||
.should.equal(true)
|
||||
})
|
||||
|
||||
it('updates the doc contents', function (ctx) {
|
||||
ctx.DocumentUpdaterHandler.promises.setDocument
|
||||
.calledWith(
|
||||
@@ -910,7 +938,8 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
ctx.existingDoc._id,
|
||||
userId,
|
||||
ctx.docLines,
|
||||
ctx.source
|
||||
ctx.source,
|
||||
false
|
||||
)
|
||||
.should.equal(true)
|
||||
})
|
||||
@@ -921,6 +950,44 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('updating an existing doc with track changes enabled for the user', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser.returns(true)
|
||||
ctx.existingDoc = { _id: docId, name: ctx.docName }
|
||||
ctx.folder = {
|
||||
_id: folderId,
|
||||
docs: [ctx.existingDoc],
|
||||
fileRefs: [],
|
||||
}
|
||||
ctx.ProjectLocator.promises.findElement.resolves({
|
||||
element: ctx.folder,
|
||||
})
|
||||
ctx.DocumentUpdaterHandler.promises.setDocument.resolves()
|
||||
|
||||
await ctx.ProjectEntityUpdateHandler.promises.upsertDoc(
|
||||
projectId,
|
||||
folderId,
|
||||
ctx.docName,
|
||||
ctx.docLines,
|
||||
ctx.source,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
it('updates the doc contents with track changes', function (ctx) {
|
||||
ctx.DocumentUpdaterHandler.promises.setDocument
|
||||
.calledWith(
|
||||
projectId,
|
||||
ctx.existingDoc._id,
|
||||
userId,
|
||||
ctx.docLines,
|
||||
ctx.source,
|
||||
true
|
||||
)
|
||||
.should.equal(true)
|
||||
})
|
||||
})
|
||||
|
||||
describe('creating a new doc', function () {
|
||||
let upsertDocResponse
|
||||
|
||||
@@ -948,7 +1015,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
it('tries to find the folder', function (ctx) {
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.calledWith({
|
||||
project_id: projectId,
|
||||
project: ctx.project,
|
||||
element_id: folderId,
|
||||
type: 'folder',
|
||||
})
|
||||
@@ -1019,7 +1086,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
ctx.filePath = '/path/to/folder/foo.tex'
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.withArgs({
|
||||
project_id: projectId,
|
||||
project: ctx.project,
|
||||
element_id: ctx.folder._id,
|
||||
type: 'folder',
|
||||
})
|
||||
@@ -3165,6 +3232,10 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
})
|
||||
|
||||
describe('appendToDoc', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.ProjectGetter.promises.getProject.resolves(ctx.project)
|
||||
})
|
||||
|
||||
describe('when document cannot be found', function () {
|
||||
let appendToDocPromise
|
||||
beforeEach(function (ctx) {
|
||||
@@ -3172,7 +3243,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
ctx.DocumentUpdaterHandler.promises.appendToDocument = sinon.stub()
|
||||
ctx.ProjectLocator.promises.findElement = sinon.stub()
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.withArgs({ project_id: projectId, element_id: docId, type: 'doc' })
|
||||
.withArgs({ project: ctx.project, element_id: docId, type: 'doc' })
|
||||
.rejects(new Errors.NotFoundError())
|
||||
appendToDocPromise =
|
||||
ctx.ProjectEntityUpdateHandler.promises.appendToDocWithPath(
|
||||
@@ -3214,6 +3285,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
describe('when document is found', function () {
|
||||
let appendToDocResult
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.project.track_changes = { 'some-user-id': true }
|
||||
ctx.appendedLines = ['5678', 'def']
|
||||
ctx.DocumentUpdaterHandler.promises.appendToDocument = sinon.stub()
|
||||
ctx.DocumentUpdaterHandler.promises.appendToDocument
|
||||
@@ -3221,7 +3293,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
.resolves({ rev: 1 })
|
||||
ctx.ProjectLocator.promises.findElement = sinon.stub()
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.withArgs({ project_id: projectId, element_id: docId, type: 'doc' })
|
||||
.withArgs({ project: ctx.project, element_id: docId, type: 'doc' })
|
||||
.resolves({ element: { _id: docId } })
|
||||
appendToDocResult =
|
||||
await ctx.ProjectEntityUpdateHandler.promises.appendToDocWithPath(
|
||||
@@ -3233,13 +3305,21 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
)
|
||||
})
|
||||
|
||||
it('should resolve the track changes state for the user', function (ctx) {
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser.should.have.been.calledWith(
|
||||
ctx.project.track_changes,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
it('should forward call to DocumentUpdaterHandler.appendToDocument', function (ctx) {
|
||||
ctx.DocumentUpdaterHandler.promises.appendToDocument.should.have.been.calledWith(
|
||||
projectId,
|
||||
docId,
|
||||
userId,
|
||||
ctx.appendedLines,
|
||||
ctx.source
|
||||
ctx.source,
|
||||
false
|
||||
)
|
||||
})
|
||||
|
||||
@@ -3248,6 +3328,38 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('when track changes is enabled for the user', function () {
|
||||
beforeEach(async function (ctx) {
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser.returns(true)
|
||||
ctx.appendedLines = ['5678', 'def']
|
||||
ctx.DocumentUpdaterHandler.promises.appendToDocument = sinon
|
||||
.stub()
|
||||
.resolves({ rev: 1 })
|
||||
ctx.ProjectLocator.promises.findElement = sinon.stub()
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.withArgs({ project: ctx.project, element_id: docId, type: 'doc' })
|
||||
.resolves({ element: { _id: docId } })
|
||||
await ctx.ProjectEntityUpdateHandler.promises.appendToDocWithPath(
|
||||
projectId,
|
||||
docId,
|
||||
ctx.appendedLines,
|
||||
ctx.source,
|
||||
userId
|
||||
)
|
||||
})
|
||||
|
||||
it('should forward the track changes flag', function (ctx) {
|
||||
ctx.DocumentUpdaterHandler.promises.appendToDocument.should.have.been.calledWith(
|
||||
projectId,
|
||||
docId,
|
||||
userId,
|
||||
ctx.appendedLines,
|
||||
ctx.source,
|
||||
true
|
||||
)
|
||||
})
|
||||
})
|
||||
|
||||
describe('when DocumentUpdater throws an error', function () {
|
||||
beforeEach(function (ctx) {
|
||||
ctx.appendedLines = ['5678', 'def']
|
||||
@@ -3257,7 +3369,7 @@ describe('ProjectEntityUpdateHandler', function () {
|
||||
)
|
||||
ctx.ProjectLocator.promises.findElement = sinon.stub()
|
||||
ctx.ProjectLocator.promises.findElement
|
||||
.withArgs({ project_id: projectId, element_id: docId, type: 'doc' })
|
||||
.withArgs({ project: ctx.project, element_id: docId, type: 'doc' })
|
||||
.resolves({ element: { _id: docId } })
|
||||
})
|
||||
|
||||
|
||||
@@ -133,6 +133,67 @@ describe('ProjectHelper', function () {
|
||||
})
|
||||
})
|
||||
|
||||
describe('isTrackChangesEnabledForUser', function () {
|
||||
const userId = '588f3ddae8ebc1bac07c9fa4'
|
||||
|
||||
it('returns true for the legacy on-for-everyone format', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(true, userId)
|
||||
).to.equal(true)
|
||||
})
|
||||
|
||||
it('returns true when enabled for the user', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(
|
||||
{ [userId]: true },
|
||||
userId
|
||||
)
|
||||
).to.equal(true)
|
||||
})
|
||||
|
||||
it('supports ObjectId user ids', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(
|
||||
{ [userId]: true },
|
||||
new ObjectId(userId)
|
||||
)
|
||||
).to.equal(true)
|
||||
})
|
||||
|
||||
it('returns false when only enabled for another user', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(
|
||||
{ '5c41deb2b4ca500153340809': true },
|
||||
userId
|
||||
)
|
||||
).to.equal(false)
|
||||
})
|
||||
|
||||
it('returns false when only enabled for guests', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(
|
||||
{ __guests__: true },
|
||||
userId
|
||||
)
|
||||
).to.equal(false)
|
||||
})
|
||||
|
||||
it('returns false when disabled', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(false, userId)
|
||||
).to.equal(false)
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser(undefined, userId)
|
||||
).to.equal(false)
|
||||
})
|
||||
|
||||
it('returns false without a user id', function (ctx) {
|
||||
expect(
|
||||
ctx.ProjectHelper.isTrackChangesEnabledForUser({ [userId]: true }, null)
|
||||
).to.equal(false)
|
||||
})
|
||||
})
|
||||
|
||||
describe('compilerFromV1Engine', function () {
|
||||
it('returns the correct engine for latex_dvipdf', function (ctx) {
|
||||
expect(ctx.ProjectHelper.compilerFromV1Engine('latex_dvipdf')).to.equal(
|
||||
|
||||
Reference in New Issue
Block a user