Просмотр исходного кода

Merge pull request #11593 from overleaf/bg-create-project-with-random-history

extend the create_project script to include history

GitOrigin-RevId: 74084731d72337eecd933a31212000f64026df8b
Brian Gough 3 лет назад
Родитель
Сommit
f996c95165
1 измененных файлов с 106 добавлено и 2 удалено
  1. 106 2
      services/web/scripts/create_project.js

+ 106 - 2
services/web/scripts/create_project.js

@@ -4,17 +4,19 @@
 
 const fs = require('fs')
 const path = require('path')
-const _ = require('underscore')
+const _ = require('lodash')
 const parseArgs = require('minimist')
 const OError = require('@overleaf/o-error')
 const { waitForDb } = require('../app/src/infrastructure/mongodb')
 const { User } = require('../app/src/models/User')
 const ProjectCreationHandler = require('../app/src/Features/Project/ProjectCreationHandler')
 const ProjectEntityUpdateHandler = require('../app/src/Features/Project/ProjectEntityUpdateHandler')
+const ProjectEntityHandler = require('../app/src/Features/Project/ProjectEntityHandler')
+const EditorController = require('../app/src/Features/Editor/EditorController')
 
 const argv = parseArgs(process.argv.slice(2), {
   string: ['user-id', 'name'],
-  boolean: ['old-history'],
+  boolean: ['old-history', 'random-content'],
   unknown: function (arg) {
     console.error('unrecognised argument', arg)
     process.exit(1)
@@ -26,6 +28,7 @@ console.log('argv', argv)
 const userId = argv['user-id']
 const projectName = argv.name || `Test Project ${new Date().toISOString()}`
 const oldHistory = argv['old-history']
+const randomContent = argv['random-content']
 
 console.log('userId', userId)
 
@@ -100,6 +103,102 @@ async function _buildTemplate(templateName, userId, projectName) {
   return output.split('\n')
 }
 
+// Create a project with some random content and file operations for testing history migrations
+// Unfortunately we cannot easily change the timestamps of the history entries, so everything
+// will be created at the same time.
+
+async function _pickRandomDoc(project) {
+  const result = await ProjectEntityHandler.promises.getAllDocs(project._id)
+  const keys = Object.keys(result)
+  if (keys.length === 0) {
+    return null
+  }
+  const filepath = _.sample(keys)
+  result[filepath].path = filepath
+  return result[filepath]
+}
+
+let COUNTER = 0
+// format counter as a 6 digit zero padded number
+function nextId() {
+  return ('000000' + COUNTER++).slice(-6)
+}
+
+async function _applyRandomDocUpdate(ownerId, project) {
+  const action = _.sample(['create', 'edit', 'delete', 'rename'])
+  switch (action) {
+    case 'create': // create a new doc
+      await EditorController.promises.upsertDocWithPath(
+        project._id,
+        `subdir/new-doc-${nextId()}.tex`,
+        [`This is a new doc ${new Date().toISOString()}`],
+        'create-project-script',
+        ownerId
+      )
+      break
+    case 'edit': {
+      // edit an existing doc
+      const doc = await _pickRandomDoc(project)
+      if (!doc) {
+        return
+      }
+      // pick a random line and either insert or delete a character
+      const lines = doc.lines
+      const index = _.random(0, lines.length - 1)
+      let thisLine = lines[index]
+      const pos = _.random(0, thisLine.length - 1)
+      if (Math.random() > 0.5) {
+        // insert a character
+        thisLine = thisLine.slice(0, pos) + 'x' + thisLine.slice(pos)
+      } else {
+        // delete a character
+        thisLine = thisLine.slice(0, pos) + thisLine.slice(pos + 1)
+      }
+      lines[index] = thisLine
+      await EditorController.promises.upsertDocWithPath(
+        project._id,
+        doc.path,
+        lines,
+        'create-project-script',
+        ownerId
+      )
+      break
+    }
+    case 'delete': {
+      // delete an existing doc (but not the root doc)
+      const doc = await _pickRandomDoc(project)
+      if (!doc || doc.path === '/main.tex') {
+        return
+      }
+
+      await EditorController.promises.deleteEntityWithPath(
+        project._id,
+        doc.path,
+        ownerId,
+        'create-project-script'
+      )
+      break
+    }
+    case 'rename': {
+      // rename an existing doc (but not the root doc)
+      const doc = await _pickRandomDoc(project)
+      if (!doc || doc.path === '/main.tex') {
+        return
+      }
+      const newName = `renamed-${nextId()}.tex`
+      await EditorController.promises.renameEntity(
+        project._id,
+        doc._id,
+        'doc',
+        newName,
+        ownerId,
+        'create-project-script'
+      )
+      break
+    }
+  }
+}
+
 async function createProject() {
   await waitForDb()
   const user = await User.findById(userId)
@@ -113,6 +212,11 @@ async function createProject() {
     attributes
   )
   await _addDefaultExampleProjectFiles(userId, projectName, project)
+  if (randomContent) {
+    for (let i = 0; i < 1000; i++) {
+      await _applyRandomDocUpdate(userId, project)
+    }
+  }
   return project
 }