mirror of
https://github.com/HabitRPG/habitica.git
synced 2025-12-16 06:07:21 +01:00
Add library to manage async resource Make Store reusable for easier testing Move plugin to libs Add getTaskFor getter with tests
151 lines
4.5 KiB
JavaScript
151 lines
4.5 KiB
JavaScript
import { asyncResourceFactory, loadAsyncResource } from 'client/libs/asyncResource';
|
|
import axios from 'axios';
|
|
import generateStore from 'client/store';
|
|
import { sleep } from '../../../../helpers/sleep';
|
|
|
|
describe('async resource', () => {
|
|
it('asyncResourceFactory', () => {
|
|
const resource = asyncResourceFactory();
|
|
expect(resource.loadingStatus).to.equal('NOT_LOADED');
|
|
expect(resource.data).to.equal(null);
|
|
expect(resource).to.not.equal(asyncResourceFactory);
|
|
});
|
|
|
|
describe('loadAsyncResource', () => {
|
|
context('errors', () => {
|
|
it('store is missing', () => {
|
|
expect(() => loadAsyncResource({})).to.throw;
|
|
});
|
|
it('path is missing', () => {
|
|
expect(() => loadAsyncResource({
|
|
store: 'store',
|
|
})).to.throw;
|
|
});
|
|
it('url is missing', () => {
|
|
expect(() => loadAsyncResource({
|
|
store: 'store',
|
|
path: 'path',
|
|
})).to.throw;
|
|
});
|
|
it('deserialize is missing', () => {
|
|
expect(() => loadAsyncResource({
|
|
store: 'store',
|
|
path: 'path',
|
|
url: 'url',
|
|
})).to.throw;
|
|
});
|
|
it('resource not found', () => {
|
|
const store = generateStore();
|
|
|
|
expect(() => loadAsyncResource({
|
|
store,
|
|
path: 'not existing path',
|
|
url: 'url',
|
|
deserialize: 'deserialize',
|
|
})).to.throw;
|
|
});
|
|
|
|
it('invalid loading status', () => {
|
|
const store = generateStore();
|
|
store.state.user.loadingStatus = 'INVALID';
|
|
|
|
expect(loadAsyncResource({
|
|
store,
|
|
path: 'user',
|
|
url: 'url',
|
|
deserialize: 'deserialize',
|
|
})).to.eventually.be.rejected;
|
|
});
|
|
});
|
|
|
|
it('returns the resource if it is already loaded and forceLoad is false', async () => {
|
|
const store = generateStore();
|
|
store.state.user.loadingStatus = 'LOADED';
|
|
store.state.user.data = {_id: 1};
|
|
|
|
sandbox.stub(axios, 'get');
|
|
|
|
const resource = await loadAsyncResource({
|
|
store,
|
|
path: 'user',
|
|
url: 'url',
|
|
deserialize: 'deserialize',
|
|
});
|
|
|
|
expect(resource).to.equal(store.state.user);
|
|
expect(axios.get).to.not.have.been.called;
|
|
});
|
|
|
|
it('load the resource if it is not loaded', async () => {
|
|
const store = generateStore();
|
|
store.state.user = asyncResourceFactory();
|
|
|
|
sandbox.stub(axios, 'get').withArgs('/api/v3/user').returns(Promise.resolve({data: {data: {_id: 1}}}));
|
|
|
|
const resource = await loadAsyncResource({
|
|
store,
|
|
path: 'user',
|
|
url: '/api/v3/user',
|
|
deserialize (response) {
|
|
return response.data.data;
|
|
},
|
|
});
|
|
|
|
expect(resource).to.equal(store.state.user);
|
|
expect(resource.loadingStatus).to.equal('LOADED');
|
|
expect(resource.data._id).to.equal(1);
|
|
expect(axios.get).to.have.been.calledOnce;
|
|
});
|
|
|
|
it('load the resource if it is loaded but forceLoad is true', async () => {
|
|
const store = generateStore();
|
|
store.state.user.loadingStatus = 'LOADED';
|
|
|
|
sandbox.stub(axios, 'get').withArgs('/api/v3/user').returns(Promise.resolve({data: {data: {_id: 1}}}));
|
|
|
|
const resource = await loadAsyncResource({
|
|
store,
|
|
path: 'user',
|
|
url: '/api/v3/user',
|
|
deserialize (response) {
|
|
return response.data.data;
|
|
},
|
|
forceLoad: true,
|
|
});
|
|
|
|
expect(resource).to.equal(store.state.user);
|
|
expect(resource.loadingStatus).to.equal('LOADED');
|
|
expect(resource.data._id).to.equal(1);
|
|
expect(axios.get).to.have.been.calledOnce;
|
|
});
|
|
|
|
it('does not send multiple requests if the resource is being loaded', async () => {
|
|
const store = generateStore();
|
|
store.state.user.loadingStatus = 'LOADING';
|
|
|
|
sandbox.stub(axios, 'get').withArgs('/api/v3/user').returns(Promise.resolve({data: {data: {_id: 1}}}));
|
|
|
|
const resourcePromise = loadAsyncResource({
|
|
store,
|
|
path: 'user',
|
|
url: '/api/v3/user',
|
|
deserialize (response) {
|
|
return response.data.data;
|
|
},
|
|
forceLoad: true,
|
|
});
|
|
|
|
await sleep(0.1);
|
|
const userData = {_id: 1};
|
|
|
|
expect(store.state.user.loadingStatus).to.equal('LOADING');
|
|
expect(axios.get).to.not.have.been.called;
|
|
store.state.user.data = userData;
|
|
store.state.user.loadingStatus = 'LOADED';
|
|
|
|
const result = await resourcePromise;
|
|
expect(axios.get).to.not.have.been.called;
|
|
expect(result).to.equal(store.state.user);
|
|
});
|
|
});
|
|
}); |