Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
83 commits
Select commit Hold shift + click to select a range
305b152
Adds names to readme
carjug Sep 15, 2015
795fb52
Added endpoint notes.
ElsaTKO Sep 15, 2015
92a469d
Added node_modules.
ElsaTKO Sep 15, 2015
4c10476
Express.
ElsaTKO Sep 15, 2015
8eab198
Zomg test passed.
ElsaTKO Sep 16, 2015
bf52ec0
Adds db/ directory and utils/ directory. Also adds express to npm pac…
carjug Sep 17, 2015
014a7d3
Pushing
carjug Sep 17, 2015
c92aa3d
Added database and movies table, seeded movies.
ElsaTKO Sep 17, 2015
c079867
Adds customers schema to schema and development.db
carjug Sep 17, 2015
f5f00c6
Adds seed data for customers.json
carjug Sep 17, 2015
24dd9d4
Adds movie_copies table
carjug Sep 17, 2015
24edeee
Added rental table to schema.
ElsaTKO Sep 17, 2015
d67a148
Added copies_available to movies table.
ElsaTKO Sep 17, 2015
5b2c72e
Added all movies endpoint. Yay.
ElsaTKO Sep 17, 2015
11bd7ae
Added movies by title endpoint. Currently returns 'Jaws' correctly bu…
ElsaTKO Sep 17, 2015
3a320b5
Added case insensitive 'like' querying by movie title.
ElsaTKO Sep 18, 2015
181b422
Parameterized movie by title sql query to prevent injection attack, m…
ElsaTKO Sep 18, 2015
5bb61b1
Added npm-debug.log to gitignore.
ElsaTKO Sep 18, 2015
24180cc
Added db commands to package.
ElsaTKO Sep 18, 2015
3f7d7cf
Added dev db to gitignore.
ElsaTKO Sep 18, 2015
a2661f8
Cleaned up console logs calls.
ElsaTKO Sep 18, 2015
2ff3bac
remove db from github tracking
ElsaTKO Sep 18, 2015
01d2fe3
Closing db after requests now.
ElsaTKO Sep 18, 2015
e9cd905
Adds route for movie by release date
carjug Sep 18, 2015
5c72dfb
Adds route for all customers
carjug Sep 18, 2015
7595884
Adds WIP customers by name route and function
carjug Sep 18, 2015
8992353
Adds WIP customers by name function
carjug Sep 18, 2015
09c44d3
Added route and action to return customers by register date. Only wor…
ElsaTKO Sep 18, 2015
da227c8
Added route and action to return customers by postal code. Only works…
ElsaTKO Sep 18, 2015
fe61825
Created movie_copies table and seeded it based on movies table invent…
ElsaTKO Sep 18, 2015
fcac8de
Got sql like to be fuzzy by adding percents to variable string before…
ElsaTKO Sep 18, 2015
2808415
WIP adding all rentals routes
carjug Sep 18, 2015
7e5904a
Adds rental seed data and creates rental endpoint
carjug Sep 18, 2015
913dc1c
add db all to all the things
carjug Sep 18, 2015
703cba6
Returns titles currently rented by a customer's id. Hard coded rental…
ElsaTKO Sep 18, 2015
0be40d8
Removed hard-coded 'Jaws' title and now querying currently checked ou…
ElsaTKO Sep 21, 2015
612b6b8
Added past movie titles by customer id endpoint.
ElsaTKO Sep 21, 2015
5c6c20c
Added 'return_status = 0' filter to current movies by customer id sql…
ElsaTKO Sep 21, 2015
1b0bdfb
Adds WIP route for querying for a customer whose associated with a gi…
carjug Sep 21, 2015
9611527
Merge pull request #1 from carjug/customers-endpoints/edm
Sep 21, 2015
ac6a146
Merge pull request #2 from carjug/caj+movies/master
carjug Sep 21, 2015
072d844
Added current status.
ElsaTKO Sep 21, 2015
3d1252c
Adds current customers for a given movie title with an order by state…
carjug Sep 21, 2015
ef04acf
Adds seed data for renters
carjug Sep 21, 2015
1a3cc8b
Finished current movie title customer ordering.
ElsaTKO Sep 21, 2015
eb41347
Merge branch 'caj+edm/master' of github.com:carjug/C3Projects--VideoS…
ElsaTKO Sep 21, 2015
896eec1
Added past customers by title and order.
ElsaTKO Sep 21, 2015
095b268
Added overdue movie endpoint.
ElsaTKO Sep 21, 2015
788c27b
Adds not-working route for post request to database
carjug Sep 21, 2015
74a11f4
Installed mocha.
ElsaTKO Sep 21, 2015
f9f4322
Added test script.
ElsaTKO Sep 21, 2015
6b94feb
Added movies tests, WIP from jnf.
ElsaTKO Sep 21, 2015
ea318b5
Adapted jnf test code to have 1 passing test. Yay.
ElsaTKO Sep 21, 2015
e14317e
So much work in progress
carjug Sep 21, 2015
36893ad
WIP. The formatted customers json HAD printed almost correctly a few …
ElsaTKO Sep 22, 2015
c58c25d
This scrub didn't fail.
ElsaTKO Sep 22, 2015
0e09325
Cleaned up to prep more WIP.
ElsaTKO Sep 22, 2015
768e5d2
Have fully working date scrubber to convert horrible customer dateti…
ElsaTKO Sep 22, 2015
f62101f
Commented out tests again.
ElsaTKO Sep 22, 2015
b00d703
Adds movie model and adds all function to controller
carjug Sep 22, 2015
c97315e
Adds model functions to movies by title
carjug Sep 22, 2015
6095ab2
fixes whitespace
carjug Sep 22, 2015
8b463ef
Adds WIP tests
carjug Sep 22, 2015
7cfefcf
Added movie find by title endpoint test, and find all customers and f…
ElsaTKO Sep 22, 2015
1889a32
Changed customers controller to use find_by_with_limit and created en…
ElsaTKO Sep 22, 2015
a71d2d1
Finished all customer endpoint tests.
ElsaTKO Sep 22, 2015
18bb933
Adds current renters route for a given movie title
carjug Sep 22, 2015
840dea7
Adds past renters by title for movies tests
carjug Sep 22, 2015
d5ebe94
Adds tests for overdue rentals
carjug Sep 22, 2015
cb8e7e2
WIP create_rental. Can't yet get full list of all available movie cop…
ElsaTKO Sep 23, 2015
0ccef33
WIP before refactor to add is_available flag to movie_copies table.
ElsaTKO Sep 23, 2015
0d4623d
Added is_available to movie_copies. Everything is available despite r…
ElsaTKO Sep 23, 2015
f8a5ee4
Can now return list of all available movie copies. Choosing to only r…
ElsaTKO Sep 23, 2015
a53401f
Can create rental records. Yay. Now actually passing date as string a…
ElsaTKO Sep 23, 2015
6a1dd25
Renamed movie data variable to accurately reflect movie copy.
ElsaTKO Sep 23, 2015
9b4b9df
Changes schema for movies to eliminate copies available. Also adds up…
carjug Sep 23, 2015
6087d0b
Adds error handling (messages not displaying) for no copies available…
carjug Sep 23, 2015
cba29bf
Created return_rental endpoint.
ElsaTKO Sep 23, 2015
8b89763
Adds WIP tests
carjug Sep 23, 2015
00bd16a
Adds WORKING result tests
carjug Sep 23, 2015
f97df89
Adds all rental tests yayyyyyy
carjug Sep 23, 2015
98c0e54
Finished model tests.
ElsaTKO Sep 23, 2015
6607852
Updated progress.
ElsaTKO Sep 23, 2015
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
.DS_Store
/node_modules
npm-debug.log
db/*
38 changes: 34 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,36 @@
# Project: VideoStoreAPI

# Carly and Elsa Project: VideoStoreAPI

## Notes
### Endpoints
*DONE* GET "/customers"
// for routes below, will need to return results offset by page number
*DONE* GET "/customers/:name" // will be dynamic
*DONE* GET "/customers/:registered_at"
*DONE* GET "/customers/:postal_code"

*DONE* GET "/customers/:id/current_movies"
*DONE* GET "/customers/:id/past_movies" // order by checkout date, include return date

*DONE* GET "/movies"
// for routes below, will need to return results offset by page number
*DONE* GET "/movies/:title" // will be dynamic
*DONE* GET "/movies/:release_date"

// for routes below, will need to pass an ordering parameter to order by customer id, name, or checkout date
*DONE* GET "/movies/:title/current_customers/:order"
*DONE* GET "/movies/:title/past_customers/:order"

// normalize database or join everything???
*DONE* GET "/movies/:title"
// includes synopsis, release date, inventory total, rentable boolean, list of customers that have it currently checkout out ...?

*DONE* POST "/rentals/:customer_id/:movie_title"
// create association, checkout date, return date, charge account, returned boolean
*DONE* PATCH "/checkin/:customer_id/:movie_title"
// modify returned boolean
*DONE* GET "/rentals/overdue"

---
The overall goal of this project is to create a system that a video store (remember those?) could use to track their inventory of rental videos and their collection of customers.

We will use [NodeJS](https://nodejs.org/en/) to construct a RESTful API. The goal of this API is to quickly serve information about the store's video collection, customer information, and to update rental status. This repository provides two JSON datafiles to serve as the initial seeds for this system.
Expand All @@ -18,7 +49,7 @@ We will use [NodeJS](https://nodejs.org/en/) to construct a RESTful API. The goa
- `registered_at`: When the customer first visited the store
- The customer's physical address, composed of:
- `address`
- `city`
- `city`
- `state`
- `postal_code`
- `phone`: Primary contact phone number
Expand Down Expand Up @@ -91,4 +122,3 @@ The API you build should have the following capabilities. The schema of your dat
- All endpoints must be tested.
- We will use [Mocha](https://mochajs.org/) for tests.
- There isn't a coverage requirement for this project, beyond demonstrating that every endpoint is covered by some manner of tests.

66 changes: 66 additions & 0 deletions app.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
var express = require('express');
var path = require('path');
var favicon = require('serve-favicon');
var logger = require('morgan');
var cookieParser = require('cookie-parser');
var bodyParser = require('body-parser');

var movies = require('./routes/movies');
var movie_copies = require('./routes/movie_copies');
var customers = require('./routes/customers');
var rentals = require('./routes/rentals');
var zomg = require('./routes/zomg');

var app = express();

// view engine setup
app.set('views', path.join(__dirname, 'views'));
app.set('view engine', 'jade');

// uncomment after placing your favicon in /public
//app.use(favicon(path.join(__dirname, 'public', 'favicon.ico')));
app.use(logger('dev'));
app.use(bodyParser.json());
app.use(bodyParser.urlencoded({ extended: false }));
app.use(cookieParser());
app.use(express.static(path.join(__dirname, 'public')));

app.use('/movies', movies);
app.use('/copies', movie_copies);
app.use('/customers', customers);
app.use('/rentals', rentals);
app.use('/zomg', zomg);

// catch 404 and forward to error handler
app.use(function(req, res, next) {
var err = new Error('Not Found');
err.status = 404;
next(err);
});

// error handlers

// development error handler
// will print stacktrace
if (app.get('env') === 'development') {
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: err
});
});
}

// production error handler
// no stacktraces leaked to user
app.use(function(err, req, res, next) {
res.status(err.status || 500);
res.render('error', {
message: err.message,
error: {}
});
});


module.exports = app;
90 changes: 90 additions & 0 deletions bin/www
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
#!/usr/bin/env node

/**
* Module dependencies.
*/

var app = require('../app');
var debug = require('debug')('C3Projects--VideoStoreAPI:server');
var http = require('http');

/**
* Get port from environment and store in Express.
*/

var port = normalizePort(process.env.PORT || '3000');
app.set('port', port);

/**
* Create HTTP server.
*/

var server = http.createServer(app);

/**
* Listen on provided port, on all network interfaces.
*/

server.listen(port);
server.on('error', onError);
server.on('listening', onListening);

/**
* Normalize a port into a number, string, or false.
*/

function normalizePort(val) {
var port = parseInt(val, 10);

if (isNaN(port)) {
// named pipe
return val;
}

if (port >= 0) {
// port number
return port;
}

return false;
}

/**
* Event listener for HTTP server "error" event.
*/

function onError(error) {
if (error.syscall !== 'listen') {
throw error;
}

var bind = typeof port === 'string'
? 'Pipe ' + port
: 'Port ' + port;

// handle specific listen errors with friendly messages
switch (error.code) {
case 'EACCES':
console.error(bind + ' requires elevated privileges');
process.exit(1);
break;
case 'EADDRINUSE':
console.error(bind + ' is already in use');
process.exit(1);
break;
default:
throw error;
}
}

/**
* Event listener for HTTP server "listening" event.
*/

function onListening() {
var addr = server.address();
var bind = typeof addr === 'string'
? 'pipe ' + addr
: 'port ' + addr.port;
debug('Listening on ' + bind);
}
96 changes: 96 additions & 0 deletions controllers/customers.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
"use strict";

var sqlite3 = require('sqlite3').verbose(),
Customer = require('../models/customer'),
db_env = process.env.DB || 'development',
db;

function addPercents(variable) {
var percented = "%" + variable + "%";
return percented;
}

exports.customersController = {
customers: function(req, res) {
var customer = new Customer();
customer.all(function(error, result) {
return res.status(200).json(result);
});
},

customers_current_movies: function(req, res) {
db = new sqlite3.Database('db/' + db_env + '.db');
var id = req.params.id;
console.log("customer id " + id);
db.all("SELECT movies.title FROM rentals \
INNER JOIN movie_copies ON rentals.movie_copy_id = movie_copies.id \
INNER JOIN movies ON movie_copies.movie_id = movies.id \
WHERE rentals.customer_id = ? AND rentals.return_status = 0", id, function(err, the_movies) {
if (err) {
console.log(err);
}
db.close();
return res.status(200).json(the_movies);
});
},

customers_past_movies: function(req, res) {
db = new sqlite3.Database('db/' + db_env + '.db');
var id = req.params.id;
console.log("customer id " + id);
db.all("SELECT movies.title, rentals.return_date FROM rentals \
INNER JOIN movie_copies ON rentals.movie_copy_id = movie_copies.id \
INNER JOIN movies ON movie_copies.movie_id = movies.id \
WHERE rentals.customer_id = ? AND rentals.return_status = 1 \
ORDER BY rentals.return_date", id, function(err, the_movies) {
if (err) {
console.log(err);
}
db.close();
return res.status(200).json(the_movies);
});
},

customers_by_name: function(req, res) {
var name = req.params.name,
per_page = req.params.per_page,
page = req.params.pg;
page = page * per_page;

name = addPercents(name);

var customer = new Customer();
customer.find_by_with_limit("name", name, per_page, page, function(error, result) {
return res.status(200).json(result);
});
},

customers_by_register_date: function(req, res) {
var date = req.params.date,
per_page = req.params.per_page,
page = req.params.pg;
page = page * per_page;

date = addPercents(date);

var customer = new Customer();
customer.find_by_with_limit("registered_at", date, per_page, page, function(error, result) {
return res.status(200).json(result);
});
},

customers_by_postal_code: function(req, res) {
var zipcode = req.params.zipcode,
per_page = req.params.per_page,
page = req.params.pg;
page = page * per_page;

zipcode = addPercents(zipcode);

var customer = new Customer();
customer.find_by_with_limit("postal_code", zipcode, per_page, page, function(error, result) {
return res.status(200).json(result);
});
},

};
22 changes: 22 additions & 0 deletions controllers/movie_copies.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
"use strict";

var sqlite3 = require('sqlite3').verbose(),
db_env = process.env.DB || 'development',
db;

function addPercents(variable) {
var percented = "%" + variable + "%";
return percented;
}

exports.movie_copiesController = {
copies: function(req, res) {
db = new sqlite3.Database('db/' + db_env + '.db');
db.all("SELECT * FROM movie_copies", function(err, all_copies) {
db.close();
return res.status(200).json(all_copies);
});

}

}; // end exports.moviesController
Loading