test/batch_test.js
import chai, { expect } from "chai";
import * as requests from "../src/requests";
import { aggregate } from "../src/batch";
chai.should();
chai.config.includeStack = true;
describe("batch module", () => {
describe("aggregate()", () => {
it("should throw if responses length doesn't match requests one", () => {
expect(() => aggregate([1], [1, 2])).to.Throw(Error, /match/);
});
it("should return an object", () => {
expect(aggregate([], [])).to.be.an("object");
});
it("should return an object with the expected keys", () => {
expect(aggregate([], [])).to.include.keys([
"published",
"conflicts",
"skipped",
"errors",
]);
});
it("should expose HTTP 500 errors in the errors list", () => {
const _requests = [
requests.createRequest("foo1", {
data: { id: 1 },
}),
requests.createRequest("foo2", { data: { id: 2 } }),
];
const responses = [
{ status: 500, body: { err: 1 } },
{ status: 503, body: { err: 2 } },
];
expect(aggregate(responses, _requests))
.to.have.property("errors")
.eql([
{
error: { err: 1 },
path: "foo1",
sent: _requests[0],
},
{
error: { err: 2 },
path: "foo2",
sent: _requests[1],
},
]);
});
it("should expose HTTP 200<=x<400 responses in the published list", () => {
const _requests = [
requests.createRequest("foo", {
data: { id: 1 },
}),
requests.createRequest("foo", { data: { id: 2 } }),
];
const responses = [
{ status: 200, body: { data: { id: 1 } } },
{ status: 201, body: { data: { id: 2 } } },
];
expect(aggregate(responses, _requests))
.to.have.property("published")
.eql(responses.map(r => r.body));
});
it("should expose HTTP 404 responses in the skipped list", () => {
const _requests = [
requests.createRequest("records/123", {
data: { id: 1 },
}),
requests.createRequest("records/123", { data: { id: 2 } }),
];
const responses = [
{ status: 404, body: { errno: 110, code: 404, error: "Not found" } },
{ status: 404, body: { errno: 110, code: 404, error: "Not found" } },
];
expect(aggregate(responses, _requests))
.to.have.property("skipped")
.eql(
responses.map(r => ({
id: "123",
path: "records/123",
error: r.body,
}))
);
});
it("should expose HTTP 412 responses in the conflicts list", () => {
const _requests = [
requests.createRequest("records/123", {
data: { id: 1 },
}),
requests.createRequest("records/123", { data: { id: 2 } }),
];
const responses = [
{ status: 412, body: { details: { existing: { remote: true } } } },
{ status: 412, body: {} },
];
expect(aggregate(responses, _requests))
.to.have.property("conflicts")
.eql([
{
type: "outgoing",
local: _requests[0].body,
remote: { remote: true },
},
{
type: "outgoing",
local: _requests[1].body,
remote: null,
},
]);
});
describe("Heterogeneous combinations", () => {
let _requests, responses, results;
beforeEach(() => {
_requests = [
requests.createRequest("collections/abc/records/123", {
data: { id: 1 },
}),
requests.createRequest("collections/abc/records/123", {
data: { id: 2 },
}),
requests.createRequest("collections/abc/records/123", {
data: { id: 3 },
}),
requests.createRequest("collections/abc/records/123", {
data: { id: 4, a: 1 },
}),
];
responses = [
{ status: 500, path: "path1", body: { err: 1 } },
{ status: 200, body: { data: { foo: "bar" } } },
{ status: 404, body: { errno: 110, code: 404, error: "Not found" } },
{ status: 412, body: { details: { existing: { remote: true } } } },
];
results = aggregate(responses, _requests);
});
it("should list errors", () => {
expect(results.errors).eql([
{
error: { err: 1 },
path: "collections/abc/records/123",
sent: _requests[0],
},
]);
});
it("should list published data", () => {
expect(results.published).eql([{ data: { foo: "bar" } }]);
});
it("should list conflicts", () => {
expect(results.conflicts).eql([
{
type: "outgoing",
local: {
data: { id: 4, a: 1 },
permissions: undefined,
},
remote: { remote: true },
},
]);
});
it("should list skips", () => {
expect(results.skipped).eql([
{
id: "123",
path: "collections/abc/records/123",
error: responses[2].body,
},
]);
});
});
});
});