rest-methods
Version:
Declaratively publish functions for remote invocation.
151 lines (126 loc) • 4.68 kB
JavaScript
import { expect } from 'chai';
import { registerMethods } from '../../src/client/Client';
import http from 'http-promises/browser';
import { FakeXMLHttpRequest } from 'sinon';
import ClientMethod from '../../src/client/ClientMethod';
import Client from '../../src/client/Client';
import { STATE } from '../../src/client/Client';
describe('Client:methods (proxy-stubs)', () => {
let client, fakeXhr;
before(() => {
// Inject a fake XHR object.
http.createXhr = () => {
fakeXhr = new FakeXMLHttpRequest();
return fakeXhr;
};
});
beforeEach(() => { client = Client({ http:http, host:'localhost' }); });
it('does not have any methods prior to loading', () => {
expect(client.isReady).to.equal(false);
expect(client.methods).to.eql({});
});
it('registers methods upon receiving manifest from server', (done) => {
client.onReady(() => {
expect(client.isReady).to.equal(true);
expect(client.methods['foo']).not.to.equal(undefined);
done();
});
fakeXhr.responseText = JSON.stringify({
methods: {
foo: { params: [] }
}
});
fakeXhr.status = 200;
fakeXhr.readyState = 4;
fakeXhr.onreadystatechange();
});
it('stores methods in state', () => {
registerMethods(client, {
'foo': {},
'foo/bar': { get:{ params:['p1'] } }
});
expect(client[STATE].methods['foo']).to.be.an.instanceof(ClientMethod);
expect(client[STATE].methods['foo/bar']).to.be.an.instanceof(ClientMethod);
});
it('has a proxy-stub for each method', () => {
registerMethods(client, {
'foo': { get: {}, put:{}, post:{}, delete:{} }
});
expect(client.methods.foo).to.be.an.instanceof(Object);
expect(client.methods.foo.get).to.be.an.instanceof(Function);
expect(client.methods.foo.put).to.be.an.instanceof(Function);
expect(client.methods.foo.post).to.be.an.instanceof(Function);
expect(client.methods.foo.delete).to.be.an.instanceof(Function);
});
it('has no proxy-stubs', () => {
registerMethods(client, {
'foo': {}
});
expect(client.methods.foo).to.be.an.instanceof(Object);
expect(client.methods.foo.get).to.equal(undefined);
expect(client.methods.foo.put).to.equal(undefined);
expect(client.methods.foo.post).to.equal(undefined);
expect(client.methods.foo.delete).to.equal(undefined);
});
it('nests methods within a namespace', () => {
registerMethods(client, {
'foo': { get: {} },
'foo/bar': { get: {} },
'foo/bar/baz': { get: {} }
});
expect(client.methods.foo).to.be.an.instanceof(Object);
expect(client.methods.foo.bar).to.be.an.instanceof(Object);
expect(client.methods.foo.bar.baz).to.be.an.instanceof(Object);
expect(client.methods.foo.get).to.be.an.instanceof(Function);
expect(client.methods.foo.bar.get).to.be.an.instanceof(Function);
expect(client.methods.foo.bar.baz.get).to.be.an.instanceof(Function);
});
it('invokes the helper method for each HTTP verb returning a promise', (done) => {
registerMethods(client, {
'foo': { get: {}, put:{}, post:{}, delete:{} }
});
['get', 'put', 'post', 'delete'].forEach(verb => {
let fakeXhr, sent;
http.createXhr = () => {
sent = [];
fakeXhr = new FakeXMLHttpRequest();
fakeXhr.send = (data) => { sent.push(data); };
return fakeXhr;
};
let args = undefined
if (verb === 'put' || verb === 'post') { args = 123; }
client.methods.foo[verb](args)
.then((result) => {
expect(fakeXhr.method).to.equal(verb.toUpperCase());
expect(result).to.eql({ myResponse: true });
if (verb === 'delete') { done(); }
})
fakeXhr.responseText = JSON.stringify({ myResponse: true });
fakeXhr.status = 200;
fakeXhr.readyState = 4;
fakeXhr.onreadystatechange();
});
});
it('invokes the proxy-stub within a nested namespace', (done) => {
registerMethods(client, {
'foo/bar/baz': { put: {} }
});
let fakeXhr, sent;
http.createXhr = () => {
sent = [];
fakeXhr = new FakeXMLHttpRequest();
fakeXhr.send = (data) => { sent.push(data); };
return fakeXhr;
};
client.methods.foo.bar.baz.put(123)
.then((result) => {
expect(fakeXhr.method).to.equal('PUT');
expect(result).to.eql({ myResponse: true });
done();
})
fakeXhr.responseText = JSON.stringify({ myResponse: true });
fakeXhr.status = 200;
fakeXhr.readyState = 4;
fakeXhr.onreadystatechange();
});
});