Added some tests (createOne and getAll)
This commit is contained in:
parent
ef7ca0315b
commit
9f0886541c
21 changed files with 2940 additions and 67 deletions
30
.babelrc
Normal file
30
.babelrc
Normal file
|
@ -0,0 +1,30 @@
|
|||
{
|
||||
"plugins": [
|
||||
[
|
||||
"@babel/plugin-transform-runtime",
|
||||
{
|
||||
"regenerator": true
|
||||
}
|
||||
],
|
||||
[
|
||||
"@babel/plugin-proposal-class-properties"
|
||||
]
|
||||
],
|
||||
"presets": [
|
||||
[
|
||||
"@babel/preset-env",
|
||||
{
|
||||
"targets": {
|
||||
"node": "current"
|
||||
}
|
||||
}
|
||||
]
|
||||
],
|
||||
"env": {
|
||||
"test": {
|
||||
"plugins": [
|
||||
"@babel/plugin-transform-modules-commonjs"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -20,6 +20,7 @@ coverage
|
|||
# nyc test coverage
|
||||
.nyc_output
|
||||
/reports/
|
||||
junit.xml
|
||||
|
||||
# Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
|
||||
.grunt
|
||||
|
|
10
config/config.json
Normal file
10
config/config.json
Normal file
|
@ -0,0 +1,10 @@
|
|||
{
|
||||
"test": {
|
||||
"username": "postgres",
|
||||
"password": "postgres",
|
||||
"database": "test",
|
||||
"host": "sequelize-middleware-db",
|
||||
"dialect": "postgres",
|
||||
"seederStorage": "sequelize"
|
||||
}
|
||||
}
|
33
docker-compose.yml
Normal file
33
docker-compose.yml
Normal file
|
@ -0,0 +1,33 @@
|
|||
version: "2"
|
||||
|
||||
services:
|
||||
sequelize-middleware:
|
||||
image: "node:latest"
|
||||
user: "node"
|
||||
working_dir: /home/node/app
|
||||
command: >
|
||||
bash -c "yarn install &&
|
||||
./node_modules/.bin/sequelize db:seed:undo:all &&
|
||||
./node_modules/.bin/sequelize db:migrate:undo:all &&
|
||||
./node_modules/.bin/sequelize db:migrate &&
|
||||
./node_modules/.bin/sequelize db:seed:all &&
|
||||
yarn test --ci --collectCoverage=true"
|
||||
volumes:
|
||||
- ./:/home/node/app
|
||||
- /home/node/node_modules
|
||||
ports:
|
||||
- "3666:4000"
|
||||
depends_on:
|
||||
- sequelize-middleware-db
|
||||
environment:
|
||||
NODE_ENV: "test"
|
||||
sequelize-middleware-db:
|
||||
image: postgres:latest
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
POSTGRES_DB: test
|
||||
sequelize-middleware-adminer:
|
||||
image: adminer
|
||||
ports:
|
||||
- 127.0.0.1:8666:8080
|
|
@ -9,8 +9,8 @@ class Middleware extends QueryBuilder {
|
|||
*/
|
||||
constructor(params, models) {
|
||||
super(params, models);
|
||||
this.params = params || {};
|
||||
this.models = models || {};
|
||||
this.params = params;
|
||||
this.models = models;
|
||||
this.includes = [];
|
||||
}
|
||||
|
||||
|
@ -157,7 +157,7 @@ class Middleware extends QueryBuilder {
|
|||
|
||||
// Un paramètre n'est pas bon dans les params
|
||||
if (error) {
|
||||
callback(new ErrorBuilder(406, error));
|
||||
callback(new ErrorBuilder(406.1, error));
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
@ -30,6 +30,7 @@ class QueryBuilder {
|
|||
(page === "next" && currentPage < maxPage)
|
||||
) {
|
||||
let newIndex = 0;
|
||||
// eslint-disable-next-line default-case
|
||||
switch (page) {
|
||||
case "first":
|
||||
newIndex = 1;
|
||||
|
@ -43,9 +44,6 @@ class QueryBuilder {
|
|||
case "next":
|
||||
newIndex = currentPage + 1;
|
||||
break;
|
||||
default:
|
||||
newIndex = currentPage;
|
||||
break;
|
||||
}
|
||||
return {
|
||||
href: href.replace(`page=${currentPage}`, `page=${newIndex}`),
|
||||
|
@ -117,6 +115,9 @@ class QueryBuilder {
|
|||
case "$in":
|
||||
newObject[Op.in] = value.split(",");
|
||||
break;
|
||||
case "$like":
|
||||
newObject[Op.like] = value;
|
||||
break;
|
||||
default:
|
||||
newObject[key] = [value];
|
||||
break;
|
||||
|
@ -128,6 +129,8 @@ class QueryBuilder {
|
|||
});
|
||||
}
|
||||
|
||||
console.log("newObject:", newObject);
|
||||
|
||||
return newObject;
|
||||
}
|
||||
|
||||
|
@ -138,6 +141,12 @@ class QueryBuilder {
|
|||
*/
|
||||
_haveRight(req) {
|
||||
let allowedRole = "all";
|
||||
if (!req.user) {
|
||||
req.user = {};
|
||||
}
|
||||
if (!req.user.role) {
|
||||
req.user.role = "guest";
|
||||
}
|
||||
|
||||
// eslint-disable-next-line default-case
|
||||
switch (req.method) {
|
||||
|
@ -218,10 +227,6 @@ class QueryBuilder {
|
|||
return override;
|
||||
}
|
||||
|
||||
if (!params) {
|
||||
return override;
|
||||
}
|
||||
|
||||
// On surcharge certains paramètres passé en query
|
||||
if (params.filters) {
|
||||
Object.keys(params.filters).map(column => {
|
||||
|
@ -259,6 +264,13 @@ class QueryBuilder {
|
|||
* @return {Mixed}
|
||||
*/
|
||||
_setInclusions(req, include) {
|
||||
if (!req.user) {
|
||||
req.user = {};
|
||||
}
|
||||
if (!req.user.role) {
|
||||
req.user.role = "guest";
|
||||
}
|
||||
|
||||
const includes = [];
|
||||
|
||||
const listOfIncludes = include || this.params.includes;
|
||||
|
@ -361,12 +373,16 @@ class QueryBuilder {
|
|||
callback(null, createdItem);
|
||||
})
|
||||
.catch(err => {
|
||||
if (err.name === "SequelizeUniqueConstraintError") {
|
||||
callback(new ErrorBuilder(409, "Duplicate item"));
|
||||
return false;
|
||||
switch (err.name) {
|
||||
case "SequelizeUniqueConstraintError":
|
||||
callback(new ErrorBuilder(409.1, "Duplicate item"));
|
||||
break;
|
||||
case "SequelizeForeignKeyConstraintError":
|
||||
callback(new ErrorBuilder(406.2, "Bad foreign key"));
|
||||
break;
|
||||
default:
|
||||
callback(new ErrorBuilder(500, err));
|
||||
}
|
||||
callback(err);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -378,10 +394,13 @@ class QueryBuilder {
|
|||
*/
|
||||
_formatItem(item, formatRule) {
|
||||
const formated = {};
|
||||
|
||||
Object.keys(formatRule).map(key => {
|
||||
switch (typeof formatRule[key]) {
|
||||
case "string":
|
||||
if (item) {
|
||||
formated[key] = item[key] || null;
|
||||
}
|
||||
break;
|
||||
case "object":
|
||||
if (Array.isArray(item[key])) {
|
||||
|
@ -451,7 +470,7 @@ class QueryBuilder {
|
|||
});
|
||||
|
||||
if (error) {
|
||||
callback(new ErrorBuilder(406, error));
|
||||
callback(new ErrorBuilder(406.1, error));
|
||||
} else {
|
||||
callback(null, value);
|
||||
}
|
||||
|
@ -471,16 +490,32 @@ class QueryBuilder {
|
|||
|
||||
// On test les droits
|
||||
if (!this._haveRight(req)) {
|
||||
callback(new ErrorBuilder(401, "You're not allowed"));
|
||||
callback(new ErrorBuilder(401.1, "You're not allowed"));
|
||||
return false;
|
||||
}
|
||||
|
||||
// On teste la query (ou les params)
|
||||
const toValidate = req.getType === "list" ? req.query : req.params;
|
||||
|
||||
if (!toValidate) {
|
||||
callback(
|
||||
new ErrorBuilder(
|
||||
406.0,
|
||||
`Missing ${req.getType === "list" ? "query" : "params"}`
|
||||
)
|
||||
);
|
||||
return false;
|
||||
}
|
||||
const { error, value } = this.params.validate[
|
||||
req.getType
|
||||
].validate(toValidate, { abortEarly: false });
|
||||
|
||||
// Un paramètre n'est pas bon dans la query
|
||||
if (error) {
|
||||
callback(new ErrorBuilder(406.1, error));
|
||||
return false;
|
||||
}
|
||||
|
||||
// On vire, pour le moment la liste des filtres un peu particuliers
|
||||
let listOfIgnoredFilters = [
|
||||
"limit",
|
||||
|
@ -512,17 +547,11 @@ class QueryBuilder {
|
|||
return true;
|
||||
});
|
||||
|
||||
// Un paramètre n'est pas bon dans la query
|
||||
if (error) {
|
||||
callback(new ErrorBuilder(406, error));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (req.getType === "list") {
|
||||
// Aucune pagination n'est passée, on set celle par défaut
|
||||
if (!value.page || !value.limit) {
|
||||
value.page = 1;
|
||||
value.limit = 20;
|
||||
value.limit = 50;
|
||||
}
|
||||
|
||||
// Un tri est spécifié
|
||||
|
@ -542,11 +571,6 @@ class QueryBuilder {
|
|||
const override = this._override(req, req.getType);
|
||||
where = Object.assign(where, override);
|
||||
|
||||
// if ( value.page) {
|
||||
// query.offset = ( value.page - 1 ) * value.limit;
|
||||
// query.limit = value.limit;
|
||||
// }
|
||||
|
||||
if (order) {
|
||||
query.order = order;
|
||||
}
|
||||
|
@ -560,11 +584,6 @@ class QueryBuilder {
|
|||
// Hack pour faire un recherche dans les nested de type hasMany
|
||||
query.subQuery = false;
|
||||
|
||||
if (!value.page || !value.limit) {
|
||||
value.page = 1;
|
||||
value.limit = 50;
|
||||
}
|
||||
|
||||
callback(null, query, {
|
||||
start: value.page * value.limit - value.limit,
|
||||
limit: value.limit
|
||||
|
|
28
migrations/20200211081052-create-brands.js
Normal file
28
migrations/20200211081052-create-brands.js
Normal file
|
@ -0,0 +1,28 @@
|
|||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
return queryInterface.createTable("Brands", {
|
||||
id: {
|
||||
allowNull: false,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
type: Sequelize.INTEGER
|
||||
},
|
||||
name: {
|
||||
type: Sequelize.STRING,
|
||||
allowNull: false,
|
||||
unique: true
|
||||
},
|
||||
createdAt: {
|
||||
allowNull: false,
|
||||
type: Sequelize.DATE
|
||||
},
|
||||
updatedAt: {
|
||||
allowNull: false,
|
||||
type: Sequelize.DATE
|
||||
}
|
||||
});
|
||||
},
|
||||
down: queryInterface => {
|
||||
return queryInterface.dropTable("Brands");
|
||||
}
|
||||
};
|
40
migrations/20200211081344-create-cars.js
Normal file
40
migrations/20200211081344-create-cars.js
Normal file
|
@ -0,0 +1,40 @@
|
|||
module.exports = {
|
||||
up: (queryInterface, Sequelize) => {
|
||||
return queryInterface.createTable("Cars", {
|
||||
id: {
|
||||
allowNull: false,
|
||||
autoIncrement: true,
|
||||
primaryKey: true,
|
||||
type: Sequelize.INTEGER
|
||||
},
|
||||
name: {
|
||||
type: Sequelize.STRING
|
||||
},
|
||||
year: {
|
||||
type: Sequelize.INTEGER
|
||||
},
|
||||
active: {
|
||||
type: Sequelize.BOOLEAN
|
||||
},
|
||||
brandId: {
|
||||
type: Sequelize.INTEGER,
|
||||
allowNull: true,
|
||||
references: {
|
||||
model: "Brands",
|
||||
key: "id"
|
||||
}
|
||||
},
|
||||
createdAt: {
|
||||
allowNull: false,
|
||||
type: Sequelize.DATE
|
||||
},
|
||||
updatedAt: {
|
||||
allowNull: false,
|
||||
type: Sequelize.DATE
|
||||
}
|
||||
});
|
||||
},
|
||||
down: queryInterface => {
|
||||
return queryInterface.dropTable("Cars");
|
||||
}
|
||||
};
|
19
models/brands.js
Normal file
19
models/brands.js
Normal file
|
@ -0,0 +1,19 @@
|
|||
module.exports = (sequelize, DataTypes) => {
|
||||
const Brands = sequelize.define(
|
||||
"Brands",
|
||||
{
|
||||
name: DataTypes.STRING
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
Brands.associate = function(models) {
|
||||
Brands.hasMany(models.Cars, {
|
||||
as: "Cars",
|
||||
foreignKey: "brandId",
|
||||
sourceKey: "id"
|
||||
});
|
||||
};
|
||||
|
||||
return Brands;
|
||||
};
|
27
models/cards.js
Normal file
27
models/cards.js
Normal file
|
@ -0,0 +1,27 @@
|
|||
module.exports = (sequelize, DataTypes) => {
|
||||
const Cars = sequelize.define(
|
||||
"Cars",
|
||||
{
|
||||
name: DataTypes.STRING,
|
||||
year: DataTypes.INTEGER,
|
||||
active: DataTypes.BOOLEAN,
|
||||
brandId: {
|
||||
type: DataTypes.INTEGER,
|
||||
references: {
|
||||
model: "Brands",
|
||||
key: "id"
|
||||
}
|
||||
}
|
||||
},
|
||||
{}
|
||||
);
|
||||
|
||||
Cars.associate = function(models) {
|
||||
Cars.belongsTo(models.Brands, {
|
||||
as: "Brand",
|
||||
foreignKey: "brandId"
|
||||
});
|
||||
};
|
||||
|
||||
return Cars;
|
||||
};
|
43
models/index.js
Normal file
43
models/index.js
Normal file
|
@ -0,0 +1,43 @@
|
|||
const fs = require("fs");
|
||||
const path = require("path");
|
||||
const Sequelize = require("sequelize");
|
||||
|
||||
const basename = path.basename(__filename);
|
||||
const env = process.env.NODE_ENV || "development";
|
||||
// eslint-disable-next-line import/no-dynamic-require
|
||||
const config = require(`${__dirname}/../config/config.json`)[env];
|
||||
const db = {};
|
||||
|
||||
let sequelize;
|
||||
if (config.use_env_variable) {
|
||||
sequelize = new Sequelize(process.env[config.use_env_variable], config);
|
||||
} else {
|
||||
sequelize = new Sequelize(
|
||||
config.database,
|
||||
config.username,
|
||||
config.password,
|
||||
config
|
||||
);
|
||||
}
|
||||
|
||||
fs.readdirSync(__dirname)
|
||||
.filter(file => {
|
||||
return (
|
||||
file.indexOf(".") !== 0 && file !== basename && file.slice(-3) === ".js"
|
||||
);
|
||||
})
|
||||
.forEach(file => {
|
||||
const model = sequelize.import(path.join(__dirname, file));
|
||||
db[model.name] = model;
|
||||
});
|
||||
|
||||
Object.keys(db).forEach(modelName => {
|
||||
if (db[modelName].associate) {
|
||||
db[modelName].associate(db);
|
||||
}
|
||||
});
|
||||
|
||||
db.sequelize = sequelize;
|
||||
db.Sequelize = Sequelize;
|
||||
|
||||
module.exports = db;
|
18
package.json
18
package.json
|
@ -5,8 +5,7 @@
|
|||
"main": "index.js",
|
||||
"scripts": {
|
||||
"lint": "./node_modules/.bin/eslint . --fix",
|
||||
"test": "jest --forceExit --detectOpenHandles --maxWorkers=10",
|
||||
"coverage": "jest --coverage"
|
||||
"test": "jest --forceExit --detectOpenHandles --maxWorkers=10"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
|
@ -30,6 +29,9 @@
|
|||
]
|
||||
},
|
||||
"jest": {
|
||||
"moduleFileExtensions": [
|
||||
"js"
|
||||
],
|
||||
"verbose": true,
|
||||
"roots": [
|
||||
"<rootDir>",
|
||||
|
@ -69,6 +71,10 @@
|
|||
},
|
||||
"dependencies": {},
|
||||
"devDependencies": {
|
||||
"@babel/plugin-proposal-class-properties": "^7.8.3",
|
||||
"@babel/plugin-transform-runtime": "^7.8.3",
|
||||
"@babel/preset-env": "^7.8.4",
|
||||
"@hapi/joi": "^16.1.8",
|
||||
"babel-eslint": "^10.0.3",
|
||||
"eslint": "^6.8.0",
|
||||
"eslint-config-airbnb-base": "^14.0.0",
|
||||
|
@ -79,9 +85,15 @@
|
|||
"husky": "^4.2.1",
|
||||
"jest": "^25.1.0",
|
||||
"jest-html-reporter": "^2.8.0",
|
||||
"jest-junit": "^10.0.0",
|
||||
"lint-staged": "^10.0.7",
|
||||
"pg": "^7.18.1",
|
||||
"pg-hstore": "^2.3.3",
|
||||
"prettier": "^1.19.1",
|
||||
"sequelize": "^5.21.3",
|
||||
"sequelize-cli": "^5.5.1",
|
||||
"sinon": "^8.1.1",
|
||||
"supertest": "^4.0.2"
|
||||
"supertest": "^4.0.2",
|
||||
"uuid": "^3.4.0"
|
||||
}
|
||||
}
|
69
rules/Brands.js
Normal file
69
rules/Brands.js
Normal file
|
@ -0,0 +1,69 @@
|
|||
import Joi from "@hapi/joi";
|
||||
|
||||
const Rules = {
|
||||
model: "Brands",
|
||||
crud: {
|
||||
read: ["admin", "user"],
|
||||
write: ["admin"],
|
||||
edit: ["admin"],
|
||||
delete: ["admin"]
|
||||
},
|
||||
includes: [
|
||||
{
|
||||
collection: "Cars",
|
||||
requiredRole: ["admin", "user"]
|
||||
}
|
||||
],
|
||||
format: {
|
||||
user: {
|
||||
id: "id",
|
||||
name: "name"
|
||||
},
|
||||
admin: {
|
||||
id: "id",
|
||||
name: "name",
|
||||
created: "createdAt",
|
||||
updated: "updatedAt",
|
||||
Cars: {
|
||||
id: "id",
|
||||
name: "name",
|
||||
year: "year",
|
||||
created: "createdAt",
|
||||
updated: "updatedAt"
|
||||
}
|
||||
}
|
||||
},
|
||||
itemId: "brandId",
|
||||
validate: {
|
||||
create: Joi.object({
|
||||
name: Joi.string().required()
|
||||
}),
|
||||
update: Joi.object({
|
||||
name: Joi.string()
|
||||
}),
|
||||
item: Joi.object({
|
||||
brandId: Joi.number().required()
|
||||
}),
|
||||
list: Joi.object({
|
||||
limit: Joi.number()
|
||||
.integer()
|
||||
.min(1)
|
||||
.max(50),
|
||||
page: Joi.number()
|
||||
.integer()
|
||||
.min(1),
|
||||
sort: Joi.string()
|
||||
.valid("id", "name", "createdAt", "updatedAt")
|
||||
.only(),
|
||||
order: Joi.string()
|
||||
.valid("asc", "desc")
|
||||
.only()
|
||||
})
|
||||
.with("limit", "page")
|
||||
.with("page", "limit")
|
||||
.with("sort", "order")
|
||||
.with("order", "sort")
|
||||
}
|
||||
};
|
||||
|
||||
export default Rules;
|
125
rules/Cars.js
Normal file
125
rules/Cars.js
Normal file
|
@ -0,0 +1,125 @@
|
|||
import Joi from "@hapi/joi";
|
||||
|
||||
const Rules = {
|
||||
model: "Cars",
|
||||
crud: {
|
||||
read: ["admin", "user"],
|
||||
write: ["admin"],
|
||||
edit: ["admin"],
|
||||
delete: ["admin"]
|
||||
},
|
||||
includes: [
|
||||
{
|
||||
collection: "Brand",
|
||||
requiredRole: ["admin", "user"]
|
||||
// },
|
||||
// {
|
||||
// collection: "Colors",
|
||||
// requiredRole: ["admin", "user"]
|
||||
}
|
||||
],
|
||||
format: {
|
||||
user: {
|
||||
id: "id",
|
||||
model: "model",
|
||||
Brand: {
|
||||
name: "name"
|
||||
}
|
||||
}
|
||||
},
|
||||
itemId: "carId",
|
||||
validate: {
|
||||
create: Joi.object({
|
||||
name: Joi.string().required(),
|
||||
active: Joi.boolean(),
|
||||
year: Joi.number()
|
||||
.integer()
|
||||
.required(),
|
||||
brandId: Joi.number().integer()
|
||||
}),
|
||||
update: Joi.object({
|
||||
name: Joi.string()
|
||||
}),
|
||||
item: Joi.object({
|
||||
carId: Joi.number().required()
|
||||
}),
|
||||
list: Joi.object({
|
||||
weirdfilter: Joi.string(),
|
||||
"name.lk": Joi.string(),
|
||||
name: Joi.string(),
|
||||
year: Joi.number().integer(),
|
||||
"year.lte": Joi.number().integer(),
|
||||
"year.gte": Joi.number().integer(),
|
||||
limit: Joi.number()
|
||||
.integer()
|
||||
.min(1)
|
||||
.max(50),
|
||||
page: Joi.number()
|
||||
.integer()
|
||||
.min(1),
|
||||
sort: Joi.string()
|
||||
.valid("id", "name", "createdAt", "updatedAt")
|
||||
.only(),
|
||||
order: Joi.string()
|
||||
.valid("asc", "desc")
|
||||
.only()
|
||||
})
|
||||
.with("year.lte", "year.gte")
|
||||
.with("year.gte", "year.lte")
|
||||
.with("limit", "page")
|
||||
.with("page", "limit")
|
||||
.with("sort", "order")
|
||||
.with("order", "sort")
|
||||
},
|
||||
restrictOn: {
|
||||
list: [
|
||||
{
|
||||
roles: ["user"],
|
||||
type: "raw",
|
||||
field: "active",
|
||||
value: "true"
|
||||
}
|
||||
],
|
||||
item: [
|
||||
{
|
||||
roles: ["user"],
|
||||
type: "raw",
|
||||
field: "active",
|
||||
value: "true"
|
||||
}
|
||||
]
|
||||
},
|
||||
override: {
|
||||
list: {
|
||||
filters: {
|
||||
weirdfilter: {
|
||||
$or: [
|
||||
{
|
||||
active: true
|
||||
},
|
||||
{
|
||||
year: 2003
|
||||
}
|
||||
]
|
||||
},
|
||||
"name.lk": {
|
||||
name: {
|
||||
$like: "%_TERM_%"
|
||||
}
|
||||
},
|
||||
"year.lte": {
|
||||
year: {
|
||||
$lte: "_TERM_"
|
||||
}
|
||||
},
|
||||
"year.gte": {
|
||||
year: {
|
||||
$gte: "_TERM_"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
export default Rules;
|
177
test/createOne.test.js
Normal file
177
test/createOne.test.js
Normal file
|
@ -0,0 +1,177 @@
|
|||
/* eslint-disable jest/no-test-callback */
|
||||
import uuid from "uuid/v4";
|
||||
import { truncate } from "./utils/common";
|
||||
|
||||
import models from "../models";
|
||||
import Brands from "../rules/Brands";
|
||||
import Cars from "../rules/Cars";
|
||||
import Middelware from "../index";
|
||||
|
||||
let createdBrand = null;
|
||||
|
||||
describe("createOne", () => {
|
||||
afterAll(done => {
|
||||
truncate(["Brands", "Cars"], done);
|
||||
});
|
||||
|
||||
test("It should return a 401 when guest tries to create new item", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "POST",
|
||||
user: null,
|
||||
body: {
|
||||
name: uuid()
|
||||
}
|
||||
};
|
||||
|
||||
middleware.createOne(req, (err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(401.1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return a 401 when unauthorized role tries to create new item", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
|
||||
middleware.createOne(
|
||||
{
|
||||
method: "POST",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
body: {
|
||||
name: uuid()
|
||||
}
|
||||
},
|
||||
(err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(401.1);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("It should return a 406 when authorized role tries to create new item with missing required values", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
|
||||
middleware.createOne(
|
||||
{
|
||||
method: "POST",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
body: {}
|
||||
},
|
||||
(err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(406.1);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("It should return new item when authorized role create new item", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const name = uuid();
|
||||
|
||||
middleware.createOne(
|
||||
{
|
||||
method: "POST",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
body: {
|
||||
name
|
||||
}
|
||||
},
|
||||
(err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("id");
|
||||
expect(res).toHaveProperty("created");
|
||||
expect(res).toHaveProperty("updated");
|
||||
expect(res).not.toHaveProperty("createdAt");
|
||||
expect(res).not.toHaveProperty("updatedAt");
|
||||
expect(res.name).toBe(name);
|
||||
|
||||
createdBrand = res;
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("It should return errorCode 409.1 when authorized role tries to create new item with same unique field", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
|
||||
middleware.createOne(
|
||||
{
|
||||
method: "POST",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
body: {
|
||||
name: createdBrand.name
|
||||
}
|
||||
},
|
||||
(err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(409.1);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("It should return errorCode 406.2 when authorized role tries to create new item with bad foreign id", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const name = uuid();
|
||||
|
||||
middleware.createOne(
|
||||
{
|
||||
method: "POST",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
body: {
|
||||
name,
|
||||
year: 2004,
|
||||
brandId: createdBrand.id + 2
|
||||
}
|
||||
},
|
||||
(err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(406.2);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
|
||||
test("It should return errorCode 500 when authorized role tries to create new item with too long value", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
|
||||
middleware.createOne(
|
||||
{
|
||||
method: "POST",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
body: {
|
||||
name:
|
||||
"ThohWaigohhieHogahthoxohpheeDah0geetai0cieNgu1The2foQueeloochoH9eulizieshuf1nivohkied8jei5oph2Lajem6ohviijai6booTh8ienaic9eipheixa4ki1iek2pheihe7een7nei7epahngaerieghoe3ahbeil3yied0ievee1moh8jeeN5quoh6uiph6HaeZ0Eiyohshafohniewaer7gaegiefi5eiquiequoow5ohtheiw6ZeihieMoM8Ejoh7leiNeavi7uapheiwoophitoi3queiBeVeip5too8cah9Ohpaetaogahw1tei0eibuyaef3aht8aighuma6ahK4huP4cew6ohd0aiSh2umeeng7Hizahtoo6xoocePhu4ahtheex3jaijooph9iexaiqu3Nu0Ebeich6iTe",
|
||||
year: 2004
|
||||
}
|
||||
},
|
||||
(err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(500.0);
|
||||
|
||||
done();
|
||||
}
|
||||
);
|
||||
});
|
||||
});
|
436
test/getAll.complex.test.js
Normal file
436
test/getAll.complex.test.js
Normal file
|
@ -0,0 +1,436 @@
|
|||
/* eslint-disable jest/no-test-callback */
|
||||
import { createBrands, createBrand, createCar, truncate } from "./utils/common";
|
||||
|
||||
import models from "../models";
|
||||
import Cars from "../rules/Cars";
|
||||
import Brands from "../rules/Brands";
|
||||
import Middelware from "../index";
|
||||
|
||||
const createdCars = [];
|
||||
|
||||
describe("getAll (with inclusions)", () => {
|
||||
beforeAll(done => {
|
||||
createBrands(6, err => {
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
createBrand((errBrand, createdBrand) => {
|
||||
if (errBrand) {
|
||||
done(errBrand);
|
||||
} else {
|
||||
createCar(createdBrand.id, true, 2004, (errCar, car) => {
|
||||
if (errCar) {
|
||||
done(errCar);
|
||||
}
|
||||
createdCars.push(car);
|
||||
createCar(createdBrand.id, false, 2004, (errCar2, car2) => {
|
||||
if (errCar2) {
|
||||
done(errCar2);
|
||||
}
|
||||
createdCars.push(car2);
|
||||
createCar(createdBrand.id, true, 2003, (errCar3, car3) => {
|
||||
if (errCar3) {
|
||||
done(errCar3);
|
||||
}
|
||||
createdCars.push(car3);
|
||||
createCar(createdBrand.id, true, 1998, (errCar4, car4) => {
|
||||
if (errCar4) {
|
||||
done(errCar4);
|
||||
}
|
||||
createdCars.push(car4);
|
||||
createCar(createdBrand.id, false, 1998, (errCar5, car5) => {
|
||||
if (errCar5) {
|
||||
done(errCar5);
|
||||
}
|
||||
createdCars.push(car5);
|
||||
createBrands(2, errLastBrand => {
|
||||
if (errLastBrand) {
|
||||
done(errLastBrand);
|
||||
} else {
|
||||
models.Cars.create({
|
||||
name: "la renault fuego",
|
||||
year: 1980,
|
||||
active: false
|
||||
})
|
||||
.then(() => {
|
||||
done();
|
||||
})
|
||||
.catch(done);
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
afterAll(done => {
|
||||
truncate(["Brands", "Cars"], done);
|
||||
});
|
||||
|
||||
test("It should return all items when allowed role call getAll without filters (except inactive)", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
params: {},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(3);
|
||||
expect(res.total).toBe(3);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
expect(res.paging.first).toBeUndefined();
|
||||
expect(res.paging.prev).toBeUndefined();
|
||||
expect(res.paging.next).toBeUndefined();
|
||||
expect(res.paging.last).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return all items when allowed role call getAll without filters", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(6);
|
||||
expect(res.total).toBe(6);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
expect(res.paging.first).toBeUndefined();
|
||||
expect(res.paging.prev).toBeUndefined();
|
||||
expect(res.paging.next).toBeUndefined();
|
||||
expect(res.paging.last).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return 2 items when set complex filters", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
"year.lte": 2005,
|
||||
"year.gte": 2004
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(2);
|
||||
expect(res.total).toBe(2);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return 1 item when set complex filters", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
"year.lte": 2005,
|
||||
"year.gte": 2004
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(1);
|
||||
expect(res.total).toBe(1);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return 1 item when get all brands", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc"
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(9);
|
||||
expect(res.total).toBe(9);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
expect(res.data[6].Cars.length).toBe(5);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return 1 item when get all brands (without cars)", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc"
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(9);
|
||||
expect(res.total).toBe(9);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
expect(res.data[6].Cars).not.toHaveProperty("Cars");
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return 3 items when admin send weirdfilter", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc",
|
||||
weirdfilter: "letsgo"
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(3);
|
||||
expect(res.total).toBe(3);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return errorCode 406.1 when trying to send unallowed filter", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc",
|
||||
id: 65
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(parseFloat(err.errorCode)).toBe(406.1);
|
||||
expect(res).toBeUndefined();
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return one item when trying to get item with name contains 'renault'", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc",
|
||||
"name.lk": "renault"
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res.data.length).toBe(1);
|
||||
expect(res.total).toBe(1);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return one item when trying to get item filtered by name", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc",
|
||||
name: "la renault fuego"
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res.data.length).toBe(1);
|
||||
expect(res.total).toBe(1);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return empty data when trying to get item filtered by name", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
sort: "id",
|
||||
order: "asc",
|
||||
name: "Clio"
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeUndefined();
|
||||
expect(res).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
142
test/getAll.test.js
Normal file
142
test/getAll.test.js
Normal file
|
@ -0,0 +1,142 @@
|
|||
/* eslint-disable jest/no-test-callback */
|
||||
import { createBrands, truncate } from "./utils/common";
|
||||
|
||||
import models from "../models";
|
||||
import Brands from "../rules/Brands";
|
||||
import Cars from "../rules/Cars";
|
||||
import Middelware from "../index";
|
||||
|
||||
describe("getAll", () => {
|
||||
beforeAll(done => {
|
||||
createBrands(40, done);
|
||||
});
|
||||
afterAll(done => {
|
||||
truncate(["Brands", "Cars"], done);
|
||||
});
|
||||
|
||||
test("It should return a 401 when guest tries to get all item", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: null,
|
||||
params: {},
|
||||
query: {}
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(res).toBeUndefined();
|
||||
expect(parseFloat(err.errorCode)).toBe(401.1);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return a empty result allowed role get items from empty collection", async done => {
|
||||
const middleware = new Middelware(Cars, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
params: {},
|
||||
query: {}
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeUndefined();
|
||||
expect(res).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return all items when allowed role call getAll without filters", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
params: {},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(40);
|
||||
expect(res.total).toBe(40);
|
||||
expect(res.maxPage).toBe(1);
|
||||
|
||||
expect(res.paging.first).toBeUndefined();
|
||||
expect(res.paging.prev).toBeUndefined();
|
||||
expect(res.paging.next).toBeUndefined();
|
||||
expect(res.paging.last).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return 5 items when allowed role call getAll with limit filter", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
params: {},
|
||||
query: {
|
||||
limit: 5,
|
||||
page: 3
|
||||
},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/?page=3&limit=5"
|
||||
};
|
||||
|
||||
middleware.getAll(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
expect(res).toHaveProperty("data");
|
||||
expect(res).toHaveProperty("paging");
|
||||
expect(res).toHaveProperty("total");
|
||||
expect(res).toHaveProperty("maxPage");
|
||||
|
||||
expect(res.data.length).toBe(5);
|
||||
expect(res.total).toBe(40);
|
||||
expect(res.maxPage).toBe(8);
|
||||
|
||||
expect(res.data[0]).toHaveProperty("id");
|
||||
expect(res.data[0]).toHaveProperty("name");
|
||||
expect(res.data[0]).not.toHaveProperty("createdAt");
|
||||
expect(res.data[0]).not.toHaveProperty("created");
|
||||
expect(res.data[0]).not.toHaveProperty("updatedAt");
|
||||
expect(res.data[0]).not.toHaveProperty("updated");
|
||||
|
||||
expect(res.paging.first.href).toBe(
|
||||
"http://internal.test/v1/?page=1&limit=5"
|
||||
);
|
||||
expect(res.paging.prev.href).toBe(
|
||||
"http://internal.test/v1/?page=2&limit=5"
|
||||
);
|
||||
expect(res.paging.next.href).toBe(
|
||||
"http://internal.test/v1/?page=4&limit=5"
|
||||
);
|
||||
expect(res.paging.last.href).toBe(
|
||||
"http://internal.test/v1/?page=8&limit=5"
|
||||
);
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
166
test/getOne.test.js
Normal file
166
test/getOne.test.js
Normal file
|
@ -0,0 +1,166 @@
|
|||
/* eslint-disable jest/no-test-callback */
|
||||
import { createBrands, createCar, truncate } from "./utils/common";
|
||||
|
||||
import models from "../models";
|
||||
import Brands from "../rules/Brands";
|
||||
import Middelware from "../index";
|
||||
|
||||
const createdCars = [];
|
||||
let createdBrand = {};
|
||||
|
||||
describe("getOne", () => {
|
||||
beforeAll(done => {
|
||||
createBrands(4, (err, res) => {
|
||||
if (err) {
|
||||
done(err);
|
||||
} else {
|
||||
// eslint-disable-next-line prefer-destructuring
|
||||
createdBrand = res[1];
|
||||
createCar(createdBrand.id, true, 2004, (errCar, car) => {
|
||||
if (errCar) {
|
||||
done(errCar);
|
||||
}
|
||||
createdCars.push(car);
|
||||
createCar(createdBrand.id, false, 2004, (errCar2, car2) => {
|
||||
if (errCar2) {
|
||||
done(errCar2);
|
||||
}
|
||||
createdCars.push(car2);
|
||||
createCar(createdBrand.id, true, 2003, (errCar3, car3) => {
|
||||
if (errCar3) {
|
||||
done(errCar3);
|
||||
}
|
||||
createdCars.push(car3);
|
||||
createCar(createdBrand.id, true, 1998, (errCar4, car4) => {
|
||||
if (errCar4) {
|
||||
done(errCar4);
|
||||
}
|
||||
createdCars.push(car4);
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
});
|
||||
afterAll(done => {
|
||||
truncate(["Brands", "Cars"], done);
|
||||
});
|
||||
|
||||
test("It should return one item with missing part", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "user"
|
||||
},
|
||||
params: {
|
||||
brandId: createdBrand.id
|
||||
},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getOne(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
|
||||
expect(res.id).toBe(createdBrand.id);
|
||||
expect(res.name).toBe(createdBrand.name);
|
||||
expect(res).not.toHaveProperty("Cars");
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return one item with all part", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {
|
||||
brandId: createdBrand.id
|
||||
},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getOne(req, (err, res) => {
|
||||
expect(err).toBeNull();
|
||||
|
||||
expect(res.id).toBe(createdBrand.id);
|
||||
expect(res.name).toBe(createdBrand.name);
|
||||
expect(res).toHaveProperty("Cars");
|
||||
expect(res.Cars.length).toBe(4);
|
||||
expect(res.Cars[0]).toHaveProperty("id");
|
||||
expect(res.Cars[0]).toHaveProperty("name");
|
||||
expect(res.Cars[0]).toHaveProperty("year");
|
||||
expect(res.Cars[0]).toHaveProperty("created");
|
||||
expect(res.Cars[0]).toHaveProperty("updated");
|
||||
expect(res.Cars[0]).not.toHaveProperty("createdAt");
|
||||
expect(res.Cars[0]).not.toHaveProperty("updatedAt");
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return errorCode 406.1 when missing itemId", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getOne(req, (err, res) => {
|
||||
expect(parseFloat(err.errorCode)).toBe(406.1);
|
||||
expect(res).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
|
||||
test("It should return empty result when item not found", async done => {
|
||||
const middleware = new Middelware(Brands, models);
|
||||
const req = {
|
||||
method: "GET",
|
||||
user: {
|
||||
role: "admin"
|
||||
},
|
||||
params: {
|
||||
brandId: createdBrand.id + 666
|
||||
},
|
||||
query: {},
|
||||
protocol: "http",
|
||||
get: () => {
|
||||
return "internal.test/";
|
||||
},
|
||||
originalUrl: "v1/"
|
||||
};
|
||||
|
||||
middleware.getOne(req, (err, res) => {
|
||||
expect(parseFloat(err.errorCode)).toBe(404.0);
|
||||
expect(res).toBeUndefined();
|
||||
|
||||
done();
|
||||
});
|
||||
});
|
||||
});
|
88
test/utils/common.js
Normal file
88
test/utils/common.js
Normal file
|
@ -0,0 +1,88 @@
|
|||
import uuid from "uuid/v4";
|
||||
import models from "../../models";
|
||||
|
||||
const _createCar = (brandId, active, year, done) => {
|
||||
models.Cars.create({
|
||||
name: uuid(),
|
||||
year,
|
||||
active,
|
||||
brandId
|
||||
})
|
||||
.then(item => {
|
||||
done(null, item);
|
||||
})
|
||||
.catch(done);
|
||||
};
|
||||
|
||||
const _createBrand = done => {
|
||||
models.Brands.create({
|
||||
name: uuid()
|
||||
})
|
||||
.then(item => {
|
||||
done(null, item);
|
||||
})
|
||||
.catch(done);
|
||||
};
|
||||
|
||||
const _createBrands = (total, done) => {
|
||||
const created = [];
|
||||
const next = () => {
|
||||
if (total === created.length) {
|
||||
done(null, created);
|
||||
}
|
||||
};
|
||||
|
||||
for (let i = 0; i < total; i += 1) {
|
||||
_createBrand((err, res) => {
|
||||
if (!err) {
|
||||
created.push(res);
|
||||
next();
|
||||
}
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
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 createBrands = _createBrands;
|
||||
export const createCar = _createCar;
|
||||
export const truncate = _truncate;
|
5
test/utils/setup.js
Normal file
5
test/utils/setup.js
Normal file
|
@ -0,0 +1,5 @@
|
|||
jest.setTimeout(3000);
|
||||
|
||||
afterAll(done => {
|
||||
done();
|
||||
});
|
Loading…
Reference in a new issue