mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-11-12 13:13:45 +01:00
[ranges-tracker] add legacy orderedRejections field in tracked-changes (#36565)
* [docstore] use more realistic test stubs for ranges * [monorepo] define ranges schemas in @overleaf/ranges-tracker * [ranges-tracker] add legacy orderedRejections field in tracked-changes * [monorepo] resolve @overleaf/ranges-tracker subpath imports in typescript * [real-time] validate comment thread ids and tracked change id seeds * [ranges-tracker] require ObjectId ids and tracked change metadata in ranges * [monorepo] require ObjectId tracked change ids on the accept routes * [web] use ObjectId comment thread ids in the DocumentController tests GitOrigin-RevId: 58b20dec311d85b917ef63f9efbe745a265a2de6
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import AbstractMockApi from './AbstractMockApi.mjs'
|
||||
import { parseReq, z, zz } from '@overleaf/validation-tools'
|
||||
import editorCoreSchemas from 'overleaf-editor-core/lib/schemas.js'
|
||||
import rangesSchemas from '@overleaf/ranges-tracker/schemas.js'
|
||||
|
||||
const docParamsSchema = z.strictObject({
|
||||
projectId: zz.objectId(),
|
||||
@@ -26,48 +27,6 @@ const setDocSchema = z.object({
|
||||
}),
|
||||
})
|
||||
|
||||
// Ranges data as document-updater persists it (RangesTracker format) --
|
||||
// mirrors services/document-updater/app/js/schemas.js's `ranges` export
|
||||
// (this mock stands in for document-updater's own API in web's acceptance
|
||||
// tests).
|
||||
const insertOp = z.strictObject({
|
||||
i: z.string(),
|
||||
p: z.number().int().min(0),
|
||||
u: z.boolean().optional(),
|
||||
fixedRemoveChange: z.boolean().optional(),
|
||||
})
|
||||
const deleteOp = z.strictObject({
|
||||
d: z.string(),
|
||||
p: z.number().int().min(0),
|
||||
u: z.boolean().optional(),
|
||||
fixedRemoveChange: z.boolean().optional(),
|
||||
})
|
||||
const commentOp = z.strictObject({
|
||||
c: z.string(),
|
||||
p: z.number().int().min(0),
|
||||
t: zz.objectId().optional(),
|
||||
u: z.boolean().optional(),
|
||||
resolved: z.boolean().optional(),
|
||||
})
|
||||
const rangeMetadata = z.strictObject({
|
||||
user_id: z.string(),
|
||||
ts: z.string(),
|
||||
})
|
||||
const comment = z.strictObject({
|
||||
id: zz.objectId().optional(),
|
||||
op: commentOp,
|
||||
metadata: rangeMetadata.optional(),
|
||||
})
|
||||
const trackedChange = z.strictObject({
|
||||
id: z.string().optional(),
|
||||
op: insertOp.or(deleteOp),
|
||||
metadata: rangeMetadata,
|
||||
})
|
||||
const rangesSchema = z.strictObject({
|
||||
comments: z.array(comment).optional(),
|
||||
changes: z.array(trackedChange).optional(),
|
||||
})
|
||||
|
||||
// Mirrors services/document-updater/app/js/HttpController.js's
|
||||
// updateProjectSchema (renameUpdateSchema/addUpdateSchema) -- this mock's
|
||||
// own routes use :projectId/:docId casing rather than document-updater's
|
||||
@@ -85,7 +44,7 @@ const addUpdateSchema = z.strictObject({
|
||||
id: zz.objectId(),
|
||||
pathname: zz.safePath(),
|
||||
docLines: z.string().optional(),
|
||||
ranges: rangesSchema.optional(),
|
||||
ranges: rangesSchemas.ranges.optional(),
|
||||
historyRangesSupport: z.boolean().optional(),
|
||||
// legacy filestore url for files without a created blob
|
||||
url: z.string().nullish(),
|
||||
|
||||
@@ -1,46 +1,7 @@
|
||||
import { db, ObjectId } from '../../../../app/src/infrastructure/mongodb.mjs'
|
||||
import AbstractMockApi from './AbstractMockApi.mjs'
|
||||
import { parseReq, z, zz } from '@overleaf/validation-tools'
|
||||
|
||||
// Mirrors services/docstore/app/js/schemas.js (this mock stands in for
|
||||
// docstore's own API in web's acceptance tests).
|
||||
const insertOp = z.strictObject({
|
||||
i: z.string(),
|
||||
p: z.number().int().min(0),
|
||||
u: z.boolean().optional(),
|
||||
fixedRemoveChange: z.boolean().optional(),
|
||||
})
|
||||
const deleteOp = z.strictObject({
|
||||
d: z.string(),
|
||||
p: z.number().int().min(0),
|
||||
u: z.boolean().optional(),
|
||||
fixedRemoveChange: z.boolean().optional(),
|
||||
})
|
||||
const commentOp = z.strictObject({
|
||||
c: z.string().optional(),
|
||||
p: z.number().int().min(0).optional(),
|
||||
t: z.string().optional(),
|
||||
u: z.boolean().optional(),
|
||||
resolved: z.boolean().optional(),
|
||||
})
|
||||
const rangeMetadata = z.strictObject({
|
||||
user_id: z.string().optional(),
|
||||
ts: z.string().optional(),
|
||||
})
|
||||
const comment = z.strictObject({
|
||||
id: z.string().optional(),
|
||||
op: commentOp,
|
||||
metadata: rangeMetadata.optional(),
|
||||
})
|
||||
const trackedChange = z.strictObject({
|
||||
id: z.string().optional(),
|
||||
op: insertOp.or(deleteOp).optional(),
|
||||
metadata: rangeMetadata.optional(),
|
||||
})
|
||||
const rangesSchema = z.strictObject({
|
||||
comments: z.array(comment).optional(),
|
||||
changes: z.array(trackedChange).optional(),
|
||||
})
|
||||
import rangesSchemas from '@overleaf/ranges-tracker/schemas.js'
|
||||
|
||||
const docParamsSchema = z.strictObject({
|
||||
projectId: zz.objectId(),
|
||||
@@ -52,7 +13,7 @@ const updateDocSchema = z.object({
|
||||
body: z.strictObject({
|
||||
lines: z.array(z.string()),
|
||||
version: z.number(),
|
||||
ranges: rangesSchema,
|
||||
ranges: rangesSchemas.ranges,
|
||||
}),
|
||||
})
|
||||
|
||||
|
||||
@@ -15,22 +15,24 @@ describe('DocumentController', function () {
|
||||
ctx.doc = { _id: '5c9a5d5b0000000000000002' }
|
||||
ctx.doc_lines = ['one', 'two', 'three']
|
||||
ctx.version = 42
|
||||
ctx.threadId1 = '5c9a5d5b0000000000000011'
|
||||
ctx.threadId2 = '5c9a5d5b0000000000000012'
|
||||
ctx.ranges = {
|
||||
comments: [
|
||||
{
|
||||
id: 'comment1',
|
||||
id: ctx.threadId1,
|
||||
op: {
|
||||
c: 'foo',
|
||||
p: 123,
|
||||
t: 'comment1',
|
||||
t: ctx.threadId1,
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'comment2',
|
||||
id: ctx.threadId2,
|
||||
op: {
|
||||
c: 'bar',
|
||||
p: 456,
|
||||
t: 'comment2',
|
||||
t: ctx.threadId2,
|
||||
},
|
||||
},
|
||||
],
|
||||
@@ -53,8 +55,8 @@ describe('DocumentController', function () {
|
||||
},
|
||||
}
|
||||
ctx.resolvedThreadIds = [
|
||||
'comment2',
|
||||
'comment4', // Comment in project but not in doc
|
||||
ctx.threadId2,
|
||||
'5c9a5d5b0000000000000014', // Comment in project but not in doc
|
||||
]
|
||||
|
||||
ctx.ProjectGetter = {
|
||||
@@ -159,7 +161,7 @@ describe('DocumentController', function () {
|
||||
pathname: ctx.pathname,
|
||||
projectHistoryId: ctx.project.overleaf.history.id,
|
||||
projectHistoryType: 'project-history',
|
||||
resolvedCommentIds: ['comment2'],
|
||||
resolvedCommentIds: [ctx.threadId2],
|
||||
historyRangesSupport: false,
|
||||
otMigrationStage: 0,
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user