Added some new tests
This commit is contained in:
parent
0039a8b4ec
commit
918f873fea
15 changed files with 887 additions and 114 deletions
|
@ -21,6 +21,7 @@ testing:
|
||||||
script:
|
script:
|
||||||
- yarn install
|
- yarn install
|
||||||
- ./node_modules/.bin/sequelize db:migrate
|
- ./node_modules/.bin/sequelize db:migrate
|
||||||
|
- ./node_modules/.bin/sequelize db:seed:all
|
||||||
- yarn test --ci --collectCoverage=true --coverage
|
- yarn test --ci --collectCoverage=true --coverage
|
||||||
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
|
coverage: /All files[^|]*\|[^|]*\s+([\d\.]+)/
|
||||||
artifacts:
|
artifacts:
|
||||||
|
|
|
@ -22,20 +22,20 @@ class Middleware extends QueryBuilder {
|
||||||
*/
|
*/
|
||||||
createOne(req, callback) {
|
createOne(req, callback) {
|
||||||
// On test les droits
|
// On test les droits
|
||||||
if (!this._haveRight(req)) {
|
if (!this.haveRight(req)) {
|
||||||
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On teste le body
|
// On teste le body
|
||||||
this._checkCreateOneValues(req, (err, value) => {
|
this.checkCreateOneValues(req, (err, value) => {
|
||||||
// Il manque un paramètre dans le body
|
// Il manque un paramètre dans le body
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, value);
|
callback(err, value);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this._insertItem(req, value, callback);
|
this.insertItem(req, value, callback);
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
@ -50,7 +50,7 @@ class Middleware extends QueryBuilder {
|
||||||
// On spécifie le type de requête (list ou item)
|
// On spécifie le type de requête (list ou item)
|
||||||
req.getType = "list";
|
req.getType = "list";
|
||||||
|
|
||||||
this._createQuery(req, (err, query, limit) => {
|
this.createQuery(req, (err, query, limit) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, query);
|
callback(err, query);
|
||||||
return false;
|
return false;
|
||||||
|
@ -82,8 +82,8 @@ class Middleware extends QueryBuilder {
|
||||||
const values = rows.slice(limit.start, limit.start + limit.limit);
|
const values = rows.slice(limit.start, limit.start + limit.limit);
|
||||||
|
|
||||||
callback(null, {
|
callback(null, {
|
||||||
data: this._formatItems(req, values),
|
data: this.formatItems(req, values),
|
||||||
...QueryBuilder._createPagination(
|
...QueryBuilder.createPagination(
|
||||||
req,
|
req,
|
||||||
total,
|
total,
|
||||||
limit.limit,
|
limit.limit,
|
||||||
|
@ -108,7 +108,7 @@ class Middleware extends QueryBuilder {
|
||||||
// On spécifie le type de requête (list ou item)
|
// On spécifie le type de requête (list ou item)
|
||||||
req.getType = "item";
|
req.getType = "item";
|
||||||
|
|
||||||
this._createQuery(req, (err, query) => {
|
this.createQuery(req, (err, query) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, query);
|
callback(err, query);
|
||||||
return false;
|
return false;
|
||||||
|
@ -122,13 +122,16 @@ class Middleware extends QueryBuilder {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
let formatedItem = item;
|
let formatedItem = item;
|
||||||
|
if (req.method === "GET") {
|
||||||
if (this.params.format) {
|
if (this.params.format) {
|
||||||
const formatRules = this.params.format[req.user.role];
|
const formatRules = this.params.format[req.user.role];
|
||||||
|
|
||||||
if (formatRules) {
|
if (formatRules) {
|
||||||
formatedItem = this._formatItem(item, formatRules);
|
formatedItem = this.formatItem(item, formatRules);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
callback(null, formatedItem);
|
callback(null, formatedItem);
|
||||||
return true;
|
return true;
|
||||||
})
|
})
|
||||||
|
@ -145,7 +148,7 @@ class Middleware extends QueryBuilder {
|
||||||
*/
|
*/
|
||||||
patchOne(req, callback) {
|
patchOne(req, callback) {
|
||||||
// On test les droits
|
// On test les droits
|
||||||
if (!this._haveRight(req)) {
|
if (!this.haveRight(req)) {
|
||||||
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -170,7 +173,45 @@ class Middleware extends QueryBuilder {
|
||||||
item
|
item
|
||||||
.update(value)
|
.update(value)
|
||||||
.then(updated => {
|
.then(updated => {
|
||||||
|
if (this.params.belongsToMany) {
|
||||||
|
const needCreate = [];
|
||||||
|
let created = 0;
|
||||||
|
const _next = errNext => {
|
||||||
|
if (errNext) {
|
||||||
|
// TODO: break and revert
|
||||||
|
} else {
|
||||||
|
created += 1;
|
||||||
|
|
||||||
|
if (created === needCreate.length) {
|
||||||
callback(null, updated);
|
callback(null, updated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
Object.keys(this.params.belongsToMany).map(key => {
|
||||||
|
if (value[key]) {
|
||||||
|
needCreate.push(key);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (needCreate.length > 0) {
|
||||||
|
for (let i = 0; i < needCreate.length; i += 1) {
|
||||||
|
const currentKey = needCreate[i];
|
||||||
|
const currentValue = value[currentKey];
|
||||||
|
this.createBelonsTo(
|
||||||
|
updated,
|
||||||
|
currentKey,
|
||||||
|
currentValue,
|
||||||
|
"add",
|
||||||
|
_next
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(null, updated);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback(null, updated);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(callback);
|
.catch(callback);
|
||||||
return true;
|
return true;
|
||||||
|
@ -186,7 +227,7 @@ class Middleware extends QueryBuilder {
|
||||||
*/
|
*/
|
||||||
deleteOne(req, callback) {
|
deleteOne(req, callback) {
|
||||||
// On test les droits
|
// On test les droits
|
||||||
if (!this._haveRight(req)) {
|
if (!this.haveRight(req)) {
|
||||||
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -194,17 +235,54 @@ class Middleware extends QueryBuilder {
|
||||||
this.getOne(req, (err, item) => {
|
this.getOne(req, (err, item) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
callback(err, item);
|
callback(err, item);
|
||||||
return false;
|
} else {
|
||||||
}
|
let deletedBelongs = 0;
|
||||||
|
const needToDeleteBelongs = [];
|
||||||
|
|
||||||
|
const _deleteItem = () => {
|
||||||
item
|
item
|
||||||
.destroy()
|
.destroy()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
callback(null, {});
|
callback(null, {});
|
||||||
})
|
})
|
||||||
.catch(callback);
|
.catch(callback);
|
||||||
|
};
|
||||||
|
|
||||||
|
const _next = () => {
|
||||||
|
deletedBelongs += 1;
|
||||||
|
|
||||||
|
if (deletedBelongs === needToDeleteBelongs.length) {
|
||||||
|
_deleteItem();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
if (this.params.belongsToMany) {
|
||||||
|
Object.keys(this.params.belongsToMany).map(key => {
|
||||||
|
const collection = this.params.belongsToMany[key];
|
||||||
|
if (item[collection].length) {
|
||||||
|
needToDeleteBelongs.push(key);
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (needToDeleteBelongs.length > 0) {
|
||||||
|
for (let i = 0; i < needToDeleteBelongs.length; i += 1) {
|
||||||
|
const currentKey = needToDeleteBelongs[i];
|
||||||
|
const collection = this.params.belongsToMany[currentKey];
|
||||||
|
const valuesToDelete = [];
|
||||||
|
for (let j = 0; j < item[collection].length; j += 1) {
|
||||||
|
valuesToDelete.push(item[collection][j].id);
|
||||||
|
}
|
||||||
|
this.deleteBelongsTo(item, currentKey, valuesToDelete, _next);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_deleteItem();
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_deleteItem();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ class QueryBuilder {
|
||||||
* @param {Number} maxPage
|
* @param {Number} maxPage
|
||||||
* @param {String} page
|
* @param {String} page
|
||||||
*/
|
*/
|
||||||
static _createLink(href, currentPage, maxPage, page) {
|
static createLink(href, currentPage, maxPage, page) {
|
||||||
if (
|
if (
|
||||||
(page === "first" && currentPage > 1) ||
|
(page === "first" && currentPage > 1) ||
|
||||||
(page === "last" && currentPage < maxPage) ||
|
(page === "last" && currentPage < maxPage) ||
|
||||||
|
@ -61,17 +61,17 @@ class QueryBuilder {
|
||||||
* @param {Number} skip
|
* @param {Number} skip
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
*/
|
*/
|
||||||
static _createPagination(req, total, limit, skip) {
|
static createPagination(req, total, limit, skip) {
|
||||||
const maxPage = Math.ceil(total / limit); // Nombre total de pages
|
const maxPage = Math.ceil(total / limit); // Nombre total de pages
|
||||||
const currentPage = Math.ceil(skip / limit) + 1; // Numéro de la page courante
|
const currentPage = Math.ceil(skip / limit) + 1; // Numéro de la page courante
|
||||||
const href = `${req.protocol}://${req.get("host")}${req.originalUrl}`; // Lien vers la page actuelle
|
const href = `${req.protocol}://${req.get("host")}${req.originalUrl}`; // Lien vers la page actuelle
|
||||||
|
|
||||||
return {
|
return {
|
||||||
paging: {
|
paging: {
|
||||||
first: QueryBuilder._createLink(href, currentPage, maxPage, "first"),
|
first: QueryBuilder.createLink(href, currentPage, maxPage, "first"),
|
||||||
prev: QueryBuilder._createLink(href, currentPage, maxPage, "prev"),
|
prev: QueryBuilder.createLink(href, currentPage, maxPage, "prev"),
|
||||||
next: QueryBuilder._createLink(href, currentPage, maxPage, "next"),
|
next: QueryBuilder.createLink(href, currentPage, maxPage, "next"),
|
||||||
last: QueryBuilder._createLink(href, currentPage, maxPage, "last")
|
last: QueryBuilder.createLink(href, currentPage, maxPage, "last")
|
||||||
},
|
},
|
||||||
total,
|
total,
|
||||||
maxPage
|
maxPage
|
||||||
|
@ -83,7 +83,7 @@ class QueryBuilder {
|
||||||
* @param {Object} obj
|
* @param {Object} obj
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
*/
|
*/
|
||||||
_replaceKeys(obj) {
|
replaceKeys(obj) {
|
||||||
const { Op } = this.models.Sequelize;
|
const { Op } = this.models.Sequelize;
|
||||||
let newObject = {};
|
let newObject = {};
|
||||||
|
|
||||||
|
@ -91,13 +91,13 @@ class QueryBuilder {
|
||||||
newObject = [];
|
newObject = [];
|
||||||
for (let i = 0; i < obj.length; i += 1) {
|
for (let i = 0; i < obj.length; i += 1) {
|
||||||
const value =
|
const value =
|
||||||
typeof obj[i] === "object" ? this._replaceKeys(obj[i]) : obj[i];
|
typeof obj[i] === "object" ? this.replaceKeys(obj[i]) : obj[i];
|
||||||
newObject.push(value);
|
newObject.push(value);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
Object.keys(obj).map(key => {
|
Object.keys(obj).map(key => {
|
||||||
const value =
|
const value =
|
||||||
typeof obj[key] === "object" ? this._replaceKeys(obj[key]) : obj[key];
|
typeof obj[key] === "object" ? this.replaceKeys(obj[key]) : obj[key];
|
||||||
if (key.indexOf("$") === 0 && key.slice(-1) !== "$") {
|
if (key.indexOf("$") === 0 && key.slice(-1) !== "$") {
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "$or":
|
case "$or":
|
||||||
|
@ -129,8 +129,6 @@ class QueryBuilder {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("newObject:", newObject);
|
|
||||||
|
|
||||||
return newObject;
|
return newObject;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -139,7 +137,7 @@ class QueryBuilder {
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
_haveRight(req) {
|
haveRight(req) {
|
||||||
let allowedRole = "all";
|
let allowedRole = "all";
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
req.user = {};
|
req.user = {};
|
||||||
|
@ -173,7 +171,7 @@ class QueryBuilder {
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
*/
|
*/
|
||||||
_restrictOn(req) {
|
restrictOn(req) {
|
||||||
const where = {};
|
const where = {};
|
||||||
if (!this.params || !this.params.restrictOn) {
|
if (!this.params || !this.params.restrictOn) {
|
||||||
return where;
|
return where;
|
||||||
|
@ -220,11 +218,15 @@ class QueryBuilder {
|
||||||
* @param {String} method
|
* @param {String} method
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
*/
|
*/
|
||||||
_override(req, method) {
|
override(req, method) {
|
||||||
let override = {};
|
let overrideValues = {};
|
||||||
const params = this.params.override ? this.params.override[method] : {};
|
|
||||||
if (!this.params.override) {
|
if (!this.params.override) {
|
||||||
return override;
|
return overrideValues;
|
||||||
|
}
|
||||||
|
const params = this.params.override ? this.params.override[method] : {};
|
||||||
|
|
||||||
|
if (!params) {
|
||||||
|
return overrideValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
// On surcharge certains paramètres passé en query
|
// On surcharge certains paramètres passé en query
|
||||||
|
@ -239,7 +241,10 @@ class QueryBuilder {
|
||||||
value
|
value
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
override = Object.assign(override, this._replaceKeys(query));
|
overrideValues = Object.assign(
|
||||||
|
overrideValues,
|
||||||
|
this.replaceKeys(query)
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
});
|
});
|
||||||
|
@ -249,12 +254,12 @@ class QueryBuilder {
|
||||||
if (params.params) {
|
if (params.params) {
|
||||||
for (let i = 0; i < params.params.length; i += 1) {
|
for (let i = 0; i < params.params.length; i += 1) {
|
||||||
const currentParam = params.params[i];
|
const currentParam = params.params[i];
|
||||||
override[currentParam.append] =
|
overrideValues[currentParam.append] =
|
||||||
req[currentParam.from][currentParam.value];
|
req[currentParam.from][currentParam.value];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return override;
|
return overrideValues;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -263,7 +268,7 @@ class QueryBuilder {
|
||||||
* @param {Array} include
|
* @param {Array} include
|
||||||
* @return {Mixed}
|
* @return {Mixed}
|
||||||
*/
|
*/
|
||||||
_setInclusions(req, include) {
|
setInclusions(req, include) {
|
||||||
if (!req.user) {
|
if (!req.user) {
|
||||||
req.user = {};
|
req.user = {};
|
||||||
}
|
}
|
||||||
|
@ -299,10 +304,7 @@ class QueryBuilder {
|
||||||
currentInclude.where = {};
|
currentInclude.where = {};
|
||||||
|
|
||||||
if (current.include) {
|
if (current.include) {
|
||||||
currentInclude.include = this._setInclusions(
|
currentInclude.include = this.setInclusions(req, current.include);
|
||||||
req,
|
|
||||||
current.include
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// On parcours la liste des règles d'inclusion pour ce modèle
|
// On parcours la liste des règles d'inclusion pour ce modèle
|
||||||
|
@ -338,14 +340,55 @@ class QueryBuilder {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fonction permettant de peupler une table de jointure (belongsToMany)
|
||||||
|
* @param {Object} item
|
||||||
|
* @param {String} key
|
||||||
|
* @param {Array} values
|
||||||
|
* @param {String} mode
|
||||||
|
* @param {Function} callback
|
||||||
|
*/
|
||||||
|
createBelonsTo(item, key, values, mode, callback) {
|
||||||
|
const collection = this.params.belongsToMany[key];
|
||||||
|
const action = `${mode}${collection}`;
|
||||||
|
|
||||||
|
item[action](values)
|
||||||
|
.then(() => {
|
||||||
|
callback();
|
||||||
|
})
|
||||||
|
.catch(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
deleteBelongsTo(item, key, values, callback) {
|
||||||
|
const collection = this.params.belongsToMany[key];
|
||||||
|
const action = `remove${collection}`;
|
||||||
|
|
||||||
|
item[action](values)
|
||||||
|
.then(() => {
|
||||||
|
callback();
|
||||||
|
})
|
||||||
|
.catch(callback);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Méthode interne permettant de créer un item
|
* Méthode interne permettant de créer un item
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {Object} value
|
* @param {Object} value
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
_insertItem(req, value, callback) {
|
insertItem(req, value, callback) {
|
||||||
const values = {};
|
const values = {};
|
||||||
|
const _done = item => {
|
||||||
|
let createdItem = item;
|
||||||
|
if (this.params.format) {
|
||||||
|
const formatRules = req.user ? this.params.format[req.user.role] : null;
|
||||||
|
|
||||||
|
if (formatRules) {
|
||||||
|
createdItem = this.formatItem(item, formatRules);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
callback(null, createdItem);
|
||||||
|
};
|
||||||
// On converti les 'null' en null (formData par exemple)
|
// On converti les 'null' en null (formData par exemple)
|
||||||
Object.keys(value).map(key => {
|
Object.keys(value).map(key => {
|
||||||
if (value[key] === "null") {
|
if (value[key] === "null") {
|
||||||
|
@ -360,17 +403,44 @@ class QueryBuilder {
|
||||||
this.models[this.params.model]
|
this.models[this.params.model]
|
||||||
.create(values)
|
.create(values)
|
||||||
.then(item => {
|
.then(item => {
|
||||||
let createdItem = item;
|
if (this.params.belongsToMany) {
|
||||||
if (this.params.format) {
|
const needCreate = [];
|
||||||
const formatRules = req.user
|
let created = 0;
|
||||||
? this.params.format[req.user.role]
|
const _next = err => {
|
||||||
: null;
|
if (err) {
|
||||||
|
// TODO: break and revert
|
||||||
|
} else {
|
||||||
|
created += 1;
|
||||||
|
|
||||||
if (formatRules) {
|
if (created === needCreate.length) {
|
||||||
createdItem = this._formatItem(item, formatRules);
|
_done(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
callback(null, createdItem);
|
};
|
||||||
|
Object.keys(this.params.belongsToMany).map(key => {
|
||||||
|
if (values[key]) {
|
||||||
|
needCreate.push(key);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (needCreate.length > 0) {
|
||||||
|
for (let i = 0; i < needCreate.length; i += 1) {
|
||||||
|
const currentKey = needCreate[i];
|
||||||
|
this.createBelonsTo(
|
||||||
|
item,
|
||||||
|
currentKey,
|
||||||
|
values[currentKey],
|
||||||
|
"set",
|
||||||
|
_next
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_done(item);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
_done(item);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.catch(err => {
|
.catch(err => {
|
||||||
switch (err.name) {
|
switch (err.name) {
|
||||||
|
@ -392,10 +462,11 @@ class QueryBuilder {
|
||||||
* @param {Object} formatRule
|
* @param {Object} formatRule
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
*/
|
*/
|
||||||
_formatItem(item, formatRule) {
|
formatItem(item, formatRule) {
|
||||||
const formated = {};
|
const formated = {};
|
||||||
|
|
||||||
Object.keys(formatRule).map(key => {
|
Object.keys(formatRule).map(key => {
|
||||||
|
// TODO: revoir ce switch
|
||||||
switch (typeof formatRule[key]) {
|
switch (typeof formatRule[key]) {
|
||||||
case "string":
|
case "string":
|
||||||
if (item) {
|
if (item) {
|
||||||
|
@ -407,11 +478,11 @@ class QueryBuilder {
|
||||||
formated[key] = [];
|
formated[key] = [];
|
||||||
for (let i = 0; i < item[key].length; i += 1) {
|
for (let i = 0; i < item[key].length; i += 1) {
|
||||||
formated[key].push(
|
formated[key].push(
|
||||||
this._formatItem(item[key][i], formatRule[key])
|
this.formatItem(item[key][i], formatRule[key])
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
formated[key] = this._formatItem(item[key], formatRule[key]);
|
formated[key] = this.formatItem(item[key], formatRule[key]);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -429,7 +500,7 @@ class QueryBuilder {
|
||||||
* @param {Object} items
|
* @param {Object} items
|
||||||
* @return {Object}
|
* @return {Object}
|
||||||
*/
|
*/
|
||||||
_formatItems(req, items) {
|
formatItems(req, items) {
|
||||||
if (!this.params.format) {
|
if (!this.params.format) {
|
||||||
return items;
|
return items;
|
||||||
}
|
}
|
||||||
|
@ -442,7 +513,7 @@ class QueryBuilder {
|
||||||
|
|
||||||
const formated = [];
|
const formated = [];
|
||||||
for (let i = 0; i < items.length; i += 1) {
|
for (let i = 0; i < items.length; i += 1) {
|
||||||
formated.push(this._formatItem(items[i], formatRules));
|
formated.push(this.formatItem(items[i], formatRules));
|
||||||
}
|
}
|
||||||
|
|
||||||
return formated;
|
return formated;
|
||||||
|
@ -453,7 +524,7 @@ class QueryBuilder {
|
||||||
* @param {Object} req
|
* @param {Object} req
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
*/
|
*/
|
||||||
_checkCreateOneValues(req, callback) {
|
checkCreateOneValues(req, callback) {
|
||||||
// On regarde s'il faut surcharger les valeurs du body avec des valeurs dérivées (req.user, req.params...)
|
// On regarde s'il faut surcharger les valeurs du body avec des valeurs dérivées (req.user, req.params...)
|
||||||
if (this.params.override && this.params.override.create) {
|
if (this.params.override && this.params.override.create) {
|
||||||
if (this.params.override.create.body) {
|
if (this.params.override.create.body) {
|
||||||
|
@ -482,14 +553,14 @@ class QueryBuilder {
|
||||||
* @param {Function} callback
|
* @param {Function} callback
|
||||||
* @return {Boolean}
|
* @return {Boolean}
|
||||||
*/
|
*/
|
||||||
_createQuery(req, callback) {
|
createQuery(req, callback) {
|
||||||
this._setInclusions(req);
|
this.setInclusions(req);
|
||||||
const query = {};
|
const query = {};
|
||||||
let where = {};
|
let where = {};
|
||||||
let order = [];
|
let order = [];
|
||||||
|
|
||||||
// On test les droits
|
// On test les droits
|
||||||
if (!this._haveRight(req)) {
|
if (!this.haveRight(req)) {
|
||||||
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -564,11 +635,11 @@ class QueryBuilder {
|
||||||
}
|
}
|
||||||
|
|
||||||
// S'il y a des restrictions (genre un utilisateur n'a le droit de voir que tel ou tel items)
|
// S'il y a des restrictions (genre un utilisateur n'a le droit de voir que tel ou tel items)
|
||||||
const restrict = this._restrictOn(req);
|
const restrict = this.restrictOn(req);
|
||||||
where = Object.assign(where, restrict);
|
where = Object.assign(where, restrict);
|
||||||
|
|
||||||
// On regarde s'il n'y a pas des valeurs à overrider
|
// On regarde s'il n'y a pas des valeurs à overrider
|
||||||
const override = this._override(req, req.getType);
|
const override = this.override(req, req.getType);
|
||||||
where = Object.assign(where, override);
|
where = Object.assign(where, override);
|
||||||
|
|
||||||
if (order) {
|
if (order) {
|
||||||
|
|
26
migrations/20200212092056-create-colors.js
Normal file
26
migrations/20200212092056-create-colors.js
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.createTable("Colors", {
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
type: Sequelize.INTEGER
|
||||||
|
},
|
||||||
|
name: {
|
||||||
|
type: Sequelize.STRING
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
down: queryInterface => {
|
||||||
|
return queryInterface.dropTable("Colors");
|
||||||
|
}
|
||||||
|
};
|
39
migrations/20200212092136-create-cars-colors.js
Normal file
39
migrations/20200212092136-create-cars-colors.js
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
module.exports = {
|
||||||
|
up: (queryInterface, Sequelize) => {
|
||||||
|
return queryInterface.createTable("CarsColors", {
|
||||||
|
id: {
|
||||||
|
allowNull: false,
|
||||||
|
autoIncrement: true,
|
||||||
|
primaryKey: true,
|
||||||
|
type: Sequelize.INTEGER
|
||||||
|
},
|
||||||
|
CarId: {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
references: {
|
||||||
|
model: "Cars",
|
||||||
|
key: "id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ColorId: {
|
||||||
|
type: Sequelize.INTEGER,
|
||||||
|
allowNull: true,
|
||||||
|
references: {
|
||||||
|
model: "Colors",
|
||||||
|
key: "id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
createdAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE
|
||||||
|
},
|
||||||
|
updatedAt: {
|
||||||
|
allowNull: false,
|
||||||
|
type: Sequelize.DATE
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
down: queryInterface => {
|
||||||
|
return queryInterface.dropTable("CarsColors");
|
||||||
|
}
|
||||||
|
};
|
15
migrations/20200212093136-setUniqueCarsColors.js
Normal file
15
migrations/20200212093136-setUniqueCarsColors.js
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
module.exports = {
|
||||||
|
up: queryInterface => {
|
||||||
|
return queryInterface.addConstraint("CarsColors", ["CarId", "ColorId"], {
|
||||||
|
type: "unique",
|
||||||
|
name: "CarsColors_unique_carId_colorId"
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
down: queryInterface => {
|
||||||
|
return queryInterface.removeConstraint(
|
||||||
|
"CarsColors",
|
||||||
|
"CarsColors_unique_carId_colorId"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
};
|
|
@ -21,6 +21,7 @@ module.exports = (sequelize, DataTypes) => {
|
||||||
as: "Brand",
|
as: "Brand",
|
||||||
foreignKey: "brandId"
|
foreignKey: "brandId"
|
||||||
});
|
});
|
||||||
|
Cars.belongsToMany(models.Colors, { through: models.CarsColors });
|
||||||
};
|
};
|
||||||
|
|
||||||
return Cars;
|
return Cars;
|
||||||
|
|
24
models/carscolors.js
Normal file
24
models/carscolors.js
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const CarsColors = sequelize.define(
|
||||||
|
"CarsColors",
|
||||||
|
{
|
||||||
|
CarId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: {
|
||||||
|
model: "Cars",
|
||||||
|
key: "id"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
ColorId: {
|
||||||
|
type: DataTypes.INTEGER,
|
||||||
|
references: {
|
||||||
|
model: "Colors",
|
||||||
|
key: "id"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
return CarsColors;
|
||||||
|
};
|
11
models/colors.js
Normal file
11
models/colors.js
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
module.exports = (sequelize, DataTypes) => {
|
||||||
|
const Colors = sequelize.define(
|
||||||
|
"Colors",
|
||||||
|
{
|
||||||
|
name: DataTypes.STRING
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
|
||||||
|
return Colors;
|
||||||
|
};
|
|
@ -12,10 +12,9 @@ const Rules = {
|
||||||
{
|
{
|
||||||
collection: "Brand",
|
collection: "Brand",
|
||||||
requiredRole: ["admin", "user"]
|
requiredRole: ["admin", "user"]
|
||||||
// },
|
},
|
||||||
// {
|
{
|
||||||
// collection: "Colors",
|
collection: "Colors"
|
||||||
// requiredRole: ["admin", "user"]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
format: {
|
format: {
|
||||||
|
@ -31,6 +30,7 @@ const Rules = {
|
||||||
validate: {
|
validate: {
|
||||||
create: Joi.object({
|
create: Joi.object({
|
||||||
name: Joi.string().required(),
|
name: Joi.string().required(),
|
||||||
|
colorsId: Joi.array().items(Joi.number().integer()),
|
||||||
active: Joi.boolean(),
|
active: Joi.boolean(),
|
||||||
year: Joi.number()
|
year: Joi.number()
|
||||||
.integer()
|
.integer()
|
||||||
|
@ -38,7 +38,9 @@ const Rules = {
|
||||||
brandId: Joi.number().integer()
|
brandId: Joi.number().integer()
|
||||||
}),
|
}),
|
||||||
update: Joi.object({
|
update: Joi.object({
|
||||||
name: Joi.string()
|
name: Joi.string(),
|
||||||
|
year: Joi.number().integer(),
|
||||||
|
colorsId: Joi.array().items(Joi.number().integer())
|
||||||
}),
|
}),
|
||||||
item: Joi.object({
|
item: Joi.object({
|
||||||
carId: Joi.number().required()
|
carId: Joi.number().required()
|
||||||
|
@ -119,6 +121,9 @@ const Rules = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
belongsToMany: {
|
||||||
|
colorsId: "Colors"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
47
seeders/20200213121737-createSomeColors.js
Normal file
47
seeders/20200213121737-createSomeColors.js
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
module.exports = {
|
||||||
|
up: queryInterface => {
|
||||||
|
return queryInterface.bulkInsert(
|
||||||
|
"Colors",
|
||||||
|
[
|
||||||
|
{
|
||||||
|
name: "Red",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Miami blue",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sirius yellow",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sunflower yellow",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Royal blue",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "White",
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedAt: new Date()
|
||||||
|
}
|
||||||
|
],
|
||||||
|
{}
|
||||||
|
);
|
||||||
|
},
|
||||||
|
|
||||||
|
down: queryInterface => {
|
||||||
|
return Promise.all([
|
||||||
|
queryInterface.bulkDelete("CarsColors", null, {}),
|
||||||
|
queryInterface.bulkDelete("Colors", null, {})
|
||||||
|
]);
|
||||||
|
}
|
||||||
|
};
|
286
test/belongsToMany.test.js
Normal file
286
test/belongsToMany.test.js
Normal file
|
@ -0,0 +1,286 @@
|
||||||
|
/* eslint-disable jest/no-test-callback */
|
||||||
|
import uuid from "uuid/v4";
|
||||||
|
import { truncate } from "./utils/common";
|
||||||
|
|
||||||
|
import models from "../models";
|
||||||
|
import Cars from "../rules/Cars";
|
||||||
|
import Middelware from "../index";
|
||||||
|
|
||||||
|
const { Op } = models.Sequelize;
|
||||||
|
|
||||||
|
let colors = [];
|
||||||
|
const colorsId = [];
|
||||||
|
let car = {};
|
||||||
|
|
||||||
|
describe("createOne", () => {
|
||||||
|
beforeAll(done => {
|
||||||
|
models.Colors.findAll({
|
||||||
|
where: {
|
||||||
|
[Op.or]: [
|
||||||
|
{
|
||||||
|
name: "White"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Miami blue"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Sunflower yellow"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(items => {
|
||||||
|
colors = items;
|
||||||
|
colorsId.push(items[0].id);
|
||||||
|
colorsId.push(items[1].id);
|
||||||
|
|
||||||
|
done();
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(done => {
|
||||||
|
truncate(["Cars"], done);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return new item after creation", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "POST",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
name: uuid(),
|
||||||
|
year: 2004,
|
||||||
|
active: true,
|
||||||
|
colorsId
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.createOne(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
|
||||||
|
expect(res.name).toBe(req.body.name);
|
||||||
|
expect(res.year).toBe(2004);
|
||||||
|
expect(res.active).toBe(true);
|
||||||
|
|
||||||
|
car = res;
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return item with relations", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "POST",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
carId: car.id
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.getOne(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
|
||||||
|
expect(res.name).toBe(car.name);
|
||||||
|
expect(res.Colors.length).toBe(2);
|
||||||
|
expect(res.year).toBe(2004);
|
||||||
|
expect(res.Colors[0].id).toBe(colorsId[0]);
|
||||||
|
expect(res.Colors[1].id).toBe(colorsId[1]);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return all items ", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "POST",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {},
|
||||||
|
query: {},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.getAll(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
|
||||||
|
expect(res.data[0].name).toBe(car.name);
|
||||||
|
expect(res.data[0].Colors.length).toBe(2);
|
||||||
|
expect(res.data[0].Colors[0].id).toBe(colorsId[0]);
|
||||||
|
expect(res.data[0].Colors[1].id).toBe(colorsId[1]);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return ok when update item", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
carId: car.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {
|
||||||
|
year: 1998,
|
||||||
|
colorsId: [colors[2].id]
|
||||||
|
},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
|
||||||
|
expect(res.name).toBe(car.name);
|
||||||
|
expect(res.year).toBe(1998);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return updated item", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
carId: car.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.getOne(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
|
||||||
|
expect(res.name).toBe(car.name);
|
||||||
|
expect(res.year).toBe(1998);
|
||||||
|
expect(res.Colors.length).toBe(3);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return empty object after delete", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "DELETE",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
carId: car.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.deleteOne(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
expect(res).toEqual({});
|
||||||
|
|
||||||
|
models.CarsColors.findAll({
|
||||||
|
where: {
|
||||||
|
CarId: car.id
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.then(carsColors => {
|
||||||
|
expect(carsColors.length).toBe(0);
|
||||||
|
|
||||||
|
models.Cars.findAll({
|
||||||
|
where: {
|
||||||
|
id: car.id
|
||||||
|
}
|
||||||
|
}).then(items => {
|
||||||
|
expect(items.length).toBe(0);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(done);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return empty item when delete item with empty belongsTo collection", async done => {
|
||||||
|
const middleware = new Middelware(Cars, models);
|
||||||
|
const req = {
|
||||||
|
method: "POST",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
body: {
|
||||||
|
name: uuid(),
|
||||||
|
year: 2004,
|
||||||
|
active: true
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.createOne(req, (err, newCar) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
|
||||||
|
expect(newCar.name).toBe(req.body.name);
|
||||||
|
expect(newCar.year).toBe(2004);
|
||||||
|
expect(newCar.active).toBe(true);
|
||||||
|
|
||||||
|
const reqItem = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
carId: newCar.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {
|
||||||
|
year: 1998
|
||||||
|
},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(reqItem, errPatch => {
|
||||||
|
expect(errPatch).toBeNull();
|
||||||
|
|
||||||
|
reqItem.method = "DELETE";
|
||||||
|
|
||||||
|
middleware.deleteOne(reqItem, errDelete => {
|
||||||
|
expect(errDelete).toBeNull();
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
163
test/patchOne.test.js
Normal file
163
test/patchOne.test.js
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/* eslint-disable jest/no-test-callback */
|
||||||
|
import { createBrand, truncate } from "./utils/common";
|
||||||
|
|
||||||
|
import models from "../models";
|
||||||
|
import Brands from "../rules/Brands";
|
||||||
|
import Middelware from "../index";
|
||||||
|
|
||||||
|
let brand = {};
|
||||||
|
|
||||||
|
describe("patchOne", () => {
|
||||||
|
beforeAll(done => {
|
||||||
|
createBrand((err, item) => {
|
||||||
|
if (err) {
|
||||||
|
done(err);
|
||||||
|
} else {
|
||||||
|
brand = item;
|
||||||
|
done();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
afterAll(done => {
|
||||||
|
truncate(["Brands"], done);
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return 401.1 if guest tries to update item", async done => {
|
||||||
|
const middleware = new Middelware(Brands, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: null,
|
||||||
|
params: {
|
||||||
|
brandId: brand.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(req, (err, res) => {
|
||||||
|
expect(res).toBeUndefined();
|
||||||
|
expect(parseFloat(err.errorCode)).toBe(401.1);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return 401.1 if bad role tries to update item", async done => {
|
||||||
|
const middleware = new Middelware(Brands, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "user"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
brandId: brand.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(req, (err, res) => {
|
||||||
|
expect(res).toBeUndefined();
|
||||||
|
expect(parseFloat(err.errorCode)).toBe(401.1);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return 406.1 if allowed user tries to patch item with unallowed values", async done => {
|
||||||
|
const middleware = new Middelware(Brands, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
brandId: brand.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {
|
||||||
|
created: "test",
|
||||||
|
name: "TEST"
|
||||||
|
},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(req, (err, res) => {
|
||||||
|
expect(res).toBeUndefined();
|
||||||
|
expect(parseFloat(err.errorCode)).toBe(406.1);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return updated item if allowed user patch item", async done => {
|
||||||
|
const middleware = new Middelware(Brands, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
brandId: brand.id
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {
|
||||||
|
name: "TEST"
|
||||||
|
},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(req, (err, res) => {
|
||||||
|
expect(err).toBeNull();
|
||||||
|
expect(res.name).toBe("TEST");
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test("It should return 404.1 if allowed user tries to patch not found item", async done => {
|
||||||
|
const middleware = new Middelware(Brands, models);
|
||||||
|
const req = {
|
||||||
|
method: "PATCH",
|
||||||
|
user: {
|
||||||
|
role: "admin"
|
||||||
|
},
|
||||||
|
params: {
|
||||||
|
brandId: brand.id + 1
|
||||||
|
},
|
||||||
|
query: {},
|
||||||
|
body: {
|
||||||
|
name: "TEST"
|
||||||
|
},
|
||||||
|
protocol: "http",
|
||||||
|
get: () => {
|
||||||
|
return "internal.test/";
|
||||||
|
},
|
||||||
|
originalUrl: "v1/"
|
||||||
|
};
|
||||||
|
|
||||||
|
middleware.patchOne(req, (err, res) => {
|
||||||
|
expect(res).toBeUndefined();
|
||||||
|
expect(parseInt(err.errorCode, 10)).toBe(404);
|
||||||
|
|
||||||
|
done();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,5 +1,6 @@
|
||||||
import uuid from "uuid/v4";
|
import uuid from "uuid/v4";
|
||||||
import models from "../../models";
|
import models from "../../models";
|
||||||
|
import truncateDefault from "./truncate";
|
||||||
|
|
||||||
const _createCar = (brandId, active, year, done) => {
|
const _createCar = (brandId, active, year, done) => {
|
||||||
models.Cars.create({
|
models.Cars.create({
|
||||||
|
@ -42,47 +43,7 @@ const _createBrands = (total, done) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const _truncateCars = (tables, done) => {
|
|
||||||
if (tables.indexOf("Cars") === -1) {
|
|
||||||
done(null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
models.Cars.destroy({
|
|
||||||
where: {}
|
|
||||||
})
|
|
||||||
.then(() => done(null))
|
|
||||||
.catch(err => done(err));
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _truncateBrands = (tables, done) => {
|
|
||||||
if (tables.indexOf("Brands") === -1) {
|
|
||||||
done(null);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
models.Brands.destroy({
|
|
||||||
where: {}
|
|
||||||
})
|
|
||||||
.then(() => done(null))
|
|
||||||
.catch(err => done(err));
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const _truncate = (tables, done) => {
|
|
||||||
_truncateCars(tables, errCars => {
|
|
||||||
if (errCars) {
|
|
||||||
done(errCars);
|
|
||||||
} else {
|
|
||||||
_truncateBrands(tables, errBrands => {
|
|
||||||
done(errBrands);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
export const createBrand = _createBrand;
|
export const createBrand = _createBrand;
|
||||||
export const createBrands = _createBrands;
|
export const createBrands = _createBrands;
|
||||||
export const createCar = _createCar;
|
export const createCar = _createCar;
|
||||||
export const truncate = _truncate;
|
export const truncate = truncateDefault;
|
||||||
|
|
45
test/utils/truncate.js
Normal file
45
test/utils/truncate.js
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
import models from "../../models";
|
||||||
|
|
||||||
|
const _truncateCars = (tables, done) => {
|
||||||
|
if (tables.indexOf("Cars") === -1) {
|
||||||
|
done(null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
models.CarsColors.destroy({
|
||||||
|
where: {}
|
||||||
|
})
|
||||||
|
.then(() => {
|
||||||
|
models.Cars.destroy({
|
||||||
|
where: {}
|
||||||
|
}).then(() => done(null));
|
||||||
|
})
|
||||||
|
.catch(err => done(err));
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
const _truncateBrands = (tables, done) => {
|
||||||
|
if (tables.indexOf("Brands") === -1) {
|
||||||
|
done(null);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
models.Brands.destroy({
|
||||||
|
where: {}
|
||||||
|
})
|
||||||
|
.then(() => done(null))
|
||||||
|
.catch(err => done(err));
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default (tables, done) => {
|
||||||
|
_truncateCars(tables, errCars => {
|
||||||
|
if (errCars) {
|
||||||
|
done(errCars);
|
||||||
|
} else {
|
||||||
|
_truncateBrands(tables, errBrands => {
|
||||||
|
done(errBrands);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
Loading…
Reference in a new issue