@rest-api/react-models
Version:
[](https://www.npmjs.com/package/@rest-api/react-models) [](https://codecov.io/gh/hector7/rest-
1,025 lines (1,024 loc) • 59.7 kB
JavaScript
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
const __1 = require("../../../../");
require("jest-expect-message");
const fake_xml_http_request_1 = __importDefault(require("fake-xml-http-request"));
const redux_1 = require("redux");
const ReducerStorage_1 = __importDefault(require("../../ReducerStorage"));
const redux_thunk_1 = __importDefault(require("redux-thunk"));
describe('IT', () => {
it('fetch get the correct data from a identifier', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(200, {}, JSON.stringify({ id: 1 }));
}
};
const s = __1.Schema({
id: { required: true, type: Number }
});
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
const obj = ss._reducer.getById(root.getState(), 1);
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.hasOwnProperty('id')).toBeTruthy();
expect(obj.id).toBe(1);
let called = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
called = true;
}
};
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
expect(called, 'this not will be called').toBe(false);
}
});
it('validate fails', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(200, {}, JSON.stringify({ id: 1, date: '' }));
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
const obj = ss._reducer.getById(root.getState(), 1);
expect(obj).toBe(null);
expect(ss._reducer.getIdError(root.getState(), 1)).not.toBe(null);
});
it('Invalidate by id works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(200, {}, JSON.stringify({ id: 1, date: 1 }));
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
expect(ss._reducer.isIdInvalidated(root.getState(), 1)).toBeTruthy();
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
expect(ss._reducer.isIdInvalidated(root.getState(), 1)).toBeFalsy();
root.dispatch(ss._actions.invalidateById(1));
expect(ss._reducer.isIdInvalidated(root.getState(), 1)).toBeTruthy();
});
it('post works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
constructor() {
super(...arguments);
this.method = 'GET';
}
open(...args) {
super.open(...args);
this.method = args[0];
}
send() {
switch (this.method) {
case 'GET': return this.respond(200, {}, JSON.stringify([{ id: 1, date: 2 }]));
case 'POST': return this.respond(200, {}, JSON.stringify({ id: 2, date: 2 }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
expect(ss._reducer.isInvalidated(root.getState())).toBeFalsy();
root.dispatch(ss._actions.post({ date: new Date() }, () => { }));
expect(ss._reducer.getById(root.getState(), 2)).not.toBe(null);
expect(ss._reducer.isInvalidated(root.getState())).toBeTruthy();
});
it('put works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
constructor() {
super(...arguments);
this.method = 'GET';
}
open(...args) {
super.open(...args);
this.method = args[0];
}
send() {
switch (this.method) {
case 'GET': return this.respond(200, {}, JSON.stringify([{ id: 1, date: 2 }]));
case 'PUT': return this.respond(200, {}, JSON.stringify({ id: 1, date: 2 }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
expect(ss._reducer.isInvalidated(root.getState())).toBeFalsy();
expect(ss._reducer.getById(root.getState(), 1)).not.toBe(null);
root.dispatch(ss._actions.put(1, { id: 1, date: new Date() }, () => { }));
expect(ss._reducer.getById(root.getState(), 1)).not.toBe(null);
expect(ss._reducer.isInvalidated(root.getState())).toBeTruthy();
});
it('patch works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
constructor() {
super(...arguments);
this.method = 'GET';
}
open(...args) {
super.open(...args);
this.method = args[0];
}
send() {
switch (this.method) {
case 'GET': return this.respond(200, {}, JSON.stringify([{ id: 1, date: 2 }]));
case 'PATCH': return this.respond(200, {}, JSON.stringify({ id: 1, date: 2 }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
expect(ss._reducer.isInvalidated(root.getState())).toBeFalsy();
expect(ss._reducer.getById(root.getState(), 1)).not.toBe(null);
root.dispatch(ss._actions.patch(1, { id: 1, date: new Date() }, () => { }));
expect(ss._reducer.getById(root.getState(), 1)).not.toBe(null);
expect(ss._reducer.isInvalidated(root.getState())).toBeTruthy();
});
it('delete works', (d) => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
constructor() {
super(...arguments);
this.method = 'GET';
}
open(...args) {
super.open(...args);
this.method = args[0];
}
send() {
switch (this.method) {
case 'GET': return this.respond(200, {}, JSON.stringify([{ id: 1, date: 2 }]));
case 'DELETE': return this.respond(200, {}, JSON.stringify({ id: 1, date: 2 }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
expect(ss._reducer.isInvalidated(root.getState())).toBeFalsy();
expect(ss._reducer.getById(root.getState(), 1)).not.toBe(null);
root.dispatch(ss._actions.delete({ id: 1, date: new Date() }, (err) => {
if (err)
d(err);
expect(ss._reducer.getById(root.getState(), 1)).toBe(null);
expect(ss._reducer.isInvalidated(root.getState())).toBeTruthy();
d();
}));
});
it('fetch get the correct data from a identifier with updateSteps', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(200, {}, JSON.stringify({ id: 1, date: new Date().getTime() }));
}
};
const s = __1.Schema({
id: { required: true, type: Number },
date: { required: true, type: Number }
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
const obj = ss._reducer.getById(root.getState(), 1);
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.hasOwnProperty('id')).toBeTruthy();
expect(obj.hasOwnProperty('date')).toBeTruthy();
expect(obj.date.constructor).toBe(Date);
expect(obj.id).toBe(1);
let called = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
called = true;
}
};
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
expect(called, 'this not will be called').toBe(false);
}
});
it('fetch fails', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(500, {}, 'here the error');
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
date: { type: String, required: true },
objectType: {
type: __1.Schema({
hola: Number
}),
required: true
},
object: __1.Schema({
hola: { required: true, type: Number, }
}),
type: {
type: String,
required: true
},
r: [{
type: __1.Schema({
jeje: Number
}),
required: true
}]
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
const obj = ss._reducer.getError(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.codeNumber).toBe(500);
expect(obj.message).toBe('here the error');
}
});
it('fetch by id fails', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(500, {}, 'here the error');
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
date: { type: String, required: true },
objectType: {
type: __1.Schema({
hola: Number
}),
required: true
},
object: __1.Schema({
hola: { required: true, type: Number, }
}),
type: {
type: String,
required: true
},
r: [{
type: __1.Schema({
jeje: Number
}),
required: true
}]
}).updateField('date', date => new Date(date));
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchByIdIfNeeded(1));
const obj = ss._reducer.getIdError(root.getState(), 1);
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.codeNumber).toBe(500);
expect(obj.message).toBe('here the error');
}
});
it('invalidate works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(200, {}, JSON.stringify([
{ id: 1, name: ['jose'] },
{ id: 2, name: ['hector'] },
{ id: 3, name: ['pepito'] },
{ id: 4, name: ['albert'] }
]));
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
const obj = ss._reducer.get(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(Array.isArray(obj), 'response is an array').toBe(true);
expect(obj.length).toBe(4);
expect(obj[0].id).toBe(1);
expect(Array.isArray(obj[0].name), 'name is an array').toBe(true);
expect(obj[0].name.length).toBe(1);
expect(obj[0].name[0]).toBe('jose');
let called = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
called = true;
}
};
root.dispatch(ss._actions.fetchIfNeeded());
expect(called, 'this not will be called').toBe(false);
expect(ss._reducer.isInvalidated(root.getState())).toBeFalsy();
root.dispatch(ss._actions.invalidate());
expect(ss._reducer.isInvalidated(root.getState())).toBeTruthy();
}
});
it('fetch get the correct data from all objects', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
this.respond(200, {}, JSON.stringify([
{ id: 1, name: ['jose'] },
{ id: 2, name: ['hector'] },
{ id: 3, name: ['pepito'] },
{ id: 4, name: ['albert'] }
]));
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const ss = new __1.Model(s, 'id', '/api/rest');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(ss._actions.fetchIfNeeded());
const obj = ss._reducer.get(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(Array.isArray(obj), 'response is an array').toBe(true);
expect(obj.length).toBe(4);
expect(obj[0].id).toBe(1);
expect(Array.isArray(obj[0].name), 'name is an array').toBe(true);
expect(obj[0].name.length).toBe(1);
expect(obj[0].name[0]).toBe('jose');
let called = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
called = true;
}
};
root.dispatch(ss._actions.fetchIfNeeded());
expect(called, 'this not will be called').toBe(false);
}
});
it('simple fetch populate is working', () => {
let called_global = false;
let called_populated = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
called_global = true;
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: 1 }
]));
case '/populatedResponse/1':
called_populated = true;
return this.respond(200, {}, JSON.stringify({ id: 1, name: ['jose'] }));
}
}
};
const ss = new __1.Model(__1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
}), 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: { type: ss, idOnly: true } }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = ss._reducer.get(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(called_global).toBeTruthy();
expect(called_populated).toBeTruthy();
}
});
it('simple fetch with schema populate is working', () => {
let called_populated = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: { model: 1 } }
]));
case '/populatedResponse/1':
called_populated = true;
return this.respond(200, {}, JSON.stringify({ id: 1, name: ['jose'] }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const ss = new __1.Model(s, 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: __1.Schema({ model: { type: ss, idOnly: true } }) }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = ss._reducer.get(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(called_populated, 'populate calls by id inside a schema').toBe(true);
}
});
it('populate of populate is working', () => {
let called_populated = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: [1] }
]));
case '/populatedResponse/1':
return this.respond(200, {}, JSON.stringify({ id: 1, model: 2 }));
case '/populatedResponse2/2':
called_populated = true;
return this.respond(200, {}, JSON.stringify({ id: 2, name: ['jose'] }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const tt = new __1.Model(s, 'id', '/populatedResponse2');
const ss = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: { type: tt, idOnly: true } }), 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: [{ type: ss, required: true, idOnly: true }] }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj1 = ss._reducer.getPopulated(root.getState());
expect(ss._reducer.isPopulated(root.getState())).toBeTruthy();
//first time is not in redux, so is not fetched.
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = ss._reducer.get(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(called_populated, 'populate call model of model is not working').toBe(true);
}
});
it('populated in progress is working', () => {
let called_populated = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: [1, 2] }
]));
case '/populatedResponse/1':
return this.respond(200, {}, JSON.stringify({ id: 1, model: 2 }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number },
name: [{ type: String, required: true }],
});
const tt = new __1.Model(s, 'id', '/populatedResponse2');
s.updateSchema({ d: { type: s, } });
const ss = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: { type: tt, idOnly: true } }), 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: [{ type: ss, required: true, idOnly: true }] }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj1 = cc._reducer.getPopulated(root.getState());
expect(cc._reducer.isPopulated(root.getState())).toBeFalsy();
//first time is not in redux, so is not fetched.
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = cc._reducer.getPopulated(root.getState());
expect(cc._reducer.isPopulated(root.getState())).toBeFalsy();
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj[0].model[0].model.id, 'id is not equal to id').toBe(2);
expect(obj[0].model[0].model.name, 'this should be undefined as not a fetched object').toBe(undefined);
}
});
it('getItems is working', () => {
let called_populated = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse/':
called_populated = true;
return this.respond(200, {}, JSON.stringify({
count: 100,
results: [{ id: 1 }, { id: 2 }]
}));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number },
name: [{ type: String, required: true }],
});
const tt = new __1.Model(s, 'id', '/generalResponse', __1.Schema({ count: Number, results: [{ type: s, required: __1.required }] }), (el) => el.results, (el) => el.count, { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(tt._actions.fetchIfNeeded());
expect(called_populated).toBeTruthy();
const obj = tt._reducer.get(root.getState());
const metadata = tt._reducer.getMetadata(root.getState());
expect(obj.length).toBe(2);
expect(metadata).toBe(100);
});
it('simple get populate is working', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: 1 }
]));
case '/populatedResponse/1':
return this.respond(200, {}, JSON.stringify({ id: 1, name: ['jose'] }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const ss = new __1.Model(s, 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: { type: ss, idOnly: true } }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
//second call
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = cc._reducer.getPopulated(root.getState());
expect(cc._reducer.isPopulated(root.getState())).toBeTruthy();
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
expect(first.model, 'model is undefined?').not.toBe(undefined);
expect(first.model.id, 'expecting populate id').toBe(1);
expect(Array.isArray(first.model.name)).toBeTruthy();
}
});
it('simple get populate is working with trailing slash', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse/':
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: 1 }
]));
case '/populatedResponse/1':
return this.respond(200, {}, JSON.stringify({ id: 1, name: ['jose'] }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const ss = new __1.Model(s, 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: { type: ss, idOnly: true } }), 'id', '/generalResponse', { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
//second call
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = cc._reducer.getPopulated(root.getState());
expect(cc._reducer.isPopulated(root.getState())).toBeTruthy();
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
expect(first.model, 'model is undefined?').not.toBe(undefined);
expect(first.model.id, 'expecting populate id').toBe(1);
expect(Array.isArray(first.model.name)).toBeTruthy();
}
});
it('simple get with schema populate is working', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: { model: 1 } }
]));
case '/populatedResponse/1':
return this.respond(200, {}, JSON.stringify({ id: 1, name: ['jose'] }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const ss = new __1.Model(s, 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: __1.Schema({ model: { type: ss, idOnly: true } }) }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = cc._reducer.getPopulated(root.getState());
expect(cc._reducer.isPopulated(root.getState())).toBeTruthy();
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
expect(first.model, 'model is undefined?').not.toBe(undefined);
expect(first.model.model, 'model is undefined?').not.toBe(undefined);
expect(first.model.model.id, 'expecting populate id').toBe(1);
expect(Array.isArray(first.model.model.name)).toBeTruthy();
}
});
it('get populate of populate is working', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
return this.respond(200, {}, JSON.stringify([
{ id: 1, subType: { model: 1 } }
]));
case '/populatedResponse/1':
return this.respond(200, {}, JSON.stringify({ id: 1, model: 2 }));
case '/populatedResponse2/2':
return this.respond(200, {}, JSON.stringify({ id: 2, name: ['jose'] }));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const tt = new __1.Model(s, 'id', '/populatedResponse2');
const ss = new __1.Model(__1.Schema({ id: { required: true, type: Number }, model: { type: tt, idOnly: true } }), 'id', '/populatedResponse');
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number }, subType: { type: __1.Schema({ model: { type: ss, idOnly: true } }), required: __1.required } }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
//first time is not in redux, so is not fetched.
root.dispatch(cc._actions.fetchPopulatedIfNeeded());
const obj = cc._reducer.getPopulated(root.getState());
expect(cc._reducer.isPopulated(root.getState())).toBeTruthy();
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
expect(first.subType.model, 'model is undefined?').not.toBe(undefined);
expect(first.subType.model.model, 'model is undefined?').not.toBe(undefined);
expect(first.subType.model.model.id, 'expecting populate id').toBe(2);
expect(Array.isArray(first.subType.model.model.name)).toBeTruthy();
}
});
it('get populate of populate is working on real case', (d) => {
let called_faculty = false;
let called_level = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/user_has_level/':
return this.respond(200, {}, JSON.stringify([
{ id: 1, name: 'test', levels: [{ faculty: 1, level: 1 }] }
]));
case '/api/faculty/1/':
return setTimeout(() => {
called_faculty = true;
this.respond(200, {}, JSON.stringify({ id: 1, name: 'e' }));
}, 20);
case '/api/level/1/':
return setTimeout(() => {
called_level = true;
this.respond(200, {}, JSON.stringify({ id: 1, name: 'e' }));
}, 20);
}
}
};
const FacultySchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String, required: __1.required }
});
const levelSchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String, required: __1.required }
});
const Level = new __1.Model(levelSchema, 'id', '/api/level', { trailingSlash: true });
const Faculty = new __1.Model(FacultySchema, 'id', '/api/faculty', { trailingSlash: true });
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const subUserHasLevelSchema = __1.Schema({
faculty: { type: Faculty, required: true, idOnly: true },
faculty_name: String,
level: { type: Level, required: true, idOnly: true },
level_name: String
});
const UserHasLevelSchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String },
levels: [{ type: subUserHasLevelSchema, required: __1.required }]
});
const UserHasLevel = new __1.Model(UserHasLevelSchema, 'id', '/api/user_has_level', { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(UserHasLevel._actions.fetchPopulatedIfNeeded());
expect(UserHasLevel._reducer.isPopulated(root.getState())).toBeFalsy();
root.dispatch(UserHasLevel._actions.fetchPopulatedIfNeeded());
setTimeout(() => {
expect(UserHasLevel._reducer.isPopulated(root.getState())).toBeTruthy();
const obj = UserHasLevel._reducer.getPopulated(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
expect(Array.isArray(first.levels)).toBeTruthy();
d();
}
}, 30);
});
it('get populate of populate is working on real case', (d) => {
let called_faculty = false;
let called_level = false;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/user_has_level/':
return this.respond(200, {}, JSON.stringify([
{ id: 1, name: 'test', level: { faculty: 1, level: 1 } }
]));
case '/api/faculty/1/':
return setTimeout(() => {
called_faculty = true;
this.respond(200, {}, JSON.stringify({ id: 1, name: 'e' }));
}, 20);
case '/api/level/1/':
return setTimeout(() => {
called_level = true;
this.respond(200, {}, JSON.stringify({ id: 1, name: 'e' }));
}, 20);
}
}
};
const FacultySchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String, required: __1.required }
});
const levelSchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String, required: __1.required }
});
const Level = new __1.Model(levelSchema, 'id', '/api/level', { trailingSlash: true });
const Faculty = new __1.Model(FacultySchema, 'id', '/api/faculty', { trailingSlash: true });
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const subUserHasLevelSchema = __1.Schema({
faculty: { type: Faculty, required: true, idOnly: true },
faculty_name: String,
level: { type: Level, required: true, idOnly: true },
level_name: String
});
const UserHasLevelSchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String },
level: { type: subUserHasLevelSchema, required: __1.required }
});
const UserHasLevel = new __1.Model(UserHasLevelSchema, 'id', '/api/user_has_level', { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(UserHasLevel._actions.fetchPopulatedIfNeeded());
expect(UserHasLevel._reducer.isPopulated(root.getState())).toBeFalsy();
root.dispatch(UserHasLevel._actions.fetchPopulatedIfNeeded());
setTimeout(() => {
expect(UserHasLevel._reducer.isPopulated(root.getState())).toBeTruthy();
const obj = UserHasLevel._reducer.getPopulated(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
d();
}
}, 30);
});
it('get populate of populate is working on real case (autopopulated)', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/user_has_level/':
return this.respond(200, {}, JSON.stringify([
{ id: 1, name: 'test', levels: [{ faculty: { id: 1, name: 'e' }, level: { id: 1, name: 'e' } }] }
]));
case '/api/faculty/1/':
return this.respond(500, {}, JSON.stringify({ id: 1, name: 'e' }));
case '/api/level/1/':
return this.respond(500, {}, JSON.stringify({ id: 1, name: 'e' }));
}
}
};
const FacultySchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String, required: __1.required }
});
const levelSchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String, required: __1.required }
});
const Level = new __1.Model(levelSchema, 'id', '/api/level', { trailingSlash: true });
const Faculty = new __1.Model(FacultySchema, 'id', '/api/faculty', { trailingSlash: true });
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const subUserHasLevelSchema = __1.Schema({
faculty: { type: Faculty, required: true, },
faculty_name: String,
level: { type: Level, required: true, },
level_name: String
});
const UserHasLevelSchema = __1.Schema({
id: { type: Number, required: __1.required },
name: { type: String },
levels: [{ type: subUserHasLevelSchema, required: __1.required }]
});
const UserHasLevel = new __1.Model(UserHasLevelSchema, 'id', '/api/user_has_level', { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(UserHasLevel._actions.fetchPopulatedIfNeeded());
expect(UserHasLevel._reducer.isPopulated(root.getState())).toBeTruthy();
const obj = UserHasLevel._reducer.getPopulated(root.getState());
expect(obj).not.toBe(null);
if (obj !== null) {
expect(obj.length).toBe(1);
const first = obj[0];
expect(first.id).toBe(1);
expect(Array.isArray(first.levels)).toBeTruthy();
}
});
it('invalidate is working', () => {
let called = 0;
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/generalResponse':
called++;
return this.respond(200, {}, JSON.stringify([
{ id: 1, model: 1 }
]));
}
}
};
const s = __1.Schema({
id: { required: true, type: Number, },
name: [{ type: String, required: true }],
});
const cc = new __1.Model(__1.Schema({ id: { required: true, type: Number } }), 'id', '/generalResponse');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(cc._actions.fetchIfNeeded());
root.dispatch(cc._actions.invalidateAll());
root.dispatch(cc._actions.fetchIfNeeded());
expect(called).toBe(2);
});
it('getItem without metadata and routeopts works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/example':
return this.respond(200, {}, JSON.stringify({
items: [
{ id: 1, name: 'Book 1' }
]
}));
}
}
};
const bookSchema = __1.Schema({
id: {
type: Number,
required: true
},
name: String,
});
const model = new __1.Model(bookSchema, 'id', '/api/example', __1.Schema({ items: [{ type: bookSchema, required: true }] }), d => d.items);
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(model._actions.fetchIfNeeded());
expect(model._reducer.get(root.getState())[0].id).toBe(1);
expect(model._reducer.getMetadata(root.getState())).toBe(null);
});
it('getItem without metadata but with routeopts works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/example/':
return this.respond(200, {}, JSON.stringify({
items: [
{ id: 1, name: 'Book 1' }
]
}));
}
}
};
const bookSchema = __1.Schema({
id: {
type: Number,
required: true
},
name: String,
});
const model = new __1.Model(bookSchema, 'id', '/api/example', __1.Schema({ items: [{ type: bookSchema, required: true }] }), d => d.items, { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(model._actions.fetchIfNeeded());
expect(model._reducer.get(root.getState())[0].id).toBe(1);
expect(model._reducer.getMetadata(root.getState())).toBe(null);
});
it('getItem with metadata and without routeopts works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/example':
return this.respond(200, {}, JSON.stringify({
items: [
{ id: 1, name: 'Book 1' }
]
}));
}
}
};
const bookSchema = __1.Schema({
id: {
type: Number,
required: true
},
name: String,
});
const model = new __1.Model(bookSchema, 'id', '/api/example', __1.Schema({ items: [{ type: bookSchema, required: true }] }), d => d.items, d => d.items.length);
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(model._actions.fetchIfNeeded());
expect(model._reducer.get(root.getState())[0].id).toBe(1);
expect(model._reducer.getMetadata(root.getState())).toBe(1);
});
it('getItem with metadata but with routeopts works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/example/':
return this.respond(200, {}, JSON.stringify({
items: [
{ id: 1, name: 'Book 1' }
]
}));
}
}
};
const bookSchema = __1.Schema({
id: {
type: Number,
required: true
},
name: String,
});
const model = new __1.Model(bookSchema, 'id', '/api/example', __1.Schema({ items: [{ type: bookSchema, required: true }] }), d => d.items, d => d.items.length, { trailingSlash: true });
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(model._actions.fetchIfNeeded());
expect(model._reducer.get(root.getState())[0].id).toBe(1);
expect(model._reducer.getMetadata(root.getState())).toBe(1);
});
it('getSubModel with key works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {
send() {
switch (this.responseURL) {
case '/api/example/Book 1':
return this.respond(200, {}, JSON.stringify({ id: 1, name: 'Book 1' }));
}
}
};
const bookSchema = __1.Schema({
id: {
type: Number,
required: true
},
name: {
type: String,
required: true
},
});
const model = new __1.Model(bookSchema, 'id', '/api/example').getSubModelWithKey('name');
const root = redux_1.createStore(ReducerStorage_1.default.generalReducer, {}, redux_1.applyMiddleware(redux_thunk_1.default));
root.dispatch(model._actions.fetchByIdIfNeeded('Book 1'));
expect(model._reducer.getById(root.getState(), 'Book 1').id).toBe(1);
});
it('getSubModel root with key works', () => {
global.XMLHttpRequest = class XMLHttpRequest extends fake_xml_http_request_1.default {