pusher-js
Version:
Pusher Channels JavaScript library for browsers, React Native, NodeJS and web workers
192 lines (156 loc) • 5.77 kB
JavaScript
var Mocks = require("mocks");
var HTTPRequest = require("core/http/http_request").default;
var Runtime = require("runtime").default;
describe("HTTPRequest", function() {
var xhr;
var hooks;
var request;
var lastXHR;
beforeEach(function() {
hooks = {
getRequest: jasmine.createSpy().and.callFake(function() {
lastXHR = Mocks.getXHR();
return lastXHR;
}),
abortRequest: jasmine.createSpy()
};
spyOn(Runtime, "addUnloadListener");
spyOn(Runtime, "removeUnloadListener");
request = new HTTPRequest(hooks, "GET", "http://example.com");
});
describe("#start", function() {
it("should create a request using the getRequest hook", function() {
request.start("test");
expect(hooks.getRequest.calls.count()).toEqual(1);
expect(hooks.getRequest).toHaveBeenCalledWith(request);
});
it("should open and send the request", function() {
request.start("test payload");
expect(lastXHR.open).toHaveBeenCalledWith(
"GET", "http://example.com", true
);
expect(lastXHR.send).toHaveBeenCalledWith("test payload");
});
it("should register an unloader", function() {
request.start("test payload");
expect(Runtime.addUnloadListener).toHaveBeenCalledWith(
jasmine.any(Function)
);
});
it("raised by XMLHttpRequest#open", function() {
hooks.getRequest = function() {
xhr = Mocks.getXHR();
xhr.open.and.throwError("open exception");
return xhr;
};
expect(function() {
request.start();
}).toThrow(new Error('open exception'));
});
it("should re-throw the exception raised by XMLHttpRequest#send", function() {
hooks.getRequest = function() {
xhr = Mocks.getXHR();
xhr.send.and.throwError("send exception");
return xhr;
};
expect(function() {
request.start();
}).toThrow(new Error('send exception'));
});
});
describe("#close", function() {
beforeEach(function() {
request.start();
});
it("should abort the request using the abortRequest hook", function() {
request.close();
expect(hooks.abortRequest.calls.count()).toEqual(1);
expect(hooks.abortRequest).toHaveBeenCalledWith(lastXHR);
});
it("should unregister the unloader", function() {
var unloader = Runtime.addUnloadListener.calls.first().args[0];
request.close();
expect(Runtime.removeUnloadListener).toHaveBeenCalledWith(unloader);
});
});
describe("on chunk", function() {
var onChunk;
beforeEach(function() {
onChunk = jasmine.createSpy("onChunk");
request.bind("chunk", onChunk);
request.start();
});
it("should emit the first chunk", function() {
request.onChunk(200, "chunk1\n");
expect(onChunk).toHaveBeenCalledWith({ status: 200, data: "chunk1" });
});
it("should emit two chunks received one after another", function() {
request.onChunk(201, "c1\n");
expect(onChunk.calls.count()).toEqual(1);
expect(onChunk).toHaveBeenCalledWith({ status: 201, data: "c1" });
request.onChunk(201, "c1\nc2\n");
expect(onChunk.calls.count()).toEqual(2);
expect(onChunk).toHaveBeenCalledWith({ status: 201, data: "c2" });
});
it("should emit all chunks send in one batch", function() {
request.onChunk(200, "c1\nc2\nc3\n");
expect(onChunk.calls.count()).toEqual(3);
expect(onChunk.calls.first().args[0]).toEqual({ status: 200, data: "c1" });
expect(onChunk.calls.argsFor(1)[0]).toEqual({
status: 200,
data: 'c2'
});
expect(onChunk.calls.argsFor(2)[0]).toEqual({ status: 200, data: "c3" });
});
it("should not emit an unfinished chunk", function() {
request.onChunk(200, "whatever");
expect(onChunk).not.toHaveBeenCalled();
});
it("should emit 'buffer_too_long' after 256KB", function() {
var onBufferTooLong = jasmine.createSpy("onBufferTooLong");
request.bind("buffer_too_long", onBufferTooLong);
var kilobyteChunk = new Array(1024).join("x"); // 1023B
var response = new Array(256).join(kilobyteChunk + "\n");
request.onChunk(200, response); // 255KB
expect(onBufferTooLong).not.toHaveBeenCalled();
response = response + kilobyteChunk + "x"; // 256KB
request.onChunk(200, response); // 255KB
expect(onBufferTooLong).not.toHaveBeenCalled();
response = response + "\n"; // 256KB + 1B
request.onChunk(200, response); // 255KB
expect(onBufferTooLong).toHaveBeenCalled();
});
it("should emit all chunks before 'buffer_too_long'", function() {
request.bind("buffer_too_long", function() {
request.unbind_all();
});
var kilobyteChunk = new Array(1024).join("x"); // 1023B
request.onChunk(
200,
new Array(256).join(kilobyteChunk + "\n") + kilobyteChunk + "x" + "\n"
); // 256KB + 1B
expect(onChunk.calls.count()).toEqual(256);
});
});
describe("on request end", function() {
beforeEach(function() {
request.start();
});
});
describe("on page unload", function() {
var unloader;
beforeEach(function() {
request.start("test payload");
unloader = Runtime.addUnloadListener.calls.first().args[0];
});
it("should abort the request using the abortRequest hook", function() {
unloader();
expect(hooks.abortRequest.calls.count()).toEqual(1);
expect(hooks.abortRequest).toHaveBeenCalledWith(lastXHR);
});
it("should unregister the unloader", function() {
unloader();
expect(Runtime.removeUnloadListener).toHaveBeenCalledWith(unloader);
});
});
});