Started adding some tests
parent
245c67188b
commit
61c59c8997
15
app.js
15
app.js
|
@ -315,7 +315,13 @@ MongoClient.connect(config.databaseConnectionString, {}, (err, client) => {
|
||||||
|
|
||||||
// select DB
|
// select DB
|
||||||
const dbUriObj = mongodbUri.parse(config.databaseConnectionString);
|
const dbUriObj = mongodbUri.parse(config.databaseConnectionString);
|
||||||
const db = client.db(dbUriObj.database);
|
let db;
|
||||||
|
// if in testing, set the testing DB
|
||||||
|
if(process.env.NODE_ENV === 'test'){
|
||||||
|
db = client.db('testingdb');
|
||||||
|
}else{
|
||||||
|
db = client.db(dbUriObj.database);
|
||||||
|
}
|
||||||
|
|
||||||
// setup the collections
|
// setup the collections
|
||||||
db.users = db.collection('users');
|
db.users = db.collection('users');
|
||||||
|
@ -326,17 +332,20 @@ MongoClient.connect(config.databaseConnectionString, {}, (err, client) => {
|
||||||
db.customers = db.collection('customers');
|
db.customers = db.collection('customers');
|
||||||
|
|
||||||
// add db to app for routes
|
// add db to app for routes
|
||||||
|
app.dbClient = client;
|
||||||
app.db = db;
|
app.db = db;
|
||||||
|
app.config = config;
|
||||||
|
app.port = app.get('port');
|
||||||
|
|
||||||
// run indexing
|
// run indexing
|
||||||
common.runIndexing(app)
|
common.runIndexing(app)
|
||||||
.then(common.testData(db, app))
|
|
||||||
.then(app.listen(app.get('port')))
|
.then(app.listen(app.get('port')))
|
||||||
.then(() => {
|
.then(() => {
|
||||||
// lift the app
|
// lift the app
|
||||||
|
app.emit('appStarted');
|
||||||
console.log(colors.green('expressCart running on host: http://localhost:' + app.get('port')));
|
console.log(colors.green('expressCart running on host: http://localhost:' + app.get('port')));
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch((err) => {
|
||||||
console.error(colors.red('Error setting up indexes:' + err));
|
console.error(colors.red('Error setting up indexes:' + err));
|
||||||
process.exit(2);
|
process.exit(2);
|
||||||
});
|
});
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
"productImage": "/uploads/duckworth-jacket/woolfill-jacket_6c39ae23-c0c8-4821-85f4-4b5d64333c62_grande.jpg"
|
"productImage": "/uploads/duckworth-jacket/woolfill-jacket_6c39ae23-c0c8-4821-85f4-4b5d64333c62_grande.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"productPermalink": "5-panel-cap",
|
"productPermalink": "5-panel-camp-cap",
|
||||||
"productTitle": "5 Panel Camp Cap",
|
"productTitle": "5 Panel Camp Cap",
|
||||||
"productPrice": "48",
|
"productPrice": "48",
|
||||||
"productDescription": "<p style=\"margin-bottom: 25px; text-rendering: optimizeLegibility;\">A classic 5 panel hat with our United By Blue logo on the front and an adjustable strap to keep fit and secure. Made with recycled polyester and organic cotton mix.<\/p><ul style=\"margin-right: 0px; margin-bottom: 25px; margin-left: 20px; padding: 0px; text-rendering: optimizeLegibility;\"><li style=\"margin-bottom: 0px;\">Made in New Jersey<\/li><li style=\"margin-bottom: 0px;\">7oz Eco-Twill fabric: 35% organic cotton, 65% recycled PET (plastic water and soda bottles) <\/li><li style=\"margin-bottom: 0px;\">Embossed leather patch<\/li><\/ul><ul class=\"tabs\" style=\"margin-right: 0px; margin-bottom: 25px; margin-left: 20px; padding: 0px; text-rendering: optimizeLegibility; color: rgb(28, 29, 29); font-family: Arapey, serif; line-height: 25.008px;\"><\/ul>",
|
"productDescription": "<p style=\"margin-bottom: 25px; text-rendering: optimizeLegibility;\">A classic 5 panel hat with our United By Blue logo on the front and an adjustable strap to keep fit and secure. Made with recycled polyester and organic cotton mix.<\/p><ul style=\"margin-right: 0px; margin-bottom: 25px; margin-left: 20px; padding: 0px; text-rendering: optimizeLegibility;\"><li style=\"margin-bottom: 0px;\">Made in New Jersey<\/li><li style=\"margin-bottom: 0px;\">7oz Eco-Twill fabric: 35% organic cotton, 65% recycled PET (plastic water and soda bottles) <\/li><li style=\"margin-bottom: 0px;\">Embossed leather patch<\/li><\/ul><ul class=\"tabs\" style=\"margin-right: 0px; margin-bottom: 25px; margin-left: 20px; padding: 0px; text-rendering: optimizeLegibility; color: rgb(28, 29, 29); font-family: Arapey, serif; line-height: 25.008px;\"><\/ul>",
|
||||||
|
@ -79,7 +79,7 @@
|
||||||
"productImage" : "/uploads/hudderton-backpack/hudderton-backpack_dc8afb13-448b-49d9-a042-5a163a97de8f_590x.jpg"
|
"productImage" : "/uploads/hudderton-backpack/hudderton-backpack_dc8afb13-448b-49d9-a042-5a163a97de8f_590x.jpg"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"productPermalink" : "Ayres",
|
"productPermalink" : "ayres-chambray",
|
||||||
"productTitle" : "Ayres Chambray",
|
"productTitle" : "Ayres Chambray",
|
||||||
"productPrice" : "77",
|
"productPrice" : "77",
|
||||||
"productDescription" : "<p style=\"margin-bottom: 25px; text-rendering: optimizeLegibility; color: rgb(34, 35, 35); font-family: Arapey, serif;\">Comfortable and practical, our chambray button down is perfect for travel or days spent on the go. The Ayres Chambray has a rich, washed out indigo color suitable to throw on for any event. Made with sustainable soft chambray featuring two chest pockets with sturdy and scratch resistant corozo buttons.</p><ul class=\"tabs-content\" style=\"margin-right: 0px; margin-bottom: 25px; margin-left: 20px; padding: 0px; text-rendering: optimizeLegibility; color: rgb(34, 35, 35); font-family: Arapey, serif;\"><li style=\"margin-bottom: 0px;\"><span style=\"line-height: 1.4;\">100% Organic Cotton Chambray, 4.9 oz Fabric.</span></li><li style=\"margin-bottom: 0px;\"><span style=\"line-height: 1.4;\">Natural Corozo Buttons.</span></li></ul>",
|
"productDescription" : "<p style=\"margin-bottom: 25px; text-rendering: optimizeLegibility; color: rgb(34, 35, 35); font-family: Arapey, serif;\">Comfortable and practical, our chambray button down is perfect for travel or days spent on the go. The Ayres Chambray has a rich, washed out indigo color suitable to throw on for any event. Made with sustainable soft chambray featuring two chest pockets with sturdy and scratch resistant corozo buttons.</p><ul class=\"tabs-content\" style=\"margin-right: 0px; margin-bottom: 25px; margin-left: 20px; padding: 0px; text-rendering: optimizeLegibility; color: rgb(34, 35, 35); font-family: Arapey, serif;\"><li style=\"margin-bottom: 0px;\"><span style=\"line-height: 1.4;\">100% Organic Cotton Chambray, 4.9 oz Fabric.</span></li><li style=\"margin-bottom: 0px;\"><span style=\"line-height: 1.4;\">Natural Corozo Buttons.</span></li></ul>",
|
||||||
|
@ -92,6 +92,28 @@
|
||||||
"productImage" : "/uploads/Ayres Chambray/chambray_5f232530-4331-492a-872c-81c225d6bafd_590x.jpg"
|
"productImage" : "/uploads/Ayres Chambray/chambray_5f232530-4331-492a-872c-81c225d6bafd_590x.jpg"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
|
"customers": [
|
||||||
|
{
|
||||||
|
"email" : "test@test.com",
|
||||||
|
"firstName" : "Testy",
|
||||||
|
"lastName" : "Cles",
|
||||||
|
"address1" : "1 test street",
|
||||||
|
"address2" : "testvile",
|
||||||
|
"country" : "Netherlands",
|
||||||
|
"state" : "",
|
||||||
|
"postcode" : "2000TW",
|
||||||
|
"phone" : "123456789",
|
||||||
|
"password" : "$2a$10$kKjnX1J/CAdgdmLI0WuPY.ILH1c7N8mD0H/ZyUXEfee1mJxJvZIS."
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"users": [
|
||||||
|
{
|
||||||
|
"usersName" : "test",
|
||||||
|
"userEmail" : "test@test.com",
|
||||||
|
"userPassword" : "$2a$10$7jQx/hQOWrRni531b/dHRuH8o1ZP8Yo8g..GpTOF4M7RrEH/pzTMy",
|
||||||
|
"isAdmin" : "false"
|
||||||
|
}
|
||||||
|
],
|
||||||
"menu": {
|
"menu": {
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
|
|
|
@ -600,25 +600,69 @@ exports.runIndexing = (app) => {
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
exports.testData = (db, app) => {
|
exports.dropTestData = (db) => {
|
||||||
db.products.count({})
|
Promise.all([
|
||||||
|
db.products.drop(),
|
||||||
|
db.users.drop(),
|
||||||
|
db.customers.drop()
|
||||||
|
])
|
||||||
|
.then((err) => {
|
||||||
|
return Promise.resolve();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
console.log('Error dropping test data', err);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.sampleData = (app) => {
|
||||||
|
const db = app.db;
|
||||||
|
|
||||||
|
db.products.count()
|
||||||
.then((products) => {
|
.then((products) => {
|
||||||
if(products > 0){
|
if(products !== 0){
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
}
|
}
|
||||||
|
|
||||||
console.info(colors.cyan('No products, inserting test data'));
|
console.log('Inserting sample data');
|
||||||
|
|
||||||
const testData = fs.readFileSync('./bin/testdata.json', 'utf-8');
|
const testData = fs.readFileSync('./bin/testdata.json', 'utf-8');
|
||||||
const jsonData = JSON.parse(testData);
|
const jsonData = JSON.parse(testData);
|
||||||
|
|
||||||
|
// Add sample data
|
||||||
return Promise.all([
|
return Promise.all([
|
||||||
db.products.insertMany(jsonData.products),
|
db.products.insertMany(jsonData.products),
|
||||||
db.menu.insertOne(jsonData.menu),
|
db.menu.insertOne(jsonData.menu)
|
||||||
exports.runIndexing(app)
|
]);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
exports.testData = async (app) => {
|
||||||
|
const db = app.db;
|
||||||
|
const testData = fs.readFileSync('./bin/testdata.json', 'utf-8');
|
||||||
|
const jsonData = JSON.parse(testData);
|
||||||
|
|
||||||
|
// TODO: A bit ugly, needs fixing
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
Promise.all([
|
||||||
|
db.users.remove({}, {}),
|
||||||
|
db.customers.remove({}, {}),
|
||||||
|
db.products.remove({}, {})
|
||||||
])
|
])
|
||||||
|
.then(() => {
|
||||||
|
Promise.all([
|
||||||
|
db.users.insertMany(jsonData.users),
|
||||||
|
db.customers.insertMany(jsonData.customers),
|
||||||
|
db.products.insertMany(jsonData.products),
|
||||||
|
db.menu.insertOne(jsonData.menu)
|
||||||
|
])
|
||||||
|
.then(() => {
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((err) => {
|
||||||
|
reject(err);
|
||||||
|
});
|
||||||
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.info(colors.red('Error inserting test data. Check `/bin/testdata.json` is correctly formatted.', err));
|
reject(err);
|
||||||
process.exit(2);
|
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
13
package.json
13
package.json
|
@ -5,7 +5,8 @@
|
||||||
"private": false,
|
"private": false,
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node app.js",
|
"start": "node app.js",
|
||||||
"deploy": "gulp deploy"
|
"deploy": "gulp deploy",
|
||||||
|
"test": "ava test/**/*.js --verbose"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"ajv": "^6.0.0",
|
"ajv": "^6.0.0",
|
||||||
|
@ -16,7 +17,7 @@
|
||||||
"body-parser": "^1.17.2",
|
"body-parser": "^1.17.2",
|
||||||
"cheerio": "^0.22.0",
|
"cheerio": "^0.22.0",
|
||||||
"colors": "^1.1.2",
|
"colors": "^1.1.2",
|
||||||
"connect-mongodb-session": "^1.3.0",
|
"connect-mongodb-session": "^1.4.0",
|
||||||
"cookie-parser": "^1.4.3",
|
"cookie-parser": "^1.4.3",
|
||||||
"express": "^4.15.3",
|
"express": "^4.15.3",
|
||||||
"express-handlebars": "^3.0.0",
|
"express-handlebars": "^3.0.0",
|
||||||
|
@ -27,8 +28,7 @@
|
||||||
"lodash": "^4.13.1",
|
"lodash": "^4.13.1",
|
||||||
"lunr": "^2.1.5",
|
"lunr": "^2.1.5",
|
||||||
"moment": "^2.15.2",
|
"moment": "^2.15.2",
|
||||||
"mongodb": "^3.0.1",
|
"mongodb": "2.2.3",
|
||||||
"mongodb-uri": "^0.9.7",
|
|
||||||
"morgan": "^1.9.0",
|
"morgan": "^1.9.0",
|
||||||
"multer": "^1.1.0",
|
"multer": "^1.1.0",
|
||||||
"nodemailer": "^4.4.1",
|
"nodemailer": "^4.4.1",
|
||||||
|
@ -42,6 +42,7 @@
|
||||||
"uglifycss": "0.0.27"
|
"uglifycss": "0.0.27"
|
||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
|
"ava": "^0.25.0",
|
||||||
"eslint": "^3.19.0",
|
"eslint": "^3.19.0",
|
||||||
"eslint-config-airbnb-base": "^12.1.0",
|
"eslint-config-airbnb-base": "^12.1.0",
|
||||||
"eslint-config-standard": "^10.2.1",
|
"eslint-config-standard": "^10.2.1",
|
||||||
|
@ -53,7 +54,9 @@
|
||||||
"gulp-clean-css": "^3.9.2",
|
"gulp-clean-css": "^3.9.2",
|
||||||
"gulp-minify": "^2.1.0",
|
"gulp-minify": "^2.1.0",
|
||||||
"gulp-rename": "^1.2.2",
|
"gulp-rename": "^1.2.2",
|
||||||
"run-sequence": "^2.2.1"
|
"mongodb-uri": "^0.9.7",
|
||||||
|
"run-sequence": "^2.2.1",
|
||||||
|
"wait.for": "^0.6.6"
|
||||||
},
|
},
|
||||||
"main": "app.js",
|
"main": "app.js",
|
||||||
"keywords": [
|
"keywords": [
|
||||||
|
|
|
@ -344,6 +344,27 @@ $(document).ready(function (){
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
$('#loginForm').on('click', function(e){
|
||||||
|
if(!e.isDefaultPrevented()){
|
||||||
|
e.preventDefault();
|
||||||
|
$.ajax({
|
||||||
|
method: 'POST',
|
||||||
|
url: '/admin/login_action',
|
||||||
|
data: {
|
||||||
|
email: $('#email').val(),
|
||||||
|
password: $('#password').val()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.done(function(msg){
|
||||||
|
window.location = '/admin';
|
||||||
|
})
|
||||||
|
.fail(function(msg){
|
||||||
|
showNotification(msg.responseJSON.message, 'danger');
|
||||||
|
});
|
||||||
|
}
|
||||||
|
e.preventDefault();
|
||||||
|
});
|
||||||
|
|
||||||
// call update settings API
|
// call update settings API
|
||||||
$('#customerLogin').on('click', function(e){
|
$('#customerLogin').on('click', function(e){
|
||||||
if(!e.isDefaultPrevented()){
|
if(!e.isDefaultPrevented()){
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -39,7 +39,7 @@ router.get('/admin/login', (req, res) => {
|
||||||
res.render('login', {
|
res.render('login', {
|
||||||
title: 'Login',
|
title: 'Login',
|
||||||
referringUrl: req.header('Referer'),
|
referringUrl: req.header('Referer'),
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
|
@ -59,17 +59,13 @@ router.post('/admin/login_action', (req, res) => {
|
||||||
|
|
||||||
db.users.findOne({userEmail: req.body.email}, (err, user) => {
|
db.users.findOne({userEmail: req.body.email}, (err, user) => {
|
||||||
if(err){
|
if(err){
|
||||||
req.session.message = 'Cannot find user.';
|
res.status(400).json({message: 'A user with that email does not exist.'});
|
||||||
req.session.messageType = 'danger';
|
|
||||||
res.redirect('/admin/login');
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if user exists with that email
|
// check if user exists with that email
|
||||||
if(user === undefined || user === null){
|
if(user === undefined || user === null){
|
||||||
req.session.message = 'A user with that email does not exist.';
|
res.status(400).json({message: 'A user with that email does not exist.'});
|
||||||
req.session.messageType = 'danger';
|
|
||||||
res.redirect('/admin/login');
|
|
||||||
}else{
|
}else{
|
||||||
// we have a user under that email so we compare the password
|
// we have a user under that email so we compare the password
|
||||||
bcrypt.compare(req.body.password, user.userPassword)
|
bcrypt.compare(req.body.password, user.userPassword)
|
||||||
|
@ -79,12 +75,10 @@ router.post('/admin/login_action', (req, res) => {
|
||||||
req.session.usersName = user.usersName;
|
req.session.usersName = user.usersName;
|
||||||
req.session.userId = user._id.toString();
|
req.session.userId = user._id.toString();
|
||||||
req.session.isAdmin = user.isAdmin;
|
req.session.isAdmin = user.isAdmin;
|
||||||
res.redirect('/admin');
|
res.status(200).json({message: 'Login successful'});
|
||||||
}else{
|
}else{
|
||||||
// password is not correct
|
// password is not correct
|
||||||
req.session.message = 'Access denied. Check password and try again.';
|
res.status(400).json({message: 'Access denied. Check password and try again.'});
|
||||||
req.session.messageType = 'danger';
|
|
||||||
res.redirect('/admin/login');
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -106,7 +100,7 @@ router.get('/admin/setup', (req, res) => {
|
||||||
req.session.needsSetup = true;
|
req.session.needsSetup = true;
|
||||||
res.render('setup', {
|
res.render('setup', {
|
||||||
title: 'Setup',
|
title: 'Setup',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
|
@ -165,9 +159,9 @@ router.get('/admin/settings', common.restrict, (req, res) => {
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
footerHtml: typeof common.getConfig().footerHtml !== 'undefined' ? escape.decode(common.getConfig().footerHtml) : null,
|
footerHtml: typeof req.app.config.footerHtml !== 'undefined' ? escape.decode(req.app.config.footerHtml) : null,
|
||||||
googleAnalytics: typeof common.getConfig().googleAnalytics !== 'undefined' ? escape.decode(common.getConfig().googleAnalytics) : null
|
googleAnalytics: typeof req.app.config.googleAnalytics !== 'undefined' ? escape.decode(req.app.config.googleAnalytics) : null
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -218,7 +212,7 @@ router.get('/admin/settings/menu', common.restrict, async (req, res) => {
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
menu: common.sortMenu(await common.getMenu(db))
|
menu: common.sortMenu(await common.getMenu(db))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -239,7 +233,7 @@ router.get('/admin/settings/pages', common.restrict, (req, res) => {
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
menu: common.sortMenu(await common.getMenu(db))
|
menu: common.sortMenu(await common.getMenu(db))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -257,7 +251,7 @@ router.get('/admin/settings/pages/new', common.restrict, common.checkAccess, asy
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
menu: common.sortMenu(await common.getMenu(db))
|
menu: common.sortMenu(await common.getMenu(db))
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -281,14 +275,14 @@ router.get('/admin/settings/pages/edit/:page', common.restrict, common.checkAcce
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
menu
|
menu
|
||||||
});
|
});
|
||||||
}else{
|
}else{
|
||||||
// 404 it!
|
// 404 it!
|
||||||
res.status(404).render('error', {
|
res.status(404).render('error', {
|
||||||
title: '404 Error - Page not found',
|
title: '404 Error - Page not found',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
message: '404 Error - Page not found',
|
message: '404 Error - Page not found',
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
showFooter: 'showFooter',
|
showFooter: 'showFooter',
|
||||||
|
@ -478,7 +472,7 @@ router.post('/admin/file/upload', common.restrict, common.checkAccess, upload.si
|
||||||
|
|
||||||
// delete a file via ajax request
|
// delete a file via ajax request
|
||||||
router.post('/admin/testEmail', common.restrict, (req, res) => {
|
router.post('/admin/testEmail', common.restrict, (req, res) => {
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
// TODO: Should fix this to properly handle result
|
// TODO: Should fix this to properly handle result
|
||||||
common.sendEmail(config.emailAddress, 'expressCart test email', 'Your email settings are working');
|
common.sendEmail(config.emailAddress, 'expressCart test email', 'Your email settings are working');
|
||||||
res.status(200).json({message: 'Test email sent'});
|
res.status(200).json({message: 'Test email sent'});
|
||||||
|
|
|
@ -74,7 +74,7 @@ router.get('/admin/customer/view/:id?', common.restrict, (req, res) => {
|
||||||
session: req.session,
|
session: req.session,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
editor: true,
|
editor: true,
|
||||||
helpers: req.handlebars.helpers
|
helpers: req.handlebars.helpers
|
||||||
});
|
});
|
||||||
|
@ -94,7 +94,7 @@ router.get('/admin/customers', common.restrict, (req, res) => {
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
config: common.getConfig()
|
config: req.app.config
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -119,7 +119,7 @@ router.get('/admin/customers/filter/:search', common.restrict, (req, res, next)
|
||||||
title: 'Customer results',
|
title: 'Customer results',
|
||||||
customers: customers,
|
customers: customers,
|
||||||
admin: true,
|
admin: true,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
searchTerm: searchTerm,
|
searchTerm: searchTerm,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
|
@ -130,7 +130,7 @@ router.get('/admin/customers/filter/:search', common.restrict, (req, res, next)
|
||||||
});
|
});
|
||||||
|
|
||||||
// login the customer and check the password
|
// login the customer and check the password
|
||||||
router.post('/customer/login_action', (req, res) => {
|
router.post('/customer/login_action', async (req, res) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
|
|
||||||
db.customers.findOne({email: req.body.loginEmail}, (err, customer) => { // eslint-disable-line
|
db.customers.findOne({email: req.body.loginEmail}, (err, customer) => { // eslint-disable-line
|
||||||
|
@ -178,7 +178,7 @@ router.get('/customer/forgotten', (req, res) => {
|
||||||
title: 'Forgotten',
|
title: 'Forgotten',
|
||||||
route: 'customer',
|
route: 'customer',
|
||||||
forgotType: 'customer',
|
forgotType: 'customer',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
|
@ -189,7 +189,7 @@ router.get('/customer/forgotten', (req, res) => {
|
||||||
// forgotten password
|
// forgotten password
|
||||||
router.post('/customer/forgotten_action', (req, res) => {
|
router.post('/customer/forgotten_action', (req, res) => {
|
||||||
const db = req.app.db;
|
const db = req.app.db;
|
||||||
const config = common.getConfig();
|
const config = req.app.config;
|
||||||
let passwordToken = randtoken.generate(30);
|
let passwordToken = randtoken.generate(30);
|
||||||
|
|
||||||
// find the user
|
// find the user
|
||||||
|
@ -240,7 +240,7 @@ router.get('/customer/reset/:token', (req, res) => {
|
||||||
title: 'Reset password',
|
title: 'Reset password',
|
||||||
token: req.params.token,
|
token: req.params.token,
|
||||||
route: 'customer',
|
route: 'customer',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
message_type: common.clearSessionValue(req.session, 'message_type'),
|
message_type: common.clearSessionValue(req.session, 'message_type'),
|
||||||
show_footer: 'show_footer',
|
show_footer: 'show_footer',
|
||||||
|
|
166
routes/index.js
166
routes/index.js
|
@ -6,10 +6,9 @@ const _ = require('lodash');
|
||||||
const common = require('../lib/common');
|
const common = require('../lib/common');
|
||||||
|
|
||||||
// These is the customer facing routes
|
// These is the customer facing routes
|
||||||
|
|
||||||
router.get('/payment/:orderId', async (req, res, next) => {
|
router.get('/payment/:orderId', async (req, res, next) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
|
|
||||||
// render the payment complete message
|
// render the payment complete message
|
||||||
db.orders.findOne({_id: common.getId(req.params.orderId)}, async (err, result) => {
|
db.orders.findOne({_id: common.getId(req.params.orderId)}, async (err, result) => {
|
||||||
|
@ -18,7 +17,7 @@ router.get('/payment/:orderId', async (req, res, next) => {
|
||||||
}
|
}
|
||||||
res.render(`${config.themeViews}payment_complete`, {
|
res.render(`${config.themeViews}payment_complete`, {
|
||||||
title: 'Payment complete',
|
title: 'Payment complete',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
pageCloseBtn: common.showCartCloseBtn('payment'),
|
pageCloseBtn: common.showCartCloseBtn('payment'),
|
||||||
result: result,
|
result: result,
|
||||||
|
@ -32,7 +31,7 @@ router.get('/payment/:orderId', async (req, res, next) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/checkout', async (req, res, next) => {
|
router.get('/checkout', async (req, res, next) => {
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
|
|
||||||
// if there is no items in the cart then render a failure
|
// if there is no items in the cart then render a failure
|
||||||
if(!req.session.cart){
|
if(!req.session.cart){
|
||||||
|
@ -45,7 +44,7 @@ router.get('/checkout', async (req, res, next) => {
|
||||||
// render the checkout
|
// render the checkout
|
||||||
res.render(`${config.themeViews}checkout`, {
|
res.render(`${config.themeViews}checkout`, {
|
||||||
title: 'Checkout',
|
title: 'Checkout',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
pageCloseBtn: common.showCartCloseBtn('checkout'),
|
pageCloseBtn: common.showCartCloseBtn('checkout'),
|
||||||
checkout: 'hidden',
|
checkout: 'hidden',
|
||||||
|
@ -58,7 +57,7 @@ router.get('/checkout', async (req, res, next) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/pay', async (req, res, next) => {
|
router.get('/pay', async (req, res, next) => {
|
||||||
const config = common.getConfig();
|
const config = req.app.config;
|
||||||
|
|
||||||
// if there is no items in the cart then render a failure
|
// if there is no items in the cart then render a failure
|
||||||
if(!req.session.cart){
|
if(!req.session.cart){
|
||||||
|
@ -71,7 +70,7 @@ router.get('/pay', async (req, res, next) => {
|
||||||
// render the payment page
|
// render the payment page
|
||||||
res.render(`${config.themeViews}pay`, {
|
res.render(`${config.themeViews}pay`, {
|
||||||
title: 'Pay',
|
title: 'Pay',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
paymentConfig: common.getPaymentConfig(),
|
paymentConfig: common.getPaymentConfig(),
|
||||||
pageCloseBtn: common.showCartCloseBtn('pay'),
|
pageCloseBtn: common.showCartCloseBtn('pay'),
|
||||||
session: req.session,
|
session: req.session,
|
||||||
|
@ -85,14 +84,14 @@ router.get('/pay', async (req, res, next) => {
|
||||||
});
|
});
|
||||||
|
|
||||||
router.get('/cartPartial', (req, res) => {
|
router.get('/cartPartial', (req, res) => {
|
||||||
const config = common.getConfig();
|
const config = req.app.config;
|
||||||
|
|
||||||
res.render(`${config.themeViews}cart`, {
|
res.render(`${config.themeViews}cart`, {
|
||||||
pageCloseBtn: common.showCartCloseBtn(req.query.path),
|
pageCloseBtn: common.showCartCloseBtn(req.query.path),
|
||||||
page: req.query.path,
|
page: req.query.path,
|
||||||
layout: false,
|
layout: false,
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session
|
session: req.session
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -100,7 +99,7 @@ router.get('/cartPartial', (req, res) => {
|
||||||
// show an individual product
|
// show an individual product
|
||||||
router.get('/product/:id', (req, res) => {
|
router.get('/product/:id', (req, res) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
|
|
||||||
db.products.findOne({$or: [{_id: common.getId(req.params.id)}, {productPermalink: req.params.id}]}, (err, result) => {
|
db.products.findOne({$or: [{_id: common.getId(req.params.id)}, {productPermalink: req.params.id}]}, (err, result) => {
|
||||||
// render 404 if page is not published
|
// render 404 if page is not published
|
||||||
|
@ -115,6 +114,12 @@ router.get('/product/:id', (req, res) => {
|
||||||
productOptions = JSON.parse(result.productOptions);
|
productOptions = JSON.parse(result.productOptions);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If JSON query param return json instead
|
||||||
|
if(req.query.json === 'true'){
|
||||||
|
res.status(200).json(result);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// show the view
|
// show the view
|
||||||
common.getImages(result._id, req, res, async (images) => {
|
common.getImages(result._id, req, res, async (images) => {
|
||||||
res.render(`${config.themeViews}product`, {
|
res.render(`${config.themeViews}product`, {
|
||||||
|
@ -223,58 +228,59 @@ router.post('/product/addtocart', (req, res, next) => {
|
||||||
db.products.findOne({_id: common.getId(req.body.productId)}, (err, product) => {
|
db.products.findOne({_id: common.getId(req.body.productId)}, (err, product) => {
|
||||||
if(err){
|
if(err){
|
||||||
console.error(colors.red('Error adding to cart', err));
|
console.error(colors.red('Error adding to cart', err));
|
||||||
|
return res.status(400).json({message: 'Error updating cart. Please try again.'});
|
||||||
}
|
}
|
||||||
|
|
||||||
// We item is found, add it to the cart
|
// No product found
|
||||||
if(product){
|
if(!product){
|
||||||
let productPrice = parseFloat(product.productPrice).toFixed(2);
|
return res.status(400).json({message: 'Error updating cart. Please try again.'});
|
||||||
|
}
|
||||||
|
|
||||||
// Doc used to test if existing in the cart with the options. If not found, we add new.
|
let productPrice = parseFloat(product.productPrice).toFixed(2);
|
||||||
let options = {};
|
|
||||||
if(req.body.productOptions){
|
|
||||||
options = JSON.parse(req.body.productOptions);
|
|
||||||
}
|
|
||||||
let findDoc = {
|
|
||||||
productId: req.body.productId,
|
|
||||||
options: options
|
|
||||||
};
|
|
||||||
|
|
||||||
// if exists we add to the existing value
|
// Doc used to test if existing in the cart with the options. If not found, we add new.
|
||||||
let cartIndex = _.findIndex(req.session.cart, findDoc);
|
let options = {};
|
||||||
if(cartIndex > -1){
|
if(req.body.productOptions){
|
||||||
req.session.cart[cartIndex].quantity = parseInt(req.session.cart[cartIndex].quantity) + productQuantity;
|
options = JSON.parse(req.body.productOptions);
|
||||||
req.session.cart[cartIndex].totalItemPrice = productPrice * parseInt(req.session.cart[cartIndex].quantity);
|
}
|
||||||
}else{
|
let findDoc = {
|
||||||
// Doesnt exist so we add to the cart session
|
productId: req.body.productId,
|
||||||
req.session.cartTotalItems = req.session.cartTotalItems + productQuantity;
|
options: options
|
||||||
|
};
|
||||||
|
|
||||||
// new product deets
|
// if exists we add to the existing value
|
||||||
let productObj = {};
|
let cartIndex = _.findIndex(req.session.cart, findDoc);
|
||||||
productObj.productId = req.body.productId;
|
if(cartIndex > -1){
|
||||||
productObj.title = product.productTitle;
|
req.session.cart[cartIndex].quantity = parseInt(req.session.cart[cartIndex].quantity) + productQuantity;
|
||||||
productObj.quantity = productQuantity;
|
req.session.cart[cartIndex].totalItemPrice = productPrice * parseInt(req.session.cart[cartIndex].quantity);
|
||||||
productObj.totalItemPrice = productPrice * productQuantity;
|
|
||||||
productObj.options = options;
|
|
||||||
productObj.productImage = product.productImage;
|
|
||||||
if(product.productPermalink){
|
|
||||||
productObj.link = product.productPermalink;
|
|
||||||
}else{
|
|
||||||
productObj.link = product._id;
|
|
||||||
}
|
|
||||||
|
|
||||||
// merge into the current cart
|
|
||||||
req.session.cart.push(productObj);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update total cart amount
|
|
||||||
common.updateTotalCartAmount(req, res);
|
|
||||||
|
|
||||||
// update how many products in the shopping cart
|
|
||||||
req.session.cartTotalItems = Object.keys(req.session.cart).length;
|
|
||||||
res.status(200).json({message: 'Cart successfully updated', totalCartItems: Object.keys(req.session.cart).length});
|
|
||||||
}else{
|
}else{
|
||||||
res.status(400).json({message: 'Error updating cart. Please try again.'});
|
// Doesnt exist so we add to the cart session
|
||||||
|
req.session.cartTotalItems = req.session.cartTotalItems + productQuantity;
|
||||||
|
|
||||||
|
// new product deets
|
||||||
|
let productObj = {};
|
||||||
|
productObj.productId = req.body.productId;
|
||||||
|
productObj.title = product.productTitle;
|
||||||
|
productObj.quantity = productQuantity;
|
||||||
|
productObj.totalItemPrice = productPrice * productQuantity;
|
||||||
|
productObj.options = options;
|
||||||
|
productObj.productImage = product.productImage;
|
||||||
|
if(product.productPermalink){
|
||||||
|
productObj.link = product.productPermalink;
|
||||||
|
}else{
|
||||||
|
productObj.link = product._id;
|
||||||
|
}
|
||||||
|
|
||||||
|
// merge into the current cart
|
||||||
|
req.session.cart.push(productObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// update total cart amount
|
||||||
|
common.updateTotalCartAmount(req, res);
|
||||||
|
|
||||||
|
// update how many products in the shopping cart
|
||||||
|
req.session.cartTotalItems = Object.keys(req.session.cart).length;
|
||||||
|
return res.status(200).json({message: 'Cart successfully updated', totalCartItems: Object.keys(req.session.cart).length});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -283,7 +289,7 @@ router.get('/search/:searchTerm/:pageNum?', (req, res) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let searchTerm = req.params.searchTerm;
|
let searchTerm = req.params.searchTerm;
|
||||||
let productsIndex = req.app.productsIndex;
|
let productsIndex = req.app.productsIndex;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
||||||
|
|
||||||
let lunrIdArray = [];
|
let lunrIdArray = [];
|
||||||
|
@ -301,12 +307,18 @@ router.get('/search/:searchTerm/:pageNum?', (req, res) => {
|
||||||
common.getMenu(db)
|
common.getMenu(db)
|
||||||
])
|
])
|
||||||
.then(([results, menu]) => {
|
.then(([results, menu]) => {
|
||||||
|
// If JSON query param return json instead
|
||||||
|
if(req.query.json === 'true'){
|
||||||
|
res.status(200).json(results.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
res.render(`${config.themeViews}index`, {
|
res.render(`${config.themeViews}index`, {
|
||||||
title: 'Results',
|
title: 'Results',
|
||||||
results: results.data,
|
results: results.data,
|
||||||
filtered: true,
|
filtered: true,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
metaDescription: common.getConfig().cartTitle + ' - Search term: ' + searchTerm,
|
metaDescription: req.app.config.cartTitle + ' - Search term: ' + searchTerm,
|
||||||
searchTerm: searchTerm,
|
searchTerm: searchTerm,
|
||||||
pageCloseBtn: common.showCartCloseBtn('search'),
|
pageCloseBtn: common.showCartCloseBtn('search'),
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
|
@ -331,7 +343,7 @@ router.get('/category/:cat/:pageNum?', (req, res) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let searchTerm = req.params.cat;
|
let searchTerm = req.params.cat;
|
||||||
let productsIndex = req.app.productsIndex;
|
let productsIndex = req.app.productsIndex;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
||||||
|
|
||||||
let lunrIdArray = [];
|
let lunrIdArray = [];
|
||||||
|
@ -351,13 +363,19 @@ router.get('/category/:cat/:pageNum?', (req, res) => {
|
||||||
.then(([results, menu]) => {
|
.then(([results, menu]) => {
|
||||||
const sortedMenu = common.sortMenu(menu);
|
const sortedMenu = common.sortMenu(menu);
|
||||||
|
|
||||||
|
// If JSON query param return json instead
|
||||||
|
if(req.query.json === 'true'){
|
||||||
|
res.status(200).json(results.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
res.render(`${config.themeViews}index`, {
|
res.render(`${config.themeViews}index`, {
|
||||||
title: 'Category',
|
title: 'Category',
|
||||||
results: results.data,
|
results: results.data,
|
||||||
filtered: true,
|
filtered: true,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
searchTerm: searchTerm,
|
searchTerm: searchTerm,
|
||||||
metaDescription: common.getConfig().cartTitle + ' - Category: ' + searchTerm,
|
metaDescription: req.app.config.cartTitle + ' - Category: ' + searchTerm,
|
||||||
pageCloseBtn: common.showCartCloseBtn('category'),
|
pageCloseBtn: common.showCartCloseBtn('category'),
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
|
@ -380,7 +398,7 @@ router.get('/category/:cat/:pageNum?', (req, res) => {
|
||||||
// return sitemap
|
// return sitemap
|
||||||
router.get('/sitemap.xml', (req, res, next) => {
|
router.get('/sitemap.xml', (req, res, next) => {
|
||||||
let sm = require('sitemap');
|
let sm = require('sitemap');
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
|
|
||||||
common.addSitemapProducts(req, res, (err, products) => {
|
common.addSitemapProducts(req, res, (err, products) => {
|
||||||
if(err){
|
if(err){
|
||||||
|
@ -412,7 +430,7 @@ router.get('/sitemap.xml', (req, res, next) => {
|
||||||
|
|
||||||
router.get('/page/:pageNum', (req, res, next) => {
|
router.get('/page/:pageNum', (req, res, next) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
||||||
|
|
||||||
Promise.all([
|
Promise.all([
|
||||||
|
@ -420,15 +438,21 @@ router.get('/page/:pageNum', (req, res, next) => {
|
||||||
common.getMenu(db)
|
common.getMenu(db)
|
||||||
])
|
])
|
||||||
.then(([results, menu]) => {
|
.then(([results, menu]) => {
|
||||||
|
// If JSON query param return json instead
|
||||||
|
if(req.query.json === 'true'){
|
||||||
|
res.status(200).json(results.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
res.render(`${config.themeViews}index`, {
|
res.render(`${config.themeViews}index`, {
|
||||||
title: 'Shop',
|
title: 'Shop',
|
||||||
results: results.data,
|
results: results.data,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
metaDescription: common.getConfig().cartTitle + ' - Products page: ' + req.params.pageNum,
|
metaDescription: req.app.config.cartTitle + ' - Products page: ' + req.params.pageNum,
|
||||||
pageCloseBtn: common.showCartCloseBtn('page'),
|
pageCloseBtn: common.showCartCloseBtn('page'),
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
productsPerPage: numberProducts,
|
productsPerPage: numberProducts,
|
||||||
totalProductCount: results.totalProducts,
|
totalProductCount: results.totalProducts,
|
||||||
pageNum: req.params.pageNum,
|
pageNum: req.params.pageNum,
|
||||||
|
@ -446,7 +470,7 @@ router.get('/page/:pageNum', (req, res, next) => {
|
||||||
// The main entry point of the shop
|
// The main entry point of the shop
|
||||||
router.get('/:page?', (req, res, next) => {
|
router.get('/:page?', (req, res, next) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
let numberProducts = config.productsPerPage ? config.productsPerPage : 6;
|
||||||
|
|
||||||
// if no page is specified, just render page 1 of the cart
|
// if no page is specified, just render page 1 of the cart
|
||||||
|
@ -456,6 +480,12 @@ router.get('/:page?', (req, res, next) => {
|
||||||
common.getMenu(db)
|
common.getMenu(db)
|
||||||
])
|
])
|
||||||
.then(([results, menu]) => {
|
.then(([results, menu]) => {
|
||||||
|
// If JSON query param return json instead
|
||||||
|
if(req.query.json === 'true'){
|
||||||
|
res.status(200).json(results.data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
res.render(`${config.themeViews}index`, {
|
res.render(`${config.themeViews}index`, {
|
||||||
title: `${config.cartTitle} - Shop`,
|
title: `${config.cartTitle} - Shop`,
|
||||||
theme: config.theme,
|
theme: config.theme,
|
||||||
|
@ -464,7 +494,7 @@ router.get('/:page?', (req, res, next) => {
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
pageCloseBtn: common.showCartCloseBtn('page'),
|
pageCloseBtn: common.showCartCloseBtn('page'),
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
productsPerPage: numberProducts,
|
productsPerPage: numberProducts,
|
||||||
totalProductCount: results.totalProducts,
|
totalProductCount: results.totalProducts,
|
||||||
pageNum: 1,
|
pageNum: 1,
|
||||||
|
@ -497,8 +527,8 @@ router.get('/:page?', (req, res, next) => {
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
pageCloseBtn: common.showCartCloseBtn('page'),
|
pageCloseBtn: common.showCartCloseBtn('page'),
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
metaDescription: common.getConfig().cartTitle + ' - ' + page,
|
metaDescription: req.app.config.cartTitle + ' - ' + page,
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
showFooter: 'showFooter',
|
showFooter: 'showFooter',
|
||||||
menu: common.sortMenu(await common.getMenu(db))
|
menu: common.sortMenu(await common.getMenu(db))
|
||||||
|
@ -506,7 +536,7 @@ router.get('/:page?', (req, res, next) => {
|
||||||
}else{
|
}else{
|
||||||
res.status(404).render('error', {
|
res.status(404).render('error', {
|
||||||
title: '404 Error - Page not found',
|
title: '404 Error - Page not found',
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
message: '404 Error - Page not found',
|
message: '404 Error - Page not found',
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
showFooter: 'showFooter',
|
showFooter: 'showFooter',
|
||||||
|
|
|
@ -15,7 +15,7 @@ router.get('/admin/orders', common.restrict, (req, res, next) => {
|
||||||
title: 'Cart',
|
title: 'Cart',
|
||||||
orders: orders,
|
orders: orders,
|
||||||
admin: true,
|
admin: true,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
|
@ -45,7 +45,7 @@ router.get('/admin/orders/bystatus/:orderstatus', common.restrict, (req, res, ne
|
||||||
admin: true,
|
admin: true,
|
||||||
filteredOrders: true,
|
filteredOrders: true,
|
||||||
filteredStatus: req.params.orderstatus,
|
filteredStatus: req.params.orderstatus,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
|
@ -69,7 +69,7 @@ router.get('/admin/order/view/:id', common.restrict, (req, res) => {
|
||||||
title: 'View order',
|
title: 'View order',
|
||||||
result: result,
|
result: result,
|
||||||
productOptions: productOptions,
|
productOptions: productOptions,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
|
@ -100,7 +100,7 @@ router.get('/admin/orders/filter/:search', common.restrict, (req, res, next) =>
|
||||||
title: 'Order results',
|
title: 'Order results',
|
||||||
orders: orders,
|
orders: orders,
|
||||||
admin: true,
|
admin: true,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
searchTerm: searchTerm,
|
searchTerm: searchTerm,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
|
|
|
@ -7,7 +7,7 @@ const router = express.Router();
|
||||||
// The homepage of the site
|
// The homepage of the site
|
||||||
router.post('/checkout_action', (req, res, next) => {
|
router.post('/checkout_action', (req, res, next) => {
|
||||||
const db = req.app.db;
|
const db = req.app.db;
|
||||||
const config = common.getConfig();
|
const config = req.app.config;
|
||||||
const authorizenetConfig = common.getPaymentConfig();
|
const authorizenetConfig = common.getPaymentConfig();
|
||||||
|
|
||||||
let authorizeUrl = 'https://api.authorize.net/xml/v1/request.api';
|
let authorizeUrl = 'https://api.authorize.net/xml/v1/request.api';
|
||||||
|
|
|
@ -10,7 +10,7 @@ router.get('/checkout_cancel', (req, res, next) => {
|
||||||
|
|
||||||
router.get('/checkout_return', (req, res, next) => {
|
router.get('/checkout_return', (req, res, next) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let paymentId = req.session.paymentId;
|
let paymentId = req.session.paymentId;
|
||||||
let payerId = req.query['PayerID'];
|
let payerId = req.query['PayerID'];
|
||||||
|
|
||||||
|
@ -107,7 +107,7 @@ router.get('/checkout_return', (req, res, next) => {
|
||||||
// The homepage of the site
|
// The homepage of the site
|
||||||
router.post('/checkout_action', (req, res, next) => {
|
router.post('/checkout_action', (req, res, next) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let paypalConfig = common.getPaymentConfig();
|
let paypalConfig = common.getPaymentConfig();
|
||||||
|
|
||||||
// setup the payment object
|
// setup the payment object
|
||||||
|
|
|
@ -7,7 +7,7 @@ let router = express.Router();
|
||||||
// The homepage of the site
|
// The homepage of the site
|
||||||
router.post('/checkout_action', (req, res, next) => {
|
router.post('/checkout_action', (req, res, next) => {
|
||||||
let db = req.app.db;
|
let db = req.app.db;
|
||||||
let config = common.getConfig();
|
let config = req.app.config;
|
||||||
let stripeConfig = common.getPaymentConfig();
|
let stripeConfig = common.getPaymentConfig();
|
||||||
|
|
||||||
// charge via stripe
|
// charge via stripe
|
||||||
|
|
|
@ -18,7 +18,7 @@ router.get('/admin/products', common.restrict, (req, res, next) => {
|
||||||
top_results: topResults,
|
top_results: topResults,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
admin: true,
|
admin: true,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers
|
helpers: req.handlebars.helpers
|
||||||
|
@ -45,7 +45,7 @@ router.get('/admin/products/filter/:search', (req, res, next) => {
|
||||||
title: 'Results',
|
title: 'Results',
|
||||||
results: results,
|
results: results,
|
||||||
admin: true,
|
admin: true,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
searchTerm: searchTerm,
|
searchTerm: searchTerm,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
|
@ -69,7 +69,7 @@ router.get('/admin/product/new', common.restrict, common.checkAccess, (req, res)
|
||||||
editor: true,
|
editor: true,
|
||||||
admin: true,
|
admin: true,
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig()
|
config: req.app.config
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -167,7 +167,7 @@ router.get('/admin/product/edit/:id', common.restrict, common.checkAccess, (req,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
editor: true,
|
editor: true,
|
||||||
helpers: req.handlebars.helpers
|
helpers: req.handlebars.helpers
|
||||||
});
|
});
|
||||||
|
|
|
@ -15,7 +15,7 @@ router.get('/admin/users', common.restrict, (req, res) => {
|
||||||
title: 'Users',
|
title: 'Users',
|
||||||
users: users,
|
users: users,
|
||||||
admin: true,
|
admin: true,
|
||||||
config: common.getConfig(),
|
config: req.app.config,
|
||||||
isAdmin: req.session.isAdmin,
|
isAdmin: req.session.isAdmin,
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
session: req.session,
|
session: req.session,
|
||||||
|
@ -49,7 +49,7 @@ router.get('/admin/user/edit/:id', common.restrict, (req, res) => {
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
config: common.getConfig()
|
config: req.app.config
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
@ -63,7 +63,7 @@ router.get('/admin/user/new', common.restrict, (req, res) => {
|
||||||
helpers: req.handlebars.helpers,
|
helpers: req.handlebars.helpers,
|
||||||
message: common.clearSessionValue(req.session, 'message'),
|
message: common.clearSessionValue(req.session, 'message'),
|
||||||
messageType: common.clearSessionValue(req.session, 'messageType'),
|
messageType: common.clearSessionValue(req.session, 'messageType'),
|
||||||
config: common.getConfig()
|
config: req.app.config
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,147 @@
|
||||||
|
const test = require('ava');
|
||||||
|
const axios = require('axios');
|
||||||
|
const fs = require('fs');
|
||||||
|
const app = require('../app');
|
||||||
|
const common = require('../lib/common');
|
||||||
|
|
||||||
|
// Get test data to compare in tests
|
||||||
|
const rawTestData = fs.readFileSync('./bin/testdata.json', 'utf-8');
|
||||||
|
const testData = JSON.parse(rawTestData);
|
||||||
|
|
||||||
|
let config;
|
||||||
|
let db;
|
||||||
|
let baseUrl;
|
||||||
|
let products;
|
||||||
|
let customers;
|
||||||
|
let users;
|
||||||
|
|
||||||
|
// Start up app and wait for it to be ready
|
||||||
|
test.before.cb(t => {
|
||||||
|
app.on('appStarted', async () => {
|
||||||
|
// Set some stuff now we have the app started
|
||||||
|
config = app.config;
|
||||||
|
db = app.db;
|
||||||
|
baseUrl = `http://localhost:${app.port}`;
|
||||||
|
await common.testData(app);
|
||||||
|
products = await db.products.find({}).toArray();
|
||||||
|
customers = await db.customers.find({}).toArray();
|
||||||
|
users = await db.users.find({}).toArray();
|
||||||
|
t.end();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Success] Get products JSON', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.get(`${baseUrl}?json=true`)
|
||||||
|
.then((response) => {
|
||||||
|
if(response.data.length < config.productsPerPage){
|
||||||
|
t.is(response.data.length, testData.products.length);
|
||||||
|
}else{
|
||||||
|
t.is(response.data.length, config.productsPerPage);
|
||||||
|
}
|
||||||
|
t.pass();
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Success] User Login', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(`${baseUrl}/admin/login_action`, {
|
||||||
|
email: users[0].userEmail,
|
||||||
|
password: 'test'
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
t.deepEqual(response.data.message, 'Login successful');
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Fail] Incorrect user password', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(`${baseUrl}/admin/login_action`, {
|
||||||
|
email: users[0].userEmail,
|
||||||
|
password: 'test1'
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
t.deepEqual(error.response.data.message, 'Access denied. Check password and try again.');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Fail] Customer login with incorrect email', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(`${baseUrl}/customer/login_action`, {
|
||||||
|
loginEmail: 'test1@test.com',
|
||||||
|
loginPassword: 'test'
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
t.deepEqual(error.response.data.err, 'A customer with that email does not exist.');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Success] Customer login with correct email', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(`${baseUrl}/customer/login_action`, {
|
||||||
|
loginEmail: 'test@test.com',
|
||||||
|
loginPassword: 'test'
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
t.deepEqual(response.data.message, 'Successfully logged in');
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Success] Add product to cart', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(`${baseUrl}/product/addtocart`, {
|
||||||
|
productId: products[0]._id,
|
||||||
|
productQuantity: 1,
|
||||||
|
productOptions: JSON.stringify(products[0].productOptions)
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
t.deepEqual(response.data.message, 'Cart successfully updated');
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('[Fail] Add incorrect product to cart', t => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
axios.post(`${baseUrl}/product/addtocart`, {
|
||||||
|
productId: 'someid'
|
||||||
|
})
|
||||||
|
.then((response) => {
|
||||||
|
t.deepEqual(response.data.message, 'Successfully logged in');
|
||||||
|
reject(new Error('Should not be allowed'));
|
||||||
|
resolve();
|
||||||
|
})
|
||||||
|
.catch((error) => {
|
||||||
|
t.deepEqual(error.response.data.message, 'Error updating cart. Please try again.');
|
||||||
|
resolve();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
|
@ -1,13 +1,13 @@
|
||||||
<div class="col-md-offset-4 col-md-4 col-lg-offset-4 col-lg-4" style="padding-top: 100px" >
|
<div class="col-md-offset-4 col-md-4 col-lg-offset-4 col-lg-4" style="padding-top: 100px" >
|
||||||
<form class="form-signin" action="login_action" method="post" role="form" data-toggle="validator">
|
<form class="form-signin" method="post" role="form" data-toggle="validator">
|
||||||
<input type="hidden" name="frm_referringUrl" value="{{referringUrl}}">
|
<input type="hidden" name="frm_referringUrl" value="{{referringUrl}}">
|
||||||
<h2 class="form-signin-heading">Please sign in</h2>
|
<h2 class="form-signin-heading">Please sign in</h2>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="email" name="email" class="form-control" placeholder="email address" required autofocus>
|
<input type="email" id="email" name="email" class="form-control" placeholder="email address" required autofocus>
|
||||||
</div>
|
</div>
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<input type="password" name="password" class="form-control" placeholder="Password" required>
|
<input type="password" id="password" name="password" class="form-control" placeholder="Password" required>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-lg btn-primary btn-block" type="submit">Sign in</button>
|
<button class="btn btn-lg btn-primary btn-block" id="loginForm" type="submit">Sign in</button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
|
|
Loading…
Reference in New Issue