Skip to content

Commit

Permalink
half-finished messages feature
Browse files Browse the repository at this point in the history
  • Loading branch information
abarnhard committed Aug 28, 2014
1 parent 11e1249 commit 6cb438d
Show file tree
Hide file tree
Showing 13 changed files with 385 additions and 4 deletions.
10 changes: 10 additions & 0 deletions app/controllers/messages.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
'use strict';

var Message = require('../models/message');

exports.index = function(req, res){
Message.find(res.locals.user._id, req.query, function(err, messages){
res.render('messages/index', {messages:messages, query:req.query});
});
};

55 changes: 55 additions & 0 deletions app/models/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
'use strict';

var User = require('./user'),
async = require('async');

function Message(fromId, toId, body){
this.fromId = fromId;
this.toId = toId;
this.body = body;
this.sent = new Date();
this.isRead = false;
}

Object.defineProperty(Message, 'collection', {
get: function(){return global.mongodb.collection('messages');}
});

Message.find = function(toId, query, cb){
var filter = {toId:toId},
sort = {};
sort.sent = (query.sort) ? query.sort * 1 : 1;
Message.collection.find(filter).sort(sort).toArray(function(err, objs){
// console.log('***objs', objs);
async.map(objs, getSenderInfo, function(err2, fullMessages){
// console.log(fullMessages);
cb(null, fullMessages);
});
});
};

Message.findOne = function(query, cb){
Message.collection.findOne(query, cb);
};

Message.prototype.save = function(cb){
Message.collection.save(this, cb);
};

Message.countUnreadForUser = function(id, cb){
Message.collection.count({toId:id, isRead:false}, cb);
};

module.exports = Message;

// helper functions
function getSenderInfo(message, done){
User.findById(message.fromId, function(err, user){
console.log(user);
message.fromName = user.name;
message.fromEmail = user.email;
// console.log(message);
done(null, message);
});
}

13 changes: 11 additions & 2 deletions app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@

var bcrypt = require('bcrypt'),
_ = require('lodash'),
Mongo = require('mongodb');
Mongo = require('mongodb'),
Message = require('./message');

function User(){
}
Expand Down Expand Up @@ -31,7 +32,10 @@ User.authenticate = function(o, cb){
if(!user){return cb();}
var isOk = bcrypt.compareSync(o.password, user.password);
if(!isOk){return cb();}
cb(user);
Message.countUnreadForUser(user._id, function(err2, count){
user.unreadMessages = count;
cb(user);
});
});
};

Expand Down Expand Up @@ -70,6 +74,7 @@ User.prototype.send = function(receiver, data, cb){
sendEmail(this, receiver.email, data.message, cb);
break;
case 'internal':
sendInternal(this._id, receiver._id, data.message, cb);
}
};

Expand Down Expand Up @@ -100,3 +105,7 @@ function sendEmail(sender, to, body, cb){
mg.messages().send(data, cb);
}

function sendInternal(fromId, toId, body, cb){
var m = new Message(fromId, toId, body);
m.save(cb);
}
2 changes: 2 additions & 0 deletions app/routes/routes.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ var morgan = require('morgan'),
security = require('../lib/security'),
debug = require('../lib/debug'),
home = require('../controllers/home'),
messages = require('../controllers/messages'),
users = require('../controllers/users');

module.exports = function(app, express){
Expand Down Expand Up @@ -36,6 +37,7 @@ module.exports = function(app, express){
app.get('/users', users.index);
app.get('/users/:email', users.showProfile);
app.post('/message/:userId', users.message);
app.get('/messages', messages.index);

console.log('Express: Routes Loaded');
};
Expand Down
22 changes: 22 additions & 0 deletions app/views/messages/index.jade
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
extends ../shared/template
block content
h2 Messages
.panel.panel-default
.panel-body
.row
.col-xs-12
table.table
thead
tr
th From
th Date
th Message
tbody
each message in messages
tr
td: a(href='/users/#{message.fromEmail}')= message.fromName
td= message.sent
td= message.body

block scripts

Empty file added app/views/messages/show.jade
Empty file.
3 changes: 2 additions & 1 deletion app/views/shared/nav.jade
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
.collapse.navbar-collapse#bs-navbar-collapse
ul.nav.navbar-nav.navbar-right
if user
li: a(href='/users') All Users
li: a(href='/messages') Messages
li: a(href='/users') Users
li: a(href='/profile') Profile
li
form.navbar-form(method='post', action='/logout')
Expand Down
25 changes: 25 additions & 0 deletions db/messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
{
"_id":{"$oid":"a00000000000000000000001"},
"sent":{"$date":477295200000},
"body":"Hi Bob, long time no see.\n You want to stop and get a drink sometime after work?",
"toId":{"$oid":"000000000000000000000001"},
"fromId" : {"$oid":"000000000000000000000002"},
"isRead":true
}
{
"_id":{"$oid":"a00000000000000000000002"},
"sent":{"$date":477295200000},
"body":"Hi Bob, following up on drinks after work. Give me a call any time, or message me with this sweet app.",
"toId":{"$oid":"000000000000000000000001"},
"fromId" : {"$oid":"000000000000000000000002"},
"isRead":false
}
{
"_id":{"$oid":"a00000000000000000000003"},
"sent":{"$date":477295200000},
"body":"Hi Sue, greate work on that project.\n If you don't get that promotion they are plain crazy.",
"toId":{"$oid":"000000000000000000000002"},
"fromId" : {"$oid":"000000000000000000000003"},
"isRead":true
}

146 changes: 146 additions & 0 deletions test/acceptance/message.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
/* global describe, before, beforeEach, it */

'use strict';

process.env.DB = 'facebook-test';

var expect = require('chai').expect,
cp = require('child_process'),
app = require('../../app/index'),
cookie = null,
request = require('supertest');

describe('users', function(){
before(function(done){
request(app).get('/').end(done);
});

beforeEach(function(done){
cp.execFile(__dirname + '/../scripts/clean-db.sh', [process.env.DB], {cwd:__dirname + '/../scripts'}, function(err, stdout, stderr){
request(app)
.post('/login')
.send('email=nodeapptest%2Bbob%40gmail.com')
.send('password=1234')
.end(function(err, res){
cookie = res.headers['set-cookie'][0];
done();
});
});
});

describe('get /profile/edit', function(){
it('should show the edit profile page', function(done){
request(app)
.get('/profile/edit')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(200);
expect(res.text).to.include('nodeapptest+bob@gmail.com');
expect(res.text).to.include('Email');
expect(res.text).to.include('Phone');
expect(res.text).to.include('Visible');
done();
});
});
});

describe('put /profile', function(){
it('should edit the profile in database', function(done){
request(app)
.post('/profile')
.send('_method=put&visible=public&email=a%40b.com&phone=555-555-5555&photo=someUrl&tagline=some+tagline&facebook=facebookUrl&twitter=%40twitterhandle')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(302);
expect(res.headers.location).to.equal('/profile');
done();
});
});
});

describe('get /profile', function(){
it('should show the logged in users profile page', function(done){
request(app)
.post('/profile')
.send('_method=put&visible=public&email=a%40b.com&phone=555-555-5555&photo=someUrl&tagline=some+tagline&facebook=facebookUrl&twitter=%40twitterhandle')
.set('cookie', cookie)
.end(function(err, res){
request(app)
.get('/profile')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(200);
expect(res.text).to.include('Phone');
expect(res.text).to.include('Twitter');
expect(res.text).to.include('Facebook');
done();
});
});
});
});

describe('get /users', function(){
it('should show links to public user profiles', function(done){
request(app)
.get('/users')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(200);
expect(res.text).to.not.include('Bob');
expect(res.text).to.include('John');
expect(res.text).to.not.include('Sue');
done();
});
});
});

describe('get /users/email', function(){
it('should return the profile page for a public profile', function(done){
request(app)
.get('/users/nodeapptest+john@gmail.com')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(200);
expect(res.text).to.include('John');
done();
});
});
it('should redirect away from private profile', function(done){
request(app)
.get('/users/nodeapptest+sue@gmail.com')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(302);
expect(res.headers.location).to.equal('/users');
done();
});
});
});

describe('post /message/userId', function(){
it('should send a text message to recipient', function(done){
request(app)
.post('/message/000000000000000000000003')
.send('mtype=text&message=hey')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(302);
expect(res.headers.location).to.equal('/users/nodeapptest+john@gmail.com');
done();
});
});
it('should send an email message to recipient', function(done){
request(app)
.post('/message/000000000000000000000003')
.send('mtype=email&message=hey')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(302);
expect(res.headers.location).to.equal('/users/nodeapptest+john@gmail.com');
done();
});
});
});

});

25 changes: 25 additions & 0 deletions test/acceptance/users.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,31 @@ describe('users', function(){
done();
});
});
it('should send an inmail message to recipient', function(done){
request(app)
.post('/message/000000000000000000000003')
.send('mtype=internal&message=hey')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(302);
expect(res.headers.location).to.equal('/users/nodeapptest+john@gmail.com');
done();
});
});
});

describe('get /messages', function(){
it('should show messages page for logged in user', function(done){
request(app)
.get('/messages')
.set('cookie', cookie)
.end(function(err, res){
expect(res.status).to.equal(200);
expect(res.text).to.include('Sue');
expect(res.text).to.include('Message');
done();
});
});
});

});
Expand Down
2 changes: 1 addition & 1 deletion test/scripts/clean-db.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ if [ -z "$1" ] ; then
exit 1
fi

mongoimport --jsonArray --drop --db $1 --collection examples --file ../../db/example.json
mongoimport --jsonArray --drop --db $1 --collection messages --file ../../db/messages.json
mongoimport --jsonArray --drop --db $1 --collection users --file ../../db/users.json

Loading

0 comments on commit 6cb438d

Please sign in to comment.