UNPKG

@ch1/xhr

Version:
237 lines (197 loc) 7.07 kB
import { noop } from '@ch1/utility'; import { Xhr, parseQuery } from './xhr'; describe('xhr wrapper', () => { describe('Xhr constructor function', () => { let xhrObj: XMLHttpRequest; function FakeHttpRequest() { return xhrObj; } beforeEach(() => { xhrObj = ({ abort: noop, open: noop, readyState: -1, setRequestHeader: noop, send: noop, status: -1 } as any) as XMLHttpRequest; // yes, this is fake :) }); it('creates with a custom ', () => { const x = Xhr(FakeHttpRequest); expect(x).not.toBe(undefined); }); it('times out if nothing happens', () => { const x = Xhr(FakeHttpRequest, 1); return expect(x.get('/foo')).rejects.toEqual( new Error('xhr: request timed out') ); }); it('resolves if the readyState is 4 and the response is 200', () => { const x = Xhr(FakeHttpRequest); const promise = x.get('/some/resource'); (xhrObj as any).readyState = 4; (xhrObj as any).responseText = 'working'; (xhrObj as any).status = 200; (xhrObj as any).onload(); return expect(promise).resolves.toEqual('working'); }); it('rejects if the readyState is 4 and the response is not 200 or 201', () => { const x = Xhr(FakeHttpRequest); const promise = x.get('/some/resource'); (xhrObj as any).readyState = 4; (xhrObj as any).responseText = 'working'; (xhrObj as any).status = 404; (xhrObj as any).onload(); return expect(promise).rejects.toEqual( new Error('xhr: non 200 status: 404') ); }); it('resolves if the readyState is 4 and the response is 201', () => { const x = Xhr(FakeHttpRequest); const promise = x.get('/some/resource'); (xhrObj as any).readyState = 4; (xhrObj as any).responseText = 'working'; (xhrObj as any).status = 201; (xhrObj as any).onload(); return expect(promise).resolves.toEqual('working'); }); it('defers until readyState is 4 and the response is 200', done => { const x = Xhr(FakeHttpRequest, 100, 1); let didRun = false; let didCheck = false; x.get('/some/resource') .then((value: string) => { didRun = true; expect(value).toBe('working'); expect(didCheck).toBe(true); done(); }) .catch(done); // Trigger the test (xhrObj as any).readyState = 2; (xhrObj as any).onload(); setTimeout(() => { didCheck = true; expect(didRun).toBe(false); // let the test pass (xhrObj as any).readyState = 4; }, 5); (xhrObj as any).status = 200; (xhrObj as any).responseText = 'working'; }); it('forwards headers', () => { const x = Xhr(FakeHttpRequest, 100, 1); const headers: { [key: string]: string } = {}; xhrObj.setRequestHeader = (key: string, value: string) => { headers[key] = value; }; x.get('/some/resource', undefined, { Authorization: 'bearer' }); expect(headers.Authorization).toBe('bearer'); }); it('allows for default headers to be set', () => { const x = Xhr(FakeHttpRequest, 100, 1); const headers: { [key: string]: string } = {}; xhrObj.setRequestHeader = (key: string, value: string) => { headers[key] = value; }; x.defaultHeader('Authorization', 'bearer'); x.get('/some/resource'); expect(headers.Authorization).toBe('bearer'); }); it('allows for default headers to be unset', () => { const x = Xhr(FakeHttpRequest, 100, 1); let headers: { [key: string]: string } = {}; xhrObj.setRequestHeader = (key: string, value: string) => { headers[key] = value; }; x.defaultHeader('Authorization', 'bearer'); x.get('/some/resource'); expect(headers.Authorization).toBe('bearer'); headers = {}; x.defaultHeader('Authorization'); x.get('/some/resource'); expect(headers.Authorization).toBe(undefined); }); it('allows for repeated calls to unset headers', () => { const x = Xhr(FakeHttpRequest, 100, 1); let headers: { [key: string]: string } = {}; xhrObj.setRequestHeader = (key: string, value: string) => { headers[key] = value; }; x.defaultHeader('Authorization', 'bearer'); x.get('/some/resource'); expect(headers.Authorization).toBe('bearer'); headers = {}; x.defaultHeader('Authorization'); x.defaultHeader('Authorization'); x.get('/some/resource'); expect(headers.Authorization).toBe(undefined); }); it('ignores falsey calls to defaultHeader', () => { const x = Xhr(FakeHttpRequest, 100, 1); const headers: { [key: string]: string } = {}; xhrObj.setRequestHeader = (key: string, value: string) => { headers[key] = value; }; x.defaultHeader('', 'bearer'); x.get('/some/resource'); expect(headers['']).toBe(undefined); }); it('forces defaultHeader values to be strings', () => { const x = Xhr(FakeHttpRequest, 100, 1); const headers: { [key: string]: string } = {}; xhrObj.setRequestHeader = (key: string, value: string) => { headers[key] = value; }; x.defaultHeader('foo', 7 as any); x.get('/some/resource'); expect(headers['foo']).toBe('7'); }); it('rejects put calls that have no data', () => { const x = Xhr(FakeHttpRequest); return expect(x.put('/somthing')).rejects.toEqual( new Error('xhr: newRequest: PUT: requires data') ); }); it('rejects post calls that have no data', () => { const x = Xhr(FakeHttpRequest); return expect(x.post('/somthing')).rejects.toEqual( new Error('xhr: newRequest: POST: requires data') ); }); it('stringifies post data', () => { const x = Xhr(FakeHttpRequest); const obj = { foo: 'bar' }; let rec: any = null; xhrObj.send = (value: any) => { rec = value; }; x.post('/somthing', obj); expect(rec).toEqual(JSON.stringify(obj)); }); it('rejects if something blows up synchronously', () => { const x = Xhr(FakeHttpRequest); const error = new Error('chaos!'); xhrObj.send = (value: any) => { throw error; }; return expect(x.get('/somthing')).rejects.toBe(error); }); }); describe('parseQuery function', () => { it('returns false if given no parameters', () => { expect(parseQuery()).toBe(false); }); it('returns false if given a non object', () => { expect(parseQuery(7 as any)).toBe(false); }); it('variablizes a single key/value pair', () => { const query = parseQuery({ foo: 'bar' }); expect(query).toBe('?foo=bar'); }); it('variablizes a multiple key/value pairs', () => { const query = parseQuery({ foo: 'bar', baz: 'bof' }); expect(query).toBe('?foo=bar&baz=bof'); }); }); });