gitlab-org--gitlab-foss/spec/javascripts/lib/utils/ajax_cache_spec.js

199 lines
5.5 KiB
JavaScript

import AjaxCache from '~/lib/utils/ajax_cache';
describe('AjaxCache', () => {
const dummyEndpoint = '/AjaxCache/dummyEndpoint';
const dummyResponse = {
important: 'dummy data',
};
beforeEach(() => {
AjaxCache.internalStorage = { };
AjaxCache.pendingRequests = { };
});
describe('get', () => {
it('returns undefined if cache is empty', () => {
const data = AjaxCache.get(dummyEndpoint);
expect(data).toBe(undefined);
});
it('returns undefined if cache contains no matching data', () => {
AjaxCache.internalStorage['not matching'] = dummyResponse;
const data = AjaxCache.get(dummyEndpoint);
expect(data).toBe(undefined);
});
it('returns matching data', () => {
AjaxCache.internalStorage[dummyEndpoint] = dummyResponse;
const data = AjaxCache.get(dummyEndpoint);
expect(data).toBe(dummyResponse);
});
});
describe('hasData', () => {
it('returns false if cache is empty', () => {
expect(AjaxCache.hasData(dummyEndpoint)).toBe(false);
});
it('returns false if cache contains no matching data', () => {
AjaxCache.internalStorage['not matching'] = dummyResponse;
expect(AjaxCache.hasData(dummyEndpoint)).toBe(false);
});
it('returns true if data is available', () => {
AjaxCache.internalStorage[dummyEndpoint] = dummyResponse;
expect(AjaxCache.hasData(dummyEndpoint)).toBe(true);
});
});
describe('remove', () => {
it('does nothing if cache is empty', () => {
AjaxCache.remove(dummyEndpoint);
expect(AjaxCache.internalStorage).toEqual({ });
});
it('does nothing if cache contains no matching data', () => {
AjaxCache.internalStorage['not matching'] = dummyResponse;
AjaxCache.remove(dummyEndpoint);
expect(AjaxCache.internalStorage['not matching']).toBe(dummyResponse);
});
it('removes matching data', () => {
AjaxCache.internalStorage[dummyEndpoint] = dummyResponse;
AjaxCache.remove(dummyEndpoint);
expect(AjaxCache.internalStorage).toEqual({ });
});
});
describe('override', () => {
it('overrides existing cache', () => {
AjaxCache.internalStorage.endpoint = 'existing-endpoint';
AjaxCache.override('endpoint', 'new-endpoint');
expect(AjaxCache.internalStorage.endpoint).toEqual('new-endpoint');
});
});
describe('retrieve', () => {
let ajaxSpy;
beforeEach(() => {
spyOn(jQuery, 'ajax').and.callFake(url => ajaxSpy(url));
});
it('stores and returns data from Ajax call if cache is empty', (done) => {
ajaxSpy = (url) => {
expect(url).toBe(dummyEndpoint);
const deferred = $.Deferred();
deferred.resolve(dummyResponse);
return deferred.promise();
};
AjaxCache.retrieve(dummyEndpoint)
.then((data) => {
expect(data).toBe(dummyResponse);
expect(AjaxCache.internalStorage[dummyEndpoint]).toBe(dummyResponse);
})
.then(done)
.catch(fail);
});
it('makes no Ajax call if request is pending', () => {
const responseDeferred = $.Deferred();
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)
.then(unexpectedResponse)
.catch(fail);
AjaxCache.retrieve(dummyEndpoint)
.then(unexpectedResponse)
.catch(fail);
expect($.ajax.calls.count()).toBe(1);
});
it('returns undefined if Ajax call fails and cache is empty', (done) => {
const dummyStatusText = 'exploded';
const dummyErrorMessage = 'server exploded';
ajaxSpy = (url) => {
expect(url).toBe(dummyEndpoint);
const deferred = $.Deferred();
deferred.reject(null, dummyStatusText, dummyErrorMessage);
return deferred.promise();
};
AjaxCache.retrieve(dummyEndpoint)
.then(data => fail(`Received unexpected data: ${JSON.stringify(data)}`))
.catch((error) => {
expect(error.message).toBe(`${dummyEndpoint}: ${dummyErrorMessage}`);
expect(error.textStatus).toBe(dummyStatusText);
done();
})
.catch(fail);
});
it('makes no Ajax call if matching data exists', (done) => {
AjaxCache.internalStorage[dummyEndpoint] = dummyResponse;
ajaxSpy = () => fail(new Error('expected no Ajax call!'));
AjaxCache.retrieve(dummyEndpoint)
.then((data) => {
expect(data).toBe(dummyResponse);
})
.then(done)
.catch(fail);
});
it('makes Ajax call even if matching data exists when forceRequest parameter is provided', (done) => {
const oldDummyResponse = {
important: 'old dummy data',
};
AjaxCache.internalStorage[dummyEndpoint] = oldDummyResponse;
ajaxSpy = (url) => {
expect(url).toBe(dummyEndpoint);
const deferred = $.Deferred();
deferred.resolve(dummyResponse);
return deferred.promise();
};
// Call without forceRetrieve param
AjaxCache.retrieve(dummyEndpoint)
.then((data) => {
expect(data).toBe(oldDummyResponse);
})
.then(done)
.catch(fail);
// Call with forceRetrieve param
AjaxCache.retrieve(dummyEndpoint, true)
.then((data) => {
expect(data).toBe(dummyResponse);
})
.then(done)
.catch(fail);
});
});
});