node-fetch/test/request.js

278 lines
7.0 KiB
JavaScript

import stream from 'stream';
import http from 'http';
import AbortController from 'abort-controller';
import chai from 'chai';
import FormData from 'form-data';
import Blob from 'fetch-blob';
import {Request} from '../src/index.js';
import TestServer from './utils/server.js';
const {expect} = chai;
describe('Request', () => {
const local = new TestServer();
let base;
before(async () => {
await local.start();
base = `http://${local.hostname}:${local.port}/`;
});
after(async () => {
return local.stop();
});
it('should have attributes conforming to Web IDL', () => {
const request = new Request('https://github.com/');
const enumerableProperties = [];
for (const property in request) {
enumerableProperties.push(property);
}
for (const toCheck of [
'body',
'bodyUsed',
'arrayBuffer',
'blob',
'json',
'text',
'method',
'url',
'headers',
'redirect',
'clone',
'signal'
]) {
expect(enumerableProperties).to.contain(toCheck);
}
for (const toCheck of [
'body', 'bodyUsed', 'method', 'url', 'headers', 'redirect', 'signal'
]) {
expect(() => {
request[toCheck] = 'abc';
}).to.throw();
}
});
it('should support wrapping Request instance', () => {
const url = `${base}hello`;
const form = new FormData();
form.append('a', '1');
const {signal} = new AbortController();
const r1 = new Request(url, {
method: 'POST',
follow: 1,
body: form,
signal
});
const r2 = new Request(r1, {
follow: 2
});
expect(r2.url).to.equal(url);
expect(r2.method).to.equal('POST');
expect(r2.signal).to.equal(signal);
// Note that we didn't clone the body
expect(r2.body).to.equal(form);
expect(r1.follow).to.equal(1);
expect(r2.follow).to.equal(2);
expect(r1.counter).to.equal(0);
expect(r2.counter).to.equal(0);
});
it('should override signal on derived Request instances', () => {
const parentAbortController = new AbortController();
const derivedAbortController = new AbortController();
const parentRequest = new Request(`${base}hello`, {
signal: parentAbortController.signal
});
const derivedRequest = new Request(parentRequest, {
signal: derivedAbortController.signal
});
expect(parentRequest.signal).to.equal(parentAbortController.signal);
expect(derivedRequest.signal).to.equal(derivedAbortController.signal);
});
it('should allow removing signal on derived Request instances', () => {
const parentAbortController = new AbortController();
const parentRequest = new Request(`${base}hello`, {
signal: parentAbortController.signal
});
const derivedRequest = new Request(parentRequest, {
signal: null
});
expect(parentRequest.signal).to.equal(parentAbortController.signal);
expect(derivedRequest.signal).to.equal(null);
});
it('should throw error with GET/HEAD requests with body', () => {
expect(() => new Request(base, {body: ''}))
.to.throw(TypeError);
expect(() => new Request(base, {body: 'a'}))
.to.throw(TypeError);
expect(() => new Request(base, {body: '', method: 'HEAD'}))
.to.throw(TypeError);
expect(() => new Request(base, {body: 'a', method: 'HEAD'}))
.to.throw(TypeError);
expect(() => new Request(base, {body: 'a', method: 'get'}))
.to.throw(TypeError);
expect(() => new Request(base, {body: 'a', method: 'head'}))
.to.throw(TypeError);
});
it('should default to null as body', () => {
const request = new Request(base);
expect(request.body).to.equal(null);
return request.text().then(result => expect(result).to.equal(''));
});
it('should support parsing headers', () => {
const url = base;
const request = new Request(url, {
headers: {
a: '1'
}
});
expect(request.url).to.equal(url);
expect(request.headers.get('a')).to.equal('1');
});
it('should support arrayBuffer() method', () => {
const url = base;
const request = new Request(url, {
method: 'POST',
body: 'a=1'
});
expect(request.url).to.equal(url);
return request.arrayBuffer().then(result => {
expect(result).to.be.an.instanceOf(ArrayBuffer);
const string = String.fromCharCode.apply(null, new Uint8Array(result));
expect(string).to.equal('a=1');
});
});
it('should support text() method', () => {
const url = base;
const request = new Request(url, {
method: 'POST',
body: 'a=1'
});
expect(request.url).to.equal(url);
return request.text().then(result => {
expect(result).to.equal('a=1');
});
});
it('should support json() method', () => {
const url = base;
const request = new Request(url, {
method: 'POST',
body: '{"a":1}'
});
expect(request.url).to.equal(url);
return request.json().then(result => {
expect(result.a).to.equal(1);
});
});
it('should support buffer() method', () => {
const url = base;
const request = new Request(url, {
method: 'POST',
body: 'a=1'
});
expect(request.url).to.equal(url);
return request.buffer().then(result => {
expect(result.toString()).to.equal('a=1');
});
});
it('should support blob() method', () => {
const url = base;
const request = new Request(url, {
method: 'POST',
body: Buffer.from('a=1')
});
expect(request.url).to.equal(url);
return request.blob().then(result => {
expect(result).to.be.an.instanceOf(Blob);
expect(result.size).to.equal(3);
expect(result.type).to.equal('');
});
});
it('should support clone() method', () => {
const url = base;
const body = stream.Readable.from('a=1');
const agent = new http.Agent();
const {signal} = new AbortController();
const request = new Request(url, {
body,
method: 'POST',
redirect: 'manual',
headers: {
b: '2'
},
follow: 3,
compress: false,
agent,
signal
});
const cl = request.clone();
expect(cl.url).to.equal(url);
expect(cl.method).to.equal('POST');
expect(cl.redirect).to.equal('manual');
expect(cl.headers.get('b')).to.equal('2');
expect(cl.follow).to.equal(3);
expect(cl.compress).to.equal(false);
expect(cl.method).to.equal('POST');
expect(cl.counter).to.equal(0);
expect(cl.agent).to.equal(agent);
expect(cl.signal).to.equal(signal);
// Clone body shouldn't be the same body
expect(cl.body).to.not.equal(body);
return Promise.all([cl.text(), request.text()]).then(results => {
expect(results[0]).to.equal('a=1');
expect(results[1]).to.equal('a=1');
});
});
it('should support ArrayBuffer as body', () => {
const encoder = new TextEncoder();
const request = new Request(base, {
method: 'POST',
body: encoder.encode('a=1').buffer
});
return request.text().then(result => {
expect(result).to.equal('a=1');
});
});
it('should support Uint8Array as body', () => {
const encoder = new TextEncoder();
const request = new Request(base, {
method: 'POST',
body: encoder.encode('a=1')
});
return request.text().then(result => {
expect(result).to.equal('a=1');
});
});
it('should support DataView as body', () => {
const encoder = new TextEncoder();
const request = new Request(base, {
method: 'POST',
body: new DataView(encoder.encode('a=1').buffer)
});
return request.text().then(result => {
expect(result).to.equal('a=1');
});
});
});