Skip to content

Commit

Permalink
REST API & tests OK, uses mongoose
Browse files Browse the repository at this point in the history
  • Loading branch information
Vinay Agarwal committed Apr 29, 2012
1 parent bef8d36 commit b4fc20c
Show file tree
Hide file tree
Showing 8 changed files with 174 additions and 78 deletions.
22 changes: 22 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
(The MIT License)

Copyright (c) 2012 Vinay Agarwal <vinkaga@gmail.com>

Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
'Software'), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
9 changes: 5 additions & 4 deletions config.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module.exports = {
'sessionSecret': 'your secret',
'port': 8080,
'uri': 'http://localhost:8080', // Without trailing /
'environment': (process.env.NODE_ENV !== 'production') ? 'development' : 'production'
sessionSecret: 'your secret',
port: 8080,
uri: 'http://localhost:8080', // Without trailing /
dbname: 'my_database',
environment: (process.env.NODE_ENV !== 'production') ? 'development' : 'production'
};

if (module.exports.environment == 'production') {
Expand Down
69 changes: 69 additions & 0 deletions lib/employee.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
var mongoose = require('mongoose');
var ObjectId = mongoose.Schema.ObjectId;

exports.Employee = mongoose.model('Employee', new mongoose.Schema(
{
firstName:String,
lastName:String,
managerId:ObjectId,
title:String,
department:String,
officePhone:String,
cellPhone:String,
email:String,
city:String,
picture:String,
twitterId:String,
blogURL:String
}));

// Seed data
var employees = [
{_id:'000000000000000000000012',firstName:'Steven',lastName:'Wells',managerId:'000000000000000000000004',title:'Software Architect',department:'Engineering',officePhone:'617-000-0012',cellPhone:'781-000-0012',email:'swells@fakemail.com',city:'Boston MA',picture:'steven_wells.jpg',twitterId:'@fakeswells',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000011',firstName:'Amy',lastName:'Jones',managerId:'000000000000000000000005',title:'Sales Representative',department:'Sales',officePhone:'617-000-0011',cellPhone:'781-000-0011',email:'ajones@fakemail.com',city:'Boston MA',picture:'amy_jones.jpg',twitterId:'@fakeajones',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000010',firstName:'Kathleen',lastName:'Byrne',managerId:'000000000000000000000005',title:'Sales Representative',department:'Sales',officePhone:'617-000-0010',cellPhone:'781-000-0010',email:'kbyrne@fakemail.com',city:'Boston MA',picture:'kathleen_byrne.jpg',twitterId:'@fakekbyrne',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000009',firstName:'Gary',lastName:'Donovan',managerId:'000000000000000000000002',title:'Marketing',department:'Marketing',officePhone:'617-000-0009',cellPhone:'781-000-0009',email:'gdonovan@fakemail.com',city:'Boston MA',picture:'gary_donovan.jpg',twitterId:'@fakegdonovan',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000008',firstName:'Lisa',lastName:'Wong',managerId:'000000000000000000000002',title:'Marketing Manager',department:'Marketing',officePhone:'617-000-0008',cellPhone:'781-000-0008',email:'lwong@fakemail.com',city:'Boston MA',picture:'lisa_wong.jpg',twitterId:'@fakelwong',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000007',firstName:'Paula',lastName:'Gates',managerId:'000000000000000000000004',title:'Software Architect',department:'Engineering',officePhone:'617-000-0007',cellPhone:'781-000-0007',email:'pgates@fakemail.com',city:'Boston MA',picture:'paula_gates.jpg',twitterId:'@fakepgates',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000005',firstName:'Ray',lastName:'Moore',managerId:'000000000000000000000001',title:'VP of Sales',department:'Sales',officePhone:'617-000-0005',cellPhone:'781-000-0005',email:'rmoore@fakemail.com',city:'Boston MA',picture:'ray_moore.jpg',twitterId:'@fakermoore',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000006',firstName:'Paul',lastName:'Jones',managerId:'000000000000000000000004',title:'QA Manager',department:'Engineering',officePhone:'617-000-0006',cellPhone:'781-000-0006',email:'pjones@fakemail.com',city:'Boston MA',picture:'paul_jones.jpg',twitterId:'@fakepjones',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000003',firstName:'Eugene',lastName:'Lee',managerId:'000000000000000000000001',title:'CFO',department:'Accounting',officePhone:'617-000-0003',cellPhone:'781-000-0003',email:'elee@fakemail.com',city:'Boston MA',picture:'eugene_lee.jpg',twitterId:'@fakeelee',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000004',firstName:'John',lastName:'Williams',managerId:'000000000000000000000001',title:'VP of Engineering',department:'Engineering',officePhone:'617-000-0004',cellPhone:'781-000-0004',email:'jwilliams@fakemail.com',city:'Boston MA',picture:'john_williams.jpg',twitterId:'@fakejwilliams',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000002',firstName:'Julie',lastName:'Taylor',managerId:'000000000000000000000001',title:'VP of Marketing',department:'Marketing',officePhone:'617-000-0002',cellPhone:'781-000-0002',email:'jtaylor@fakemail.com',city:'Boston MA',picture:'julie_taylor.jpg',twitterId:'@fakejtaylor',blogURL:'http://coenraets.org'},
{_id:'000000000000000000000001',firstName:'James',lastName:'King',managerId:'000000000000000000000000',title:'President and CEO',department:'Corporate',officePhone:'617-000-0001',cellPhone:'781-000-0001',email:'jking@fakemail.com',city:'Boston MA',picture:'james_king.jpg',twitterId:'@fakejking',blogURL:'http://coenraets.org'}];

exports.seed = function() {
mongoose.connection.db.executeDbCommand({dropDatabase:1});
for (var i = 0; i < employees.length; i++) {
var employee = new exports.Employee(employees[i]);
employee.save();
}
}

exports.getEmployees = function(req, res) {
exports.Employee.find({}, ['lastName', 'firstName'], function(err, objs){
res.json(objs);
});
};

exports.getEmployee = function(req, res) {
var id = req.params.id;
exports.Employee.findById(id, function(err, obj){
res.json(obj);
});
};

exports.getReports = function(req, res) {
var id = req.params.id;
exports.Employee.find({ managerId:id}, ['lastName', 'firstName'], function(err, objs){
res.json(objs);
});
};

exports.findByName = function(req, res) {
var query = req.params.query;
var re = new RegExp(query, 'i');
exports.Employee.find({ $or: [ {lastName:re}, {firstName:re} ]}, function(err, obj){
res.json(obj);
});
}
5 changes: 3 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"version":"0.0.1",
"dependencies":{
"connect":">=2.1.2",
"express":"2",
"express":"2.x.x",
"connect-redis" : ">=1.3.0",
"jade":">=0.24.0",
"mongoose":">=2.5.14",
Expand All @@ -14,7 +14,8 @@
"devDependencies":{
"vows":">=0.6.2",
"mocha":">=1.0.1",
"should":">=0.6.1"
"should":">=0.6.1",
"request":">=2.9.x"
},
"engine":"node >= 0.6.12"
}
62 changes: 0 additions & 62 deletions seeddata.js

This file was deleted.

20 changes: 17 additions & 3 deletions server.js
Original file line number Diff line number Diff line change
@@ -1,21 +1,30 @@
//setup Dependencies
var rootdir = __dirname;
var express = require('express');
var sio = require('socket.io');
var RedisStore = require('connect-redis')(express);
var sessionStore = new RedisStore();
var mongoose = require('mongoose');
var config = require('./config.js');
var useragent = require('./lib/useragent.js');
var employee = require('./lib/employee.js');

// Connect to data
mongoose.connect('mongodb://localhost/' + config.dbname);

// Init seed data - this may not be needed in your application
employee.seed();

//Setup Express
var server = express.createServer();
server.configure(function() {
server.set('environment', config.environment);
server.set('views', __dirname + '/views');
server.set('views', rootdir + '/views');
server.set('view options', { layout:false });
server.use(express.bodyParser());
server.use(express.cookieParser());
server.use(express.session({ 'store':sessionStore, secret:config.sessionSecret }));
server.use(express.static(__dirname + '/static'));
server.use(express.static(rootdir + '/static'));
server.use(server.router);
});

Expand Down Expand Up @@ -59,7 +68,7 @@ io.sockets.on('connection', function(socket) {
///////////////////////////////////////////

/////// ADD ALL YOUR ROUTES HERE /////////

// Index route - depends upon the useragent
server.get('/', function(req, res) {
useragent(req, res);
console.log(req.agent);
Expand All @@ -72,6 +81,11 @@ server.get('/', function(req, res) {
});
});

// API routes return JSON
server.get('/employees', employee.getEmployees);
server.get('/employees/:id', employee.getEmployee);
server.get('/employees/:id/reports', employee.getReports);
server.get('/employees/search/:query', employee.findByName);

//A Route for Creating a 500 Error (Useful to keep around)
server.get('/500', function(req, res) {
Expand Down
58 changes: 58 additions & 0 deletions test/apiTest.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
var request = require('request');
var should = require('should');
var config = require('../config.js');

describe('API', function(){

describe('Employees', function(){

it('should get all employees', function(done) {
request(config.uri + '/employees', function (err, res, body) {
should.not.exist(err);
var objs = JSON.parse(body);
should.exist(objs);
objs.should.have.lengthOf(12);
done();
});
});

it('should get an employee', function(done) {
request(config.uri + '/employees/000000000000000000000002', function (err, res, body) {
should.not.exist(err);
var obj = JSON.parse(body);
should.exist(obj);
obj.firstName.should.equal('Julie');
obj.lastName.should.equal('Taylor');
done();
});
});

it('should get direct reports', function(done) {
request(config.uri + '/employees/000000000000000000000002/reports', function (err, res, body) {
should.not.exist(err);
var objs = JSON.parse(body);
should.exist(objs);
objs.should.have.lengthOf(2);
objs[0].firstName.should.equal('Gary');
objs[0].lastName.should.equal('Donovan');
objs[1].firstName.should.equal('Lisa');
objs[1].lastName.should.equal('Wong');
done();
});
});

it('should search', function(done) {
request(config.uri + '/employees/search/jo', function (err, res, body) {
should.not.exist(err);
var objs = JSON.parse(body);
should.exist(objs);
objs.should.have.lengthOf(3);
objs[0].lastName.should.equal('Jones');
objs[1].lastName.should.equal('Jones');
objs[2].firstName.should.equal('John');
done();
});
});
});

});
7 changes: 0 additions & 7 deletions test/stub.js

This file was deleted.

0 comments on commit b4fc20c

Please sign in to comment.