ajax_helpers.js 4.48 KB
Newer Older
1 2
define(['sinon', 'underscore'], function(sinon, _) {
    var fakeServer, fakeRequests, expectRequest, expectJsonRequest,
3
        respondWithJson, respondWithError, respondWithTextError, responseWithNoContent;
4

cahrens committed
5 6 7 8 9 10 11 12 13
    /* These utility methods are used by Jasmine tests to create a mock server or
     * get reference to mock requests. In either case, the cleanup (restore) is done with
     * an after function.
     *
     * This pattern is being used instead of the more common beforeEach/afterEach pattern
     * because we were seeing sporadic failures in the afterEach restore call. The cause of the
     * errors were that one test suite was incorrectly being linked as the parent of an unrelated
     * test suite (causing both suites' afterEach methods to be called). No solution for the root
     * cause has been found, but initializing sinon and cleaning it up on a method-by-method
14
     * basis seems to work. For more details, see STUD-1264.
cahrens committed
15 16 17 18 19 20
     */

    /**
     * Get a reference to the mocked server, and respond
     * to all requests with the specified statusCode.
     */
21
    fakeServer = function (statusCode, that) {
22 23 24 25 26 27 28 29
        var server = sinon.fakeServer.create();
        that.after(function() {
            server.restore();
        });
        server.respondWith([statusCode, {}, '']);
        return server;
    };

cahrens committed
30 31 32 33 34
    /**
     * Keep track of all requests to a fake server, and
     * return a reference to the Array. This allows tests
     * to respond for individual requests.
     */
35 36 37
    fakeRequests = function (that) {
        var requests = [],
            xhr = sinon.useFakeXMLHttpRequest();
38
        xhr.onCreate = function(request) {
39
            requests.push(request);
40 41 42 43 44 45 46 47 48
        };

        that.after(function() {
            xhr.restore();
        });

        return requests;
    };

49 50 51 52 53 54 55 56 57 58 59
    expectRequest = function(requests, method, url, body, requestIndex) {
        var request;
        if (_.isUndefined(requestIndex)) {
            requestIndex = requests.length - 1;
        }
        request = requests[requestIndex];
        expect(request.url).toEqual(url);
        expect(request.method).toEqual(method);
        expect(request.requestBody).toEqual(body);
    };

60 61 62 63 64 65 66 67 68 69 70
    expectJsonRequest = function(requests, method, url, jsonRequest, requestIndex) {
        var request;
        if (_.isUndefined(requestIndex)) {
            requestIndex = requests.length - 1;
        }
        request = requests[requestIndex];
        expect(request.url).toEqual(url);
        expect(request.method).toEqual(method);
        expect(JSON.parse(request.requestBody)).toEqual(jsonRequest);
    };

71
    respondWithJson = function(requests, jsonResponse, requestIndex) {
72 73 74
        if (_.isUndefined(requestIndex)) {
            requestIndex = requests.length - 1;
        }
75
        requests[requestIndex].respond(200,
76
            { 'Content-Type': 'application/json' },
77 78 79
            JSON.stringify(jsonResponse));
    };

80
    respondWithError = function(requests, statusCode, jsonResponse, requestIndex) {
81 82 83
        if (_.isUndefined(requestIndex)) {
            requestIndex = requests.length - 1;
        }
84 85 86 87 88 89 90
        if (_.isUndefined(statusCode)) {
            statusCode = 500;
        }
        if (_.isUndefined(jsonResponse)) {
            jsonResponse = {};
        }
        requests[requestIndex].respond(statusCode,
91
            { 'Content-Type': 'application/json' },
92 93
            JSON.stringify(jsonResponse)
        );
94 95
    };

96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111
    respondWithTextError = function(requests, statusCode, textResponse, requestIndex) {
        if (_.isUndefined(requestIndex)) {
            requestIndex = requests.length - 1;
        }
        if (_.isUndefined(statusCode)) {
            statusCode = 500;
        }
        if (_.isUndefined(textResponse)) {
            textResponse = "";
        }
        requests[requestIndex].respond(statusCode,
            { 'Content-Type': 'text/plain' },
            textResponse
        );
    };

112
    respondWithNoContent = function(requests, requestIndex) {
113 114 115 116
        if (_.isUndefined(requestIndex)) {
            requestIndex = requests.length - 1;
        }
        requests[requestIndex].respond(204,
117
            { 'Content-Type': 'application/json' });
118 119
    };

120
    return {
121 122 123 124 125 126
        'server': fakeServer,
        'requests': fakeRequests,
        'expectRequest': expectRequest,
        'expectJsonRequest': expectJsonRequest,
        'respondWithJson': respondWithJson,
        'respondWithError': respondWithError,
127
        'respondWithTextError': respondWithTextError,
128
        'respondWithNoContent': respondWithNoContent,
129 130
    };
});