mirror of
https://github.com/yu-i-i/overleaf-cep.git
synced 2026-05-31 12:51:35 +02:00
[web] last infrastructure conversions GitOrigin-RevId: ad1aff9b7df0610ed0303157d9e2c8032f32c02b
226 lines
7.6 KiB
JavaScript
226 lines
7.6 KiB
JavaScript
import { exec } from 'node:child_process'
|
|
import { promisify } from 'node:util'
|
|
import { expect } from 'chai'
|
|
import logger from '@overleaf/logger'
|
|
import { filterOutput } from './helpers/settings.mjs'
|
|
import { db, ObjectId } from '../../../app/src/infrastructure/mongodb.mjs'
|
|
|
|
const DUMMY_NAME = 'unknown.tex'
|
|
const DUMMY_TIME = new Date('2021-04-12T00:00:00.000Z')
|
|
|
|
function getObjectIdFromDate(date) {
|
|
const seconds = new Date(date).getTime() / 1000
|
|
return ObjectId.createFromTime(seconds)
|
|
}
|
|
|
|
describe('BackFillDummyDocMeta', function () {
|
|
let docIds
|
|
let projectIds
|
|
beforeEach('create docs', async function () {
|
|
docIds = []
|
|
docIds[0] = getObjectIdFromDate('2021-04-01T00:00:00.000Z')
|
|
docIds[1] = getObjectIdFromDate('2021-04-02T00:00:00.000Z')
|
|
docIds[2] = getObjectIdFromDate('2021-04-11T00:00:00.000Z')
|
|
docIds[3] = getObjectIdFromDate('2021-04-12T00:00:00.000Z')
|
|
docIds[4] = getObjectIdFromDate('2021-04-13T00:00:00.000Z')
|
|
docIds[5] = getObjectIdFromDate('2021-04-14T00:00:00.000Z')
|
|
docIds[6] = getObjectIdFromDate('2021-04-15T00:00:00.000Z')
|
|
docIds[7] = getObjectIdFromDate('2021-04-16T00:01:00.000Z')
|
|
docIds[8] = getObjectIdFromDate('2021-04-16T00:02:00.000Z')
|
|
docIds[9] = getObjectIdFromDate('2021-04-16T00:03:00.000Z')
|
|
docIds[10] = getObjectIdFromDate('2021-04-16T00:04:00.000Z')
|
|
docIds[11] = getObjectIdFromDate('2021-04-16T00:05:00.000Z')
|
|
|
|
projectIds = []
|
|
projectIds[0] = getObjectIdFromDate('2021-04-01T00:00:00.000Z')
|
|
projectIds[1] = getObjectIdFromDate('2021-04-02T00:00:00.000Z')
|
|
projectIds[2] = getObjectIdFromDate('2021-04-11T00:00:00.000Z')
|
|
projectIds[3] = getObjectIdFromDate('2021-04-12T00:00:00.000Z')
|
|
projectIds[4] = getObjectIdFromDate('2021-04-13T00:00:00.000Z')
|
|
projectIds[5] = getObjectIdFromDate('2021-04-14T00:00:00.000Z')
|
|
projectIds[6] = getObjectIdFromDate('2021-04-15T00:00:00.000Z')
|
|
projectIds[7] = getObjectIdFromDate('2021-04-16T00:01:00.000Z')
|
|
projectIds[8] = getObjectIdFromDate('2021-04-16T00:02:00.000Z')
|
|
projectIds[9] = getObjectIdFromDate('2021-04-16T00:03:00.000Z')
|
|
// two docs in the same project
|
|
projectIds[10] = projectIds[9]
|
|
projectIds[11] = projectIds[4]
|
|
})
|
|
const now = new Date()
|
|
beforeEach('insert doc stubs into docs collection', async function () {
|
|
// don't look here, just drop duplicates from the list of projectIds :)
|
|
await db.projects.insertMany(
|
|
Array.from(new Set(projectIds.map(id => id.toString()))).map(_id => ({
|
|
_id: new ObjectId(_id),
|
|
}))
|
|
)
|
|
await db.docs.insertMany([
|
|
// incomplete, without deletedDocs context
|
|
{ _id: docIds[0], project_id: projectIds[0], deleted: true },
|
|
{ _id: docIds[1], project_id: projectIds[1], deleted: true },
|
|
{ _id: docIds[2], project_id: projectIds[2], deleted: true },
|
|
{ _id: docIds[3], project_id: projectIds[3], deleted: true },
|
|
// incomplete, with deletedDocs context
|
|
{ _id: docIds[4], project_id: projectIds[4], deleted: true },
|
|
// complete
|
|
{
|
|
_id: docIds[5],
|
|
project_id: projectIds[5],
|
|
deleted: true,
|
|
name: 'foo.tex',
|
|
deletedAt: now,
|
|
},
|
|
// not deleted
|
|
{ _id: docIds[6], project_id: projectIds[6] },
|
|
// multiple in a single batch
|
|
{ _id: docIds[7], project_id: projectIds[7], deleted: true },
|
|
{ _id: docIds[8], project_id: projectIds[8], deleted: true },
|
|
{ _id: docIds[9], project_id: projectIds[9], deleted: true },
|
|
// two docs in one project
|
|
{ _id: docIds[10], project_id: projectIds[10], deleted: true },
|
|
{ _id: docIds[11], project_id: projectIds[11], deleted: true },
|
|
])
|
|
})
|
|
beforeEach('insert deleted project context', async function () {
|
|
await db.deletedProjects.insertMany([
|
|
// projectIds[0] and projectIds[1] have no entry
|
|
|
|
// hard-deleted
|
|
{ deleterData: { deletedProjectId: projectIds[2] } },
|
|
// soft-deleted, no entry for doc
|
|
{
|
|
deleterData: { deletedProjectId: projectIds[3] },
|
|
project: { deletedDocs: [] },
|
|
},
|
|
// soft-deleted, has entry for doc
|
|
{
|
|
deleterData: { deletedProjectId: projectIds[4] },
|
|
project: {
|
|
deletedDocs: [
|
|
{ _id: docIds[4], name: 'main.tex', deletedAt: now },
|
|
{ _id: docIds[11], name: 'main.tex', deletedAt: now },
|
|
],
|
|
},
|
|
},
|
|
])
|
|
})
|
|
|
|
async function runScript() {
|
|
let result
|
|
try {
|
|
result = await promisify(exec)(
|
|
'cd ../../tools/migrations && east migrate -t saas --force 20210728115327_ce_sp_backfill_dummy_doc_meta'
|
|
)
|
|
} catch (error) {
|
|
// dump details like exit code, stdErr and stdOut
|
|
logger.error({ error }, 'script failed')
|
|
throw error
|
|
}
|
|
let { stdout: stdOut } = result
|
|
stdOut = stdOut.split('\n').filter(filterOutput)
|
|
|
|
expect(stdOut.filter(filterOutput)).to.include.members([
|
|
`Orphaned deleted doc ${docIds[0]} (no deletedProjects entry)`,
|
|
`Orphaned deleted doc ${docIds[1]} (no deletedProjects entry)`,
|
|
`Orphaned deleted doc ${docIds[2]} (failed hard deletion)`,
|
|
`Missing deletedDoc for ${docIds[3]}`,
|
|
`Found deletedDoc for ${docIds[4]}`,
|
|
`Found deletedDoc for ${docIds[11]}`,
|
|
`Orphaned deleted doc ${docIds[7]} (no deletedProjects entry)`,
|
|
`Orphaned deleted doc ${docIds[8]} (no deletedProjects entry)`,
|
|
`Orphaned deleted doc ${docIds[9]} (no deletedProjects entry)`,
|
|
`Orphaned deleted doc ${docIds[10]} (no deletedProjects entry)`,
|
|
])
|
|
}
|
|
|
|
describe('DRY_RUN=false', function () {
|
|
beforeEach('run script', async function () {
|
|
await runScript(false)
|
|
})
|
|
|
|
it('should back fill name and deletedAt dates into broken docs', async function () {
|
|
const docs = await db.docs.find({}).toArray()
|
|
expect(docs).to.deep.equal([
|
|
{
|
|
_id: docIds[0],
|
|
project_id: projectIds[0],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[1],
|
|
project_id: projectIds[1],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[2],
|
|
project_id: projectIds[2],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[3],
|
|
project_id: projectIds[3],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[4],
|
|
project_id: projectIds[4],
|
|
deleted: true,
|
|
name: 'main.tex',
|
|
deletedAt: now,
|
|
},
|
|
{
|
|
_id: docIds[5],
|
|
project_id: projectIds[5],
|
|
deleted: true,
|
|
name: 'foo.tex',
|
|
deletedAt: now,
|
|
},
|
|
{ _id: docIds[6], project_id: projectIds[6] },
|
|
{
|
|
_id: docIds[7],
|
|
project_id: projectIds[7],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[8],
|
|
project_id: projectIds[8],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[9],
|
|
project_id: projectIds[9],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[10],
|
|
project_id: projectIds[10],
|
|
deleted: true,
|
|
name: DUMMY_NAME,
|
|
deletedAt: DUMMY_TIME,
|
|
},
|
|
{
|
|
_id: docIds[11],
|
|
project_id: projectIds[11],
|
|
deleted: true,
|
|
name: 'main.tex',
|
|
deletedAt: now,
|
|
},
|
|
])
|
|
})
|
|
})
|
|
})
|