Merge pull request #14413 from overleaf/gs-kustomize-tpref

Add Kustomization for third-party-references

GitOrigin-RevId: 5e9508e0f66df6b462fb49786b0941d52c2eb1f4
This commit is contained in:
Gernot Schulz 2023-08-31 09:54:08 +02:00 committed by Copybot
parent 2d9db134a2
commit 1a7b0f0414
7 changed files with 1867 additions and 0 deletions

View file

@ -0,0 +1 @@
module.exports = {}

View file

@ -0,0 +1,7 @@
const base = require(process.env.BASE_CONFIG)
module.exports = base.mergeWith({
test: {
counterInit: 190000,
},
})

View file

@ -0,0 +1,347 @@
/* eslint-disable
max-len,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const { expect } = require('chai')
const _ = require('lodash')
const {
db,
ObjectId,
} = require('../../../../../app/src/infrastructure/mongodb')
const User = require('../../../../../test/acceptance/src/helpers/User')
const MockV1HistoryApiClass = require('../../../../../test/acceptance/src/mocks/MockV1HistoryApi')
let MockV1HistoryApi
before(function () {
MockV1HistoryApi = MockV1HistoryApiClass.instance()
})
describe('History', function () {
beforeEach(function (done) {
this.owner = new User()
return this.owner.login(done)
})
describe('zip download of version', function () {
it('should stream the zip file of a version', function (done) {
return this.owner.createProject('example-project', (error, projectId) => {
this.project_id = projectId
if (error != null) {
return done(error)
}
this.v1_history_id = 42
return db.projects.updateOne(
{
_id: ObjectId(this.project_id),
},
{
$set: {
'overleaf.history.id': this.v1_history_id,
},
},
error => {
if (error != null) {
return done(error)
}
return this.owner.request(
`/project/${this.project_id}/version/42/zip`,
(error, response, body) => {
if (error != null) {
return done(error)
}
expect(response.statusCode).to.equal(200)
expect(response.headers['content-type']).to.equal(
'application/zip'
)
expect(response.headers['content-disposition']).to.equal(
'attachment; filename="example-project (Version 42).zip"'
)
expect(body).to.equal(
`Mock zip for ${this.v1_history_id} at version 42`
)
return done()
}
)
}
)
})
})
describe('request abort', function () {
// Optional manual verification: add unique logging statements into
// HistoryController._pipeHistoryZipToResponse
// in each of the `req.destroyed` branches and confirm that each branch
// was covered.
beforeEach(function setupNewProject(done) {
this.owner.createProject('example-project', (error, projectId) => {
this.project_id = projectId
if (error) {
return done(error)
}
this.v1_history_id = 42
db.projects.updateOne(
{ _id: ObjectId(this.project_id) },
{
$set: {
'overleaf.history.id': this.v1_history_id,
},
},
done
)
})
})
it('should abort the upstream request', function (done) {
const request = this.owner.request(
`/project/${this.project_id}/version/100/zip`
)
request.on('error', err => {
if (err.code !== 'ECONNRESET') {
done(err)
}
})
request.on('response', response => {
expect(response.statusCode).to.equal(200)
let receivedChunks = 0
response.on('data', () => {
receivedChunks++
})
response.resume()
setTimeout(() => {
request.abort()
const receivedSoFar = receivedChunks
const sentSoFar = MockV1HistoryApi.sentChunks
// Ihe next assertions should verify that chunks are emitted
// and received -- the exact number is not important.
// In theory we are now emitting the 3rd chunk,
// so this should be exactly 3, to not make this
// test flaky, we allow +- 2 chunks.
expect(sentSoFar).to.be.within(1, 4)
expect(receivedSoFar).to.be.within(1, 4)
setTimeout(() => {
// The fake-s3 service should have stopped emitting chunks.
// If not, that would be +5 in an ideal world (1 every 100ms).
// On the happy-path (it stopped) it emitted +1 which was
// in-flight and another +1 before it received the abort.
expect(MockV1HistoryApi.sentChunks).to.be.below(sentSoFar + 5)
expect(MockV1HistoryApi.sentChunks).to.be.within(
sentSoFar,
sentSoFar + 2
)
done()
}, 500)
}, 200)
})
})
it('should skip the v1-history request', function (done) {
const request = this.owner.request(
`/project/${this.project_id}/version/100/zip`
)
setTimeout(() => {
// This is a race-condition to abort the request after the
// processing of all the the express middleware completed.
// In case we abort before they complete, we do not hit our
// abort logic, but express internal logic, which is OK.
request.abort()
}, 2)
request.on('error', done)
setTimeout(() => {
expect(MockV1HistoryApi.requestedZipPacks).to.equal(0)
done()
}, 500)
})
it('should skip the async-polling', function (done) {
const request = this.owner.request(
`/project/${this.project_id}/version/100/zip`
)
MockV1HistoryApi.events.on('v1-history-pack-zip', () => {
request.abort()
})
request.on('error', done)
setTimeout(() => {
expect(MockV1HistoryApi.fakeZipCall).to.equal(0)
done()
}, 3000) // initial polling delay is 2s
})
it('should skip the upstream request', function (done) {
const request = this.owner.request(
`/project/${this.project_id}/version/100/zip`
)
MockV1HistoryApi.events.on('v1-history-pack-zip', () => {
setTimeout(() => {
request.abort()
}, 1000)
})
request.on('error', done)
setTimeout(() => {
expect(MockV1HistoryApi.fakeZipCall).to.equal(0)
done()
}, 3000) // initial polling delay is 2s
})
})
it('should return 402 for non-v2-history project', function (done) {
return this.owner.createProject('non-v2-project', (error, projectId) => {
this.project_id = projectId
if (error != null) {
return done(error)
}
return db.projects.updateOne(
{
_id: ObjectId(this.project_id),
},
{
$unset: {
'overleaf.history.id': true,
},
},
error => {
if (error != null) {
return done(error)
}
return this.owner.request(
`/project/${this.project_id}/version/42/zip`,
(error, response, body) => {
if (error != null) {
return done(error)
}
expect(response.statusCode).to.equal(402)
return done()
}
)
}
)
})
})
})
describe('zip download, with upstream 404', function () {
beforeEach(function () {
_.remove(
MockV1HistoryApi.app._router.stack,
appRoute =>
(appRoute.route != null ? appRoute.route.path : undefined) ===
'/api/projects/:project_id/version/:version/zip'
)
MockV1HistoryApi.app.post(
'/api/projects/:project_id/version/:version/zip',
(req, res, next) => {
res.sendStatus(404)
}
)
})
afterEach(function () {
MockV1HistoryApi = MockV1HistoryApiClass.instance()
MockV1HistoryApi.reset()
MockV1HistoryApi.applyRoutes()
})
it('should produce 404 when post request produces 404', function (done) {
this.owner.createProject('example-project', (error, projectId) => {
if (error) {
return done(error)
}
this.project_id = projectId
this.v1_history_id = 42
return db.projects.updateOne(
{
_id: ObjectId(this.project_id),
},
{
$set: {
'overleaf.history.id': this.v1_history_id,
},
},
error => {
if (error) {
return done(error)
}
this.owner.request(
`/project/${this.project_id}/version/42/zip`,
(error, response, body) => {
if (error != null) {
return done(error)
}
expect(response.statusCode).to.equal(404)
return done()
}
)
}
)
})
})
})
describe('zip download, with no zipUrl from upstream', function () {
beforeEach(function () {
_.remove(
MockV1HistoryApi.app._router.stack,
appRoute =>
(appRoute.route != null ? appRoute.route.path : undefined) ===
'/api/projects/:project_id/version/:version/zip'
)
MockV1HistoryApi.app.post(
'/api/projects/:project_id/version/:version/zip',
(req, res, next) => {
res.json({ message: 'lol' })
}
)
})
afterEach(function () {
MockV1HistoryApi = MockV1HistoryApiClass.instance()
MockV1HistoryApi.reset()
MockV1HistoryApi.applyRoutes()
})
it('should produce 404 when post request produces 404', function (done) {
this.owner.createProject('example-project', (error, projectId) => {
if (error) {
return done(error)
}
this.project_id = projectId
this.v1_history_id = 42
return db.projects.updateOne(
{
_id: ObjectId(this.project_id),
},
{
$set: {
'overleaf.history.id': this.v1_history_id,
},
},
error => {
if (error) {
return done(error)
}
this.owner.request(
`/project/${this.project_id}/version/42/zip`,
(error, response, body) => {
if (error != null) {
return done(error)
}
expect(response.statusCode).to.equal(500)
return done()
}
)
}
)
})
})
})
})

View file

@ -0,0 +1,23 @@
require('../../../../../test/acceptance/src/helpers/InitApp')
const MockDocstoreApi = require('../../../../../test/acceptance/src/mocks/MockDocstoreApi')
const MockDocUpdaterApi = require('../../../../../test/acceptance/src/mocks/MockDocUpdaterApi')
const MockFilestoreApi = require('../../../../../test/acceptance/src/mocks/MockFilestoreApi')
const MockNotificationsApi = require('../../../../../test/acceptance/src/mocks/MockNotificationsApi')
const MockProjectHistoryApi = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi')
const MockSpellingApi = require('../../../../../test/acceptance/src/mocks/MockSpellingApi')
const MockV1Api = require('../../../../../test/acceptance/src/mocks/MockV1Api')
const MockV1HistoryApi = require('../../../../../test/acceptance/src/mocks/MockV1HistoryApi')
const mockOpts = {
debug: ['1', 'true', 'TRUE'].includes(process.env.DEBUG_MOCKS),
}
MockDocstoreApi.initialize(23016, mockOpts)
MockDocUpdaterApi.initialize(23003, mockOpts)
MockFilestoreApi.initialize(23009, mockOpts)
MockNotificationsApi.initialize(23042, mockOpts)
MockProjectHistoryApi.initialize(23054, mockOpts)
MockSpellingApi.initialize(23005, mockOpts)
MockV1Api.initialize(25000, mockOpts)
MockV1HistoryApi.initialize(23100, mockOpts)

View file

@ -0,0 +1,126 @@
/* eslint-disable
max-len,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const _ = require('underscore')
const { expect } = require('chai')
const { ObjectId } = require('mongodb')
const User = require('../../../../../test/acceptance/src/helpers/User')
const MockProjectHistoryApiClass = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi')
let MockProjectHistoryApi
before(function () {
MockProjectHistoryApi = MockProjectHistoryApiClass.instance()
})
describe('Labels', function () {
beforeEach(function (done) {
this.owner = new User()
return this.owner.login(error => {
if (error != null) {
throw error
}
return this.owner.createProject(
'example-project',
{ template: 'example' },
(error, projectId) => {
this.project_id = projectId
if (error != null) {
throw error
}
return done()
}
)
})
})
it('getting labels', function (done) {
const labelId = new ObjectId().toString()
const comment = 'a label comment'
const version = 3
MockProjectHistoryApi.addLabel(this.project_id, {
id: labelId,
comment,
version,
})
return this.owner.request(
{
method: 'GET',
url: `/project/${this.project_id}/labels`,
json: true,
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
expect(body).to.deep.equal([{ id: labelId, comment, version }])
return done()
}
)
})
it('creating a label', function (done) {
const comment = 'a label comment'
const version = 3
return this.owner.request(
{
method: 'POST',
url: `/project/${this.project_id}/labels`,
json: { comment, version },
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
const { label_id: labelId } = body
expect(MockProjectHistoryApi.getLabels(this.project_id)).to.deep.equal([
{ id: labelId, comment, version },
])
return done()
}
)
})
it('deleting a label', function (done) {
const labelId = new ObjectId().toString()
const comment = 'a label comment'
const version = 3
MockProjectHistoryApi.addLabel(this.project_id, {
id: labelId,
comment,
version,
})
return this.owner.request(
{
method: 'DELETE',
url: `/project/${this.project_id}/labels/${labelId}`,
json: true,
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(204)
expect(MockProjectHistoryApi.getLabels(this.project_id)).to.deep.equal(
[]
)
return done()
}
)
})
})

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,292 @@
/* eslint-disable
max-len,
no-unused-vars,
*/
// TODO: This file was created by bulk-decaffeinate.
// Fix any style issues and re-enable lint.
/*
* decaffeinate suggestions:
* DS102: Remove unnecessary code created because of implicit returns
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const { expect } = require('chai')
const _ = require('underscore')
const fs = require('fs')
const Path = require('path')
const User = require('../../../../../test/acceptance/src/helpers/User')
const MockProjectHistoryApiClass = require('../../../../../test/acceptance/src/mocks/MockProjectHistoryApi')
const MockDocstoreApiClass = require('../../../../../test/acceptance/src/mocks/MockDocstoreApi')
const MockFilestoreApiClass = require('../../../../../test/acceptance/src/mocks/MockFilestoreApi')
let MockProjectHistoryApi, MockDocstoreApi, MockFilestoreApi
before(function () {
MockProjectHistoryApi = MockProjectHistoryApiClass.instance()
MockDocstoreApi = MockDocstoreApiClass.instance()
MockFilestoreApi = MockFilestoreApiClass.instance()
})
describe('RestoringFiles', function () {
beforeEach(function (done) {
this.owner = new User()
return this.owner.login(error => {
if (error != null) {
throw error
}
return this.owner.createProject(
'example-project',
{ template: 'example' },
(error, projectId) => {
this.project_id = projectId
if (error != null) {
throw error
}
return done()
}
)
})
})
describe('restoring from v2 history', function () {
describe('restoring a text file', function () {
beforeEach(function (done) {
MockProjectHistoryApi.addOldFile(
this.project_id,
42,
'foo.tex',
'hello world, this is foo.tex!'
)
return this.owner.request(
{
method: 'POST',
url: `/project/${this.project_id}/restore_file`,
json: {
pathname: 'foo.tex',
version: 42,
},
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
return done()
}
)
})
it('should have created a doc', function (done) {
return this.owner.getProject(this.project_id, (error, project) => {
if (error != null) {
throw error
}
let doc = _.find(
project.rootFolder[0].docs,
doc => doc.name === 'foo.tex'
)
doc = MockDocstoreApi.docs[this.project_id][doc._id]
expect(doc.lines).to.deep.equal(['hello world, this is foo.tex!'])
return done()
})
})
})
describe('restoring a binary file', function () {
beforeEach(function (done) {
this.pngData = fs.readFileSync(
Path.resolve(
__dirname,
'../../../../../test/acceptance/files/1pixel.png'
),
'binary'
)
MockProjectHistoryApi.addOldFile(
this.project_id,
42,
'image.png',
this.pngData
)
return this.owner.request(
{
method: 'POST',
url: `/project/${this.project_id}/restore_file`,
json: {
pathname: 'image.png',
version: 42,
},
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
return done()
}
)
})
it('should have created a file', function (done) {
return this.owner.getProject(this.project_id, (error, project) => {
if (error != null) {
throw error
}
let file = _.find(
project.rootFolder[0].fileRefs,
file => file.name === 'image.png'
)
file = MockFilestoreApi.files[this.project_id][file._id]
expect(file.content).to.equal(this.pngData)
return done()
})
})
})
describe('restoring to a directory that exists', function () {
beforeEach(function (done) {
MockProjectHistoryApi.addOldFile(
this.project_id,
42,
'foldername/foo2.tex',
'hello world, this is foo-2.tex!'
)
return this.owner.request.post(
{
uri: `project/${this.project_id}/folder`,
json: {
name: 'foldername',
},
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
return this.owner.request(
{
method: 'POST',
url: `/project/${this.project_id}/restore_file`,
json: {
pathname: 'foldername/foo2.tex',
version: 42,
},
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
return done()
}
)
}
)
})
it('should have created the doc in the named folder', function (done) {
return this.owner.getProject(this.project_id, (error, project) => {
if (error != null) {
throw error
}
const folder = _.find(
project.rootFolder[0].folders,
folder => folder.name === 'foldername'
)
let doc = _.find(folder.docs, doc => doc.name === 'foo2.tex')
doc = MockDocstoreApi.docs[this.project_id][doc._id]
expect(doc.lines).to.deep.equal(['hello world, this is foo-2.tex!'])
return done()
})
})
})
describe('restoring to a directory that no longer exists', function () {
beforeEach(function (done) {
MockProjectHistoryApi.addOldFile(
this.project_id,
42,
'nothere/foo3.tex',
'hello world, this is foo-3.tex!'
)
return this.owner.request(
{
method: 'POST',
url: `/project/${this.project_id}/restore_file`,
json: {
pathname: 'nothere/foo3.tex',
version: 42,
},
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
return done()
}
)
})
it('should have created the folder and restored the doc to it', function (done) {
return this.owner.getProject(this.project_id, (error, project) => {
if (error != null) {
throw error
}
const folder = _.find(
project.rootFolder[0].folders,
folder => folder.name === 'nothere'
)
expect(folder).to.exist
let doc = _.find(folder.docs, doc => doc.name === 'foo3.tex')
doc = MockDocstoreApi.docs[this.project_id][doc._id]
expect(doc.lines).to.deep.equal(['hello world, this is foo-3.tex!'])
return done()
})
})
})
describe('restoring to a filename that already exists', function () {
beforeEach(function (done) {
MockProjectHistoryApi.addOldFile(
this.project_id,
42,
'main.tex',
'hello world, this is main.tex!'
)
return this.owner.request(
{
method: 'POST',
url: `/project/${this.project_id}/restore_file`,
json: {
pathname: 'main.tex',
version: 42,
},
},
(error, response, body) => {
if (error != null) {
throw error
}
expect(response.statusCode).to.equal(200)
return done()
}
)
})
it('should have created the doc in the root folder', function (done) {
return this.owner.getProject(this.project_id, (error, project) => {
if (error != null) {
throw error
}
let doc = _.find(project.rootFolder[0].docs, doc =>
doc.name.match(/main \(Restored on/)
)
expect(doc).to.exist
doc = MockDocstoreApi.docs[this.project_id][doc._id]
expect(doc.lines).to.deep.equal(['hello world, this is main.tex!'])
return done()
})
})
})
})
})