mirror of
https://github.com/Terreii/andromeda-viewer.git
synced 2026-08-14 00:57:49 +00:00
test(httpProxy): add tests for server/httpProxy
This commit is contained in:
+1
-1
@@ -235,7 +235,7 @@ api.use((err, req, res, next) => {
|
||||
const format = anError => ({
|
||||
status: getStatus(anError),
|
||||
title: anError.title || anError.name,
|
||||
detail: anError.detail || anError.message
|
||||
detail: anError.reason || anError.detail || anError.message
|
||||
})
|
||||
|
||||
if (Array.isArray(err)) {
|
||||
|
||||
+34
-5
@@ -9,12 +9,12 @@ module.exports = router
|
||||
|
||||
const proxy = httpProxy.createProxyServer({})
|
||||
|
||||
proxy.on('proxyReq', (proxyReq, req, res, options) => {
|
||||
proxy.on('proxyReq', (proxyReq, _req, _res, _options) => {
|
||||
// Remove the internal session id
|
||||
proxyReq.setHeader('x-andromeda-session-id', '')
|
||||
proxyReq.removeHeader('x-andromeda-session-id')
|
||||
})
|
||||
|
||||
proxy.on('error', (err, req, res) => {
|
||||
proxy.on('error', (err, _req, res) => {
|
||||
res.statusCode = 500
|
||||
res.setHeader('content-type', 'application/json')
|
||||
res.write(JSON.stringify({
|
||||
@@ -45,13 +45,42 @@ router.all('/:protocol/:hostname/:path(*$)', validateSession, (req, res) => {
|
||||
})
|
||||
})
|
||||
|
||||
// Error handler
|
||||
// This transforms the different error styles into application/vnd.api+json errors.
|
||||
router.use((err, _req, res, next) => {
|
||||
if (!err) {
|
||||
next()
|
||||
return
|
||||
}
|
||||
res.type('application/vnd.api+json')
|
||||
|
||||
const getStatus = anError => Number(anError.status || anError.statusCode) || 500
|
||||
const format = anError => ({
|
||||
status: getStatus(anError),
|
||||
title: anError.title || anError.name,
|
||||
detail: anError.reason || anError.detail || anError.message
|
||||
})
|
||||
|
||||
if (Array.isArray(err)) {
|
||||
res.status(getStatus(err[0]))
|
||||
res.json({
|
||||
errors: err.map(format)
|
||||
})
|
||||
} else {
|
||||
res.status(getStatus(err))
|
||||
res.json({
|
||||
errors: [format(err)]
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
/**
|
||||
* Validate if the request is made by a logged in user.
|
||||
* @param {express.Request} req Express Request Object.
|
||||
* @param {express.Response} res Express Response Object.
|
||||
* @param {express.Response} _res Express Response Object.
|
||||
* @param {express.NextFunction} next Call next middleware.
|
||||
*/
|
||||
function validateSession (req, res, next) {
|
||||
function validateSession (req, _res, next) {
|
||||
try {
|
||||
const sessionId = req.headers['x-andromeda-session-id']
|
||||
const checkSession = req.app.get('checkSession')
|
||||
|
||||
+2
-1
@@ -33,4 +33,5 @@ const server = app.listen(port, () => {
|
||||
|
||||
webSocketBridge.createWebSocketServer(app, server, '/api/bridge')
|
||||
|
||||
module.exports = server
|
||||
exports.app = app
|
||||
exports.server = server
|
||||
|
||||
+1
-1
@@ -263,7 +263,7 @@ function sendError (res, error) {
|
||||
errors: [{
|
||||
status: error.status || error.statusCode || 500,
|
||||
title: error.title || error.name,
|
||||
detail: error.detail || error.message
|
||||
detail: error.reason || error.detail || error.message
|
||||
}]
|
||||
})
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ describe('account', function () {
|
||||
|
||||
usersDbCreateIndex.resolves()
|
||||
|
||||
server = proxyquire('../server/index', {
|
||||
const backend = proxyquire('../server/index', {
|
||||
'./db': {
|
||||
'@global': true,
|
||||
usersDB: {
|
||||
@@ -52,6 +52,7 @@ describe('account', function () {
|
||||
},
|
||||
'node-fetch': fetch
|
||||
})
|
||||
server = backend.server
|
||||
})
|
||||
|
||||
afterEach('close server', function (done) {
|
||||
@@ -220,7 +221,7 @@ describe('account', function () {
|
||||
{
|
||||
status: 409,
|
||||
title: 'conflict',
|
||||
detail: 'Document update conflict'
|
||||
detail: 'An account with that id already exists'
|
||||
}
|
||||
]
|
||||
}, done)
|
||||
@@ -294,7 +295,7 @@ describe('account', function () {
|
||||
{
|
||||
status: 409,
|
||||
title: 'conflict',
|
||||
detail: 'Document update conflict'
|
||||
detail: 'An account with that username already exists'
|
||||
}
|
||||
]
|
||||
}, done)
|
||||
|
||||
@@ -0,0 +1,131 @@
|
||||
const assert = require('assert')
|
||||
const express = require('express')
|
||||
const proxyquire = require('proxyquire')
|
||||
const sinon = require('sinon')
|
||||
const request = require('supertest')
|
||||
const uuid = require('uuid')
|
||||
|
||||
describe('httpProxy', function () {
|
||||
let testServer
|
||||
let testServerPort
|
||||
|
||||
let clock
|
||||
let server // express server
|
||||
let app // express app
|
||||
|
||||
beforeEach(function (done) {
|
||||
const testApp = express()
|
||||
testApp.use((req, res) => {
|
||||
for (const [key, value] of Object.entries(req.headers)) {
|
||||
res.setHeader(key, value)
|
||||
}
|
||||
res.setHeader('x-request-method', req.method)
|
||||
res.send({ something: 'Hello World!' })
|
||||
})
|
||||
testServer = testApp.listen(() => {
|
||||
testServerPort = testServer.address().port
|
||||
done()
|
||||
})
|
||||
})
|
||||
|
||||
beforeEach(function () {
|
||||
clock = sinon.useFakeTimers(Date.now())
|
||||
})
|
||||
|
||||
beforeEach(function () {
|
||||
const backend = proxyquire('../server/index', {})
|
||||
app = backend.app
|
||||
server = backend.server
|
||||
})
|
||||
|
||||
afterEach('close server', function (done) {
|
||||
server.close(done)
|
||||
})
|
||||
|
||||
afterEach('restore timers', function () {
|
||||
clock.restore()
|
||||
})
|
||||
|
||||
afterEach('close test target server', function (done) {
|
||||
testServer.close(done)
|
||||
})
|
||||
|
||||
it('should fail if the user in not logged in', function (done) {
|
||||
request(server)
|
||||
.get(`/api/proxy/http/127.0.0.1:${testServerPort}/`)
|
||||
.expect('Content-Type', 'application/vnd.api+json; charset=utf-8')
|
||||
.expect(403, {
|
||||
errors: [
|
||||
{
|
||||
status: 403,
|
||||
title: 'forbidden',
|
||||
detail: '"x-andromeda-session-id" is wrong'
|
||||
}
|
||||
]
|
||||
}, done)
|
||||
})
|
||||
|
||||
it('should proxy the requests to the passed address', function (done) {
|
||||
const id = uuid.v4()
|
||||
app.get('gridSessions').set(id, 'active')
|
||||
|
||||
request(server)
|
||||
.get(`/api/proxy/http/127.0.0.1:${testServerPort}/somePath`)
|
||||
.set('x-andromeda-session-id', id)
|
||||
.expect('x-request-method', 'GET')
|
||||
.expect(res => {
|
||||
assert.strictEqual(res.headers['x-andromeda-session-id'], undefined)
|
||||
})
|
||||
.expect(200, { something: 'Hello World!' }, done)
|
||||
})
|
||||
|
||||
it('should proxy the request the the passed path-less address', function (done) {
|
||||
const id = uuid.v4()
|
||||
app.get('gridSessions').set(id, 'active')
|
||||
|
||||
request(server)
|
||||
.get(`/api/proxy/http/127.0.0.1:${testServerPort}/`)
|
||||
.set('x-andromeda-session-id', id)
|
||||
.expect('x-request-method', 'GET')
|
||||
.expect(res => {
|
||||
assert.strictEqual(res.headers['x-andromeda-session-id'], undefined)
|
||||
})
|
||||
.expect(200, { something: 'Hello World!' }, done)
|
||||
})
|
||||
|
||||
describe('methods', function () {
|
||||
for (const method of ['GET', 'HEAD', 'POST', 'PUT', 'DELETE', 'OPTIONS', 'TRACE', 'PATCH']) {
|
||||
it(`should handle ${method} requests`, function (done) {
|
||||
const id = uuid.v4()
|
||||
app.get('gridSessions').set(id, 'active')
|
||||
|
||||
let req = request(server)
|
||||
[method.toLowerCase()](`/api/proxy/http/127.0.0.1:${testServerPort}/`)
|
||||
.set('x-andromeda-session-id', id)
|
||||
|
||||
// Methods with body
|
||||
if (['POST', 'PUT', 'PATCH'].includes(method)) {
|
||||
req.send({ data: 'moar' })
|
||||
.expect('x-request-method', method)
|
||||
.expect(res => {
|
||||
assert.strictEqual(res.headers['x-andromeda-session-id'], undefined)
|
||||
})
|
||||
.expect(200, { something: 'Hello World!' }, done)
|
||||
} else {
|
||||
req
|
||||
.expect('x-request-method', method)
|
||||
.expect(res => {
|
||||
assert.strictEqual(res.headers['x-andromeda-session-id'], undefined)
|
||||
})
|
||||
.expect(
|
||||
200,
|
||||
method === 'HEAD'
|
||||
? {}
|
||||
: { something: 'Hello World!' },
|
||||
done
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
})
|
||||
+2
-1
@@ -27,7 +27,7 @@ describe('login', function () {
|
||||
|
||||
usersDbCreateIndex.resolves()
|
||||
|
||||
server = proxyquire('../server/index', {
|
||||
const backend = proxyquire('../server/index', {
|
||||
'./db': {
|
||||
'@global': true,
|
||||
usersDB: {
|
||||
@@ -43,6 +43,7 @@ describe('login', function () {
|
||||
},
|
||||
'node-fetch': fetch
|
||||
})
|
||||
server = backend.server
|
||||
})
|
||||
|
||||
afterEach('close server', function (done) {
|
||||
|
||||
Reference in New Issue
Block a user