You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
94 lines
2.5 KiB
94 lines
2.5 KiB
4 years ago
|
const http = require('http')
|
||
|
|
||
|
/**
|
||
|
* This is the default error handler to be used by this mock segment server.
|
||
|
* It will print the error to the console and exit the process.
|
||
|
*
|
||
|
* @param {Error} error - The server error
|
||
|
*/
|
||
|
function defaultOnError(error) {
|
||
|
console.log(error)
|
||
|
process.exit(1)
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @typedef {import('http').IncomingMessage} IncomingMessage
|
||
|
* @typedef {import('http').ServerResponse} ServerResponse
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* This function handles requests for the mock Segment server
|
||
|
* @typedef {(request: IncomingMessage, response: ServerResponse, metricEvents: Array<Object>) => void} MockSegmentRequestHandler
|
||
|
*/
|
||
|
|
||
|
/**
|
||
|
* Creates a HTTP server that acts as a fake version of the Segment API.
|
||
|
* The bevahiour is rudimentary at the moment - it returns HTTP 200 in response
|
||
|
* to every request. The only function this serves is to spy on requests sent to
|
||
|
* this server, and to parse the request payloads as Segment batch events.
|
||
|
*
|
||
|
* @param {MockSegmentRequestHandler} onRequest- A callback for each request the server receives.
|
||
|
* @param {(error: Error) => void} [onError] - A callback for server error events
|
||
|
*/
|
||
|
function createSegmentServer(onRequest, onError = defaultOnError) {
|
||
|
const server = http.createServer(async (request, response) => {
|
||
|
const chunks = []
|
||
|
|
||
|
request.on('data', (chunk) => {
|
||
|
chunks.push(chunk)
|
||
|
})
|
||
|
|
||
|
await new Promise((resolve) => {
|
||
|
request.on('end', () => {
|
||
|
resolve()
|
||
|
})
|
||
|
})
|
||
|
|
||
|
// respond to preflight request
|
||
|
if (request.method === 'OPTIONS') {
|
||
|
response.setHeader('Access-Control-Allow-Origin', '*')
|
||
|
response.setHeader('Access-Control-Allow-Methods', '*')
|
||
|
response.setHeader('Access-Control-Allow-Headers', '*')
|
||
|
response.statusCode = 200
|
||
|
response.end()
|
||
|
return
|
||
|
}
|
||
|
|
||
|
let metricEvents = []
|
||
|
if (chunks.length) {
|
||
|
const body = Buffer.concat(chunks).toString()
|
||
|
const segmentPayload = JSON.parse(body)
|
||
|
metricEvents = segmentPayload.batch
|
||
|
}
|
||
|
|
||
|
onRequest(request, response, metricEvents)
|
||
|
})
|
||
|
|
||
|
server.on('error', onError)
|
||
|
|
||
|
return {
|
||
|
start: async (port) => {
|
||
|
await new Promise((resolve, reject) => {
|
||
|
server.listen(port, (error) => {
|
||
|
if (error) {
|
||
|
return reject(error)
|
||
|
}
|
||
|
return resolve()
|
||
|
})
|
||
|
})
|
||
|
},
|
||
|
stop: async () => {
|
||
|
await new Promise((resolve, reject) => {
|
||
|
server.close((error) => {
|
||
|
if (error) {
|
||
|
return reject(error)
|
||
|
}
|
||
|
return resolve()
|
||
|
})
|
||
|
})
|
||
|
},
|
||
|
}
|
||
|
}
|
||
|
|
||
|
module.exports = { createSegmentServer }
|