-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
18 changed files
with
1,315 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
node_modules | ||
npm-debug.log | ||
.env |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
web: node index.js |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
{ | ||
"dummy_username": "zl48test", | ||
"dummy_password": "quick-phrase-fifth", | ||
"dummy_url": "https://webdev-dummy.herokuapp.com", | ||
"site_username": "zl48test", | ||
"site_password": "quick-phrase-fifth", | ||
"site_url": "http://localhost:3000" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
const express = require('express') | ||
const bodyParser = require('body-parser') | ||
|
||
if (process.env.NODE_ENV !== "production") { | ||
require('dotenv').load() | ||
} | ||
|
||
const hello = (req, res) => res.send({ hello: 'world' }) | ||
|
||
const middlewareCORS = (req, res, next) => { | ||
console.log("[CORS] origin: " + req.headers.origin) | ||
res.header('Access-Control-Allow-Origin', req.headers.origin) | ||
res.header('Access-Control-Allow-Credentials', true) | ||
res.header('Access-Control-Allow-Methods', 'GET,PUT,POST,DELETE') | ||
res.header('Access-Control-Allow-Headers', 'Authorization, Content-Type, X-Requested-With, X-Session-Id') | ||
res.header('Access-Control-Expose-Headers', 'Location, X-Session-Id') | ||
|
||
if(req.method == 'OPTIONS') { | ||
res.status(200).send("OK") | ||
}else{ | ||
next() | ||
} | ||
} | ||
|
||
const middlewareDebug = (req, res, next) => { | ||
console.log("url " + req.url) | ||
console.log("method " + req.method) | ||
console.log("body: " + JSON.stringify(req.body)) | ||
next() | ||
} | ||
|
||
const app = express() | ||
app.use(bodyParser.json()) | ||
app.use(middlewareCORS) | ||
app.use(middlewareDebug) | ||
|
||
|
||
app.get('/',hello) | ||
|
||
console.log(process.env.NODE_ENV) | ||
|
||
require('./src/auth')(app) | ||
require('./src/articles')(app) | ||
require('./src/following')(app) | ||
require('./src/profile')(app) | ||
require('./src/uploadCloudinary.js').setup(app) | ||
|
||
|
||
// Get the port from the environment, i.e., Heroku sets it | ||
const port = process.env.PORT || 3000 | ||
const server = app.listen(port, () => { | ||
const addr = server.address() | ||
console.log(`Server listening at http://${addr.address}:${addr.port}`) | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
|
||
// This script logs into the dummy server and logs into your server | ||
// it pulls data from the dummy server and pushes it into your server | ||
|
||
var fs = require('fs') | ||
var request = require('request').defaults({jar: true}) | ||
|
||
var cred = {} | ||
fs.readFile('./cred.json', function(err, data) { | ||
var d = JSON.parse(data) | ||
Object.keys(d).forEach(function(key) { | ||
cred[key] = d[key] | ||
}) | ||
login() | ||
}) | ||
|
||
function login() { | ||
request({ url: cred.dummy_url + '/login', method: 'POST', | ||
json: { "username": cred.dummy_username, "password": cred.dummy_password } | ||
}, function (err, res, body) { | ||
if (err || body.result !== "success") { | ||
console.error("There was an error logging into the dummy server with credentials: " + cred, err) | ||
process.exit(1) | ||
} | ||
getArticles() | ||
}) | ||
} | ||
|
||
var articlesToPost; | ||
function getArticles(cookie) { | ||
request({ url: cred.dummy_url + '/articles', method: 'GET', json:true }, function(err, res, body) { | ||
if (err) { | ||
console.error("There was an error grabbing articles from the dummy server", err) | ||
process.exit(1) | ||
} | ||
articlesToPost = body.articles | ||
console.log("Read " + articlesToPost.length + " articles from dummy server") | ||
loginToSite() | ||
}) | ||
} | ||
|
||
function loginToSite() { | ||
request({ url: cred.site_url + '/login', method: 'POST', | ||
json: { "username": cred.site_username, "password": cred.site_password } | ||
}, function(err, res, body) { | ||
if (err) { | ||
console.error("There was an error logging into YOUR server with credentials: " + cred, err) | ||
process.exit(1) | ||
} | ||
getArticleCount(sendArticles) | ||
}) | ||
} | ||
|
||
function sendArticles() { | ||
var article = articlesToPost.pop() | ||
if (article) { | ||
request({ url: cred.site_url + '/article', method: 'POST', json: article }, function(err, res, body) { | ||
if (err) { | ||
console.error("There was an error POSTing an article to YOUR server. article=" + article, err) | ||
process.exit(1) | ||
} | ||
sendArticles() | ||
}) | ||
} else { | ||
getArticleCount(function() { | ||
console.log('You now have some data in your database!') | ||
}) | ||
} | ||
} | ||
|
||
function getArticleCount(next) { | ||
request({ url: cred.site_url + '/articles', method: 'GET', json:true }, function(err, res, body) { | ||
if (err) { | ||
console.error("There was an error grabbing articles from YOUR server", err) | ||
process.exit(1) | ||
} | ||
console.log("Read " + body.articles.length + " articles from YOUR server") | ||
if (next) { | ||
next() | ||
} | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
--recursive | ||
--colors | ||
--timeout 10000 | ||
--bail |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
{ | ||
"name": "RiceBookServer", | ||
"private": true, | ||
"version": "0.0.0", | ||
"description": "Demo RiceBookServer", | ||
"license": "MIT", | ||
"repository": "https://github.com/skotep/webdev", | ||
"main": "index.js", | ||
"dependencies": { | ||
"body-parser": "^1.14.1", | ||
"cloudinary": "^1.4.4", | ||
"cookie-parser": "^1.4.3", | ||
"crypto": "0.0.3", | ||
"express": "^4.13.3", | ||
"md5": "^2.2.1", | ||
"mongoose": "^4.6.8", | ||
"morgan": "^1.7.0", | ||
"multer": "^1.2.0", | ||
"passport": "^0.3.2", | ||
"passport-facebook": "^2.1.1", | ||
"redis": "^2.6.3", | ||
"request": "^2.79.0" | ||
}, | ||
"scripts": { | ||
"start": "node index.js", | ||
"watch": "nodemon index.js", | ||
"test": "mocha --opts mocha.opts src/**/*.spec.js", | ||
"test:watch": "npm run test -- -w" | ||
}, | ||
"devDependencies": { | ||
"chai": "^3.5.0", | ||
"dotenv": "^2.0.0", | ||
"isomorphic-fetch": "^2.2.1", | ||
"mocha": "^3.1.2", | ||
"nodemon": "^1.11.0" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
|
||
> [email protected] test /Users/zhou/Desktop/COMP531/hw6/backend | ||
> mocha --opts mocha.opts src/**/*.spec.js "-R" "xunit" | ||
|
||
<testsuite name="Mocha Tests" tests="14" failures="0" errors="0" skipped="0" timestamp="Tue, 08 Nov 2016 09:50:13 GMT" time="0.083"> | ||
<testcase classname="Validate Article functionality" name="should give me three or more articles" time="0.026"/> | ||
<testcase classname="Validate Article functionality" name="should add a new article" time="0.008"/> | ||
<testcase classname="Validate Article functionality" name="should return an article with a specified id" time="0.002"/> | ||
<testcase classname="Validate Article functionality" name="should return ID not found" time="0.005"/> | ||
<testcase classname="Validate Article functionality" name="should return nothing for an invalid id " time="0.004"/> | ||
<testcase classname="Validate Article functionality" name="should update the article" time="0.003"/> | ||
<testcase classname="Validate Auth functionality" name="should register a new user" time="0.004"/> | ||
<testcase classname="Validate Auth functionality" name="should login a previously registered user" time="0.004"/> | ||
<testcase classname="Validate Auth functionality" name="should return Missing username or password!" time="0.003"/> | ||
<testcase classname="Validate Auth functionality" name="should return User doesn't exist!" time="0.003"/> | ||
<testcase classname="Validate Auth functionality" name="should return Incorrect username or password!" time="0.002"/> | ||
<testcase classname="Validate Auth functionality" name="should logout" time="0.003"/> | ||
<testcase classname="Validate following functionality" name="should show following list" time="0.003"/> | ||
<testcase classname="Unit test to validate PUT /headline" name="should updates the headline message," time="0.003"/> | ||
</testsuite> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,180 @@ | ||
var models = require('./model.js') | ||
var Article = models.Article | ||
// var Comment = models.Comment | ||
const md5 = require('md5') | ||
|
||
|
||
const addArticle = (req, res) => { | ||
console.log('[addArticle]Payload received: ', req.body) | ||
newArticle = new Article({ | ||
author: req.username, | ||
text: req.body.text, | ||
date: new Date(), | ||
comments:[] | ||
}) | ||
newArticle.save((err, newArticle) => { | ||
if(err){ | ||
console.log("[addArticle] Error " + err) | ||
res.status(401).send(err) | ||
}else{ | ||
var article = { | ||
author:newArticle.author, | ||
text:newArticle.text, | ||
date:newArticle.date, | ||
comments:newArticle.comments | ||
} | ||
res.status(200).send({articles:[article]}) | ||
} | ||
}) | ||
} | ||
|
||
const getArticles = (req, res) => { | ||
if(req.params.id) { | ||
Article.find({_id:req.params.id}, (err,articles) => { | ||
if(err){ | ||
console.log("[getArticles] " + err) | ||
res.status(400).send(err) | ||
}else{ | ||
res.status(200).send({ | ||
articles:articles | ||
}) | ||
} | ||
}) | ||
}else{ | ||
Article.find({}, (err, articles) => { | ||
if(err){ | ||
console.log("[getArticles] " + err) | ||
res.status(400).send(err) | ||
}else{ | ||
res.status(200).send({ | ||
articles:articles | ||
}) | ||
} | ||
}) | ||
} | ||
} | ||
|
||
const updateArticle = (req, res) => { | ||
if(!req.params.id){ | ||
res.status(400).send("id not found!") | ||
}else{ | ||
if(req.body.commentId){ | ||
// new comment | ||
if(req.body.commentId === -1){ | ||
console.log("[updateArticle] create new comment") | ||
var commentId = md5(req.username + new Date().getTime()) | ||
// const newComment = new Comment({ | ||
// commentId:commentId, | ||
// author: req.username, | ||
// text: req.body.text, | ||
// date: new Date() | ||
// }) | ||
const newComment = { | ||
commentId:commentId, | ||
author: req.username, | ||
text: req.body.text, | ||
date: new Date() | ||
} | ||
|
||
Article.findByIdAndUpdate(req.params.id, | ||
{$addToSet: {comments:newComment}},{new:true},(err, article) => { | ||
if(err){ | ||
console.log("[updateArticle] " + err) | ||
res.status(400).send(err) | ||
}else{ | ||
res.status(200).send({articles:[article]}) | ||
} | ||
}) | ||
}else{ | ||
console.log("[updateArticle] update a comment") | ||
// Comment.findOne({commentId:req.body.commentId}, (err, comment) => { | ||
// if(err){ | ||
// console.log("[updateArticle] " + err) | ||
// res.status(400).send(err) | ||
// }else{ | ||
// if(!comment){ | ||
// res.status(400).send("No comment of this id found!") | ||
// return | ||
// } | ||
// if(comment.author !== req.username){ | ||
// res.status(401).send("You are not the author!") | ||
// return | ||
// }else{ | ||
// Comment.findOneAndUpdate({commentId:req.body.commentId}, | ||
// {$set:{text: req.body.text}},{new:true}, (err,comment) => { | ||
// if(err){ | ||
// console.log("[updateArticle] " + err) | ||
// res.status(400).send(err) | ||
// }else{ | ||
// Article.findById(req.params.id, (err,article) => { | ||
// if(err){ | ||
// console.log("[updateArticle] " + err) | ||
// res.status(400).send(err) | ||
// }else{ | ||
// res.status(200).send({articles:[article]}) | ||
// } | ||
// }) | ||
// } | ||
// }) | ||
// } | ||
// } | ||
// }) | ||
Article.findById(req.params.id,(err, article) => { | ||
if(err){ | ||
console.log("[updateArticle] " + err) | ||
res.status(400).send(err) | ||
}else{ | ||
var newComments = article.comments.map((comment) => { | ||
if(comment.commentId === req.body.commentId){ | ||
return { | ||
commentId:comment.commentId, | ||
author:comment.author, | ||
text:req.body.text, | ||
date:comment.date | ||
} | ||
}else{ | ||
return comment | ||
} | ||
}) | ||
console.log("[updateArticle] newComments: " + newComments) | ||
Article.update({_id:req.params.id},{comments:newComments},(err,count) => { | ||
if(err){ | ||
console.log("[updateArticle] " + err) | ||
res.status(400).send(err) | ||
} | ||
}) | ||
res.status(200).send({articles:[article]}) | ||
} | ||
}) | ||
} | ||
}else{ | ||
Article.findById(req.params.id,(err, article) => { | ||
if(err){ | ||
console.log("[updateArticle] " + err) | ||
res.status(400).send(err) | ||
}else if(article.author !== req.username){ | ||
res.status(401).send("You are not the author!") | ||
return | ||
}else{ | ||
Article.findByIdAndUpdate(req.params.id,{text:req.body.text},{new:true}, | ||
(err,article) => { | ||
if(err){ | ||
console.log("[updateArticle] " + err) | ||
res.status(400).send(err) | ||
}else{ | ||
res.status(200).send({articles:[article]}) | ||
} | ||
}) | ||
} | ||
}) | ||
} | ||
} | ||
} | ||
|
||
const hello = (req, res) => res.send({ hello: 'world' }) | ||
|
||
module.exports = app => { | ||
app.post('/article', addArticle) | ||
app.get('/articles/:id?', getArticles) | ||
app.put('/articles/:id', updateArticle) | ||
} |
Oops, something went wrong.