Commit ae401d03 authored by Phil Hughes's avatar Phil Hughes

Converted ajax_cache to axios

parent 3ae2d90b
import axios from './axios_utils';
import Cache from './cache'; import Cache from './cache';
class AjaxCache extends Cache { class AjaxCache extends Cache {
...@@ -18,22 +19,15 @@ class AjaxCache extends Cache { ...@@ -18,22 +19,15 @@ class AjaxCache extends Cache {
let pendingRequest = this.pendingRequests[endpoint]; let pendingRequest = this.pendingRequests[endpoint];
if (!pendingRequest) { if (!pendingRequest) {
pendingRequest = new Promise((resolve, reject) => { pendingRequest = axios.get(endpoint)
// jQuery 2 is not Promises/A+ compatible (missing catch) .then(({ data }) => {
$.ajax(endpoint) // eslint-disable-line promise/catch-or-return
.then(data => resolve(data),
(jqXHR, textStatus, errorThrown) => {
const error = new Error(`${endpoint}: ${errorThrown}`);
error.textStatus = textStatus;
reject(error);
},
);
})
.then((data) => {
this.internalStorage[endpoint] = data; this.internalStorage[endpoint] = data;
delete this.pendingRequests[endpoint]; delete this.pendingRequests[endpoint];
}) })
.catch((error) => { .catch((e) => {
const error = new Error(`${endpoint}: ${e.message}`);
error.textStatus = e.message;
delete this.pendingRequests[endpoint]; delete this.pendingRequests[endpoint];
throw error; throw error;
}); });
......
import MockAdapter from 'axios-mock-adapter';
import axios from '~/lib/utils/axios_utils';
import AjaxCache from '~/lib/utils/ajax_cache'; import AjaxCache from '~/lib/utils/ajax_cache';
describe('AjaxCache', () => { describe('AjaxCache', () => {
...@@ -86,67 +88,55 @@ describe('AjaxCache', () => { ...@@ -86,67 +88,55 @@ describe('AjaxCache', () => {
}); });
}); });
describe('retrieve', () => { fdescribe('retrieve', () => {
let ajaxSpy; let ajaxSpy;
let mock;
beforeEach(() => { beforeEach(() => {
spyOn(jQuery, 'ajax').and.callFake(url => ajaxSpy(url)); mock = new MockAdapter(axios);
spyOn(axios, 'get').and.callThrough();
});
afterEach(() => {
mock.restore();
}); });
it('stores and returns data from Ajax call if cache is empty', (done) => { it('stores and returns data from Ajax call if cache is empty', (done) => {
ajaxSpy = (url) => { mock.onGet(dummyEndpoint).reply(200, dummyResponse);
expect(url).toBe(dummyEndpoint);
const deferred = $.Deferred();
deferred.resolve(dummyResponse);
return deferred.promise();
};
AjaxCache.retrieve(dummyEndpoint) AjaxCache.retrieve(dummyEndpoint)
.then((data) => { .then((data) => {
expect(data).toBe(dummyResponse); expect(data).toEqual(dummyResponse);
expect(AjaxCache.internalStorage[dummyEndpoint]).toBe(dummyResponse); expect(AjaxCache.internalStorage[dummyEndpoint]).toEqual(dummyResponse);
}) })
.then(done) .then(done)
.catch(fail); .catch(fail);
}); });
it('makes no Ajax call if request is pending', () => { it('makes no Ajax call if request is pending', (done) => {
const responseDeferred = $.Deferred(); mock.onGet(dummyEndpoint).reply(200, dummyResponse);
ajaxSpy = (url) => {
expect(url).toBe(dummyEndpoint);
// neither reject nor resolve to keep request pending
return responseDeferred.promise();
};
const unexpectedResponse = data => fail(`Did not expect response: ${data}`);
AjaxCache.retrieve(dummyEndpoint) AjaxCache.retrieve(dummyEndpoint)
.then(unexpectedResponse) .then(done)
.catch(fail); .catch(fail);
AjaxCache.retrieve(dummyEndpoint) AjaxCache.retrieve(dummyEndpoint)
.then(unexpectedResponse) .then(done)
.catch(fail); .catch(fail);
expect($.ajax.calls.count()).toBe(1); expect(axios.get.calls.count()).toBe(1);
}); });
it('returns undefined if Ajax call fails and cache is empty', (done) => { it('returns undefined if Ajax call fails and cache is empty', (done) => {
const dummyStatusText = 'exploded'; const errorMessage = 'Network Error';
const dummyErrorMessage = 'server exploded'; mock.onGet(dummyEndpoint).networkError();
ajaxSpy = (url) => {
expect(url).toBe(dummyEndpoint);
const deferred = $.Deferred();
deferred.reject(null, dummyStatusText, dummyErrorMessage);
return deferred.promise();
};
AjaxCache.retrieve(dummyEndpoint) AjaxCache.retrieve(dummyEndpoint)
.then(data => fail(`Received unexpected data: ${JSON.stringify(data)}`)) .then(data => fail(`Received unexpected data: ${JSON.stringify(data)}`))
.catch((error) => { .catch((error) => {
expect(error.message).toBe(`${dummyEndpoint}: ${dummyErrorMessage}`); expect(error.message).toBe(`${dummyEndpoint}: ${errorMessage}`);
expect(error.textStatus).toBe(dummyStatusText); expect(error.textStatus).toBe(errorMessage);
done(); done();
}) })
.catch(fail); .catch(fail);
...@@ -154,7 +144,9 @@ describe('AjaxCache', () => { ...@@ -154,7 +144,9 @@ describe('AjaxCache', () => {
it('makes no Ajax call if matching data exists', (done) => { it('makes no Ajax call if matching data exists', (done) => {
AjaxCache.internalStorage[dummyEndpoint] = dummyResponse; AjaxCache.internalStorage[dummyEndpoint] = dummyResponse;
ajaxSpy = () => fail(new Error('expected no Ajax call!')); mock.onGet(dummyEndpoint).reply(() => {
fail(new Error('expected no Ajax call!'));
});
AjaxCache.retrieve(dummyEndpoint) AjaxCache.retrieve(dummyEndpoint)
.then((data) => { .then((data) => {
...@@ -171,12 +163,7 @@ describe('AjaxCache', () => { ...@@ -171,12 +163,7 @@ describe('AjaxCache', () => {
AjaxCache.internalStorage[dummyEndpoint] = oldDummyResponse; AjaxCache.internalStorage[dummyEndpoint] = oldDummyResponse;
ajaxSpy = (url) => { mock.onGet(dummyEndpoint).reply(200, dummyResponse);
expect(url).toBe(dummyEndpoint);
const deferred = $.Deferred();
deferred.resolve(dummyResponse);
return deferred.promise();
};
// Call without forceRetrieve param // Call without forceRetrieve param
AjaxCache.retrieve(dummyEndpoint) AjaxCache.retrieve(dummyEndpoint)
...@@ -189,7 +176,7 @@ describe('AjaxCache', () => { ...@@ -189,7 +176,7 @@ describe('AjaxCache', () => {
// Call with forceRetrieve param // Call with forceRetrieve param
AjaxCache.retrieve(dummyEndpoint, true) AjaxCache.retrieve(dummyEndpoint, true)
.then((data) => { .then((data) => {
expect(data).toBe(dummyResponse); expect(data).toEqual(dummyResponse);
}) })
.then(done) .then(done)
.catch(fail); .catch(fail);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment