From f90c7d431abf6bb5d8e73e256fc1a3b560bc8897 Mon Sep 17 00:00:00 2001 From: Raywire Date: Sat, 17 Aug 2019 10:35:14 +0300 Subject: [PATCH 1/2] Sets up babel - Adds babel setup - Moves app.js to server folder - Moves bin folder to server folder --- .babelrc | 9 ++ package.json | 19 ++- app.js => server/app.js | 27 ++--- {bin => server/bin}/www | 0 server/config/passport.js | 10 +- server/controllers/index.js | 10 +- server/controllers/todoitems.js | 88 +++++++------- server/controllers/todos.js | 121 ++++++++++--------- server/controllers/users.js | 22 ++-- server/middlewares/asyncHandler.js | 2 +- server/middlewares/checkOwner.js | 47 ++++--- server/middlewares/joiErrors.js | 4 +- server/middlewares/pagination.js | 26 ++-- server/middlewares/reqParamChecker.js | 12 +- server/models/index.js | 12 +- server/models/todo.js | 4 +- server/models/todoitem.js | 4 +- server/models/user.js | 6 +- server/routes/authRouter.js | 20 +-- server/routes/index.js | 11 +- server/routes/todosRouter.js | 43 ++++--- server/routes/usersRouter.js | 22 ++-- server/tests/integration/authRouter.spec.js | 16 ++- server/tests/integration/server.spec.js | 6 +- server/tests/integration/todoRouter.spec.js | 33 ++--- server/tests/integration/usersRouter.spec.js | 12 +- server/tests/unit/asyncHandler.spec.js | 36 +++--- server/tests/unit/checkOwner.spec.js | 34 +++--- server/tests/unit/joiErrors.spec.js | 10 +- server/tests/unit/paginate.spec.js | 42 +++---- server/tests/unit/reqParamChecker.spec.js | 108 ++++++++--------- server/tests/unit/todo.spec.js | 20 +-- server/tests/unit/todoItem.spec.js | 26 ++-- server/tests/unit/typeChecker.spec.js | 18 +-- server/tests/unit/user.spec.js | 24 ++-- server/tests/unit/validator.spec.js | 6 +- server/tests/utils.js | 17 +-- server/utils/typeChecker.js | 4 +- server/validators/validators.js | 4 +- 39 files changed, 490 insertions(+), 445 deletions(-) create mode 100644 .babelrc rename app.js => server/app.js (58%) rename {bin => server/bin}/www (100%) diff --git a/.babelrc b/.babelrc new file mode 100644 index 0000000..36bb1c5 --- /dev/null +++ b/.babelrc @@ -0,0 +1,9 @@ +{ + "presets": [ + ["@babel/preset-env", { + "useBuiltIns": "usage", + "corejs": 3, + }] + ], + "plugins": ["@babel/plugin-transform-runtime"] +} \ No newline at end of file diff --git a/package.json b/package.json index 8b27066..b539b79 100644 --- a/package.json +++ b/package.json @@ -2,12 +2,12 @@ "name": "postgres-express-node", "version": "1.0.0", "description": "Setting up a todo list backend", - "main": "index.js", + "main": "build/bin/www", "scripts": { - "start": "node ./bin/www", - "start:dev": "nodemon ./bin/www", - "build": "exit 0", - "test": "NODE_ENV=test npm run reset:db && NODE_ENV=test nyc mocha --timeout 5000 server/tests/**/*.spec.js", + "start": "node build/bin/www", + "start:dev": "nodemon --exec babel-node -- server/bin/www", + "build": "rm -rf build && babel server -d build --copy-files", + "test": "NODE_ENV=test npm run reset:db && NODE_ENV=test nyc mocha --require @babel/register --timeout 5000 server/tests/**/*.spec.js", "migrate": "sequelize db:migrate", "reset:db": "sequelize db:migrate:undo:all && npm run migrate", "coveralls-coverage": "nyc report --reporter=text-lcov | coveralls", @@ -24,6 +24,7 @@ "**/*.spec.js", "coverage", "dist", + "build", "server/tests", "server/migrations", ".eslintrc.js" @@ -38,9 +39,11 @@ "author": "Ryan Wire", "license": "ISC", "dependencies": { + "@babel/runtime": "^7.5.5", "bcrypt": "^3.0.6", "body-parser": "^1.19.0", "celebrate": "^10.0.1", + "core-js": "^3.2.1", "cors": "^2.8.5", "dotenv": "^8.0.0", "express": "^4.17.1", @@ -53,6 +56,12 @@ "sequelize": "^5.8.9" }, "devDependencies": { + "@babel/cli": "^7.5.5", + "@babel/core": "^7.5.5", + "@babel/node": "^7.5.5", + "@babel/plugin-transform-runtime": "^7.5.5", + "@babel/preset-env": "^7.5.5", + "@babel/register": "^7.5.5", "chai": "^4.2.0", "chai-http": "^4.3.0", "coveralls": "^3.0.6", diff --git a/app.js b/server/app.js similarity index 58% rename from app.js rename to server/app.js index 31c91fa..4c40c15 100644 --- a/app.js +++ b/server/app.js @@ -1,17 +1,16 @@ -const express = require('express'); -const cors = require('cors'); -const logger = require('morgan'); -const bodyParser = require('body-parser'); -const passport = require('passport'); -require('dotenv').config(); -const joiErrors = require('./server/middlewares/joiErrors'); +import express from 'express'; +import cors from 'cors'; +import logger from 'morgan'; +import bodyParser from 'body-parser'; +import passport from 'passport'; +import dotenv from 'dotenv'; +import joiErrors from './middlewares/joiErrors'; // Require our routes and passport into the application -const todosRouter = require('./server/routes').todosRouter(); -const authRouter = require('./server/routes').authRouter(); -const usersRouter = require('./server/routes').usersRouter(); -const { passportAuth } = require('./server/config/passport'); +import routers from './routes'; +import passportAuth from './config/passport'; +dotenv.config(); passportAuth(passport); const apiPrefix = '/api'; @@ -33,9 +32,9 @@ app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); app.use(apiPrefix, passport.authenticate('jwt', { session: false })); -app.use(apiPrefix, usersRouter); -app.use(apiPrefix, todosRouter); -app.use(authRouter); +app.use(apiPrefix, routers.usersRouter()); +app.use(apiPrefix, routers.todosRouter()); +app.use(routers.authRouter()); app.use(joiErrors); diff --git a/bin/www b/server/bin/www similarity index 100% rename from bin/www rename to server/bin/www diff --git a/server/config/passport.js b/server/config/passport.js index 7b50af6..16cdaf1 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -1,5 +1,5 @@ -const passportJWT = require('passport-jwt'); -const { User } = require('../models'); +import passportJWT from 'passport-jwt'; +import db from '../models'; const { ExtractJwt } = passportJWT; const JwtStrategy = passportJWT.Strategy; @@ -9,7 +9,7 @@ jwtOptions.jwtFromRequest = ExtractJwt.fromAuthHeaderAsBearerToken(); jwtOptions.secretOrKey = process.env.SECRET_KEY; const passportAuth = (passport) => { - const getUser = async (username) => User.findOne({ + const getUser = async (username) => db.User.findOne({ attributes: ['id', 'username', 'createdAt', 'updatedAt'], where: { username, @@ -27,6 +27,4 @@ const passportAuth = (passport) => { passport.use(strategy); }; -module.exports = { - passportAuth, -}; +export default passportAuth; diff --git a/server/controllers/index.js b/server/controllers/index.js index a292b5e..634060a 100644 --- a/server/controllers/index.js +++ b/server/controllers/index.js @@ -1,9 +1,11 @@ -const todos = require('./todos'); -const todoItems = require('./todoitems'); -const users = require('./users'); +import todos from './todos'; +import todoItems from './todoitems'; +import users from './users'; -module.exports = { +const controllers = { todos, todoItems, users, }; + +export default controllers; diff --git a/server/controllers/todoitems.js b/server/controllers/todoitems.js index 68efe1b..2441237 100644 --- a/server/controllers/todoitems.js +++ b/server/controllers/todoitems.js @@ -1,48 +1,54 @@ -const { TodoItem } = require('../models'); +import db from '../models'; -module.exports = { - async createTodoItem(req, res) { - const todoItem = await TodoItem.create({ - content: req.body.content, +const createTodoItem = async (req, res) => { + const todoItem = await db.TodoItem.create({ + content: req.body.content, + todoId: req.params.todoId, + }); + return res.status(201).send(todoItem); +}; + +const update = async (req, res) => { + const todoItem = await db.TodoItem.findOne({ + attributes: ['id', 'todoId', 'content', 'complete', 'updatedAt'], + where: { + id: req.params.todoItemId, todoId: req.params.todoId, - }); - return res.status(201).send(todoItem); - }, - async update(req, res) { - const todoItem = await TodoItem.findOne({ - attributes: ['id', 'todoId', 'content', 'complete', 'updatedAt'], - where: { - id: req.params.todoItemId, - todoId: req.params.todoId, - }, - }); + }, + }); - if (!todoItem) { - return res.status(404).send({ - message: 'TodoItem Not Found', - }); - } - const updatedTodoItem = await todoItem.update({ - content: req.body.content || todoItem.content, - complete: req.body.complete || todoItem.complete, + if (!todoItem) { + return res.status(404).send({ + message: 'TodoItem Not Found', }); - return res.status(200).send(updatedTodoItem); - }, - async destroy(req, res) { - const todoItem = await TodoItem.findOne({ - attributes: ['id'], - where: { - id: req.params.todoItemId, - todoId: req.params.todoId, - }, + } + const updatedTodoItem = await todoItem.update({ + content: req.body.content || todoItem.content, + complete: req.body.complete || todoItem.complete, + }); + return res.status(200).send(updatedTodoItem); +}; + +const destroy = async (req, res) => { + const todoItem = await db.TodoItem.findOne({ + attributes: ['id'], + where: { + id: req.params.todoItemId, + todoId: req.params.todoId, + }, + }); + + if (!todoItem) { + return res.status(404).send({ + message: 'TodoItem Not Found', }); + } + await todoItem.destroy(); + return res.sendStatus(204); +}; - if (!todoItem) { - return res.status(404).send({ - message: 'TodoItem Not Found', - }); - } - await todoItem.destroy(); - return res.sendStatus(204); - }, +export default { + createTodoItem, + update, + destroy, }; diff --git a/server/controllers/todos.js b/server/controllers/todos.js index 5184804..fce706b 100644 --- a/server/controllers/todos.js +++ b/server/controllers/todos.js @@ -1,60 +1,63 @@ -const { Todo } = require('../models'); -const { TodoItem } = require('../models'); - -module.exports = { - async createTodo(req, res) { - const { body, user } = req; - const createdTodo = await Todo.create({ - title: body.title, - UserId: user.id, - }); - return res.status(201).send(createdTodo); - }, - - async list(req, res) { - const { limit, page, offset } = req.query; - - const todos = await Todo.findAndCountAll({ - limit, - offset, - where: { UserId: req.user.id }, - include: [ - { - model: TodoItem, - attributes: ['id', 'complete', 'content', 'todoId', 'createdAt', 'updatedAt'], - as: 'todoItems', - }, - ], - order: [ - ['createdAt', 'DESC'], - [{ model: TodoItem, as: 'todoItems' }, 'createdAt', 'ASC'], - ], - }); - - const meta = { - total: todos.count, - pageCount: Math.ceil(todos.count / limit), - perPage: limit, - page, - }; - return res.status(200).send({ meta, data: todos.rows }); - }, - - retrieve(req, res) { - return res.status(200).send(req.todo); - }, - - async update(req, res) { - const { todo, body } = req; - const updatedTodo = await todo.update({ - title: body.title, - }); - return res.status(200).send(updatedTodo); - }, - - async destroy(req, res) { - const { todo } = req; - await todo.destroy(); - return res.sendStatus(204); - }, +import db from '../models'; + +const createTodo = async (req, res) => { + const { body, user } = req; + const createdTodo = await db.Todo.create({ + title: body.title, + UserId: user.id, + }); + return res.status(201).send(createdTodo); +}; + +const list = async (req, res) => { + const { limit, page, offset } = req.query; + + const todos = await db.Todo.findAndCountAll({ + limit, + offset, + where: { UserId: req.user.id }, + include: [ + { + model: db.TodoItem, + attributes: ['id', 'complete', 'content', 'todoId', 'createdAt', 'updatedAt'], + as: 'todoItems', + }, + ], + order: [ + ['createdAt', 'DESC'], + [{ model: db.TodoItem, as: 'todoItems' }, 'createdAt', 'ASC'], + ], + }); + + const meta = { + total: todos.count, + pageCount: Math.ceil(todos.count / limit), + perPage: limit, + page, + }; + return res.status(200).send({ meta, data: todos.rows }); +}; + +const retrieve = (req, res) => res.status(200).send(req.todo); + +const update = async (req, res) => { + const { todo, body } = req; + const updatedTodo = await todo.update({ + title: body.title, + }); + return res.status(200).send(updatedTodo); +}; + +const destroy = async (req, res) => { + const { todo } = req; + await todo.destroy(); + return res.sendStatus(204); +}; + +export default { + createTodo, + list, + retrieve, + update, + destroy, }; diff --git a/server/controllers/users.js b/server/controllers/users.js index d72f2aa..d50de3f 100644 --- a/server/controllers/users.js +++ b/server/controllers/users.js @@ -1,10 +1,10 @@ -const jwt = require('jsonwebtoken'); -const { User } = require('../models'); +import jwt from 'jsonwebtoken'; +import db from '../models'; const secretKey = process.env.SECRET_KEY; -async function signup(req, res) { - const user = await User.findOne({ +const signup = async (req, res) => { + const user = await db.User.findOne({ attributes: ['username'], where: { username: req.body.username, @@ -17,7 +17,7 @@ async function signup(req, res) { message: 'Email address already exists', }); } - const newUser = await User.create({ + const newUser = await db.User.create({ username: req.body.username, password: req.body.password, }); @@ -26,10 +26,10 @@ async function signup(req, res) { success: true, user: { id: newUser.id, username: newUser.username, createdAt: newUser.createdAt }, }); -} +}; -async function login(req, res) { - const user = await User.findOne({ +const login = async (req, res) => { + const user = await db.User.findOne({ attributes: ['id', 'password', 'username'], where: { username: req.body.username, @@ -53,11 +53,11 @@ async function login(req, res) { res.status(401).send({ success: false, message: 'Authentication failed. Wrong password' }); } }); -} +}; const updatePassword = async (req, res) => { const { body, params } = req; - const user = await User.findByPk(params.userId); + const user = await db.User.findByPk(params.userId); if (!user) { return res.status(404).send({ @@ -82,7 +82,7 @@ const updatePassword = async (req, res) => { }); }; -module.exports = { +export default { signup, login, updatePassword, diff --git a/server/middlewares/asyncHandler.js b/server/middlewares/asyncHandler.js index 680ef5a..57d5ecc 100644 --- a/server/middlewares/asyncHandler.js +++ b/server/middlewares/asyncHandler.js @@ -9,4 +9,4 @@ const asyncHandler = (cb) => async (req, res, next) => { } }; -module.exports = asyncHandler; +export default asyncHandler; diff --git a/server/middlewares/checkOwner.js b/server/middlewares/checkOwner.js index a228832..50bee7a 100644 --- a/server/middlewares/checkOwner.js +++ b/server/middlewares/checkOwner.js @@ -1,29 +1,28 @@ -const { Todo } = require('../models'); -const { TodoItem } = require('../models'); +import db from '../models'; -module.exports = { - async findTodo(req, res, next) { - const todo = await Todo.findByPk(req.params.todoId, { - include: [ - { - model: TodoItem, - attributes: ['id', 'complete', 'content', 'todoId', 'createdAt', 'updatedAt'], - as: 'todoItems', - }, - ], - }); +const checkOwner = async (req, res, next) => { + const todo = await db.Todo.findByPk(req.params.todoId, { + include: [ + { + model: db.TodoItem, + attributes: ['id', 'complete', 'content', 'todoId', 'createdAt', 'updatedAt'], + as: 'todoItems', + }, + ], + }); - if (!todo) { - return res.status(404).send({ - message: 'Todo Not Found', - }); - } + if (!todo) { + return res.status(404).send({ + message: 'Todo Not Found', + }); + } - if (todo.UserId !== req.user.id) { - return res.status(403).send({ message: 'Forbidden, only the owner can perform this action' }); - } + if (todo.UserId !== req.user.id) { + return res.status(403).send({ message: 'Forbidden, only the owner can perform this action' }); + } - req.todo = todo; - return next(); - }, + req.todo = todo; + return next(); }; + +export default checkOwner; diff --git a/server/middlewares/joiErrors.js b/server/middlewares/joiErrors.js index 60d0292..5d09cc9 100644 --- a/server/middlewares/joiErrors.js +++ b/server/middlewares/joiErrors.js @@ -1,4 +1,4 @@ -const { isCelebrate } = require('celebrate'); +import { isCelebrate } from 'celebrate'; const joiErrors = (err, req, res, next) => { if (!isCelebrate(err)) { @@ -13,4 +13,4 @@ const joiErrors = (err, req, res, next) => { }); }; -module.exports = joiErrors; +export default joiErrors; diff --git a/server/middlewares/pagination.js b/server/middlewares/pagination.js index 5d23821..77700c9 100644 --- a/server/middlewares/pagination.js +++ b/server/middlewares/pagination.js @@ -1,18 +1,18 @@ -module.exports = { - paginate(req, res, next) { - let { limit, page } = req.query; +const paginate = (req, res, next) => { + let { limit, page } = req.query; - page = (typeof page === 'string') ? parseInt(page, 10) || 1 : 1; - limit = (typeof limit === 'string') ? parseInt(limit, 10) || 0 : 10; + page = (typeof page === 'string') ? parseInt(page, 10) || 1 : 1; + limit = (typeof limit === 'string') ? parseInt(limit, 10) || 0 : 10; - if (page < 1) { page = 1; } - if (limit < 0) { limit = 0; } + if (page < 1) { page = 1; } + if (limit < 0) { limit = 0; } - const offset = limit * (page - 1); + const offset = limit * (page - 1); - req.query.limit = limit; - req.query.offset = offset; - req.query.page = page; - return next(); - }, + req.query.limit = limit; + req.query.offset = offset; + req.query.page = page; + return next(); }; + +export default paginate; diff --git a/server/middlewares/reqParamChecker.js b/server/middlewares/reqParamChecker.js index 89001ce..4af371c 100644 --- a/server/middlewares/reqParamChecker.js +++ b/server/middlewares/reqParamChecker.js @@ -8,7 +8,7 @@ const responseTwo = { message: 'URL params must be greater than zero', }; -const checkParams = (req, res, next) => { +const checkTodoParams = (req, res, next) => { const { todoId, todoItemId } = req.params; if (!Number.isInteger(Number(todoId))) { @@ -25,7 +25,7 @@ const checkParams = (req, res, next) => { return next(); }; -const checkUserRouteParams = (req, res, next) => { +const checkUserParams = (req, res, next) => { const { userId } = req.params; if (!Number.isInteger(Number(userId))) { @@ -38,7 +38,9 @@ const checkUserRouteParams = (req, res, next) => { return next(); }; -module.exports = { - checkParams, - checkUserRouteParams, +const paramChecker = { + checkTodoParams, + checkUserParams, }; + +export default paramChecker; diff --git a/server/models/index.js b/server/models/index.js index 0cf5d2d..35db74f 100644 --- a/server/models/index.js +++ b/server/models/index.js @@ -1,8 +1,8 @@ -const fs = require('fs'); -const path = require('path'); -const Sequelize = require('sequelize'); -const dotenv = require('dotenv'); -const DBConfig = require('../config/config'); +import fs from 'fs'; +import path from 'path'; +import Sequelize from 'sequelize'; +import dotenv from 'dotenv'; +import DBConfig from '../config/config'; dotenv.config(); const basename = path.basename(__filename); @@ -30,4 +30,4 @@ Object.keys(db).forEach((modelName) => { db.sequelize = sequelize; db.Sequelize = Sequelize; -module.exports = db; +export default db; diff --git a/server/models/todo.js b/server/models/todo.js index 2adb4ed..68176fc 100644 --- a/server/models/todo.js +++ b/server/models/todo.js @@ -1,4 +1,4 @@ -module.exports = (sequelize, DataTypes) => { +const todoModel = (sequelize, DataTypes) => { const Todo = sequelize.define('Todo', { title: { type: DataTypes.STRING, @@ -18,3 +18,5 @@ module.exports = (sequelize, DataTypes) => { }; return Todo; }; + +export default todoModel; diff --git a/server/models/todoitem.js b/server/models/todoitem.js index 80fb7ec..0ac445c 100644 --- a/server/models/todoitem.js +++ b/server/models/todoitem.js @@ -1,4 +1,4 @@ -module.exports = (sequelize, DataTypes) => { +const todoItemModel = (sequelize, DataTypes) => { const TodoItem = sequelize.define('TodoItem', { content: { type: DataTypes.STRING, @@ -17,3 +17,5 @@ module.exports = (sequelize, DataTypes) => { }; return TodoItem; }; + +export default todoItemModel; diff --git a/server/models/user.js b/server/models/user.js index 5e8adb2..90778f1 100644 --- a/server/models/user.js +++ b/server/models/user.js @@ -1,6 +1,6 @@ -const bcrypt = require('bcrypt'); +import bcrypt from 'bcrypt'; -module.exports = (sequelize, DataTypes) => { +const userModel = (sequelize, DataTypes) => { const User = sequelize.define('User', { username: { type: DataTypes.STRING, @@ -34,3 +34,5 @@ module.exports = (sequelize, DataTypes) => { }; return User; }; + +export default userModel; diff --git a/server/routes/authRouter.js b/server/routes/authRouter.js index 842535c..afda61f 100644 --- a/server/routes/authRouter.js +++ b/server/routes/authRouter.js @@ -1,18 +1,18 @@ -const express = require('express'); -const { celebrate } = require('celebrate'); -const usersController = require('../controllers').users; -const validator = require('../validators/validators'); -const asyncHandler = require('../middlewares/asyncHandler'); +import express from 'express'; +import { celebrate } from 'celebrate'; +import validator from '../validators/validators'; +import asyncHandler from '../middlewares/asyncHandler'; +import controller from '../controllers'; -function authRoutes() { +const authRoutes = () => { const authRouter = express.Router(); authRouter.route('/auth/signup') - .post(celebrate({ body: validator.validateUser }), asyncHandler(usersController.signup)); + .post(celebrate({ body: validator.validateUser }), asyncHandler(controller.users.signup)); authRouter.route('/auth/login') - .post(celebrate({ body: validator.validateLogin }), asyncHandler(usersController.login)); + .post(celebrate({ body: validator.validateLogin }), asyncHandler(controller.users.login)); return authRouter; -} +}; -module.exports = authRoutes; +export default authRoutes; diff --git a/server/routes/index.js b/server/routes/index.js index f0781a5..cf7f899 100644 --- a/server/routes/index.js +++ b/server/routes/index.js @@ -1,10 +1,11 @@ -const todosRouter = require('./todosRouter'); -const authRouter = require('./authRouter'); -const usersRouter = require('./usersRouter'); +import todosRouter from './todosRouter'; +import authRouter from './authRouter'; +import usersRouter from './usersRouter'; - -module.exports = { +const routers = { todosRouter, authRouter, usersRouter, }; + +export default routers; diff --git a/server/routes/todosRouter.js b/server/routes/todosRouter.js index 8f379de..9c1930f 100644 --- a/server/routes/todosRouter.js +++ b/server/routes/todosRouter.js @@ -1,32 +1,31 @@ -const express = require('express'); -const { celebrate } = require('celebrate'); -const todosController = require('../controllers').todos; -const todoItemsController = require('../controllers').todoItems; -const validator = require('../validators/validators'); -const checkOwner = require('../middlewares/checkOwner'); -const asyncHandler = require('../middlewares/asyncHandler'); -const { checkParams } = require('../middlewares/reqParamChecker'); -const { paginate } = require('../middlewares/pagination'); +import express from 'express'; +import { celebrate } from 'celebrate'; +import validator from '../validators/validators'; +import checkOwner from '../middlewares/checkOwner'; +import asyncHandler from '../middlewares/asyncHandler'; +import paramChecker from '../middlewares/reqParamChecker'; +import paginate from '../middlewares/pagination'; +import controller from '../controllers'; -function todosRoutes() { +const todosRoutes = () => { const todosRouter = express.Router(); todosRouter.use('/', paginate); todosRouter.route('/todos') - .post(celebrate({ body: validator.validateTodo }), asyncHandler(todosController.createTodo)) - .get(asyncHandler(todosController.list)); - todosRouter.use('/todos/:todoId', checkParams, asyncHandler(checkOwner.findTodo)); + .post(celebrate({ body: validator.validateTodo }), asyncHandler(controller.todos.createTodo)) + .get(asyncHandler(controller.todos.list)); + todosRouter.use('/todos/:todoId', paramChecker.checkTodoParams, asyncHandler(checkOwner)); todosRouter.route('/todos/:todoId') - .get(asyncHandler(todosController.retrieve)) - .put(celebrate({ body: validator.validateTodo }), asyncHandler(todosController.update)) - .delete(asyncHandler(todosController.destroy)); + .get(asyncHandler(controller.todos.retrieve)) + .put(celebrate({ body: validator.validateTodo }), asyncHandler(controller.todos.update)) + .delete(asyncHandler(controller.todos.destroy)); todosRouter.route('/todos/:todoId/items') .post(celebrate({ body: validator.validateTodoItem, - }), asyncHandler(todoItemsController.createTodoItem)); - todosRouter.use('/todos/:todoId/items/:todoItemId', checkParams); + }), asyncHandler(controller.todoItems.createTodoItem)); + todosRouter.use('/todos/:todoId/items/:todoItemId', paramChecker.checkTodoParams); todosRouter.route('/todos/:todoId/items/:todoItemId') - .put(celebrate({ body: validator.validateTodoItem }), asyncHandler(todoItemsController.update)) - .delete(asyncHandler(todoItemsController.destroy)); + .put(celebrate({ body: validator.validateTodoItem }), asyncHandler(controller.todoItems.update)) + .delete(asyncHandler(controller.todoItems.destroy)); todosRouter.route('*') .all((req, res) => { res.status(405).send({ @@ -35,6 +34,6 @@ function todosRoutes() { }); return todosRouter; -} +}; -module.exports = todosRoutes; +export default todosRoutes; diff --git a/server/routes/usersRouter.js b/server/routes/usersRouter.js index e427b0b..6e501ca 100644 --- a/server/routes/usersRouter.js +++ b/server/routes/usersRouter.js @@ -1,20 +1,20 @@ -const express = require('express'); -const { celebrate } = require('celebrate'); -const usersController = require('../controllers').users; -const validator = require('../validators/validators'); -const asyncHandler = require('../middlewares/asyncHandler'); -const { checkUserRouteParams } = require('../middlewares/reqParamChecker'); +import express from 'express'; +import { celebrate } from 'celebrate'; +import validator from '../validators/validators'; +import asyncHandler from '../middlewares/asyncHandler'; +import paramChecker from '../middlewares/reqParamChecker'; +import controller from '../controllers'; -function userRoutes() { +const userRoutes = () => { const userRouter = express.Router(); - userRouter.use('/users/:userId', checkUserRouteParams); + userRouter.use('/users/:userId', paramChecker.checkUserParams); userRouter.route('/users/:userId') .patch(celebrate({ body: validator.validatePassword, - }), asyncHandler(usersController.updatePassword)); + }), asyncHandler(controller.users.updatePassword)); return userRouter; -} +}; -module.exports = userRoutes; +export default userRoutes; diff --git a/server/tests/integration/authRouter.spec.js b/server/tests/integration/authRouter.spec.js index a20c0b3..1f43573 100644 --- a/server/tests/integration/authRouter.spec.js +++ b/server/tests/integration/authRouter.spec.js @@ -1,9 +1,9 @@ -const chai = require('chai'); +import chai from 'chai'; +import chaiHttp from 'chai-http'; +import app from '../../app'; +import { deleteTestUser } from '../utils'; const { expect } = chai; -const chaiHttp = require('chai-http'); -const app = require('../../../app'); -const { deleteTestUser } = require('../utils'); chai.use(chaiHttp); @@ -33,4 +33,12 @@ describe('Login', () => { expect(res).to.have.status(400); }); + it('should return 400 Bad Request when password is missing', async () => { + const res = await chai + .request(app) + .post('/auth/login') + .send({ username: 'lukecage@alias.com', password1: 'breaker' }); + + expect(res).to.have.status(400); + }); }); diff --git a/server/tests/integration/server.spec.js b/server/tests/integration/server.spec.js index 6ae291b..07dd4ec 100644 --- a/server/tests/integration/server.spec.js +++ b/server/tests/integration/server.spec.js @@ -1,8 +1,8 @@ -const chai = require('chai'); +import chai from 'chai'; +import chaiHttp from 'chai-http'; +import app from '../../app'; const { expect } = chai; -const chaiHttp = require('chai-http'); -const app = require('../../../app'); chai.use(chaiHttp); diff --git a/server/tests/integration/todoRouter.spec.js b/server/tests/integration/todoRouter.spec.js index 210204f..defac78 100644 --- a/server/tests/integration/todoRouter.spec.js +++ b/server/tests/integration/todoRouter.spec.js @@ -1,12 +1,15 @@ -const chai = require('chai'); +import chai from 'chai'; +import chaiHttp from 'chai-http'; +import app from '../../app'; +import { deleteTestUser, tokenInvalid } from '../utils'; const { expect } = chai; -const chaiHttp = require('chai-http'); -const app = require('../../../app'); -const { deleteTestUser, tokenInvalid } = require('../utils'); chai.use(chaiHttp); +let token; +let res2; + describe('TodoRouter', () => { before(async () => { await chai @@ -80,7 +83,7 @@ describe('TodoRouter', () => { it('Should return 200 when a single todo is fetched', async () => { const res = await chai .request(app).get(`/api/todos/${res2.body.id}`) - .set('Authorization', `Bearer ${token}`) + .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(200); expect(res.body).to.include.keys('id', 'title', 'UserId', 'updatedAt', 'createdAt'); @@ -89,7 +92,7 @@ describe('TodoRouter', () => { it('Should return 200 when all todos are fetched', async () => { const res = await chai .request(app).get('/api/todos/') - .set('Authorization', `Bearer ${token}`) + .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(200); expect(res.body.data).to.be.a('array'); @@ -98,7 +101,7 @@ describe('TodoRouter', () => { it('Should return 200 when all todos are fetched with pagination query params', async () => { const res = await chai .request(app).get('/api/todos/?limit=1&page=1') - .set('Authorization', `Bearer ${token}`) + .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(200); expect(res.body.data).to.be.a('array'); @@ -107,7 +110,7 @@ describe('TodoRouter', () => { it('Should return 200 when all todos are fetched with incorrect(negative) page query param', async () => { const res = await chai .request(app).get('/api/todos/?page=-1') - .set('Authorization', `Bearer ${token}`) + .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(200); expect(res.body.data).to.be.a('array'); @@ -116,7 +119,7 @@ describe('TodoRouter', () => { it('Should return 200 when all todos are fetched with incorrect(negative) limit query param', async () => { const res = await chai .request(app).get('/api/todos/?limit=-1') - .set('Authorization', `Bearer ${token}`) + .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(200); expect(res.body.data).to.be.a('array'); @@ -150,7 +153,7 @@ describe('TodoRouter', () => { it('Should return 404 when a todo does not exist', async () => { const res = await chai .request(app) - .delete(`/api/todos/10000`) + .delete('/api/todos/10000') .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(404); @@ -160,7 +163,7 @@ describe('TodoRouter', () => { describe('Todo Items actions', () => { it('Should return 201 when a todo item is created successfully', async () => { - const res2 = await chai + const res3 = await chai .request(app) .post('/api/todos') .set('Authorization', `Bearer ${token}`) @@ -168,7 +171,7 @@ describe('TodoRouter', () => { const res = await chai .request(app) - .post(`/api/todos/${res2.body.id}/items`) + .post(`/api/todos/${res3.body.id}/items`) .set('Authorization', `Bearer ${token}`) .send({ content: 'I beat the hell out of Luke Cage' }); @@ -177,7 +180,7 @@ describe('TodoRouter', () => { }); it('Should return 204 when a todo item is deleted successfully', async () => { - const res2 = await chai + const resCreate = await chai .request(app) .post('/api/todos') .set('Authorization', `Bearer ${token}`) @@ -185,13 +188,13 @@ describe('TodoRouter', () => { const res3 = await chai .request(app) - .post(`/api/todos/${res2.body.id}/items`) + .post(`/api/todos/${resCreate.body.id}/items`) .set('Authorization', `Bearer ${token}`) .send({ content: 'I beat the hell out of Luke Cage' }); const res = await chai .request(app) - .delete(`/api/todos/${res2.body.id}/items/${res3.body.id}`) + .delete(`/api/todos/${resCreate.body.id}/items/${res3.body.id}`) .set('Authorization', `Bearer ${token}`); expect(res).to.have.status(204); diff --git a/server/tests/integration/usersRouter.spec.js b/server/tests/integration/usersRouter.spec.js index c37c5a5..d11f9c7 100644 --- a/server/tests/integration/usersRouter.spec.js +++ b/server/tests/integration/usersRouter.spec.js @@ -1,12 +1,15 @@ -const chai = require('chai'); +import chai from 'chai'; +import chaiHttp from 'chai-http'; +import app from '../../app'; +import { deleteTestUser } from '../utils'; const { expect } = chai; -const chaiHttp = require('chai-http'); -const app = require('../../../app'); -const { deleteTestUser } = require('../utils'); chai.use(chaiHttp); +let token; +let userId; + describe('A user', () => { before(async () => { await chai @@ -38,5 +41,4 @@ describe('A user', () => { expect(res).to.have.status(200); }); }); - }); diff --git a/server/tests/unit/asyncHandler.spec.js b/server/tests/unit/asyncHandler.spec.js index f100ed5..dc1c67d 100644 --- a/server/tests/unit/asyncHandler.spec.js +++ b/server/tests/unit/asyncHandler.spec.js @@ -1,33 +1,33 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import sinon from 'sinon'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import asyncHandler from '../../middlewares/asyncHandler'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const sinon = require('sinon'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const asyncHandler = require('../../middlewares/asyncHandler'); -chai.use(sinonChai) +chai.use(sinonChai); describe('asyncHandler', () => { it('should throw an error and return status code of 500', async () => { const throwError = async (req, res, next) => { const { data: { functionThatDoesNotExist }, - } = req - functionThatDoesNotExist() - } + } = req; + functionThatDoesNotExist(); + }; const request = { headers: { authorization: '', }, - } - const req = mockReq(request) - const res = mockRes() - const next = sinon.spy() + }; + const req = mockReq(request); + const res = mockRes(); + const next = sinon.spy(); - const response = await asyncHandler(throwError) - await response(req, res, next) - expect(res.status).to.have.been.calledWith(500) - }) -}) + const response = await asyncHandler(throwError); + await response(req, res, next); + expect(res.status).to.have.been.calledWith(500); + }); +}); diff --git a/server/tests/unit/checkOwner.spec.js b/server/tests/unit/checkOwner.spec.js index b5ea864..fe06a63 100644 --- a/server/tests/unit/checkOwner.spec.js +++ b/server/tests/unit/checkOwner.spec.js @@ -1,22 +1,26 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinon from 'sinon'; +import sinonChai from 'sinon-chai'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import checkOwner from '../../middlewares/checkOwner'; +import db from '../../models'; + +import { deleteTestUser } from '../utils'; + const { expect } = chai; -const sinon = require('sinon'); -const sinonChai = require('sinon-chai'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const checkOwner = require('../../middlewares/checkOwner'); -const { Todo } = require('../../models'); -const { TodoItem } = require('../../models'); -const { deleteTestUser } = require('../utils'); -const { User } = require('../../models'); chai.use(sinonChai); +let user; +let todo; +let todoItem; + describe('utils', () => { before(async () => { - user = await User.create({ username: 'testuser4@test.com', password: '1234567' }); - todo = await Todo.create({ title: 'Watch Jessica Jones', UserId: user.id }); - todoItem = await TodoItem.create({ content: 'Watch Season 1', todoId: todo.id }); + user = await db.User.create({ username: 'testuser4@test.com', password: '1234567' }); + todo = await db.Todo.create({ title: 'Watch Jessica Jones', UserId: user.id }); + todoItem = await db.TodoItem.create({ content: 'Watch Season 1', todoId: todo.id }); }); after(async () => { @@ -38,7 +42,7 @@ describe('utils', () => { const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - await checkOwner.findTodo(req, res, next); + await checkOwner(req, res, next); expect(next.called).to.be.true; }); @@ -56,7 +60,7 @@ describe('utils', () => { const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - await checkOwner.findTodo(req, res, next); + await checkOwner(req, res, next); expect(res.status).to.have.been.calledWith(404); }); @@ -74,7 +78,7 @@ describe('utils', () => { const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - await checkOwner.findTodo(req, res, next); + await checkOwner(req, res, next); expect(res.status).to.have.been.calledWith(403); }); }); diff --git a/server/tests/unit/joiErrors.spec.js b/server/tests/unit/joiErrors.spec.js index d69ce2f..1b67a3e 100644 --- a/server/tests/unit/joiErrors.spec.js +++ b/server/tests/unit/joiErrors.spec.js @@ -1,9 +1,9 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import joiErrors from '../../middlewares/joiErrors'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const joiErrors = require('../../middlewares/joiErrors'); chai.use(sinonChai); @@ -18,7 +18,7 @@ describe('middlewares', () => { joiErrors(err, req, res, () => { expect(req.joiError).to.be.false; done(); - }) + }); }); }); }); diff --git a/server/tests/unit/paginate.spec.js b/server/tests/unit/paginate.spec.js index 75baefb..b381567 100644 --- a/server/tests/unit/paginate.spec.js +++ b/server/tests/unit/paginate.spec.js @@ -1,9 +1,9 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import paginate from '../../middlewares/pagination'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const { paginate } = require('../../middlewares/pagination'); chai.use(sinonChai); @@ -13,15 +13,15 @@ describe('pagination', () => { const request = { query: { page: 's', - limit: 10 - } + limit: 10, + }, }; const req = mockReq(request); const res = mockRes(); paginate(req, res, () => { expect(req.query.page).to.equal(1); - done() + done(); }); }); @@ -29,63 +29,59 @@ describe('pagination', () => { const request = { query: { page: 1, - limit: 's' - } + limit: 's', + }, }; const req = mockReq(request); const res = mockRes(); paginate(req, res, () => { expect(req.query.limit).to.equal(0); - done() + done(); }); - }); it('should return 0 when limit number is less than 0', (done) => { const request = { query: { page: 1, - limit: '-2' - } + limit: '-2', + }, }; const req = mockReq(request); const res = mockRes(); paginate(req, res, () => { expect(req.query.limit).to.equal(0); - done() + done(); }); - }); it('should return 1 when page number is less than 1', (done) => { const request = { query: { page: '-1', - limit: 2 - } + limit: 2, + }, }; const req = mockReq(request); const res = mockRes(); paginate(req, res, () => { expect(req.query.page).to.equal(1); - done() + done(); }); - }); it('should return actual page when page number is greater than 1', (done) => { const request = { query: { - page: 1 - } + page: 1, + }, }; const req = mockReq(request); const res = mockRes(); paginate(req, res, () => { expect(req.query.page).to.equal(1); - done() + done(); }); - }); }); }); diff --git a/server/tests/unit/reqParamChecker.spec.js b/server/tests/unit/reqParamChecker.spec.js index dc4ce85..dba6c0f 100644 --- a/server/tests/unit/reqParamChecker.spec.js +++ b/server/tests/unit/reqParamChecker.spec.js @@ -1,10 +1,10 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import sinon from 'sinon'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import paramChecker from '../../middlewares/reqParamChecker'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const sinon = require('sinon'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const { checkParams, checkUserRouteParams } = require('../../middlewares/reqParamChecker'); chai.use(sinonChai); @@ -14,75 +14,75 @@ describe('Request param checker', () => { const request = { params: { todoId: -2, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoId is a string', (done) => { const request = { params: { todoId: 's', - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoId is a float', (done) => { const request = { params: { todoId: 1.1, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); xit('should return 400 if the todoId is a .0 float', (done) => { const request = { params: { todoId: 1.0, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoId is a string that is alphanumeric', (done) => { const request = { params: { todoId: '4s', - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoItemId is not a positive integer', (done) => { @@ -90,15 +90,15 @@ describe('Request param checker', () => { params: { todoId: 1, todoItemId: -2, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoItemId is a string', (done) => { @@ -106,15 +106,15 @@ describe('Request param checker', () => { params: { todoId: 1, todoItemId: 's', - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoItemId is an alphanumeric string', (done) => { @@ -122,15 +122,15 @@ describe('Request param checker', () => { params: { todoId: 1, todoItemId: '4s', - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the todoItemId is a float', (done) => { @@ -138,15 +138,15 @@ describe('Request param checker', () => { params: { todoId: 1, todoItemId: 2.3, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); xit('should return 400 if the todoItemId is a .0 float', (done) => { @@ -154,15 +154,15 @@ describe('Request param checker', () => { params: { todoId: 1, todoItemId: 2.0, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return call next if all checks pass', (done) => { @@ -170,15 +170,15 @@ describe('Request param checker', () => { params: { todoId: 1, todoItemId: 4, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkParams(req, res, next); + paramChecker.checkTodoParams(req, res, next); expect(next.called).to.be.true; - done() + done(); }); describe('checkParams for user', () => { @@ -186,76 +186,76 @@ describe('Request param checker', () => { const request = { params: { userId: -2, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkUserRouteParams(req, res, next); + paramChecker.checkUserParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the userId is a string', (done) => { const request = { params: { userId: 's', - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkUserRouteParams(req, res, next); + paramChecker.checkUserParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the userId is a float', (done) => { const request = { params: { userId: 1.1, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkUserRouteParams(req, res, next); + paramChecker.checkUserParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); xit('should return 400 if the userId is a .0 float', (done) => { const request = { params: { userId: 1.0, - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkUserRouteParams(req, res, next); + paramChecker.checkUserParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); it('should return 400 if the userId is a string that is alphanumeric', (done) => { const request = { params: { userId: '4s', - } + }, }; const req = mockReq(request); const res = mockRes(); const next = sinon.spy(); - checkUserRouteParams(req, res, next); + paramChecker.checkUserParams(req, res, next); expect(res.status).to.have.been.calledWith(400); - done() + done(); }); - }) + }); }); }); diff --git a/server/tests/unit/todo.spec.js b/server/tests/unit/todo.spec.js index 6fc005e..b0dfb94 100644 --- a/server/tests/unit/todo.spec.js +++ b/server/tests/unit/todo.spec.js @@ -1,19 +1,21 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import todosController from '../../controllers/todos'; +import db from '../../models'; +import { deleteTestUser } from '../utils'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const todosController = require('../../controllers/todos'); -const { Todo } = require('../../models'); -const { User } = require('../../models'); -const { deleteTestUser } = require('../utils'); chai.use(sinonChai); +let user; +let todo; + describe('todo.controller', () => { before(async () => { - user = await User.create({ username: 'testuser2@test.com', password: '1234567' }); - todo = await Todo.create({ title: 'Watch Jessica Jones', UserId: user.id }); + user = await db.User.create({ username: 'testuser2@test.com', password: '1234567' }); + todo = await db.Todo.create({ title: 'Watch Jessica Jones', UserId: user.id }); }); after(async () => { diff --git a/server/tests/unit/todoItem.spec.js b/server/tests/unit/todoItem.spec.js index a262cf3..290a3cf 100644 --- a/server/tests/unit/todoItem.spec.js +++ b/server/tests/unit/todoItem.spec.js @@ -1,21 +1,23 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import todosItemsController from '../../controllers/todoitems'; +import db from '../../models'; +import { deleteTestUser } from '../utils'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const todosItemsController = require('../../controllers/todoitems'); -const { Todo } = require('../../models'); -const { TodoItem } = require('../../models'); -const { User } = require('../../models'); -const { deleteTestUser } = require('../utils'); chai.use(sinonChai); +let user; +let todo; +let todoItem; + describe('todoItem.controller', () => { before(async () => { - user = await User.create({ username: 'testuser@test.com', password: '1234567' }); - todo = await Todo.create({ title: 'Watch Jessica Jones', UserId: user.id }); - todoItem = await TodoItem.create({ content: 'Watch Season 1', todoId: todo.id }); + user = await db.User.create({ username: 'testuser@test.com', password: '1234567' }); + todo = await db.Todo.create({ title: 'Watch Jessica Jones', UserId: user.id }); + todoItem = await db.TodoItem.create({ content: 'Watch Season 1', todoId: todo.id }); }); after(async () => { @@ -56,7 +58,7 @@ describe('todoItem.controller', () => { const req = mockReq(request); const res = mockRes(); await todosItemsController.update(req, res); - expect(res.status).to.have.been.calledWith(200); + expect(res.status).to.have.been.calledWith(200); }); it('should return 404', async () => { const request = { diff --git a/server/tests/unit/typeChecker.spec.js b/server/tests/unit/typeChecker.spec.js index 461f914..89530a2 100644 --- a/server/tests/unit/typeChecker.spec.js +++ b/server/tests/unit/typeChecker.spec.js @@ -1,8 +1,8 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import isNumber from '../../utils/typeChecker'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const { isNumber } = require('../../utils/typeChecker'); chai.use(sinonChai); @@ -11,33 +11,33 @@ describe('typeChecker', () => { it('should return true if value is a positive integer', (done) => { expect(isNumber(4)).to.be.true; expect(isNumber(434)).to.be.true; - done() + done(); }); it('should return false if value is a negative integer', (done) => { expect(isNumber(-4)).to.be.false; - done() + done(); }); it('should return false if value is a float', (done) => { expect(isNumber(4.1)).to.be.false; expect(isNumber(4.9)).to.be.false; - done() + done(); }); xit('should return false if value is a .0 float', (done) => { expect(isNumber(4.0)).to.be.false; - done() + done(); }); it('should return true if value is a string of a valid number', (done) => { expect(isNumber('4')).to.be.true; - done() + done(); }); it('should return false if value is a string of a valid number', (done) => { expect(isNumber('4s')).to.be.false; - done() + done(); }); }); }); diff --git a/server/tests/unit/user.spec.js b/server/tests/unit/user.spec.js index e9aca47..d5a970f 100644 --- a/server/tests/unit/user.spec.js +++ b/server/tests/unit/user.spec.js @@ -1,17 +1,19 @@ -const chai = require('chai'); +import chai from 'chai'; +import sinonChai from 'sinon-chai'; +import { mockReq, mockRes } from 'sinon-express-mock'; +import db from '../../models'; +import usersController from '../../controllers/users'; +import { deleteTestUser } from '../utils'; const { expect } = chai; -const sinonChai = require('sinon-chai'); -const { mockReq, mockRes } = require('sinon-express-mock'); -const { User } = require('../../models'); -const usersController = require('../../controllers/users'); -const { deleteTestUser } = require('../utils'); chai.use(sinonChai); +let user; + describe('user.controller', () => { before(async () => { - user = await User.create({ username: 'testuserchange@test.com', password: '1234567' }); + user = await db.User.create({ username: 'testuserchange@test.com', password: '1234567' }); }); after(async () => { @@ -85,8 +87,8 @@ describe('user.controller', () => { userId: user.id, }, user: { - id: 44 - } + id: 44, + }, }; const req = mockReq(request); const res = mockRes(); @@ -102,8 +104,8 @@ describe('user.controller', () => { userId: user.id, }, user: { - id: user.id - } + id: user.id, + }, }; const req = mockReq(request); const res = mockRes(); diff --git a/server/tests/unit/validator.spec.js b/server/tests/unit/validator.spec.js index 4e3b3af..d292cc5 100644 --- a/server/tests/unit/validator.spec.js +++ b/server/tests/unit/validator.spec.js @@ -1,6 +1,6 @@ -const { expect } = require('chai'); -const { Joi } = require('celebrate'); -const validator = require('../../validators/validators'); +import { expect } from 'chai'; +import { Joi } from 'celebrate'; +import validator from '../../validators/validators'; describe('validators', () => { describe('todosRouter', () => { diff --git a/server/tests/utils.js b/server/tests/utils.js index 9e3f26b..13f138e 100644 --- a/server/tests/utils.js +++ b/server/tests/utils.js @@ -1,22 +1,17 @@ -const { User } = require('../models'); +import db from '../models'; -const deleteTestUser = async (username) => { - const user = await User.findOne({ +export const deleteTestUser = async (username) => { + const user = await db.User.findOne({ attributes: ['id', 'username'], where: { username, }, - }) + }); if (user) { await user.destroy(); return null; } -} +}; -const tokenInvalid = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjUzNSwidXNlcm5hbWUiOiJyeWFud2lyZTFAb3V0bG9vay5jb20iLCJpYXQiOjE1NjU1MzkzMTYsImV4cCI6MTU2ODEzMTMxNn0._wdtfKOKv4GKsIg7ORPdrtqRATqj5OWcpHqEC_xqwmM'; - -module.exports = { - deleteTestUser, - tokenInvalid -} +export const tokenInvalid = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ1c2VySWQiOjUzNSwidXNlcm5hbWUiOiJyeWFud2lyZTFAb3V0bG9vay5jb20iLCJpYXQiOjE1NjU1MzkzMTYsImV4cCI6MTU2ODEzMTMxNn0._wdtfKOKv4GKsIg7ORPdrtqRATqj5OWcpHqEC_xqwmM'; diff --git a/server/utils/typeChecker.js b/server/utils/typeChecker.js index 91aebe9..d2d811f 100644 --- a/server/utils/typeChecker.js +++ b/server/utils/typeChecker.js @@ -1,5 +1,3 @@ const isNumber = (value) => /^\d+$/.test(value); -module.exports = { - isNumber, -}; +export default isNumber; diff --git a/server/validators/validators.js b/server/validators/validators.js index 205b88d..a02445d 100644 --- a/server/validators/validators.js +++ b/server/validators/validators.js @@ -1,4 +1,4 @@ -const { Joi } = require('celebrate'); +import { Joi } from 'celebrate'; const validateTodo = Joi.object().keys({ title: Joi.string().required(), @@ -23,7 +23,7 @@ const validatePassword = Joi.object().keys({ password: Joi.string().alphanum().min(7).required(), }); -module.exports = { +export default { validateTodo, validateTodoItem, validateUser, From c083e425eeed6f6988aeb829c6ccf4ac8ac8692d Mon Sep 17 00:00:00 2001 From: Raywire Date: Fri, 13 Sep 2019 23:05:36 +0300 Subject: [PATCH 2/2] Adds build script to azure-pipeline.yml file --- azure-pipelines.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e02ca62..71247a6 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -21,7 +21,8 @@ steps: - script: | npm install - displayName: 'npm install' + npm run build + displayName: 'npm install and build' - task: ArchiveFiles@2 displayName: 'Archive files'