first commit

This commit is contained in:
2025-04-24 13:11:28 +08:00
commit ff9c54d5e4
5960 changed files with 834111 additions and 0 deletions

View File

@@ -0,0 +1,38 @@
/* eslint-disable
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
*/
let MockClient
const sinon = require('sinon')
let idCounter = 0
module.exports = MockClient = class MockClient {
constructor() {
this.attributes = {}
this.join = sinon.stub()
this.emit = sinon.stub()
this.disconnect = sinon.stub()
this.id = idCounter++
}
set(key, value, callback) {
this.attributes[key] = value
if (callback != null) {
return callback()
}
}
get(key, callback) {
return callback(null, this.attributes[key])
}
disconnect() {}
}

View File

@@ -0,0 +1,39 @@
const SandboxedModule = require('sandboxed-module')
const mongoose = require('mongoose')
/**
* Imports a model as we would usually do with e.g. `require('models/User')`
* an returns a model an schema, but without connecting to Mongo. This allows
* us to use model classes in tests, and to use them with `sinon-mongoose`
*
* @param modelName the name of the model - e.g. 'User'
* @param requires additional `requires` to be passed to SanboxedModule in
* the event that these also need to be stubbed. For example,
* additional dependent models to be included
*
* @return model and schema pair - e.g. { User, UserSchema }
*/
module.exports = (modelName, requires = {}) => {
const model = {}
requires['../infrastructure/Mongoose'] = {
createConnection: () => {
return {
model: () => {},
}
},
model: (modelName, schema) => {
model[modelName + 'Schema'] = schema
model[modelName] = mongoose.model(modelName, schema)
},
Schema: mongoose.Schema,
Types: mongoose.Types,
}
SandboxedModule.require('../../../../app/src/models/' + modelName, {
requires,
})
return model
}

View File

@@ -0,0 +1,32 @@
const sinon = require('sinon')
class MockRequest {
constructor() {
this.session = { destroy() {} }
this.ip = '42.42.42.42'
this.headers = {}
this.params = {}
this.query = {}
this.body = {}
this._parsedUrl = {}
this.i18n = {
translate(str) {
return str
},
}
this.route = { path: '' }
this.accepts = () => {}
this.setHeader = () => {}
this.logger = {
addFields: sinon.stub(),
setLevel: sinon.stub(),
}
}
param(param) {
return this.params[param]
}
}
module.exports = MockRequest

View File

@@ -0,0 +1,187 @@
/* eslint-disable
no-return-assign,
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
* DS206: Consider reworking classes to avoid initClass
* DS207: Consider shorter variations of null checks
* Full docs: https://github.com/decaffeinate/decaffeinate/blob/master/docs/suggestions.md
*/
const sinon = require('sinon')
const Path = require('path')
const contentDisposition = require('content-disposition')
class MockResponse {
static initClass() {
// Added via ExpressLocals.
this.prototype.setContentDisposition = sinon.stub() // FIXME: should be reset between each test
}
constructor() {
this.rendered = false
this.redirected = false
this.returned = false
this.headers = {}
this.locals = {}
sinon.spy(this, 'contentType')
sinon.spy(this, 'header')
sinon.spy(this, 'json')
sinon.spy(this, 'send')
sinon.spy(this, 'sendStatus')
sinon.spy(this, 'status')
sinon.spy(this, 'render')
sinon.spy(this, 'redirect')
}
header(field, val) {
this.headers[field] = val
}
render(template, variables) {
this.success = true
this.rendered = true
this.returned = true
this.renderedTemplate = template
this.renderedVariables = variables
if (this.callback != null) {
return this.callback()
}
}
redirect(url) {
this.success = true
this.redirected = true
this.returned = true
this.redirectedTo = url
if (this.callback != null) {
return this.callback()
}
}
sendStatus(status) {
if (arguments.length < 2) {
if (typeof status !== 'number') {
status = 200
}
}
this.statusCode = status
this.returned = true
if (status >= 200 && status < 300) {
this.success = true
} else {
this.success = false
}
if (this.callback != null) {
return this.callback()
}
}
writeHead(status) {
this.statusCode = status
}
send(status, body) {
if (arguments.length < 2) {
if (typeof status !== 'number') {
body = status
status = this.statusCode || 200
}
}
this.statusCode = status
this.returned = true
if (status >= 200 && status < 300) {
this.success = true
} else {
this.success = false
}
if (body) {
this.body = body
}
if (this.callback != null) {
return this.callback()
}
}
json(status, body) {
if (arguments.length < 2) {
if (typeof status !== 'number') {
body = status
status = this.statusCode || 200
}
}
this.statusCode = status
this.returned = true
this.contentType('application/json')
if (status >= 200 && status < 300) {
this.success = true
} else {
this.success = false
}
if (body) {
this.body = JSON.stringify(body)
}
if (this.callback != null) {
return this.callback()
}
}
status(status) {
this.statusCode = status
return this
}
setHeader(header, value) {
this.header(header, value)
}
appendHeader(header, value) {
if (this.headers[header]) {
this.headers[header] += `, ${value}`
} else {
this.headers[header] = value
}
}
setTimeout(timout) {
this.timout = timout
}
end(data, encoding) {
if (this.callback) {
return this.callback()
}
}
attachment(filename) {
switch (Path.extname(filename)) {
case '.csv':
this.contentType('text/csv; charset=utf-8')
break
case '.zip':
this.contentType('application/zip')
break
default:
throw new Error('unexpected extension')
}
this.header('Content-Disposition', contentDisposition(filename))
return this
}
contentType(type) {
this.header('Content-Type', type)
this.type = type
return this
}
type(type) {
return this.contentType(type)
}
}
MockResponse.initClass()
module.exports = MockResponse

View File

@@ -0,0 +1,3 @@
const mockModel = require('../MockModel')
module.exports = mockModel('DeletedFile')

View File

@@ -0,0 +1,5 @@
const mockModel = require('../MockModel')
module.exports = mockModel('DeletedProject', {
'./Project': require('./Project'),
})

View File

@@ -0,0 +1,5 @@
const mockModel = require('../MockModel')
module.exports = mockModel('DeletedUser', {
'./User': require('./User'),
})

View File

@@ -0,0 +1,3 @@
const mockModel = require('../MockModel')
module.exports = mockModel('Doc')

View File

@@ -0,0 +1,3 @@
const mockModel = require('../MockModel')
module.exports = mockModel('File')

View File

@@ -0,0 +1,6 @@
const mockModel = require('../MockModel')
module.exports = mockModel('Folder', {
'./Doc': require('./Doc'),
'./File': require('./File'),
})

View File

@@ -0,0 +1,5 @@
const mockModel = require('../MockModel')
module.exports = mockModel('Project', {
'./Folder': require('./Folder'),
})

View File

@@ -0,0 +1,3 @@
const mockModel = require('../MockModel')
module.exports = mockModel('Tag')

View File

@@ -0,0 +1,5 @@
const mockModel = require('../MockModel')
module.exports = mockModel('User', {
'./Project': require('./Project'),
})

View File

@@ -0,0 +1,3 @@
const mockModel = require('../MockModel')
module.exports = mockModel('UserAuditLogEntry')