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.
 

189 lines
4.1 KiB

import fs from 'fs';
import SlowStream from 'slow-stream';
import intoStream from 'into-stream';
import getStream from 'get-stream';
import FormData from 'form-data';
import tempfile from 'tempfile';
import pify from 'pify';
import test from 'ava';
import got from '..';
import {createServer} from './helpers/server';
const checkEvents = (t, events, bodySize = null) => {
t.true(events.length >= 2);
const hasBodySize = typeof bodySize === 'number';
let lastEvent = events.shift();
if (!hasBodySize) {
t.is(lastEvent.percent, 0);
}
for (const [index, event] of events.entries()) {
if (hasBodySize) {
t.is(event.percent, event.transferred / bodySize);
t.true(event.percent > lastEvent.percent);
} else {
const isLastEvent = index === events.length - 1;
t.is(event.percent, isLastEvent ? 1 : 0);
}
t.true(event.transferred >= lastEvent.transferred);
t.is(event.total, bodySize);
lastEvent = event;
}
};
const file = Buffer.alloc(1024 * 1024 * 2);
let s;
test.before('setup', async () => {
s = await createServer();
s.on('/download', (req, res) => {
res.setHeader('content-length', file.length);
intoStream(file)
.pipe(new SlowStream({maxWriteInterval: 50}))
.pipe(res);
});
s.on('/download/no-total', (req, res) => {
res.write('hello');
res.end();
});
s.on('/upload', (req, res) => {
req
.pipe(new SlowStream({maxWriteInterval: 100}))
.on('end', () => res.end());
});
await s.listen(s.port);
});
test('download progress', async t => {
const events = [];
const res = await got(`${s.url}/download`, {encoding: null})
.on('downloadProgress', e => events.push(e));
checkEvents(t, events, res.body.length);
});
test('download progress - missing total size', async t => {
const events = [];
await got(`${s.url}/download/no-total`)
.on('downloadProgress', e => events.push(e));
checkEvents(t, events);
});
test('download progress - stream', async t => {
const events = [];
const stream = got.stream(`${s.url}/download`, {encoding: null})
.on('downloadProgress', e => events.push(e));
await getStream(stream);
checkEvents(t, events, file.length);
});
test('upload progress - file', async t => {
const events = [];
await got.post(`${s.url}/upload`, {body: file})
.on('uploadProgress', e => events.push(e));
checkEvents(t, events, file.length);
});
test('upload progress - file stream', async t => {
const path = tempfile();
fs.writeFileSync(path, file);
const events = [];
await got.post(`${s.url}/upload`, {body: fs.createReadStream(path)})
.on('uploadProgress', e => events.push(e));
checkEvents(t, events, file.length);
});
test('upload progress - form data', async t => {
const events = [];
const body = new FormData();
body.append('key', 'value');
body.append('file', file);
const size = await pify(body.getLength.bind(body))();
await got.post(`${s.url}/upload`, {body})
.on('uploadProgress', e => events.push(e));
checkEvents(t, events, size);
});
test('upload progress - json', async t => {
const body = JSON.stringify({key: 'value'});
const size = Buffer.byteLength(body);
const events = [];
await got.post(`${s.url}/upload`, {body})
.on('uploadProgress', e => events.push(e));
checkEvents(t, events, size);
});
test('upload progress - stream with known body size', async t => {
const events = [];
const options = {
headers: {'content-length': file.length}
};
const req = got.stream.post(`${s.url}/upload`, options)
.on('uploadProgress', e => events.push(e));
await getStream(intoStream(file).pipe(req));
checkEvents(t, events, file.length);
});
test('upload progress - stream with unknown body size', async t => {
const events = [];
const req = got.stream.post(`${s.url}/upload`)
.on('uploadProgress', e => events.push(e));
await getStream(intoStream(file).pipe(req));
checkEvents(t, events);
});
test('upload progress - no body', async t => {
const events = [];
await got.post(`${s.url}/upload`)
.on('uploadProgress', e => events.push(e));
t.deepEqual(events, [
{
percent: 0,
transferred: 0,
total: 0
},
{
percent: 1,
transferred: 0,
total: 0
}
]);
});
test.after('cleanup', async () => {
await s.close();
});