service-core/test/client.test.mjs
Jonatan Nilsson 47344c5e7a
Some checks failed
continuous-integration/appveyor/branch AppVeyor build failed
Updated core logic and how stable is calculated.
Fixed some minor bugs.
Will now no longer travel through history but instead stop at last stable version.
2022-02-18 13:32:44 +00:00

284 lines
8.1 KiB
JavaScript

import { Eltro as t, assert} from 'eltro'
import fs from 'fs/promises'
import http from 'http'
import Util from '../core/util.mjs'
import { request } from '../core/client.mjs'
const util = new Util(import.meta.url)
const testTargetFile = util.getPathFromRoot('./filetest.html')
const port = 61412
const defaultHandler = function(req, res) {
res.statusCode = 200
res.end('{"a":1}');
}
let server = null
let prefix = `http://localhost:${port}/`
let handler = defaultHandler
t.before(function(cb) {
server = http.createServer(function(req, res) {
req.on('error', function(err) {
console.log('error', err)
})
res.on('error', function(err) {
console.log('error', err)
})
handler(req, res)
})
server.listen(port, cb)
})
t.after(function() {
return fs.rm(testTargetFile)
.catch(function() { })
})
t.describe('Basics', function() {
t.beforeEach(function() {
handler = defaultHandler
})
t.test('should require valid config', async function() {
function checkError(err) {
assert.match(err.message, /config/i)
}
await assert.isRejected(request(prefix)).then(checkError)
await assert.isRejected(request('', prefix)).then(checkError)
await assert.isRejected(request([], prefix)).then(checkError)
await assert.isRejected(request(123, prefix)).then(checkError)
await assert.isRejected(request(0, prefix)).then(checkError)
})
t.test('should fail if url is invalid', async function() {
function checkError(check, err) {
assert.match(err.message, /invalid/i)
assert.match(err.message, /url/i)
if (check) {
assert.match(err.message, new RegExp(check))
}
}
await assert.isRejected(request({}, 123)).then(checkError.bind(this, null))
await assert.isRejected(request({}, [])).then(checkError.bind(this, null))
await assert.isRejected(request({}, {})).then(checkError.bind(this, null))
await assert.isRejected(request({}, '')).then(checkError.bind(this, null))
await assert.isRejected(request({}, 'asdf')).then(checkError.bind(this, 'asdf'))
await assert.isRejected(request({}, 'httpppp')).then(checkError.bind(this, 'httpppp'))
})
})
t.describe('Request', function() {
t.test('should work normally', async function() {
let res = await request({}, prefix)
assert.deepEqual(res.body, {a:1})
})
t.test('should follow redirects', async function() {
let counter = 0
handler = function(req, res) {
if (counter < 3) {
res.statusCode = 302
res.setHeader('Location', encodeURI(prefix))
res.end();
counter++
return
}
assert.strictEqual(req.url, '/')
res.statusCode = 200
res.end('{"a":1}');
return
}
let res = await request({}, prefix)
assert.deepEqual(res.body, {a:1})
assert.strictEqual(counter, 3)
})
t.test('should fail gracefully if HTML is received', async function() {
handler = function(req, res) {
res.statusCode = 200
res.end(`<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
</body>
</html>`);
}
let err = await assert.isRejected(request({}, prefix))
assert.match(err.message, /html/i)
assert.notMatch(err.message, /Unexpected token/i)
handler = function(req, res) {
res.statusCode = 200
res.end(`<html>
<head>
</head>
<body>
</body>
</html>`);
}
err = await assert.isRejected(request({}, prefix))
assert.match(err.message, /html/i)
assert.notMatch(err.message, /Unexpected token/i)
})
t.test('should fail if infinite redirect', async function() {
const assertRelativeLocation = 'some/text/here'
const assertLocation = prefix + assertRelativeLocation
let counter = 0
handler = function(req, res) {
res.statusCode = 302
res.setHeader('Location', encodeURI(assertLocation))
if (counter === 0) {
assert.strictEqual(req.url, '/')
} else {
assert.strictEqual(req.url, '/' + assertRelativeLocation)
}
res.end();
counter++
}
let err = await assert.isRejected(request({}, prefix))
assert.strictEqual(counter, 6)
assert.match(err.message, /redirect/i)
assert.match(err.message, new RegExp(assertRelativeLocation))
})
t.test('should fail if redirect is missing location', async function() {
let counter = 0
handler = function(req, res) {
res.statusCode = 302
res.end();
counter++
}
let err = await assert.isRejected(request({}, prefix))
assert.strictEqual(counter, 1)
assert.match(err.message, /redirect/i)
assert.match(err.message, /location/i)
})
t.test('should follow relative redirects', async function() {
const assertUrl = 'asdf1234'
let counter = 0
let url = ''
handler = function(req, res) {
if (counter < 1) {
res.statusCode = 302
res.setHeader('Location', encodeURI(assertUrl))
res.end();
counter++
return
}
url = req.url
res.statusCode = 200
res.end('{"a":1}');
return
}
let res = await request({}, prefix)
assert.deepEqual(res.body, {a:1})
assert.strictEqual(counter, 1)
assert.strictEqual(url, '/' + assertUrl)
counter = 0
res = await request({}, prefix + 'some/url/here')
assert.deepEqual(res.body, {a:1})
assert.strictEqual(counter, 1)
assert.strictEqual(url, '/some/url/' + assertUrl)
})
t.timeout(30).test('should support timeout on invalid url', async function() {
// blocked off port, should time out
let err = await assert.isRejected(request({ timeout: 15 }, 'http://git.nfp.is:8080'))
assert.match(err.message, /timed out/i)
assert.match(err.message, /15/i)
})
})
t.describe('Request download', function() {
const assertBody = `<!DOCTYPE html>
<html lang="en">
<head>
</head>
<body>
</body>
</html>`
t.beforeEach(function() {
handler = defaultHandler
})
t.afterEach(function() {
return fs.rm(testTargetFile)
.catch(function() { })
})
t.test('should support downloading file successfully', async function() {
handler = function(req, res) {
res.statusCode = 200
res.end(assertBody);
}
await request({}, prefix, testTargetFile)
let stat = await fs.stat(testTargetFile)
assert.notStrictEqual(stat.size, 0)
assert.strictEqual(stat.size, assertBody.length)
let contents = await (await fs.readFile(testTargetFile)).toString()
assert.strictEqual(contents, assertBody)
})
t.test('should support downloading file after redirect successfully', async function() {
let counter = 0
handler = function(req, res) {
if (counter < 3) {
res.statusCode = 302
res.setHeader('Location', encodeURI(prefix))
res.end();
counter++
return
}
res.statusCode = 200
res.end(assertBody);
}
await request({}, prefix, testTargetFile)
assert.strictEqual(counter, 3)
let stat = await fs.stat(testTargetFile)
assert.notStrictEqual(stat.size, 0)
assert.strictEqual(stat.size, assertBody.length)
let contents = await (await fs.readFile(testTargetFile)).toString()
assert.strictEqual(contents, assertBody)
})
t.test('should not create file if download redirects too many times', async function() {
handler = function(req, res) {
res.statusCode = 302
res.setHeader('Location', encodeURI(prefix))
res.end(assertBody);
}
let err = await assert.isRejected(request({}, prefix, testTargetFile))
assert.match(err.message, /redirects/)
let errStat = await assert.isRejected(fs.stat(testTargetFile))
assert.strictEqual(errStat.code, 'ENOENT')
})
t.test('should not create file if download fails', async function() {
handler = function(req, res) {
res.statusCode = 404
res.end('{}');
}
let err = await assert.isRejected(request({}, prefix, testTargetFile))
assert.match(err.message, /HTTP/)
assert.match(err.message, /404/)
let errStat = await assert.isRejected(fs.stat(testTargetFile))
assert.strictEqual(errStat.code, 'ENOENT')
})
})
t.after(function(cb) {
server.close(cb)
})