diff --git a/.env.sample b/.env.sample new file mode 100644 index 0000000..b02a564 --- /dev/null +++ b/.env.sample @@ -0,0 +1,11 @@ +JWT_SECRET=sampleJWT +DBUSERNAME=sampledb +DBPASSWORD=password +DB=sampledb +DBADDRESS=SampleIpaddress +DBDIALECT=Sampledialect +TESTDB=sampletestdb +ISBNRANDOM_MIN_ID =test_random_id +ISBNRANDOM_MAX_ID=test_random_id +DATABASE_URL=databaseurl +NODE_ENV=environment diff --git a/.eslintrc b/.eslintrc index 85d0bc3..f57224d 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,37 +1,49 @@ { - "root": true, - "extends": "airbnb-base", - "env": { - "node": true, - "es6": true, - "mocha": true - }, - "rules": { - "one-var": 0, - "one-var-declaration-per-line": 0, - "new-cap": 0, - "consistent-return": 0, - "no-param-reassign": 0, - "comma-dangle": 0, - "curly": ["error", "multi-line"], - "prefer-destructuring": ["error", {"object": false,"array": false}], - "import/no-unresolved": [2, { "commonjs": true }], - "no-shadow": ["error", { "allow": ["req", "res", "err"] }], - "valid-jsdoc": ["error", { - "requireReturn": true, - "requireReturnType": true, - "requireParamDescription": false, - "requireReturnDescription": true - }], - "require-jsdoc": ["error", { - "require": { - "FunctionDeclaration": true, - "MethodDefinition": true, - "ClassDeclaration": true - } - }] - }, - "settings": { - "import/resolver": "node" -} + "root": true, + "extends": "airbnb-base", + "env": { + "browser": true, + "jquery": true, + "node": true, + "es6": true, + "mocha": true + }, + "globals": { + "describe": true, + "expect": true + }, + "rules": { + "one-var": 0, + "one-var-declaration-per-line": 0, + "new-cap": 0, + "consistent-return": 0, + "no-param-reassign": 0, + "comma-dangle": 0, + "curly": [ "error", "multi-line" ], + "prefer-destructuring": [ "error", { "object": false, "array": false } ], + "import/no-unresolved": [ 2, { "commonjs": true } ], + "no-shadow": [ "error", { "allow": [ "req", "res", "err" ] } ], + "valid-jsdoc": [ + "error", + { + "requireReturn": true, + "requireReturnType": true, + "requireParamDescription": false, + "requireReturnDescription": true + } + ], + "require-jsdoc": [ + "error", + { + "require": { + "FunctionDeclaration": true, + "MethodDefinition": true, + "ClassDeclaration": true + } + } + ] + }, + "settings": { + "import/resolver": "node" + } } diff --git a/.travis.yml b/.travis.yml index 62f069b..5f6d7fb 100644 --- a/.travis.yml +++ b/.travis.yml @@ -28,7 +28,6 @@ before_script: - npm install -g sequelize - psql -c 'drop database if exists travis;' -U postgres - psql -c 'create database travis;' -U postgres - - NODE_ENV=test && npm run test:db script: - npm test diff --git a/Procfile b/Procfile index c27f5a3..28fe750 100644 --- a/Procfile +++ b/Procfile @@ -1 +1 @@ -web: node ./server/dist/bin/www.js \ No newline at end of file +web: npm run start diff --git a/client/src/app/actions/auth.js b/client/src/app/actions/auth.js index c67bf0b..dc73e08 100644 --- a/client/src/app/actions/auth.js +++ b/client/src/app/actions/auth.js @@ -72,8 +72,8 @@ export const login = credentials => dispatch => api dispatch(signInUserFailure(user)); return Promise.reject(token); } - global.localStorage.setItem('token', token); - global.localStorage.setItem('username', username); + localStorage.setItem('token', token); + localStorage.setItem('username', username); setAuthorizationToken(token); dispatch(userLoggedIn(user.data)); @@ -88,8 +88,8 @@ export const login = credentials => dispatch => api * @param {*} dispatch */ export const logout = () => (dispatch) => { - global.localStorage.removeItem('token'); - global.localStorage.removeItem('username'); + localStorage.removeItem('token'); + localStorage.removeItem('username'); setAuthorizationToken(false); dispatch(userLoggedOut()); }; diff --git a/client/src/app/store/configStore.dev.js b/client/src/app/store/configStore.dev.js index ba469b8..466bb15 100644 --- a/client/src/app/store/configStore.dev.js +++ b/client/src/app/store/configStore.dev.js @@ -22,9 +22,9 @@ const store = createStore( ); -if (global.localStorage.token) { - setAuthorizationToken(global.localStorage.token); - store.dispatch(setCurrentUser(jwtdecode(global.localStorage.token))); +if (localStorage.token) { + setAuthorizationToken(localStorage.token); + store.dispatch(setCurrentUser(jwtdecode(localStorage.token))); } store.subscribe(throttle(() => { diff --git a/client/src/app/store/configStore.js b/client/src/app/store/configStore.js index c819a42..62d8190 100644 --- a/client/src/app/store/configStore.js +++ b/client/src/app/store/configStore.js @@ -1,5 +1,8 @@ +import configDev from './configStore.dev'; +import configProd from './configStore.prod'; + if (process.env.NODE_ENV === 'production') { - module.exports = require('./configStore.prod'); + module.exports = configProd; } else { - module.exports = require('./configStore.dev'); + module.exports = configDev; } diff --git a/client/src/app/store/configStore.prod.js b/client/src/app/store/configStore.prod.js index 578a953..6ed2db0 100644 --- a/client/src/app/store/configStore.prod.js +++ b/client/src/app/store/configStore.prod.js @@ -6,9 +6,9 @@ import thunk from 'redux-thunk'; import setAuthorizationToken from '../utils/setAuthorizationToken'; import { setCurrentUser } from '../actions/auth'; import rootReducer from '../reducers/rootReducers'; -import { loadState, saveState } from '../utils/Localsave'; +import { saveState } from '../utils/Localsave'; -const initialState = loadState; +const initialState = {}; const store = createStore( rootReducer, initialState, @@ -16,9 +16,9 @@ const store = createStore( ); -if (global.localStorage.token) { - setAuthorizationToken(global.localStorage.token); - store.dispatch(setCurrentUser(jwtdecode(global.localStorage.token))); +if (localStorage.token) { + setAuthorizationToken(localStorage.token); + store.dispatch(setCurrentUser(jwtdecode(localStorage.token))); } store.subscribe(throttle(() => { diff --git a/client/src/app/utils/Localsave.js b/client/src/app/utils/Localsave.js index 6552ce8..2c88a29 100644 --- a/client/src/app/utils/Localsave.js +++ b/client/src/app/utils/Localsave.js @@ -1,11 +1,10 @@ +/* +eslint-disable no-console +*/ export const saveState = (state) => { try { - // localStorage.setItem('username', state.user.user.username || null); - //let serializedState; const serializedState = JSON.stringify(state); localStorage.setItem('state', serializedState); - - } catch (e) { console.log(e); } diff --git a/package.json b/package.json index c3cfd36..1f21a71 100644 --- a/package.json +++ b/package.json @@ -1,134 +1,129 @@ { - "name": "server", - "version": "1.0.0", - "description": "", - "main": "app.js", - "scripts": { - "start": "node server/dist/bin/www.js", - "test:migrate": "sequelize db:migrate --env=test", - "test:db": "npm run build:travis", - "start:migrate": "sequelize db:migrate", - "undo:migratetest": "sequelize db:migrate:undo:all --env=test", - "undo:migrate": "sequelize db:migrate:undo:all", - "start:dev": "nodemon server/dist/bin/www.js", - "start:webdev": "npm run build:webdev", - "build:webdev": "webpack -d && webpack-dev-server && --content-base client/src/ --inline --hot ", - "clean-dist": "npm run remove-dist && mkdir client/dist", - "remove-dist": "rimraf client/dist", - "build:prod-webdev": "npm run clean-dist && export NODE_ENV=production && webpack && cp client/src/index.html client/dist/index.html", - "heroku-postbuild": "npm run build:prod-webdev", - "build": "babel server/src --watch --out-dir server/dist --presets es2015", - "build:travis": "babel server/src --out-dir server/dist --presets es2015", - "pretest": "npm run undo:migratetest && npm run test:migrate && sequelize db:seed:all", - "test": "export NODE_ENV=test && mocha server/dist/test/*.js --timeout 10000 && export NODE_ENV=development", - "coverage": "cross-env NODE_ENV=test && npm run pretest && nyc --reporter=lcov --reporter=text --reporter=lcovonly mocha --compilers js:babel-register server/src/test/* --exclude 'server/dist/' " - }, - "engines": { - "npm": "5.3.0", - "node": "7.4.0" - }, - "keywords": [], - "author": "", - "license": "ISC", - "dependencies": { - "axios": "^0.16.2", - "babel-cli": "^6.24.1", - "babel-core": "^6.26.0", - "babel-eslint": "^7.2.3", - "babel-loader": "^7.1.2", - "babel-polyfill": "^6.23.0", - "babel-preset-env": "^1.6.0", - "babel-preset-es2015": "^6.24.1", - "babel-preset-react": "^6.24.1", - "babel-preset-stage-2": "^6.24.1", - "bcrypt": "^1.0.2", - "bcrypt-nodejs": "0.0.3", - "body-parser": "^1.17.2", - "chai": "^4.1.0", - "chai-http": "^3.0.0", - "cheerio": "^1.0.0-rc.2", - "colors": "^1.1.2", - "cross-env": "^5.0.5", - "css-loader": "^0.28.7", - "debug": "^3.0.0", - "dotenv": "^4.0.0", - "eslint": "^4.3.0", - "express": "^4.15.3", - "express-boom": "^2.0.0", - "extract-text-webpack-plugin": "^3.0.0", - "faker": "^4.1.0", - "fakerator": "^0.3.0", - "file-loader": "^0.11.2", - "foreman": "^2.0.0", - "html-loader": "^0.5.1", - "html-webpack-plugin": "^2.30.1", - "json": "^9.0.6", - "jsonwebtoken": "^7.4.1", - "jwt-decode": "^2.2.0", - "lodash": "^4.17.4", - "materialize-css": "^0.100.2", - "mocha": "^3.5.0", - "morgan": "^1.8.2", - "muicss": "^0.9.25", - "node-sass": "^4.5.3", - "nodemon": "^1.11.0", - "pg": "^7.0.2", - "pg-hstore": "^2.3.2", - "prop-types": "^15.5.10", - "react": "^15.6.1", - "react-cookie": "^2.0.8", - "react-dom": "^15.6.1", - "react-materialize": "^1.0.11", - "react-md": "^1.0.19", - "react-redux": "^5.0.6", - "react-router": "^4.2.0", - "react-router-dom": "^4.2.2", - "react-router-redux": "^4.0.8", - "react-tabs": "^2.0.0", - "redux": "^3.7.2", - "redux-devtools-extension": "^2.13.2", - "redux-form": "^6.0.0-rc.3", - "redux-logger": "^3.0.6", - "redux-persist": "^4.10.1", - "redux-thunk": "^2.2.0", - "rimraf": "^2.6.2", - "sass-loader": "^6.0.6", - "scss-loader": "0.0.1", - "semantic-ui-react": "^0.73.0", - "sentence-case": "^2.1.1", - "sequelize": "^4.7.5", - "sequelize-cli": "^2.8.0", - "style-loader": "^0.18.2", - "swagger-jsdoc": "^1.3.0", - "sweetalert2": "^6.7.0", - "to-title-case": "^1.0.0", - "unique-random": "^1.0.0", - "validator": "^8.2.0", - "validators": "^0.3.1", - "webpack": "^3.5.5", - "webpack-dev-server": "^2.7.1" - }, - "devDependencies": { - "babel-cli": "^6.26.0", - "babel-register": "^6.24.1", - "clean-webpack-plugin": "^0.1.16", - "coveralls": "^2.13.1", - "cross-env": "^5.0.5", - "eslint-config-airbnb-base": "^12.0.0", - "eslint-plugin-import": "^2.7.0", - "git-flow": "^0.2.0", - "mocha-lcov-reporter": "^1.3.0", - "nodemailer": "^4.1.0", - "nyc": "^11.1.0", - "path": "^0.12.7", - "prop-types": "^15.5.10", - "purify-css": "^1.2.5", - "purifycss": "^1.2.6", - "purifycss-webpack": "^0.7.0", - "react-addons-css-transition-group": "^15.6.0", - "react-addons-transition-group": "^15.6.0", - "react-burger-menu": "^2.1.6", - "reactstrap": "^4.8.0", - "redux-promise-middleware": "^4.4.1" - } + "name": "server", + "version": "1.0.0", + "description": "", + "main": "app.js", + "scripts": { + "start": "babel-watch server/dist/bin/www.js", + "build": "babel server/src --out-dir server/dist --presets es2015", + "build:continuous": "babel server/src --watch --out-dir server/dist --presets es2015", + "pretest": "rimraf server/dist && mkdir server/dist && npm run build && sequelize db:migrate:undo:all --env=test && sequelize db:migrate --env=test && sequelize db:seed:all --env=test ", + "test": "export NODE_ENV=test && mocha server/dist/test/index.js --timeout 10000 && export NODE_ENV=development", + "coverage": "cross-env NODE_ENV=test && npm run pretest && nyc --reporter=lcov --reporter=text --reporter=lcovonly mocha --compilers js:babel-register server/src/test/* --exclude 'server/dist/' ", + "start:migrate": "sequelize db:migrate", + "undo:migrate": "sequelize db:migrate:undo:all", + "start:dev": "babel-node server/dist/bin/www.js", + "start-prod": "babel server/src --out-dir server/dist --presets es2015 && npm run heroku-postbuild", + "build:webdev": "webpack -d && webpack-dev-server && --content-base client/src/ --inline --hot ", + "heroku-postbuild": "rimraf client/dist && mkdir client/dist && npm run build && export NODE_ENV=production && npm run undo:migrate && npm run start:migrate && webpack" + }, + "engines": { + "npm": "5.3.0", + "node": "7.4.0" + }, + "keywords": [], + "author": "", + "license": "ISC", + "dependencies": { + "axios": "^0.16.2", + "babel-cli": "^6.24.1", + "babel-core": "^6.26.0", + "babel-eslint": "^7.2.3", + "babel-loader": "^7.1.2", + "babel-polyfill": "^6.23.0", + "babel-preset-env": "^1.6.0", + "babel-preset-es2015": "^6.24.1", + "babel-preset-react": "^6.24.1", + "babel-preset-stage-2": "^6.24.1", + "babel-watch": "^2.0.7", + "bcrypt": "^1.0.3", + "body-parser": "^1.17.2", + "chai": "^4.1.0", + "chai-http": "^3.0.0", + "cheerio": "^1.0.0-rc.2", + "colors": "^1.1.2", + "concurrently": "^3.5.0", + "cross-env": "^5.0.5", + "css-loader": "^0.28.7", + "debug": "^3.0.0", + "dotenv": "^4.0.0", + "eslint": "^4.3.0", + "express": "^4.15.3", + "express-boom": "^2.0.0", + "extract-text-webpack-plugin": "^3.0.0", + "faker": "^4.1.0", + "fakerator": "^0.3.0", + "file-loader": "^0.11.2", + "foreman": "^2.0.0", + "html-loader": "^0.5.1", + "html-webpack-plugin": "^2.30.1", + "json": "^9.0.6", + "jsonwebtoken": "^7.4.1", + "jwt-decode": "^2.2.0", + "lodash": "^4.17.4", + "materialize-css": "^0.100.2", + "mocha": "^3.5.0", + "morgan": "^1.8.2", + "muicss": "^0.9.25", + "node-sass": "^4.5.3", + "nodemon": "^1.11.0", + "pg": "^7.0.2", + "pg-hstore": "^2.3.2", + "prop-types": "^15.5.10", + "react": "^15.6.1", + "react-cookie": "^2.0.8", + "react-dom": "^15.6.1", + "react-materialize": "^1.0.11", + "react-md": "^1.0.19", + "react-redux": "^5.0.6", + "react-router": "^4.2.0", + "react-router-dom": "^4.2.2", + "react-router-redux": "^4.0.8", + "react-tabs": "^2.0.0", + "redux": "^3.7.2", + "redux-devtools-extension": "^2.13.2", + "redux-form": "^6.0.0-rc.3", + "redux-logger": "^3.0.6", + "redux-persist": "^4.10.1", + "redux-thunk": "^2.2.0", + "rimraf": "^2.6.2", + "sass-loader": "^6.0.6", + "scss-loader": "0.0.1", + "semantic-ui-react": "^0.73.0", + "sentence-case": "^2.1.1", + "sequelize": "^4.7.5", + "sequelize-cli": "^2.8.0", + "style-loader": "^0.18.2", + "swagger-jsdoc": "^1.3.0", + "sweetalert2": "^6.7.0", + "to-title-case": "^1.0.0", + "unique-random": "^1.0.0", + "validator": "^8.2.0", + "validators": "^0.3.1", + "webpack": "^3.5.5", + "webpack-dev-server": "^2.7.1" + }, + "devDependencies": { + "babel-cli": "^6.26.0", + "babel-register": "^6.24.1", + "clean-webpack-plugin": "^0.1.16", + "coveralls": "^2.13.1", + "cross-env": "^5.0.5", + "eslint-config-airbnb-base": "^12.0.0", + "eslint-plugin-import": "^2.7.0", + "git-flow": "^0.2.0", + "mocha-lcov-reporter": "^1.3.0", + "nodemailer": "^4.1.0", + "nyc": "^11.1.0", + "path": "^0.12.7", + "prop-types": "^15.5.10", + "purify-css": "^1.2.5", + "purifycss": "^1.2.6", + "purifycss-webpack": "^0.7.0", + "react-addons-css-transition-group": "^15.6.0", + "react-addons-transition-group": "^15.6.0", + "react-burger-menu": "^2.1.6", + "reactstrap": "^4.8.0", + "redux-promise-middleware": "^4.4.1" + } } diff --git a/server/src/app.js b/server/src/app.js index 5f22bac..05e34fd 100644 --- a/server/src/app.js +++ b/server/src/app.js @@ -18,7 +18,8 @@ app.use(logger('dev')); app.use(bodyParser.json()); app.use(bodyParser.urlencoded({ extended: false })); -app.use('/apiDocs', express.static(path.join(__dirname, '../../apiDocs/'))); +app.use('/api-docs', express.static(path.join(__dirname, '../../apiDocs/'))); +app.use(express.static(path.join(__dirname, '../../client/dist/app'))); app.use((req, res, next) => { res.header('Access-Control-Allow-Headers', 'Authorization, X-PINGOTHER, Origin, X-Requested-With, Content-Type, Accept, x-ac' + @@ -27,8 +28,8 @@ app.use((req, res, next) => { }); -app.use('/api/v1', routes, authenticateRoutes); +app.use('/api/v1', authenticateRoutes, routes); -app.get('*', (req, res) => res.status(404).send({ message: 'You are at a wrong route' })); +app.get('*', (req, res) => res.sendFile(path.join(__dirname, '../../client/dist/app/index.html'))); export default(app); diff --git a/server/src/config/config.js b/server/src/config/config.js index 333969a..427eec8 100644 --- a/server/src/config/config.js +++ b/server/src/config/config.js @@ -21,8 +21,7 @@ module.exports = { }, production: { - dialect: process.env.DBDIALECT, - use_env_variable: process.env.DATABASE_URL - + use_env_variable: 'DATABASE_URL', + dialect: process.env.DBDIALECT } }; diff --git a/server/src/config/config.json b/server/src/config/config.json deleted file mode 100644 index 1fbd445..0000000 --- a/server/src/config/config.json +++ /dev/null @@ -1,25 +0,0 @@ -{ - "development": { - "username": "postgres", - "password": "root", - - "database": "hello_books", - "host": "127.0.0.1", - "dialect": "postgres" - }, - "test": { - "username": "postgres", - "password": "root", - "database": "travis", - "host": "127.0.0.1", - "dialect": "postgres" - }, - - "production": { - - "dialect": "postgres", - "use_env_variable": "DATABASE_URL" - - } - -} diff --git a/server/src/controllers/user.js b/server/src/controllers/user.js index 0e08abb..cb3675f 100644 --- a/server/src/controllers/user.js +++ b/server/src/controllers/user.js @@ -1,4 +1,4 @@ -import bcrypt from 'bcrypt-nodejs'; +import bcrypt from 'bcrypt'; import models from '../models'; // import sendResetPasswordEmail from '../mailer/mailer'; import generateToken from '../controllers/middleware/authenticate'; diff --git a/server/src/models/index.js b/server/src/models/index.js index 8052aeb..de8ccf0 100644 --- a/server/src/models/index.js +++ b/server/src/models/index.js @@ -4,7 +4,6 @@ import Sequelize from 'sequelize'; import configenv from '../config/config'; - const env = process.env.NODE_ENV || 'development'; const config = configenv[env]; diff --git a/server/src/models/user.js b/server/src/models/user.js index 06a7735..e07ab79 100644 --- a/server/src/models/user.js +++ b/server/src/models/user.js @@ -1,4 +1,4 @@ -import bcrypt from 'bcrypt-nodejs'; +import bcrypt from 'bcrypt'; import toTitleCase from 'to-title-case'; export default(sequelize, DataTypes) => { diff --git a/server/src/routes/index.js b/server/src/routes/index.js index 0a48f35..d272a6d 100644 --- a/server/src/routes/index.js +++ b/server/src/routes/index.js @@ -18,17 +18,17 @@ Router.post('/auth/users/signup', fieldValidationMiddleware, nullvalidationMiddl Router.post('/auth/users/signin', nullvalidationMiddleware, UserController.signin); -Router.post('/books', authorization, nullvalidationMiddleware, BooksController.create); +Router.post('/books', nullvalidationMiddleware, BooksController.create); -Router.put('/books/:bookId', authorization, nullvalidationMiddleware, BooksController.update); +Router.put('/books/:bookId', nullvalidationMiddleware, BooksController.update); -Router.get('/books/', authorization, BooksController.getAllBooks); +Router.get('/books/', BooksController.getAllBooks); -Router.post('/users/:userId/books', authorization, UserBooksController.loanbook); +Router.post('/users/:userId/books', UserBooksController.loanbook); -Router.put('/users/:userId/books', authorization, UserBooksController.returnbook); +Router.put('/users/:userId/books', UserBooksController.returnbook); -Router.get('/users/:userId/books', authorization, UserBooksController.getborrowerslist); +Router.get('/users/:userId/books', UserBooksController.getborrowerslist); // Router.delete('books/:bookId', BooksController.destroybooks); // Router.put('/users/:userId', UserController.updateUserInfo); diff --git a/server/src/seeders/books.js b/server/src/seeders/seedbooks.js similarity index 98% rename from server/src/seeders/books.js rename to server/src/seeders/seedbooks.js index 0ddb33f..1551020 100644 --- a/server/src/seeders/books.js +++ b/server/src/seeders/seedbooks.js @@ -50,6 +50,5 @@ module.exports = { ]), down: queryInterface => queryInterface.bulkDelete('Books', [{ - username: 'aimee' }]) }; diff --git a/server/src/seeders/seeds.js b/server/src/seeders/seedusers.js similarity index 97% rename from server/src/seeders/seeds.js rename to server/src/seeders/seedusers.js index 00cae5b..504bcfc 100644 --- a/server/src/seeders/seeds.js +++ b/server/src/seeders/seedusers.js @@ -27,7 +27,7 @@ module.exports = { ]), down: queryInterface => queryInterface.bulkDelete('User', [{ - username: 'aimee' + }]) }; diff --git a/server/src/test/booksSpec.js b/server/src/test/booksSpec.js index 8046acc..8127f5f 100644 --- a/server/src/test/booksSpec.js +++ b/server/src/test/booksSpec.js @@ -89,7 +89,7 @@ describe('HelloBooks', () => { done(); }); }); - it('should return books when given a default and an offset', (done) => { + it('should return books when given a default limit and an offset', (done) => { chai .request(app) .get('/api/v1/books') diff --git a/server/src/test/index.js b/server/src/test/index.js new file mode 100644 index 0000000..4b52efa --- /dev/null +++ b/server/src/test/index.js @@ -0,0 +1,5 @@ +require('./userSpec'); +require('./booksSpec'); +require('./userbooksSpec'); +require('./modelSpec'); + diff --git a/server/src/test/userSpec.js b/server/src/test/userSpec.js index d7a736f..3396119 100644 --- a/server/src/test/userSpec.js +++ b/server/src/test/userSpec.js @@ -100,7 +100,7 @@ describe('HelloBooks', () => { }); describe('/POST Signing up a user', () => { - it('should only all users are to register, Sign up successful', (done) => { + it('should only all register users who fill in all the fields', (done) => { const email = faker .internet .email(); diff --git a/server/src/test/userbooksSpec.js b/server/src/test/userbooksSpec.js index a0021c4..0efc037 100644 --- a/server/src/test/userbooksSpec.js +++ b/server/src/test/userbooksSpec.js @@ -305,7 +305,7 @@ describe('HelloBooks', () => { it('should return a list of books loaned by the user', (done) => { chai .request(app) - .get(`/api/v1//users/${userId}/books`) + .get(`/api/v1/users/${userId}/books`) .set('Accept', 'application/x-www-form-urlencoded') .query({ returned: false }) .set('x-access-token', token) @@ -319,7 +319,7 @@ describe('HelloBooks', () => { it('should not return a borrow list if return query is not set', (done) => { chai .request(app) - .get(`/api/v1//users/${userId}/books`) + .get(`/api/v1/users/${userId}/books`) .set('Accept', 'application/x-www-form-urlencoded') .set('x-access-token', token) .end((err, res) => { diff --git a/webpack.config.js b/webpack.config.js index 6573c8f..168297f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -20,46 +20,40 @@ if (isProd) { output: { path: `${__dirname}/client/dist/app/`, publicPath: '/', - filename: 'bundle.js', - }, - devServer: { - contentBase: path.resolve(__dirname, 'dist') + filename: 'bundle.js' }, plugins: [ - new webpack.optimize.OccurrenceOrderPlugin(), + new webpack + .optimize + .OccurrenceOrderPlugin(), new webpack.DefinePlugin(GLOBALS), new ExtractTextPlugin('styles.css'), - new webpack.optimize.UglifyJsPlugin({ minimize: true }), - new HtmlPlugin({ template: './client/src/index.html', filename: './index.html', inject: 'body' }) - + new webpack + .optimize + .UglifyJsPlugin({minimize: true}), + new HtmlPlugin({template: './client/src/index.html', filename: './index.html', inject: 'body'}) ], module: { loaders: [ { test: /(\.css)$/, - use: ExtractTextPlugin.extract({ - use: 'css-loader' - }) - }, - { + use: ExtractTextPlugin.extract({use: 'css-loader'}) + }, { test: /\.scss$/, use: ExtractTextPlugin.extract({ use: ['css-loader', 'sass-loader'] }) - }, - { + }, { test: /\.(js|jsx)$/, loader: 'babel-loader', exclude: /node_modules/, query: { presets: ['react', 'es2015', 'stage-2'] - }, - }, - { + } + }, { test: /\.(woff|woff2)$/, loader: 'url?prefix=font/&limit=5000' - }, - { + }, { test: /\.(jpg|png)$/, exclude: /node-modules/, loader: 'file-loader', @@ -68,7 +62,7 @@ if (isProd) { } } - ], + ] }, node: { dns: 'empty', @@ -79,7 +73,7 @@ if (isProd) { } else { const DIST_DIR = path.resolve(__dirname, './client/dist'); const SRC_DIR = path.resolve(__dirname, './client/src'); - const extractscss = new ExtractTextPlugin({ filename: 'style.css' }); + const extractscss = new ExtractTextPlugin({filename: 'style.css'}); config = { entry: `${SRC_DIR}/app/index.js`, output: { @@ -116,7 +110,7 @@ if (isProd) { query: { presets: ['react', 'es2015', 'stage-2'] }, - // rules:[ + // rules:[ }, { test: /\.(scss|sass)$/, exclude: /node-modules/, @@ -148,7 +142,7 @@ if (isProd) { .optimize .OccurrenceOrderPlugin(), extractscss, - new HtmlPlugin({ template: './client/src/index.html', filename: './index.html', inject: 'body' }), + new HtmlPlugin({ template: './client/src/index.html', filename: './index.html', inject: 'body' }) ] };