Jonatan Nilsson
47344c5e7a
Some checks failed
continuous-integration/appveyor/branch AppVeyor build failed
Fixed some minor bugs. Will now no longer travel through history but instead stop at last stable version.
284 lines
8.1 KiB
JavaScript
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)
|
|
})
|