UNPKG

superdata

Version:

A lightweight data layer module motivated by extjs' data layer. It can be used with any client-side framework.

473 lines (377 loc) 12.3 kB
var createAjaxHelpers = require("../../src/proxy/ajaxHelpers"); describe("ajax helpers", function() { var request; var createReader; var ajaxHelpers; function createMockRequest(config) { var endError = config.endError || false; var obj = { get: get, put: put, post: post, del: del, query: query, accept: accept, timeout: timeout, withCredentials: withCredentials, type: type, send: send, end: end }; function get() { return obj; } function put() { return obj; } function post() { return obj; } function del() { return obj; } function query() { return obj; } function accept() { return obj; } function timeout() { return obj; } function withCredentials() { return obj; } function type() { return obj; } function send() { return obj; } function end(callback) { setTimeout(function() { if(endError) { callback("some error message", ""); } else { callback("", { body: "body of result" }); } }, 0); return obj; } spyOn(obj,"get").and.callThrough(); spyOn(obj,"put").and.callThrough(); spyOn(obj,"post").and.callThrough(); spyOn(obj,"del").and.callThrough(); spyOn(obj,"query").and.callThrough(); spyOn(obj,"accept").and.callThrough(); spyOn(obj,"timeout").and.callThrough(); spyOn(obj, "withCredentials").and.callThrough(); spyOn(obj,"type").and.callThrough(); spyOn(obj,"send").and.callThrough(); spyOn(obj,"end").and.callThrough(); return obj; } beforeEach(function() { request = createMockRequest({ endError: false }); createReader = jasmine.createSpy("mockCreateReader"); ajaxHelpers = createAjaxHelpers({ request: request, createReader: createReader }); }); describe("with missing dependencies", function() { it("should throw error if dependencies.createReader is missing", function() { expect(function() { createAjaxHelpers({ request: request }); }).toThrowError("dependencies.createReader is mandatory!"); }); it("should throw error if dependencies.request is missing", function() { expect(function() { createAjaxHelpers({ createReader: createReader }); }).toThrowError("dependencies.request is mandatory!"); }); }); describe("with valid config", function() { describe("createOperationConfig", function() { it("should return a common object with properties of id, data and every property of config", function() { var config = { prop1: "prop1", prop2: "prop2" }; var data = "data"; var id = "id"; var operationConfig = ajaxHelpers.createOperationConfig(config, 3500, id, data); expect(operationConfig.prop1).toBe(config.prop1); expect(operationConfig.prop2).toBe(config.prop2); expect(operationConfig.data).toBe(data); expect(operationConfig.id).toBe(id); expect(operationConfig.timeout).toBe(3500); }); it("should return a common object with properties of id, every property of config and a data property containing an empty object", function() { var config = { prop1: "prop1", prop2: "prop2" }; var data; var id = "id"; var operationConfig = ajaxHelpers.createOperationConfig(config, 3500, id, data); expect(operationConfig.prop1).toBe(config.prop1); expect(operationConfig.prop2).toBe(config.prop2); expect(operationConfig.data).toEqual({}); expect(operationConfig.id).toBe(id); }); it("should set timeout property to defaultTimeout if timeout parameter is not truthy", function() { var operationConfig = ajaxHelpers.createOperationConfig({}, null); expect(operationConfig.timeout).toBe(3000); }); }); describe("dispatchAjax", function() { var actConfig; var callback; var manyRoutes; var read; beforeEach(function() { read = function() { return { err: "" }; }; actConfig = { route: "some route", timeout: 2000, idProperty: "id", method: "get", reader: { read: read } }; spyOn(actConfig.reader, "read").and.callThrough(); callback = jasmine.createSpy("callback"); manyRoutes = [ "some route 1", "some route 2", "some route 3" ]; }); describe("without filters", function() { describe("with one route", function() { it("has to call mocked request functions", function(done) { ajaxHelpers.dispatchAjax(actConfig, function() { expect(actConfig.reader.read).toHaveBeenCalledTimes(1); done(); }); expect(request.get).toHaveBeenCalledTimes(1); expect(request.query).toHaveBeenCalledTimes(1); expect(request.accept).toHaveBeenCalledTimes(1); expect(request.timeout).toHaveBeenCalledTimes(1); expect(request.withCredentials).toHaveBeenCalledTimes(1); expect(request.type).toHaveBeenCalledTimes(1); expect(request.send).toHaveBeenCalledTimes(1); expect(request.end).toHaveBeenCalledTimes(1); }); }); describe("with several methods", function() { it("has to call request.post when actConfig.method is post and has to call callback function", function(done) { actConfig.method = "post"; ajaxHelpers.dispatchAjax(actConfig, function() { done(); }); expect(request.post).toHaveBeenCalledTimes(1); }); it("has to call request.put when actConfig.method is put and has to call callback function", function(done) { actConfig.method = "put"; ajaxHelpers.dispatchAjax(actConfig, function() { expect(actConfig.reader.read).toHaveBeenCalledTimes(1); done(); }); expect(request.put).toHaveBeenCalledTimes(1); }); it("has to call request.del when actConfig.method is del and has to call callback function", function(done) { actConfig.method = "del"; ajaxHelpers.dispatchAjax(actConfig, function() { expect(actConfig.reader.read).toHaveBeenCalledTimes(1); done(); }); expect(request.del).toHaveBeenCalledTimes(1); }); }); describe("with many routes", function() { it("has to call request's methods 3 times", function(done) { request = createMockRequest({ endError: true }); ajaxHelpers = createAjaxHelpers({ request: request, createReader: createReader }); actConfig.route = manyRoutes; ajaxHelpers.dispatchAjax(actConfig, function(err) { expect(request.get).toHaveBeenCalledTimes(3); expect(request.query).toHaveBeenCalledTimes(3); expect(request.accept).toHaveBeenCalledTimes(3); expect(request.timeout).toHaveBeenCalledTimes(3); expect(request.withCredentials).toHaveBeenCalledTimes(3); expect(request.type).toHaveBeenCalledTimes(3); expect(request.send).toHaveBeenCalledTimes(3); expect(request.end).toHaveBeenCalledTimes(3); expect(actConfig.reader.read).not.toHaveBeenCalled(); expect(err).toBe("some error message"); done(); }); }); }); }); describe("with filters", function() { it("has to replace filter values in actRoute", function() { var filters = { "projectID": "2", "userID": "7" }; actConfig.route = "/some/path/to/request/projectID/:projectID/userID/:userID"; ajaxHelpers.dispatchAjax(actConfig, filters, callback); expect(request.get.calls.argsFor(0)[0]).toBe("/some/path/to/request/projectID/2/userID/7"); }); }); }); describe("prepareOperationsConfig", function() { describe("with invalid config", function() { it("should throw an error when config parameter is not an object", function() { expect(function() { ajaxHelpers.prepareOperationsConfig(); }).toThrowError("config.operations should be a config object"); expect(function() { ajaxHelpers.prepareOperationsConfig("notAnObject"); }).toThrowError("config.operations should be a config object"); }); it("should throw an error when one property's value of config is undefined", function() { expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: undefined }); }).toThrowError("prop should be configured"); expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: null }); }).toThrowError("prop should be configured"); }); it("should throw an error when one of config's properties hasn't property route and method with given truthy value", function() { expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: { notRouteProperty: "some value" } }); }).toThrowError("prop route should be configured"); expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: { route: undefined } }); }).toThrowError("prop route should be configured"); expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: { route: null } }); }).toThrowError("prop route should be configured"); expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: { route: "some value", notMethodProperty: "some other value" } }); }).toThrowError("prop method should be configured"); expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: { route: "some value", method: undefined } }); }).toThrowError("prop method should be configured"); expect(function() { ajaxHelpers.prepareOperationsConfig({ prop: { route: "some value", method: null } }); }).toThrowError("prop method should be configured"); }); }); describe("with valid config", function() { it("should have properties 'queries', 'accept', 'type', 'reader' of each property of config object after calling function prepareOperationsConfig", function() { var config = { prop1: { route: "some route", method: "some method" }, prop2: { route: "some other route", method: "some other method with CAPITAL LETTERS", queries: "some queries", accept: "some accept", type: "some type", reader: "some reader" }, read: { route: "read route", method: "read method" } }; ajaxHelpers.prepareOperationsConfig(config); expect(createReader).toHaveBeenCalled(); expect(createReader).toHaveBeenCalledTimes(3); expect(typeof config.prop1.queries).toBe("object"); expect(config.prop1.queries).toEqual({}); expect(config.prop1.accept).toBe("application/json"); expect(config.prop1.type).toBe("application/json"); expect(config.prop1.hasOwnProperty("reader")).toBe(true); expect(config.prop2.queries).toBe("some queries"); expect(config.prop2.accept).toBe("some accept"); expect(config.prop2.type).toBe("some type"); expect(config.prop2.reader).toBe(undefined); expect(typeof config.read.queries).toBe("object"); expect(config.read.queries).toEqual({}); expect(config.read.accept).toBe("application/json"); expect(config.read.type).toBe("application/json"); expect(config.read.hasOwnProperty("reader")).toBe(true); }); }); }); describe("assert", function() { it("should throw error when condition is not given", function() { expect(function() { ajaxHelpers.assert(); }).toThrowError("Assertion failed"); expect(function() { ajaxHelpers.assert(undefined,"Some error message"); }).toThrowError("Some error message"); expect(function() { ajaxHelpers.assert(null,"Custom error message"); }).toThrowError("Custom error message"); expect(function() { ajaxHelpers.assert("","Empty string message"); }).toThrowError("Empty string message"); expect(function() { ajaxHelpers.assert(false,"Condition false message"); }).toThrowError("Condition false message"); expect(function() { ajaxHelpers.assert(true,"Condition true message"); }).not.toThrowError("Condition true message"); }); }); }); });