rest-methods
Version:
Declaratively publish functions for remote invocation.
173 lines (137 loc) • 5.15 kB
JavaScript
import { expect } from "chai";
import ClientMethod from "../../src/client/ClientMethod";
import { ServerMethodError } from "../../src/errors";
import { FakeXMLHttpRequest } from "sinon";
import Promise from "bluebird";
import sinon from "sinon";
import http from "http-promises/browser";
describe("Client:ClientMethod", () => {
describe("state", () => {
it("stores the method name", () => {
let method = new ClientMethod("foo", http);
expect(method.name).to.equal("foo");
});
it("has no verbs", () => {
let method = new ClientMethod("foo", http);
expect(method.verbs).to.eql({});
});
it("has verbs", () => {
const options = {
get: {}, put: { params:["text"] }
};
let method = new ClientMethod("foo", http, options);
expect(method.verbs.get).to.eql({});
expect(method.verbs.put.params).to.eql(["text"]);
});
});
describe("url", () => {
it("derives the URL from the method name", () => {
let method = new ClientMethod("////foo/bar", http);
expect(method.urlPattern).to.equal("/foo/bar");
expect(method.url()).to.equal("/foo/bar");
});
it("takes a custom URL (no parameters)", () => {
let method = new ClientMethod("foo", http, { url:"/foo" });
expect(method.url()).to.equal("/foo");
});
it("prepends the host-name", () => {
let method = new ClientMethod("foo", http, { url:"/foo", host:"http://localhost:3030" });
expect(method.url()).to.equal("http://localhost:3030/foo");
});
it("constructs URL with parameters", () => {
let method = new ClientMethod("foo", http, { url:"/foo/:org/:org/:id/edit?q=abc" });
let url = method.url("acme", "edge-case", "bob");
expect(url).to.equal("/foo/acme/edge-case/bob/edit?q=abc");
});
it("throws if there are not enough arguments", () => {
let method = new ClientMethod("foo", http, { url:"/foo/:org/:id/edit?q=abc" });
let fn = () => { method.url(); };
expect(fn).to.throw();
});
});
describe("invoke()", () => {
let fakeXhr, sent;
beforeEach(() => {
sent = [];
http.createXhr = () => {
fakeXhr = new FakeXMLHttpRequest();
fakeXhr.send = (data) => {
if (data) { data = JSON.parse(data); }
sent.push(data);
};
return fakeXhr;
};
});
it("sends to the method URL", () => {
let method = new ClientMethod("foo/bar", http);
method.invoke();
expect(fakeXhr.url).to.equal("/foo/bar");
});
it("sends to a simple URL", () => {
let method = new ClientMethod("foo/bar", http, { url:"/yo" });
method.invoke();
expect(fakeXhr.url).to.equal("/yo");
});
it("sends to a paramatised URL", () => {
let method = new ClientMethod("foo", http, { url:"/foo/:id/edit" });
method.invoke("GET", "my-id");
expect(fakeXhr.url).to.equal("/foo/my-id/edit");
});
it("invokes with no arguments", () => {
let method = new ClientMethod("foo", http);
method.invoke("PUT");
expect(sent[0].method).to.equal("foo");
expect(sent[0].verb).to.equal("PUT");
expect(sent[0].args).to.eql([]);
});
it("invokes with arguments", () => {
let method = new ClientMethod("foo/bar", http);
method.invoke("PUT", 1, "two", { three:3 });
expect(sent[0].verb).to.equal("PUT");
expect(sent[0].args).to.eql([1, "two", { three:3 }]);
});
it("removes the arguments passed in the URL", () => {
let method = new ClientMethod("foo", http, { url:"foo/:id" });
method.invoke("PUT", "my-id", 1, 2);
expect(sent[0].args).to.eql([1, 2]);
});
it("resolves promise with return value", (done) => {
new ClientMethod("foo", http).invoke()
.then((result) => {
expect(result).to.eql({ foo:123 });
done()
});
fakeXhr.responseText = JSON.stringify({ foo:123 });
fakeXhr.status = 200;
fakeXhr.readyState = 4;
fakeXhr.onreadystatechange();
});
it("throws an error (malformed, no reponse-text from server)", (done) => {
new ClientMethod("foo", http).invoke()
.catch((err) => {
expect(err).to.be.an.instanceof(ServerMethodError);
expect(err.status).to.equal(500);
done()
});
fakeXhr.status = 500;
fakeXhr.readyState = 4;
fakeXhr.onreadystatechange();
});
it("throws an error ([ServerMethodError] returned from server)", (done) => {
new ClientMethod("foo", http).invoke()
.catch((err) => {
expect(err).to.be.an.instanceof(ServerMethodError);
expect(err.status).to.equal(503);
expect(err.method).to.equal("my-method");
expect(err.args).to.eql([1,2,3]);
expect(err.message).to.equal(":(");
done()
});
let serverError = new ServerMethodError(503, "my-method", [1,2,3], ":(");
fakeXhr.responseText = JSON.stringify(serverError);
fakeXhr.status = 500;
fakeXhr.readyState = 4;
fakeXhr.onreadystatechange();
});
});
});