From b1d8b08c192fc762d9f1191e0c7de8347fa592d9 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 15 Sep 2015 16:00:46 -0700 Subject: [PATCH 001/189] created new Node/Express app --- app.js | 60 ++++++++++++++++++++++++ bin/www | 90 ++++++++++++++++++++++++++++++++++++ package.json | 17 +++++++ public/stylesheets/style.css | 8 ++++ routes/index.js | 9 ++++ routes/users.js | 9 ++++ views/error.jade | 6 +++ views/index.jade | 5 ++ views/layout.jade | 7 +++ 9 files changed, 211 insertions(+) create mode 100644 app.js create mode 100755 bin/www create mode 100644 package.json create mode 100644 public/stylesheets/style.css create mode 100644 routes/index.js create mode 100644 routes/users.js create mode 100644 views/error.jade create mode 100644 views/index.jade create mode 100644 views/layout.jade diff --git a/app.js b/app.js new file mode 100644 index 0000000..80a3c36 --- /dev/null +++ b/app.js @@ -0,0 +1,60 @@ +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 routes = require('./routes/index'); +var users = require('./routes/users'); + +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('/', routes); +app.use('/users', users); + +// 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; diff --git a/bin/www b/bin/www new file mode 100755 index 0000000..cc43085 --- /dev/null +++ b/bin/www @@ -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); +} diff --git a/package.json b/package.json new file mode 100644 index 0000000..0ab806b --- /dev/null +++ b/package.json @@ -0,0 +1,17 @@ +{ + "name": "C3Projects--VideoStoreAPI", + "version": "0.0.0", + "private": true, + "scripts": { + "start": "node ./bin/www" + }, + "dependencies": { + "body-parser": "~1.13.2", + "cookie-parser": "~1.3.5", + "debug": "~2.2.0", + "express": "~4.13.1", + "jade": "~1.11.0", + "morgan": "~1.6.1", + "serve-favicon": "~2.3.0" + } +} \ No newline at end of file diff --git a/public/stylesheets/style.css b/public/stylesheets/style.css new file mode 100644 index 0000000..9453385 --- /dev/null +++ b/public/stylesheets/style.css @@ -0,0 +1,8 @@ +body { + padding: 50px; + font: 14px "Lucida Grande", Helvetica, Arial, sans-serif; +} + +a { + color: #00B7FF; +} diff --git a/routes/index.js b/routes/index.js new file mode 100644 index 0000000..ecca96a --- /dev/null +++ b/routes/index.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET home page. */ +router.get('/', function(req, res, next) { + res.render('index', { title: 'Express' }); +}); + +module.exports = router; diff --git a/routes/users.js b/routes/users.js new file mode 100644 index 0000000..623e430 --- /dev/null +++ b/routes/users.js @@ -0,0 +1,9 @@ +var express = require('express'); +var router = express.Router(); + +/* GET users listing. */ +router.get('/', function(req, res, next) { + res.send('respond with a resource'); +}); + +module.exports = router; diff --git a/views/error.jade b/views/error.jade new file mode 100644 index 0000000..51ec12c --- /dev/null +++ b/views/error.jade @@ -0,0 +1,6 @@ +extends layout + +block content + h1= message + h2= error.status + pre #{error.stack} diff --git a/views/index.jade b/views/index.jade new file mode 100644 index 0000000..3d63b9a --- /dev/null +++ b/views/index.jade @@ -0,0 +1,5 @@ +extends layout + +block content + h1= title + p Welcome to #{title} diff --git a/views/layout.jade b/views/layout.jade new file mode 100644 index 0000000..15af079 --- /dev/null +++ b/views/layout.jade @@ -0,0 +1,7 @@ +doctype html +html + head + title= title + link(rel='stylesheet', href='/stylesheets/style.css') + body + block content From 18bbe6c17c1165e06af8cb9b526e68d30f8443dd Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 15 Sep 2015 16:10:54 -0700 Subject: [PATCH 002/189] added node_modules to gitignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index e43b0f9..83c46df 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,4 @@ .DS_Store + +# Let package.json handle dependencies +/node_modules From 27ef18e788c718f2361cf1e180ec8985d7a68deb Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 15 Sep 2015 16:28:51 -0700 Subject: [PATCH 003/189] pseudo-coded Customer routes --- pseudoRoutes.md | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 pseudoRoutes.md diff --git a/pseudoRoutes.md b/pseudoRoutes.md new file mode 100644 index 0000000..aca73e2 --- /dev/null +++ b/pseudoRoutes.md @@ -0,0 +1,19 @@ +Customers + +GET '/customers' +- returns list of all customers +- no data provided + + +GET '/customers?sort_by=:column&number=:number&offset=:offset' +- how to tell route to stop at the & ?? +- columns are: name, registered_at, postal_code +- number is # of customer records to be returned +- offset is how far into the total records you want to start grabbing records + - can be used for pagination +- need to provide column name, number, and offset + +GET '/customers/:id' +- returns customer object, which has two objects: current and past +- need to provide: customer id + From af553c810d58b4ab79ec707de634be18da3e3d0d Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 15 Sep 2015 16:44:03 -0700 Subject: [PATCH 004/189] pseudo-coded start of Movie routes --- pseudoRoutes.md | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/pseudoRoutes.md b/pseudoRoutes.md index aca73e2..86a40af 100644 --- a/pseudoRoutes.md +++ b/pseudoRoutes.md @@ -1,11 +1,14 @@ -Customers +##Customers GET '/customers' -- returns list of all customers +- returns an object of all customer objects - no data provided -GET '/customers?sort_by=:column&number=:number&offset=:offset' +GET '/customers/:sort_by/:number/:offset' +(GET '/customers?sort_by=:column&number=:number&offset=:offset') + +- returns select collection of customer objects - how to tell route to stop at the & ?? - columns are: name, registered_at, postal_code - number is # of customer records to be returned @@ -14,6 +17,16 @@ GET '/customers?sort_by=:column&number=:number&offset=:offset' - need to provide column name, number, and offset GET '/customers/:id' -- returns customer object, which has two objects: current and past +- returns an object for that customer, which has two objects: current and past + - each of current and past contain a collection of movie objects + - see resources card on Trello for image of architecture - need to provide: customer id +## Movies + +GET '/movies' +- returns an object of all movie objects + +GET '/movies/:sort_by/:number/:offset' +- returns select collection of movie objects +- columns are: title, release_date From 400fc5b1fcf653c0415518b679329578711310b7 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 16 Sep 2015 09:03:50 -0700 Subject: [PATCH 005/189] removed space for formatting --- pseudoRoutes.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pseudoRoutes.md b/pseudoRoutes.md index 86a40af..eabc10b 100644 --- a/pseudoRoutes.md +++ b/pseudoRoutes.md @@ -22,7 +22,7 @@ GET '/customers/:id' - see resources card on Trello for image of architecture - need to provide: customer id -## Movies +##Movies GET '/movies' - returns an object of all movie objects From 5e0edc0d66edd26a8187e78b76418e857e06d19d Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 17 Sep 2015 13:52:00 -0700 Subject: [PATCH 006/189] schema set up with updates to endpoints for movies and rentals --- pseudoRoutes.md | 68 ++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 61 insertions(+), 7 deletions(-) diff --git a/pseudoRoutes.md b/pseudoRoutes.md index eabc10b..bd66899 100644 --- a/pseudoRoutes.md +++ b/pseudoRoutes.md @@ -1,11 +1,12 @@ -##Customers +Customers +--------- -GET '/customers' +### GET '/customers' - returns an object of all customer objects - no data provided -GET '/customers/:sort_by/:number/:offset' +### GET '/customers/:sort_by/:number/:offset' (GET '/customers?sort_by=:column&number=:number&offset=:offset') - returns select collection of customer objects @@ -16,17 +17,70 @@ GET '/customers/:sort_by/:number/:offset' - can be used for pagination - need to provide column name, number, and offset -GET '/customers/:id' +### GET '/customers/:id' - returns an object for that customer, which has two objects: current and past - each of current and past contain a collection of movie objects - see resources card on Trello for image of architecture - need to provide: customer id -##Movies -GET '/movies' +Movies +------ +### GET '/movies' - returns an object of all movie objects -GET '/movies/:sort_by/:number/:offset' +### GET '/movies/:sort_by/:number/:offset' - returns select collection of movie objects - columns are: title, release_date + +### GET '/movies/:title/:order' +- customer id: /movies/jaws&id=4 +- customer name: /movies/jaws&name=alice +- checkout date: /movies/jaws&date=20150922 (YYYYMMDD) +- returns an object for that movie, has two objects inside: current and past + - current contains a list of customers that have checked out the film + - past contains customers that have previously checked out the film + - :order - allows sorting by: customer id, customer name, or checkout date + +Rental +------ + +### GET '/rental/:title' +- returns a movie object based on title with synopsis, release date, and inventory + - info on availability: boolean + - object with list of customers that currently have that movie checked out + +### POST '/rental' (checkout) +- creates a record of rental movie object + +### PUT '/rental' (checkin) +- updates rental record, returned: to true + +```javascript +var movies = [ + ['title', 'text'], + ['overview', 'text'], + ['release_date', 'text'], + ['inventory', 'integer'] +] + +var customers = [ + ['name', 'text'], + ['registered_at', 'text'], + ['address', 'text'], + ['city', 'text'], + ['state', 'text'], + ['postal_code', 'text'], + ['phone', 'text'], + ['account_credit', 'integer'] // multiplied by 100 to be stored as cents +] + +var rentals = [ + ['customer_id', 'integer'], + ['movie_id', 'integer'], + ['checkout_date', 'text'], + ['return_date', 'text'], + ['returned', 'text'] // boolean +] +``` + From 0f9ffc17958f1672cf14c226997a11921dd9067c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 13:58:10 -0700 Subject: [PATCH 007/189] added sqlite3 and mocha --- package.json | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 0ab806b..286d1a9 100644 --- a/package.json +++ b/package.json @@ -11,7 +11,9 @@ "debug": "~2.2.0", "express": "~4.13.1", "jade": "~1.11.0", + "mocha": "^2.3.2", "morgan": "~1.6.1", - "serve-favicon": "~2.3.0" + "serve-favicon": "~2.3.0", + "sqlite3": "^3.1.0" } -} \ No newline at end of file +} From fea2c1427c510b78de8b2e4174c5de361b94893a Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 14:08:03 -0700 Subject: [PATCH 008/189] created schema --- utils/schema.js | 55 +++++++++++++++++++++++++++++++++++++++++++++++++ utils/seed.js | 0 2 files changed, 55 insertions(+) create mode 100644 utils/schema.js create mode 100644 utils/seed.js diff --git a/utils/schema.js b/utils/schema.js new file mode 100644 index 0000000..7a021fc --- /dev/null +++ b/utils/schema.js @@ -0,0 +1,55 @@ +"use strict"; + +var sqlite3 = require('sqlite3').verbose(), + db_env = process.env.DB || 'development', + db = new sqlite3.Database('db/' + db_env + '.db'); + +var movie_fields = [ + ['title', 'text'], + ['overview', 'text'], + ['release_date', 'text'], + ['inventory', 'integer'] +]; + +var customer_fields = [ + ['name', 'text'], + ['registered_at', 'text'], + ['address', 'text'], + ['city', 'text'], + ['state', 'text'], + ['postal_code', 'text'], + ['phone', 'text'], + ['account_credit', 'integer'] // multiplied by 100 to be stored as cents +]; + +var rental_fields = [ + ['customer_id', 'integer'], + ['movie_id', 'integer'], + ['checkout_date', 'text'], + ['return_date', 'text'], + ['returned', 'text'] // boolean +]; + +function reset(table_name, table_fields) { + db.serialize(function() { + db.run("DROP TABLE IF EXISTS " + table_name + ";"); + + // create fresh versions of those tables + db.run("CREATE TABLE " + table_name + " (id INTEGER PRIMARY KEY);"); + + // add columns that I need to those tables + for (var i = 0; i < table_fields.length; i++) { + var name = table_fields[i][0], + type = table_fields[i][1]; + + // ALTER TABLE movies ADD COLUMN title text; + db.run("ALTER TABLE " + table_name + " ADD COLUMN " + name + " " + type + ";"); + }; + }); +} + +reset("movies", movie_fields); +reset("customers", customer_fields); +reset("rentals", rental_fields); + +db.close(); diff --git a/utils/seed.js b/utils/seed.js new file mode 100644 index 0000000..e69de29 From ad03cecdd3c8def6a57e0662e8d3afdaf2f77852 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 14:09:25 -0700 Subject: [PATCH 009/189] created dev db with schema --- db/development.db | Bin 0 -> 4096 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 db/development.db diff --git a/db/development.db b/db/development.db new file mode 100644 index 0000000000000000000000000000000000000000..c2c1416344796ccdcce9465512d26332b6ab859f GIT binary patch literal 4096 zcmeH`K~KUk6vw*_f@{ok*BFV8~`48I8(5x|$IhAazRVT=%J=vmXV7{B*c@#CMhfi6Bz zPW1uDK0?mIUhBn-su4)foO-j}wpJY=uOX8x1`?`#soi*Pf8^p(|9a@++=j(eCU3Pi-DuMhAT*o4U*j>Md^l7~(ieHRJ%0nyJ7*a!4&;HbTKSpGB9q!0PD$$4y2QzKGlIa6hyk|u~l!jT2?yAO3C=B&DSm!vGMJ%062t2 zE-`0Pb6(^kB?}o*>?cni&-L93x!el*?#)t{SM6;YJ%)fGa4-U<{||=N1U3XJPr&ql N<*&#HGz1Pt;0uxOwrT(X literal 0 HcmV?d00001 From 16439d94c2718641ff32710baa7e3f7fc8d43133 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 14:17:26 -0700 Subject: [PATCH 010/189] moved seed data files to utils dir --- utils/customers.json | 2202 ++++++++++++++++++++++++++++++++++++++++++ utils/movies.json | 602 ++++++++++++ 2 files changed, 2804 insertions(+) create mode 100644 utils/customers.json create mode 100644 utils/movies.json diff --git a/utils/customers.json b/utils/customers.json new file mode 100644 index 0000000..a615fdd --- /dev/null +++ b/utils/customers.json @@ -0,0 +1,2202 @@ +[ + { + "id": "1", + "name": "Shelley Rocha", + "registered_at": "Wed, 29 Apr 2015 07:54:14 -0700", + "address": "Ap #292-5216 Ipsum Rd.", + "city": "Hillsboro", + "state": "OR", + "postal_code": "24309", + "phone": "(322) 510-8695", + "account_credit": 13.15 + }, + { + "id": "2", + "name": "Curran Stout", + "registered_at": "Wed, 16 Apr 2014 21:40:20 -0700", + "address": "Ap #658-1540 Erat Rd.", + "city": "San Francisco", + "state": "California", + "postal_code": "94267", + "phone": "(908) 949-6758", + "account_credit": 35.66 + }, + { + "id": "3", + "name": "Roanna Robinson", + "registered_at": "Fri, 28 Nov 2014 13:14:08 -0800", + "address": "Ap #561-4214 Eget St.", + "city": "Harrisburg", + "state": "PA", + "postal_code": "15867", + "phone": "(323) 336-1841", + "account_credit": 50.39 + }, + { + "id": "4", + "name": "Carolyn Chandler", + "registered_at": "Fri, 04 Jul 2014 11:05:11 -0700", + "address": "133-8707 Arcu. Avenue", + "city": "Fort Wayne", + "state": "IN", + "postal_code": "73684", + "phone": "(234) 837-2886", + "account_credit": 21.79 + }, + { + "id": "5", + "name": "Aquila Riddle", + "registered_at": "Thu, 27 Aug 2015 08:17:24 -0700", + "address": "Ap #187-9582 Primis St.", + "city": "Tacoma", + "state": "WA", + "postal_code": "73251", + "phone": "(925) 161-2223", + "account_credit": 17.82 + }, + { + "id": "6", + "name": "Phyllis Russell", + "registered_at": "Wed, 02 Apr 2014 21:44:46 -0700", + "address": "746-8511 Ipsum Ave", + "city": "Boise", + "state": "Idaho", + "postal_code": "76759", + "phone": "(961) 964-5158", + "account_credit": 88.67 + }, + { + "id": "7", + "name": "Rajah Riggs", + "registered_at": "Tue, 28 Jan 2014 22:28:45 -0800", + "address": "Ap #881-3920 Malesuada Avenue", + "city": "Norman", + "state": "OK", + "postal_code": "36134", + "phone": "(540) 515-2339", + "account_credit": 30.14 + }, + { + "id": "8", + "name": "Amanda Curtis", + "registered_at": "Tue, 18 Nov 2014 00:43:15 -0800", + "address": "Ap #773-125 Nunc St.", + "city": "Iowa City", + "state": "Iowa", + "postal_code": "18538", + "phone": "(253) 271-5290", + "account_credit": 47.22 + }, + { + "id": "9", + "name": "Jacqueline Perry", + "registered_at": "Thu, 23 Jul 2015 10:18:35 -0700", + "address": "Ap #288-7228 Dis Rd.", + "city": "Anchorage", + "state": "AK", + "postal_code": "99789", + "phone": "(479) 207-8414", + "account_credit": 96.28 + }, + { + "id": "10", + "name": "Quinlan Rich", + "registered_at": "Fri, 10 Jul 2015 15:23:06 -0700", + "address": "Ap #727-9607 Nibh Avenue", + "city": "Hilo", + "state": "HI", + "postal_code": "63747", + "phone": "(521) 124-5753", + "account_credit": 68.41 + }, + { + "id": "11", + "name": "Ciara Summers", + "registered_at": "Thu, 09 Jul 2015 22:12:11 -0700", + "address": "Ap #412-1462 Molestie St.", + "city": "Grand Rapids", + "state": "Michigan", + "postal_code": "44906", + "phone": "(473) 496-4835", + "account_credit": 56.88 + }, + { + "id": "12", + "name": "Alfreda Hines", + "registered_at": "Wed, 19 Aug 2015 23:18:27 -0700", + "address": "P.O. Box 754, 627 Erat Avenue", + "city": "Anchorage", + "state": "Alaska", + "postal_code": "99915", + "phone": "(921) 910-1283", + "account_credit": 55.59 + }, + { + "id": "13", + "name": "Eugenia Roberson", + "registered_at": "Sun, 23 Feb 2014 10:19:11 -0800", + "address": "Ap #781-1953 Suspendisse Road", + "city": "Jackson", + "state": "MS", + "postal_code": "67415", + "phone": "(900) 501-6947", + "account_credit": 22.71 + }, + { + "id": "14", + "name": "Ferris Robles", + "registered_at": "Mon, 16 Mar 2015 16:45:12 -0700", + "address": "P.O. Box 344, 4911 Semper Rd.", + "city": "Independence", + "state": "Missouri", + "postal_code": "46428", + "phone": "(569) 834-1872", + "account_credit": 4.91 + }, + { + "id": "15", + "name": "Sopoline Fisher", + "registered_at": "Sun, 18 May 2014 18:25:58 -0700", + "address": "543-8042 Porttitor Avenue", + "city": "Knoxville", + "state": "TN", + "postal_code": "23142", + "phone": "(603) 919-2974", + "account_credit": 53.63 + }, + { + "id": "16", + "name": "Vivien Justice", + "registered_at": "Mon, 22 Sep 2014 16:07:07 -0700", + "address": "790-3681 Lobortis Rd.", + "city": "Sterling Heights", + "state": "MI", + "postal_code": "54505", + "phone": "(563) 349-0325", + "account_credit": 83.76 + }, + { + "id": "17", + "name": "Ginger Heath", + "registered_at": "Fri, 27 Feb 2015 03:10:39 -0800", + "address": "Ap #395-9452 Quisque St.", + "city": "Billings", + "state": "Montana", + "postal_code": "25054", + "phone": "(572) 140-2058", + "account_credit": 89.69 + }, + { + "id": "18", + "name": "Kieran Calhoun", + "registered_at": "Sun, 24 Aug 2014 03:03:45 -0700", + "address": "Ap #854-9111 Nunc, Road", + "city": "Savannah", + "state": "GA", + "postal_code": "47373", + "phone": "(909) 486-8575", + "account_credit": 61.8 + }, + { + "id": "19", + "name": "Winter Stephenson", + "registered_at": "Fri, 07 Aug 2015 08:09:11 -0700", + "address": "P.O. Box 887, 4257 Lorem Rd.", + "city": "Salt Lake City", + "state": "Utah", + "postal_code": "63684", + "phone": "(466) 617-0803", + "account_credit": 1.41 + }, + { + "id": "20", + "name": "Mallory Weaver", + "registered_at": "Sat, 12 Jul 2014 18:15:55 -0700", + "address": "7297 Tortor, Avenue", + "city": "Houston", + "state": "Texas", + "postal_code": "89807", + "phone": "(727) 342-1336", + "account_credit": 65.24 + }, + { + "id": "21", + "name": "Audra Vance", + "registered_at": "Sat, 01 Nov 2014 01:37:40 -0700", + "address": "P.O. Box 906, 9067 A Street", + "city": "Columbus", + "state": "Ohio", + "postal_code": "43007", + "phone": "(832) 502-4114", + "account_credit": 76.71 + }, + { + "id": "22", + "name": "Aladdin Fowler", + "registered_at": "Mon, 25 May 2015 02:50:55 -0700", + "address": "Ap #548-6390 Ornare Av.", + "city": "Aurora", + "state": "IL", + "postal_code": "92483", + "phone": "(201) 728-7318", + "account_credit": 90.12 + }, + { + "id": "23", + "name": "Dominique Battle", + "registered_at": "Sat, 25 Jan 2014 01:47:14 -0800", + "address": "P.O. Box 753, 5236 At Rd.", + "city": "Gaithersburg", + "state": "MD", + "postal_code": "49893", + "phone": "(385) 326-1715", + "account_credit": 88.51 + }, + { + "id": "24", + "name": "Kimberly Savage", + "registered_at": "Sat, 20 Sep 2014 02:37:33 -0700", + "address": "Ap #888-6281 Aliquam Av.", + "city": "Virginia Beach", + "state": "VA", + "postal_code": "50164", + "phone": "(285) 195-0154", + "account_credit": 41.86 + }, + { + "id": "25", + "name": "Branden Craig", + "registered_at": "Mon, 22 Sep 2014 21:05:52 -0700", + "address": "768-8145 Elit Road", + "city": "Hattiesburg", + "state": "MS", + "postal_code": "99128", + "phone": "(972) 938-4626", + "account_credit": 92.64 + }, + { + "id": "26", + "name": "Hammett Beach", + "registered_at": "Sat, 23 Aug 2014 13:57:12 -0700", + "address": "206-6384 Morbi Road", + "city": "Butte", + "state": "MT", + "postal_code": "54656", + "phone": "(833) 249-0504", + "account_credit": 60.65 + }, + { + "id": "27", + "name": "Dai Meadows", + "registered_at": "Sun, 17 Aug 2014 03:38:21 -0700", + "address": "1083 Enim, St.", + "city": "Sioux City", + "state": "IA", + "postal_code": "63549", + "phone": "(204) 993-4985", + "account_credit": 87.9 + }, + { + "id": "28", + "name": "Grady Chang", + "registered_at": "Mon, 18 May 2015 04:03:19 -0700", + "address": "8819 Nam St.", + "city": "Sacramento", + "state": "CA", + "postal_code": "90337", + "phone": "(306) 153-3636", + "account_credit": 75.94 + }, + { + "id": "29", + "name": "Cody Woodard", + "registered_at": "Tue, 24 Jun 2014 01:42:54 -0700", + "address": "P.O. Box 990, 1927 Quis Ave", + "city": "Gaithersburg", + "state": "Maryland", + "postal_code": "68459", + "phone": "(606) 363-0837", + "account_credit": 97.75 + }, + { + "id": "30", + "name": "Ulysses Whitfield", + "registered_at": "Thu, 20 Nov 2014 19:38:20 -0800", + "address": "906-7966 Adipiscing Street", + "city": "Laramie", + "state": "Wyoming", + "postal_code": "95684", + "phone": "(371) 627-1105", + "account_credit": 93.18 + }, + { + "id": "31", + "name": "Olympia Dyer", + "registered_at": "Wed, 25 Jun 2014 16:02:49 -0700", + "address": "152-525 Odio St.", + "city": "Sandy", + "state": "Utah", + "postal_code": "25061", + "phone": "(124) 172-2031", + "account_credit": 55.17 + }, + { + "id": "32", + "name": "Kristen Snyder", + "registered_at": "Fri, 13 Feb 2015 18:00:19 -0800", + "address": "P.O. Box 610, 7930 Vivamus Av.", + "city": "West Jordan", + "state": "UT", + "postal_code": "50965", + "phone": "(977) 906-9656", + "account_credit": 61.89 + }, + { + "id": "33", + "name": "Mira Stokes", + "registered_at": "Tue, 01 Apr 2014 06:42:52 -0700", + "address": "Ap #630-1483 Luctus Rd.", + "city": "Columbia", + "state": "MD", + "postal_code": "66923", + "phone": "(473) 271-3425", + "account_credit": 95.92 + }, + { + "id": "34", + "name": "Ulla Skinner", + "registered_at": "Mon, 21 Jul 2014 11:28:05 -0700", + "address": "318-7550 Placerat St.", + "city": "Colorado Springs", + "state": "Colorado", + "postal_code": "91540", + "phone": "(718) 770-3057", + "account_credit": 41.64 + }, + { + "id": "35", + "name": "Amelia Brock", + "registered_at": "Thu, 21 May 2015 09:58:26 -0700", + "address": "499-4567 Metus Av.", + "city": "Jackson", + "state": "Mississippi", + "postal_code": "19969", + "phone": "(313) 638-8556", + "account_credit": 29.1 + }, + { + "id": "36", + "name": "Dexter Frank", + "registered_at": "Sat, 01 Aug 2015 20:01:22 -0700", + "address": "P.O. Box 413, 407 Senectus St.", + "city": "Wyoming", + "state": "Wyoming", + "postal_code": "71026", + "phone": "(753) 112-2298", + "account_credit": 83.79 + }, + { + "id": "37", + "name": "Yoshi Willis", + "registered_at": "Sun, 02 Mar 2014 05:18:40 -0800", + "address": "9648 Magna Rd.", + "city": "Sioux City", + "state": "Iowa", + "postal_code": "57062", + "phone": "(592) 873-3593", + "account_credit": 56.74 + }, + { + "id": "38", + "name": "Marah Ballard", + "registered_at": "Sat, 24 Jan 2015 01:05:36 -0800", + "address": "6452 Integer Av.", + "city": "Juneau", + "state": "AK", + "postal_code": "99933", + "phone": "(482) 351-7984", + "account_credit": 68.42 + }, + { + "id": "39", + "name": "Eugenia Cherry", + "registered_at": "Wed, 15 Jul 2015 14:04:05 -0700", + "address": "P.O. Box 749, 4159 Aliquam Rd.", + "city": "Stamford", + "state": "Connecticut", + "postal_code": "29863", + "phone": "(318) 627-4305", + "account_credit": 75.71 + }, + { + "id": "40", + "name": "Porter Mclean", + "registered_at": "Mon, 27 Jan 2014 05:32:30 -0800", + "address": "Ap #450-3061 Turpis St.", + "city": "New Orleans", + "state": "Louisiana", + "postal_code": "70087", + "phone": "(764) 362-7391", + "account_credit": 44.94 + }, + { + "id": "41", + "name": "Philip Patton", + "registered_at": "Tue, 24 Jun 2014 01:28:07 -0700", + "address": "P.O. Box 210, 857 Non, Street", + "city": "Aurora", + "state": "Illinois", + "postal_code": "88138", + "phone": "(188) 787-8862", + "account_credit": 17.53 + }, + { + "id": "42", + "name": "Charlotte Turner", + "registered_at": "Mon, 26 May 2014 21:16:12 -0700", + "address": "8543 Cubilia Avenue", + "city": "Bridgeport", + "state": "CT", + "postal_code": "26116", + "phone": "(629) 711-4885", + "account_credit": 73.15 + }, + { + "id": "43", + "name": "Camden Aguirre", + "registered_at": "Fri, 17 Oct 2014 00:21:57 -0700", + "address": "P.O. Box 100, 8703 Libero Ave", + "city": "Nampa", + "state": "ID", + "postal_code": "13381", + "phone": "(277) 267-0388", + "account_credit": 76.4 + }, + { + "id": "44", + "name": "Samuel Santana", + "registered_at": "Sun, 22 Mar 2015 02:28:48 -0700", + "address": "1605 Quis St.", + "city": "Bellevue", + "state": "Washington", + "postal_code": "67560", + "phone": "(678) 717-4843", + "account_credit": 71.72 + }, + { + "id": "45", + "name": "Sheila Olsen", + "registered_at": "Wed, 18 Feb 2015 17:11:30 -0800", + "address": "2058 Tristique Av.", + "city": "Eugene", + "state": "Oregon", + "postal_code": "63846", + "phone": "(574) 608-9527", + "account_credit": 49.09 + }, + { + "id": "46", + "name": "Acton Gilliam", + "registered_at": "Thu, 26 Feb 2015 20:00:53 -0800", + "address": "Ap #508-8214 Senectus Av.", + "city": "Portland", + "state": "Oregon", + "postal_code": "62594", + "phone": "(903) 973-1984", + "account_credit": 48.64 + }, + { + "id": "47", + "name": "Carla Fox", + "registered_at": "Fri, 16 Jan 2015 21:56:04 -0800", + "address": "4092 Duis St.", + "city": "Biloxi", + "state": "MS", + "postal_code": "67389", + "phone": "(438) 573-5618", + "account_credit": 25.7 + }, + { + "id": "48", + "name": "Ursa Harrell", + "registered_at": "Fri, 21 Nov 2014 23:21:44 -0800", + "address": "8070 Nec Rd.", + "city": "Henderson", + "state": "NV", + "postal_code": "87045", + "phone": "(951) 243-9155", + "account_credit": 41.1 + }, + { + "id": "49", + "name": "Stephanie Foley", + "registered_at": "Mon, 19 May 2014 22:06:51 -0700", + "address": "6806 Volutpat. Street", + "city": "Sioux City", + "state": "IA", + "postal_code": "48520", + "phone": "(562) 674-5565", + "account_credit": 2.94 + }, + { + "id": "50", + "name": "Isabelle Riley", + "registered_at": "Thu, 24 Jul 2014 22:30:47 -0700", + "address": "365-2351 Metus. St.", + "city": "San Antonio", + "state": "Texas", + "postal_code": "42972", + "phone": "(592) 610-6185", + "account_credit": 38.76 + }, + { + "id": "51", + "name": "Olivia Guy", + "registered_at": "Wed, 14 May 2014 08:39:33 -0700", + "address": "8409 Libero Rd.", + "city": "San Francisco", + "state": "California", + "postal_code": "90775", + "phone": "(373) 139-6846", + "account_credit": 44.63 + }, + { + "id": "52", + "name": "Kenneth Rowland", + "registered_at": "Fri, 13 Jun 2014 21:21:50 -0700", + "address": "Ap #862-3617 Cursus Avenue", + "city": "Chattanooga", + "state": "TN", + "postal_code": "54509", + "phone": "(650) 912-9706", + "account_credit": 88.74 + }, + { + "id": "53", + "name": "Zorita Buchanan", + "registered_at": "Sat, 12 Jul 2014 22:22:47 -0700", + "address": "3413 Lectus Avenue", + "city": "Richmond", + "state": "Virginia", + "postal_code": "49611", + "phone": "(109) 544-5498", + "account_credit": 73.2 + }, + { + "id": "54", + "name": "Galvin Daniels", + "registered_at": "Wed, 08 Jan 2014 03:33:40 -0800", + "address": "506-7584 Adipiscing Street", + "city": "Birmingham", + "state": "Alabama", + "postal_code": "36049", + "phone": "(863) 203-7464", + "account_credit": 99.37 + }, + { + "id": "55", + "name": "Hamilton Hunter", + "registered_at": "Tue, 17 Jun 2014 12:08:25 -0700", + "address": "Ap #353-2344 Sodales Street", + "city": "Honolulu", + "state": "Hawaii", + "postal_code": "18980", + "phone": "(531) 196-0181", + "account_credit": 47.93 + }, + { + "id": "56", + "name": "Dieter Frye", + "registered_at": "Mon, 01 Sep 2014 01:11:16 -0700", + "address": "P.O. Box 572, 4852 Nec, Rd.", + "city": "Los Angeles", + "state": "California", + "postal_code": "93004", + "phone": "(843) 603-1249", + "account_credit": 0.19 + }, + { + "id": "57", + "name": "Anne Mclean", + "registered_at": "Sun, 05 Oct 2014 16:05:52 -0700", + "address": "Ap #642-6158 Convallis St.", + "city": "Lawton", + "state": "OK", + "postal_code": "34188", + "phone": "(703) 764-9176", + "account_credit": 52.81 + }, + { + "id": "58", + "name": "Gretchen Gray", + "registered_at": "Fri, 25 Jul 2014 05:15:39 -0700", + "address": "4557 Arcu Ave", + "city": "Virginia Beach", + "state": "VA", + "postal_code": "15836", + "phone": "(629) 782-2033", + "account_credit": 29.02 + }, + { + "id": "59", + "name": "Theodore Ingram", + "registered_at": "Sun, 13 Apr 2014 15:08:45 -0700", + "address": "P.O. Box 362, 9274 Nibh. St.", + "city": "Tucson", + "state": "AZ", + "postal_code": "86869", + "phone": "(227) 651-0229", + "account_credit": 55.08 + }, + { + "id": "60", + "name": "Otto Leblanc", + "registered_at": "Sun, 12 Apr 2015 00:56:48 -0700", + "address": "P.O. Box 210, 6616 Ipsum Ave", + "city": "Detroit", + "state": "Michigan", + "postal_code": "27552", + "phone": "(974) 976-6329", + "account_credit": 38.44 + }, + { + "id": "61", + "name": "Pearl Blackwell", + "registered_at": "Mon, 04 May 2015 20:38:13 -0700", + "address": "797-3332 Nam St.", + "city": "Sterling Heights", + "state": "Michigan", + "postal_code": "51429", + "phone": "(960) 110-2636", + "account_credit": 64.18 + }, + { + "id": "62", + "name": "Caesar Stanley", + "registered_at": "Fri, 31 Jul 2015 01:59:58 -0700", + "address": "Ap #295-1886 Lorem St.", + "city": "Saint Paul", + "state": "MN", + "postal_code": "10029", + "phone": "(841) 157-1769", + "account_credit": 49.14 + }, + { + "id": "63", + "name": "Rebekah Conrad", + "registered_at": "Wed, 01 Jul 2015 10:38:00 -0700", + "address": "112-656 Duis Ave", + "city": "Davenport", + "state": "IA", + "postal_code": "76937", + "phone": "(691) 802-4154", + "account_credit": 67.99 + }, + { + "id": "64", + "name": "Robert Harmon", + "registered_at": "Wed, 08 Apr 2015 21:49:26 -0700", + "address": "333-2529 Duis Road", + "city": "Kaneohe", + "state": "Hawaii", + "postal_code": "58444", + "phone": "(165) 718-1361", + "account_credit": 27.08 + }, + { + "id": "65", + "name": "Maris Puckett", + "registered_at": "Thu, 22 May 2014 19:01:18 -0700", + "address": "Ap #422-3446 A Road", + "city": "Gaithersburg", + "state": "MD", + "postal_code": "39939", + "phone": "(952) 204-5010", + "account_credit": 96.49 + }, + { + "id": "66", + "name": "Lara Ellison", + "registered_at": "Tue, 30 Sep 2014 09:34:25 -0700", + "address": "660-756 Arcu. St.", + "city": "Cedar Rapids", + "state": "Iowa", + "postal_code": "96377", + "phone": "(928) 139-4812", + "account_credit": 60.97 + }, + { + "id": "67", + "name": "Dai Baldwin", + "registered_at": "Thu, 02 Apr 2015 21:28:28 -0700", + "address": "5574 Varius Ave", + "city": "South Bend", + "state": "Indiana", + "postal_code": "27284", + "phone": "(642) 404-1198", + "account_credit": 6.51 + }, + { + "id": "68", + "name": "Mira Lyons", + "registered_at": "Tue, 18 Feb 2014 10:31:37 -0800", + "address": "P.O. Box 176, 9193 Enim Road", + "city": "Topeka", + "state": "KS", + "postal_code": "30606", + "phone": "(355) 309-3105", + "account_credit": 66.25 + }, + { + "id": "69", + "name": "Laurel Diaz", + "registered_at": "Thu, 27 Feb 2014 08:24:02 -0800", + "address": "501 Eu St.", + "city": "Fayetteville", + "state": "Arkansas", + "postal_code": "72463", + "phone": "(382) 883-9819", + "account_credit": 50.13 + }, + { + "id": "70", + "name": "Breanna Kim", + "registered_at": "Fri, 06 Feb 2015 14:42:21 -0800", + "address": "752-6391 Quis Ave", + "city": "Little Rock", + "state": "AR", + "postal_code": "71072", + "phone": "(182) 564-6516", + "account_credit": 58.31 + }, + { + "id": "71", + "name": "Hayes Levine", + "registered_at": "Wed, 13 May 2015 17:46:32 -0700", + "address": "646-9160 Ultrices St.", + "city": "Grand Island", + "state": "NE", + "postal_code": "89643", + "phone": "(624) 302-2419", + "account_credit": 77.3 + }, + { + "id": "72", + "name": "Taylor Spence", + "registered_at": "Wed, 09 Jul 2014 14:10:42 -0700", + "address": "7109 In St.", + "city": "Portland", + "state": "Oregon", + "postal_code": "91240", + "phone": "(993) 724-6663", + "account_credit": 24.11 + }, + { + "id": "73", + "name": "Camille Walton", + "registered_at": "Thu, 19 Mar 2015 01:25:46 -0700", + "address": "718-6981 Libero Road", + "city": "Boise", + "state": "Idaho", + "postal_code": "72346", + "phone": "(332) 249-7842", + "account_credit": 21.88 + }, + { + "id": "74", + "name": "Yardley Mckenzie", + "registered_at": "Mon, 22 Jun 2015 05:10:11 -0700", + "address": "8911 Justo Rd.", + "city": "Huntsville", + "state": "AL", + "postal_code": "36334", + "phone": "(731) 311-1108", + "account_credit": 95.41 + }, + { + "id": "75", + "name": "Rachel Munoz", + "registered_at": "Sun, 04 May 2014 08:20:55 -0700", + "address": "8466 Aliquam Ave", + "city": "Madison", + "state": "Wisconsin", + "postal_code": "56718", + "phone": "(651) 904-9661", + "account_credit": 80.08 + }, + { + "id": "76", + "name": "Bevis Jimenez", + "registered_at": "Sun, 11 May 2014 07:35:02 -0700", + "address": "Ap #222-2891 Magnis St.", + "city": "Columbus", + "state": "Georgia", + "postal_code": "35209", + "phone": "(526) 934-4237", + "account_credit": 25.63 + }, + { + "id": "77", + "name": "Malik Barber", + "registered_at": "Sat, 14 Feb 2015 10:24:50 -0800", + "address": "Ap #364-1684 Quam. St.", + "city": "Waterbury", + "state": "Connecticut", + "postal_code": "75696", + "phone": "(575) 915-7794", + "account_credit": 92.24 + }, + { + "id": "78", + "name": "Nell Bishop", + "registered_at": "Fri, 01 May 2015 18:59:31 -0700", + "address": "7623 Torquent Street", + "city": "Minneapolis", + "state": "MN", + "postal_code": "27078", + "phone": "(819) 107-0728", + "account_credit": 9.35 + }, + { + "id": "79", + "name": "Leigh Anderson", + "registered_at": "Tue, 22 Jul 2014 13:05:46 -0700", + "address": "Ap #149-1154 Cras Rd.", + "city": "Montgomery", + "state": "Alabama", + "postal_code": "36037", + "phone": "(176) 966-1214", + "account_credit": 86.77 + }, + { + "id": "80", + "name": "Chava Kirby", + "registered_at": "Wed, 25 Jun 2014 13:45:50 -0700", + "address": "570-6835 Ac Ave", + "city": "Allentown", + "state": "PA", + "postal_code": "84384", + "phone": "(795) 896-0405", + "account_credit": 5.45 + }, + { + "id": "81", + "name": "Inez Gamble", + "registered_at": "Mon, 09 Feb 2015 17:28:45 -0800", + "address": "471-8542 Et Ave", + "city": "Virginia Beach", + "state": "VA", + "postal_code": "23365", + "phone": "(288) 595-2741", + "account_credit": 32.92 + }, + { + "id": "82", + "name": "Jacob Villarreal", + "registered_at": "Mon, 16 Mar 2015 06:03:28 -0700", + "address": "3480 Amet, Street", + "city": "Grand Island", + "state": "NE", + "postal_code": "53804", + "phone": "(676) 686-4808", + "account_credit": 76.99 + }, + { + "id": "83", + "name": "Velma Mcfadden", + "registered_at": "Wed, 13 Aug 2014 17:48:11 -0700", + "address": "164-557 At St.", + "city": "Juneau", + "state": "AK", + "postal_code": "99806", + "phone": "(520) 661-1866", + "account_credit": 4.31 + }, + { + "id": "84", + "name": "Berk Carroll", + "registered_at": "Mon, 09 Jun 2014 07:18:28 -0700", + "address": "1640 Blandit. Rd.", + "city": "Frankfort", + "state": "Kentucky", + "postal_code": "88958", + "phone": "(937) 237-7054", + "account_credit": 55.15 + }, + { + "id": "85", + "name": "Serina Collins", + "registered_at": "Wed, 12 Aug 2015 11:48:57 -0700", + "address": "6117 Lorem, Avenue", + "city": "South Bend", + "state": "Indiana", + "postal_code": "39108", + "phone": "(216) 221-5456", + "account_credit": 55.52 + }, + { + "id": "86", + "name": "Larissa Soto", + "registered_at": "Wed, 04 Mar 2015 06:32:01 -0800", + "address": "597-5077 Purus St.", + "city": "Tampa", + "state": "Florida", + "postal_code": "19281", + "phone": "(693) 833-8618", + "account_credit": 98.77 + }, + { + "id": "87", + "name": "Erin Mckenzie", + "registered_at": "Fri, 17 Apr 2015 09:24:27 -0700", + "address": "P.O. Box 822, 6254 Etiam Rd.", + "city": "Madison", + "state": "WI", + "postal_code": "94031", + "phone": "(646) 241-7827", + "account_credit": 78.13 + }, + { + "id": "88", + "name": "Katell Lewis", + "registered_at": "Fri, 06 Jun 2014 00:36:28 -0700", + "address": "P.O. Box 794, 8686 Libero St.", + "city": "San Antonio", + "state": "TX", + "postal_code": "90724", + "phone": "(307) 332-5251", + "account_credit": 1.13 + }, + { + "id": "89", + "name": "Yeo Humphrey", + "registered_at": "Mon, 14 Jul 2014 03:21:54 -0700", + "address": "121 Porta Ave", + "city": "Bear", + "state": "DE", + "postal_code": "61381", + "phone": "(770) 120-6205", + "account_credit": 42.14 + }, + { + "id": "90", + "name": "Brynne Stuart", + "registered_at": "Tue, 16 Jun 2015 07:18:47 -0700", + "address": "778-6903 Urna Rd.", + "city": "Jonesboro", + "state": "AR", + "postal_code": "72921", + "phone": "(949) 800-1135", + "account_credit": 84.26 + }, + { + "id": "91", + "name": "Brynne Fuentes", + "registered_at": "Tue, 19 May 2015 01:36:10 -0700", + "address": "8106 Habitant Av.", + "city": "Minneapolis", + "state": "Minnesota", + "postal_code": "23965", + "phone": "(535) 656-2981", + "account_credit": 76.08 + }, + { + "id": "92", + "name": "Giacomo Strong", + "registered_at": "Sat, 13 Dec 2014 10:01:42 -0800", + "address": "1121 Vivamus Av.", + "city": "Madison", + "state": "Wisconsin", + "postal_code": "18820", + "phone": "(938) 428-0683", + "account_credit": 62.64 + }, + { + "id": "93", + "name": "Ruth Nelson", + "registered_at": "Sun, 07 Dec 2014 03:40:07 -0800", + "address": "P.O. Box 324, 7958 Rutrum Avenue", + "city": "Lewiston", + "state": "Maine", + "postal_code": "35597", + "phone": "(821) 465-3951", + "account_credit": 22.11 + }, + { + "id": "94", + "name": "Alexander Brennan", + "registered_at": "Fri, 20 Feb 2015 10:58:42 -0800", + "address": "P.O. Box 778, 9617 Sapien, Avenue", + "city": "San Antonio", + "state": "Texas", + "postal_code": "74395", + "phone": "(452) 676-2428", + "account_credit": 94.6 + }, + { + "id": "95", + "name": "Eagan Lynch", + "registered_at": "Tue, 08 Apr 2014 15:32:50 -0700", + "address": "Ap #209-5829 Gravida St.", + "city": "Dallas", + "state": "Texas", + "postal_code": "45352", + "phone": "(874) 234-9834", + "account_credit": 4.26 + }, + { + "id": "96", + "name": "Charity Buckley", + "registered_at": "Mon, 13 Jul 2015 09:05:22 -0700", + "address": "Ap #822-4239 Aliquam Rd.", + "city": "San Antonio", + "state": "Texas", + "postal_code": "48690", + "phone": "(580) 120-8164", + "account_credit": 5.49 + }, + { + "id": "97", + "name": "Aspen Le", + "registered_at": "Mon, 19 May 2014 22:41:26 -0700", + "address": "Ap #373-9486 A Ave", + "city": "Essex", + "state": "Vermont", + "postal_code": "53433", + "phone": "(179) 428-6526", + "account_credit": 27.07 + }, + { + "id": "98", + "name": "Jana Foster", + "registered_at": "Sat, 31 May 2014 16:18:00 -0700", + "address": "521-938 Odio. Rd.", + "city": "Clarksville", + "state": "TN", + "postal_code": "41791", + "phone": "(828) 240-0643", + "account_credit": 88.61 + }, + { + "id": "99", + "name": "Basia Contreras", + "registered_at": "Sat, 11 Oct 2014 06:25:54 -0700", + "address": "P.O. Box 325, 3668 Donec St.", + "city": "Independence", + "state": "Missouri", + "postal_code": "44890", + "phone": "(847) 205-9126", + "account_credit": 74.62 + }, + { + "id": "100", + "name": "Barbara Jacobson", + "registered_at": "Mon, 03 Nov 2014 07:33:03 -0800", + "address": "489-4471 Commodo Avenue", + "city": "Duluth", + "state": "Minnesota", + "postal_code": "59354", + "phone": "(823) 257-9965", + "account_credit": 12.41 + }, + { + "id": "101", + "name": "Ria Little", + "registered_at": "Wed, 01 Apr 2015 17:10:16 -0700", + "address": "P.O. Box 423, 7795 Aenean St.", + "city": "Athens", + "state": "GA", + "postal_code": "88306", + "phone": "(496) 600-9071", + "account_credit": 0.84 + }, + { + "id": "102", + "name": "Jael Hoover", + "registered_at": "Sun, 12 Apr 2015 04:10:37 -0700", + "address": "P.O. Box 817, 1753 Ac Rd.", + "city": "Seattle", + "state": "Washington", + "postal_code": "17749", + "phone": "(953) 751-2907", + "account_credit": 95.32 + }, + { + "id": "103", + "name": "Howard Meyer", + "registered_at": "Sun, 14 Dec 2014 21:19:41 -0800", + "address": "2813 Pede. Rd.", + "city": "Colchester", + "state": "Vermont", + "postal_code": "11479", + "phone": "(735) 816-9513", + "account_credit": 43.79 + }, + { + "id": "104", + "name": "Brian Yates", + "registered_at": "Mon, 10 Mar 2014 00:26:55 -0700", + "address": "2961 Integer Ave", + "city": "Kearney", + "state": "NE", + "postal_code": "49867", + "phone": "(292) 138-3176", + "account_credit": 9.51 + }, + { + "id": "105", + "name": "Amber Nicholson", + "registered_at": "Thu, 13 Feb 2014 11:15:19 -0800", + "address": "1666 Urna Ave", + "city": "Knoxville", + "state": "Tennessee", + "postal_code": "57653", + "phone": "(154) 850-1394", + "account_credit": 84.42 + }, + { + "id": "106", + "name": "Silas Barton", + "registered_at": "Fri, 06 Feb 2015 00:37:52 -0800", + "address": "Ap #441-4537 Vitae Road", + "city": "Gulfport", + "state": "MS", + "postal_code": "72241", + "phone": "(817) 405-3562", + "account_credit": 5.98 + }, + { + "id": "107", + "name": "Justina Weber", + "registered_at": "Sun, 26 Jul 2015 09:22:06 -0700", + "address": "9004 Dui Rd.", + "city": "Cleveland", + "state": "OH", + "postal_code": "35970", + "phone": "(653) 921-2923", + "account_credit": 35.95 + }, + { + "id": "108", + "name": "Raven Cote", + "registered_at": "Wed, 29 Apr 2015 09:17:30 -0700", + "address": "P.O. Box 944, 5312 Donec Street", + "city": "Savannah", + "state": "GA", + "postal_code": "56882", + "phone": "(212) 164-3612", + "account_credit": 54.27 + }, + { + "id": "109", + "name": "Ahmed Massey", + "registered_at": "Sat, 13 Sep 2014 10:01:23 -0700", + "address": "675-7569 Neque. Rd.", + "city": "Metairie", + "state": "Louisiana", + "postal_code": "74601", + "phone": "(798) 424-7871", + "account_credit": 31.59 + }, + { + "id": "110", + "name": "Thomas Mcbride", + "registered_at": "Sun, 28 Dec 2014 03:52:26 -0800", + "address": "Ap #911-5536 Proin Road", + "city": "Little Rock", + "state": "AR", + "postal_code": "71114", + "phone": "(557) 571-0355", + "account_credit": 62.9 + }, + { + "id": "111", + "name": "April Humphrey", + "registered_at": "Tue, 04 Feb 2014 14:31:31 -0800", + "address": "P.O. Box 153, 5975 Molestie Ave", + "city": "Olathe", + "state": "Kansas", + "postal_code": "84858", + "phone": "(795) 813-1088", + "account_credit": 18.44 + }, + { + "id": "112", + "name": "Sierra Rosa", + "registered_at": "Thu, 15 May 2014 12:18:28 -0700", + "address": "Ap #753-7173 Purus St.", + "city": "Knoxville", + "state": "Tennessee", + "postal_code": "86369", + "phone": "(433) 397-7483", + "account_credit": 12.75 + }, + { + "id": "113", + "name": "Sara Gay", + "registered_at": "Fri, 27 Feb 2015 08:26:18 -0800", + "address": "6311 Felis, Rd.", + "city": "Knoxville", + "state": "Tennessee", + "postal_code": "60949", + "phone": "(239) 940-6734", + "account_credit": 44.11 + }, + { + "id": "114", + "name": "Alexis Ward", + "registered_at": "Mon, 27 Apr 2015 21:02:39 -0700", + "address": "888 Feugiat Rd.", + "city": "Miami", + "state": "Florida", + "postal_code": "65771", + "phone": "(189) 124-7774", + "account_credit": 84.48 + }, + { + "id": "115", + "name": "Justina Dixon", + "registered_at": "Fri, 17 Jul 2015 03:14:57 -0700", + "address": "P.O. Box 279, 5229 Mattis Street", + "city": "Green Bay", + "state": "Wisconsin", + "postal_code": "28463", + "phone": "(488) 172-0802", + "account_credit": 48.41 + }, + { + "id": "116", + "name": "Scott Wise", + "registered_at": "Sat, 20 Dec 2014 10:18:05 -0800", + "address": "P.O. Box 237, 9683 Elit, Road", + "city": "Dover", + "state": "DE", + "postal_code": "80375", + "phone": "(744) 266-9954", + "account_credit": 11.75 + }, + { + "id": "117", + "name": "Cameran Terry", + "registered_at": "Thu, 19 Feb 2015 16:38:52 -0800", + "address": "133-7353 Eu Avenue", + "city": "Rutland", + "state": "VT", + "postal_code": "13964", + "phone": "(232) 667-7186", + "account_credit": 74.33 + }, + { + "id": "118", + "name": "Cooper Suarez", + "registered_at": "Mon, 10 Nov 2014 10:16:37 -0800", + "address": "P.O. Box 632, 4595 Nec Rd.", + "city": "Montpelier", + "state": "Vermont", + "postal_code": "21186", + "phone": "(792) 641-6482", + "account_credit": 20.07 + }, + { + "id": "119", + "name": "Karleigh Ingram", + "registered_at": "Sun, 21 Sep 2014 23:49:59 -0700", + "address": "3480 Nulla Road", + "city": "San Diego", + "state": "CA", + "postal_code": "92064", + "phone": "(819) 878-4232", + "account_credit": 7.66 + }, + { + "id": "120", + "name": "Fiona Santana", + "registered_at": "Thu, 11 Dec 2014 22:20:46 -0800", + "address": "P.O. Box 950, 8105 Gravida. Ave", + "city": "Independence", + "state": "MO", + "postal_code": "64612", + "phone": "(364) 302-8535", + "account_credit": 47.27 + }, + { + "id": "121", + "name": "Cheryl Shelton", + "registered_at": "Mon, 07 Jul 2014 08:34:34 -0700", + "address": "145-5466 Nec Rd.", + "city": "Anchorage", + "state": "AK", + "postal_code": "99971", + "phone": "(666) 421-3975", + "account_credit": 27.65 + }, + { + "id": "122", + "name": "Raya Burgess", + "registered_at": "Fri, 01 May 2015 01:45:27 -0700", + "address": "9695 Lacus. Avenue", + "city": "Owensboro", + "state": "KY", + "postal_code": "72801", + "phone": "(118) 782-5871", + "account_credit": 31.05 + }, + { + "id": "123", + "name": "Hakeem Stokes", + "registered_at": "Fri, 31 Jul 2015 07:26:43 -0700", + "address": "975-799 Sit Street", + "city": "Helena", + "state": "MT", + "postal_code": "67768", + "phone": "(285) 662-1132", + "account_credit": 60.43 + }, + { + "id": "124", + "name": "Macon Crosby", + "registered_at": "Sun, 27 Apr 2014 14:02:28 -0700", + "address": "4714 Aliquet. Road", + "city": "Hartford", + "state": "Connecticut", + "postal_code": "56565", + "phone": "(347) 348-8116", + "account_credit": 66.21 + }, + { + "id": "125", + "name": "Brittany Harris", + "registered_at": "Wed, 19 Mar 2014 05:09:44 -0700", + "address": "183-9407 A Road", + "city": "Bozeman", + "state": "MT", + "postal_code": "56384", + "phone": "(489) 746-9013", + "account_credit": 8.05 + }, + { + "id": "126", + "name": "Galena Ford", + "registered_at": "Fri, 04 Sep 2015 11:09:52 -0700", + "address": "8088 Eget Road", + "city": "Gary", + "state": "IN", + "postal_code": "25479", + "phone": "(538) 724-6020", + "account_credit": 82.15 + }, + { + "id": "127", + "name": "Nehru Smith", + "registered_at": "Sun, 04 Jan 2015 00:43:42 -0800", + "address": "317 Arcu. Avenue", + "city": "Austin", + "state": "TX", + "postal_code": "83794", + "phone": "(127) 566-2347", + "account_credit": 60.36 + }, + { + "id": "128", + "name": "Craig Higgins", + "registered_at": "Mon, 13 Jul 2015 01:16:50 -0700", + "address": "Ap #592-2711 Non, Ave", + "city": "Cambridge", + "state": "Massachusetts", + "postal_code": "50503", + "phone": "(123) 194-5906", + "account_credit": 46.3 + }, + { + "id": "129", + "name": "Ria Goodwin", + "registered_at": "Thu, 29 Jan 2015 07:14:41 -0800", + "address": "860-5993 Vivamus Road", + "city": "Augusta", + "state": "Maine", + "postal_code": "25217", + "phone": "(251) 172-1155", + "account_credit": 88 + }, + { + "id": "130", + "name": "Griffith Key", + "registered_at": "Mon, 10 Feb 2014 02:08:23 -0800", + "address": "152-5468 Ac Road", + "city": "Nampa", + "state": "Idaho", + "postal_code": "51195", + "phone": "(624) 463-6111", + "account_credit": 71.11 + }, + { + "id": "131", + "name": "Kasper Fischer", + "registered_at": "Wed, 13 May 2015 17:02:25 -0700", + "address": "6153 Sed Road", + "city": "Independence", + "state": "Missouri", + "postal_code": "91560", + "phone": "(319) 149-4379", + "account_credit": 40.96 + }, + { + "id": "132", + "name": "Stuart Goodwin", + "registered_at": "Tue, 01 Sep 2015 14:57:31 -0700", + "address": "P.O. Box 689, 2792 Quis, St.", + "city": "Augusta", + "state": "Georgia", + "postal_code": "71303", + "phone": "(538) 387-3287", + "account_credit": 88.19 + }, + { + "id": "133", + "name": "Dawn Carlson", + "registered_at": "Sat, 18 Apr 2015 07:51:41 -0700", + "address": "5366 Id Street", + "city": "Aurora", + "state": "Illinois", + "postal_code": "79365", + "phone": "(994) 905-9769", + "account_credit": 78.41 + }, + { + "id": "134", + "name": "Natalie Schroeder", + "registered_at": "Wed, 24 Jun 2015 01:04:02 -0700", + "address": "392-2462 Luctus Road", + "city": "Boston", + "state": "Massachusetts", + "postal_code": "99200", + "phone": "(891) 649-2871", + "account_credit": 95.95 + }, + { + "id": "135", + "name": "Justine Goodwin", + "registered_at": "Mon, 20 Oct 2014 22:26:35 -0700", + "address": "Ap #406-6268 Morbi Av.", + "city": "Columbus", + "state": "Ohio", + "postal_code": "85028", + "phone": "(155) 830-0119", + "account_credit": 71.42 + }, + { + "id": "136", + "name": "Wilma Velez", + "registered_at": "Sun, 06 Apr 2014 16:31:42 -0700", + "address": "4400 Aliquam Rd.", + "city": "Virginia Beach", + "state": "Virginia", + "postal_code": "36713", + "phone": "(279) 153-9870", + "account_credit": 7.6 + }, + { + "id": "137", + "name": "Chiquita Burks", + "registered_at": "Tue, 18 Feb 2014 20:20:50 -0800", + "address": "Ap #979-8936 Egestas. St.", + "city": "Dover", + "state": "DE", + "postal_code": "48328", + "phone": "(264) 440-3911", + "account_credit": 84.17 + }, + { + "id": "138", + "name": "Christian Mclaughlin", + "registered_at": "Sun, 19 Apr 2015 09:47:16 -0700", + "address": "765 Tristique Avenue", + "city": "Des Moines", + "state": "Iowa", + "postal_code": "35850", + "phone": "(962) 941-9645", + "account_credit": 8.08 + }, + { + "id": "139", + "name": "Aurelia Giles", + "registered_at": "Sun, 07 Dec 2014 21:43:39 -0800", + "address": "P.O. Box 745, 1594 Ante. Rd.", + "city": "Wyoming", + "state": "WY", + "postal_code": "51587", + "phone": "(724) 380-8095", + "account_credit": 62.69 + }, + { + "id": "140", + "name": "Josephine Browning", + "registered_at": "Fri, 12 Dec 2014 06:36:20 -0800", + "address": "459-9737 Donec Rd.", + "city": "Davenport", + "state": "Iowa", + "postal_code": "21255", + "phone": "(436) 817-2557", + "account_credit": 21.97 + }, + { + "id": "141", + "name": "Kasper Morton", + "registered_at": "Tue, 21 Oct 2014 22:31:15 -0700", + "address": "3938 Cursus. Street", + "city": "Philadelphia", + "state": "Pennsylvania", + "postal_code": "56267", + "phone": "(191) 710-5107", + "account_credit": 65.15 + }, + { + "id": "142", + "name": "Renee Higgins", + "registered_at": "Sat, 07 Jun 2014 22:19:01 -0700", + "address": "P.O. Box 523, 9963 Arcu. Road", + "city": "Newport News", + "state": "VA", + "postal_code": "25802", + "phone": "(933) 431-7021", + "account_credit": 67.97 + }, + { + "id": "143", + "name": "Brody Coleman", + "registered_at": "Sat, 22 Feb 2014 06:39:59 -0800", + "address": "Ap #269-5956 Proin Rd.", + "city": "Rutland", + "state": "Vermont", + "postal_code": "72539", + "phone": "(482) 790-5904", + "account_credit": 68.91 + }, + { + "id": "144", + "name": "Jennifer Greer", + "registered_at": "Sun, 12 Jul 2015 08:51:24 -0700", + "address": "923-7286 Dui. Rd.", + "city": "Virginia Beach", + "state": "Virginia", + "postal_code": "97476", + "phone": "(547) 641-6594", + "account_credit": 71.19 + }, + { + "id": "145", + "name": "Gannon Abbott", + "registered_at": "Wed, 24 Sep 2014 14:47:00 -0700", + "address": "Ap #754-9349 Nec Road", + "city": "Rochester", + "state": "Minnesota", + "postal_code": "22689", + "phone": "(363) 394-9351", + "account_credit": 27.97 + }, + { + "id": "146", + "name": "Adrian Nguyen", + "registered_at": "Mon, 28 Apr 2014 10:51:17 -0700", + "address": "956-1243 Libero Av.", + "city": "Fort Smith", + "state": "Arkansas", + "postal_code": "71182", + "phone": "(109) 817-4149", + "account_credit": 92.54 + }, + { + "id": "147", + "name": "Carter Morris", + "registered_at": "Mon, 08 Sep 2014 21:10:38 -0700", + "address": "P.O. Box 304, 5040 Malesuada Rd.", + "city": "Kaneohe", + "state": "Hawaii", + "postal_code": "26814", + "phone": "(450) 765-0057", + "account_credit": 81.11 + }, + { + "id": "148", + "name": "Basia Ratliff", + "registered_at": "Wed, 01 Jan 2014 19:21:29 -0800", + "address": "Ap #907-6837 Diam Ave", + "city": "Knoxville", + "state": "Tennessee", + "postal_code": "80562", + "phone": "(734) 180-1477", + "account_credit": 67.26 + }, + { + "id": "149", + "name": "Genevieve Nieves", + "registered_at": "Tue, 13 May 2014 04:26:45 -0700", + "address": "Ap #864-1195 Sit Street", + "city": "Wichita", + "state": "KS", + "postal_code": "17313", + "phone": "(660) 218-7246", + "account_credit": 38.71 + }, + { + "id": "150", + "name": "Axel Morton", + "registered_at": "Fri, 02 May 2014 02:32:29 -0700", + "address": "459-6656 Ultricies Av.", + "city": "West Jordan", + "state": "Utah", + "postal_code": "99969", + "phone": "(929) 552-4291", + "account_credit": 48.18 + }, + { + "id": "151", + "name": "Montana Wynn", + "registered_at": "Sun, 03 Aug 2014 01:01:44 -0700", + "address": "Ap #236-806 Sem, Av.", + "city": "Springfield", + "state": "Missouri", + "postal_code": "41345", + "phone": "(697) 916-8606", + "account_credit": 33.85 + }, + { + "id": "152", + "name": "Allistair Bradley", + "registered_at": "Fri, 22 May 2015 08:03:48 -0700", + "address": "P.O. Box 384, 7086 At Avenue", + "city": "Juneau", + "state": "Alaska", + "postal_code": "99972", + "phone": "(627) 610-6902", + "account_credit": 68.34 + }, + { + "id": "153", + "name": "Jacob Foley", + "registered_at": "Mon, 17 Mar 2014 17:44:22 -0700", + "address": "785-7522 Duis St.", + "city": "Little Rock", + "state": "AR", + "postal_code": "72550", + "phone": "(310) 834-5542", + "account_credit": 52.03 + }, + { + "id": "154", + "name": "Noelani Burton", + "registered_at": "Sat, 15 Mar 2014 01:00:31 -0700", + "address": "428-8345 Enim. St.", + "city": "Burlington", + "state": "VT", + "postal_code": "83655", + "phone": "(461) 724-9721", + "account_credit": 81.67 + }, + { + "id": "155", + "name": "Abigail Lara", + "registered_at": "Wed, 12 Aug 2015 03:21:43 -0700", + "address": "P.O. Box 388, 1190 Donec St.", + "city": "Shreveport", + "state": "Louisiana", + "postal_code": "41243", + "phone": "(235) 178-3417", + "account_credit": 88.56 + }, + { + "id": "156", + "name": "Driscoll Shepard", + "registered_at": "Sat, 12 Apr 2014 03:01:43 -0700", + "address": "Ap #375-2818 Ac St.", + "city": "Minneapolis", + "state": "MN", + "postal_code": "30682", + "phone": "(433) 449-9825", + "account_credit": 13.79 + }, + { + "id": "157", + "name": "Elaine Carney", + "registered_at": "Thu, 22 May 2014 07:13:57 -0700", + "address": "P.O. Box 495, 1408 Laoreet, Rd.", + "city": "Miami", + "state": "Florida", + "postal_code": "78257", + "phone": "(213) 954-9127", + "account_credit": 82.97 + }, + { + "id": "158", + "name": "Jonas Galloway", + "registered_at": "Sun, 25 Jan 2015 06:05:43 -0800", + "address": "Ap #190-5298 Ornare, Rd.", + "city": "Bloomington", + "state": "MN", + "postal_code": "86280", + "phone": "(113) 365-9867", + "account_credit": 56.1 + }, + { + "id": "159", + "name": "Abel Oneil", + "registered_at": "Sat, 19 Apr 2014 16:26:15 -0700", + "address": "P.O. Box 129, 2669 Arcu. Avenue", + "city": "Colorado Springs", + "state": "CO", + "postal_code": "52301", + "phone": "(857) 528-9424", + "account_credit": 89.69 + }, + { + "id": "160", + "name": "Maia Brock", + "registered_at": "Sat, 13 Jun 2015 04:54:46 -0700", + "address": "Ap #354-4024 Cubilia Road", + "city": "Essex", + "state": "Vermont", + "postal_code": "67149", + "phone": "(392) 863-4448", + "account_credit": 74.13 + }, + { + "id": "161", + "name": "Alden Cabrera", + "registered_at": "Tue, 18 Feb 2014 01:57:47 -0800", + "address": "P.O. Box 904, 6349 Tortor Ave", + "city": "Rutland", + "state": "Vermont", + "postal_code": "96595", + "phone": "(535) 175-9355", + "account_credit": 31.45 + }, + { + "id": "162", + "name": "Kerry Steele", + "registered_at": "Thu, 24 Jul 2014 23:24:08 -0700", + "address": "441-2182 Turpis Av.", + "city": "Anchorage", + "state": "AK", + "postal_code": "99922", + "phone": "(178) 897-7367", + "account_credit": 63.9 + }, + { + "id": "163", + "name": "Charissa Browning", + "registered_at": "Wed, 11 Mar 2015 11:00:37 -0700", + "address": "873-2320 Et, Street", + "city": "Jacksonville", + "state": "Florida", + "postal_code": "14335", + "phone": "(840) 128-0317", + "account_credit": 5.28 + }, + { + "id": "164", + "name": "Darius Mendez", + "registered_at": "Fri, 25 Jul 2014 21:31:44 -0700", + "address": "P.O. Box 505, 730 Nonummy Road", + "city": "Casper", + "state": "WY", + "postal_code": "51369", + "phone": "(335) 359-1497", + "account_credit": 63.72 + }, + { + "id": "165", + "name": "Megan Gates", + "registered_at": "Mon, 09 Mar 2015 05:43:43 -0700", + "address": "955-5227 Nunc Av.", + "city": "Reading", + "state": "PA", + "postal_code": "81062", + "phone": "(443) 918-1564", + "account_credit": 2.86 + }, + { + "id": "166", + "name": "Paloma Horne", + "registered_at": "Mon, 21 Apr 2014 05:04:50 -0700", + "address": "7419 Quis, St.", + "city": "North Las Vegas", + "state": "NV", + "postal_code": "43059", + "phone": "(293) 295-3992", + "account_credit": 55.75 + }, + { + "id": "167", + "name": "Alec Schneider", + "registered_at": "Fri, 05 Sep 2014 06:54:39 -0700", + "address": "958 Arcu. Street", + "city": "Newport News", + "state": "Virginia", + "postal_code": "90428", + "phone": "(378) 745-6478", + "account_credit": 94.93 + }, + { + "id": "168", + "name": "Keegan Porter", + "registered_at": "Tue, 15 Jul 2014 05:47:49 -0700", + "address": "2383 Fusce St.", + "city": "Omaha", + "state": "Nebraska", + "postal_code": "36496", + "phone": "(235) 797-5965", + "account_credit": 83.54 + }, + { + "id": "169", + "name": "Dorian Brooks", + "registered_at": "Thu, 08 Jan 2015 05:35:34 -0800", + "address": "863 Nisi Av.", + "city": "Cedar Rapids", + "state": "Iowa", + "postal_code": "21997", + "phone": "(543) 949-5105", + "account_credit": 85.74 + }, + { + "id": "170", + "name": "Xyla Oneal", + "registered_at": "Wed, 17 Jun 2015 04:22:58 -0700", + "address": "625-1521 Adipiscing Avenue", + "city": "Tuscaloosa", + "state": "Alabama", + "postal_code": "35503", + "phone": "(586) 384-9718", + "account_credit": 92.1 + }, + { + "id": "171", + "name": "Urielle Brock", + "registered_at": "Mon, 11 May 2015 16:37:45 -0700", + "address": "P.O. Box 248, 1197 Adipiscing St.", + "city": "Newport News", + "state": "VA", + "postal_code": "96073", + "phone": "(374) 344-9156", + "account_credit": 97.75 + }, + { + "id": "172", + "name": "Hadley Snow", + "registered_at": "Tue, 04 Feb 2014 06:50:21 -0800", + "address": "Ap #795-8212 Erat. Av.", + "city": "Fort Collins", + "state": "Colorado", + "postal_code": "41558", + "phone": "(290) 857-4604", + "account_credit": 35.67 + }, + { + "id": "173", + "name": "Jenna Conley", + "registered_at": "Wed, 24 Jun 2015 12:00:49 -0700", + "address": "9806 In Rd.", + "city": "South Bend", + "state": "Indiana", + "postal_code": "27537", + "phone": "(965) 898-4616", + "account_credit": 90.28 + }, + { + "id": "174", + "name": "Hermione Combs", + "registered_at": "Thu, 13 Feb 2014 14:01:18 -0800", + "address": "Ap #571-9079 Lobortis Street", + "city": "Cambridge", + "state": "MA", + "postal_code": "77897", + "phone": "(711) 537-2715", + "account_credit": 14.77 + }, + { + "id": "175", + "name": "Scarlet Bridges", + "registered_at": "Tue, 07 Oct 2014 03:48:37 -0700", + "address": "P.O. Box 684, 1366 Cras St.", + "city": "Atlanta", + "state": "GA", + "postal_code": "85419", + "phone": "(303) 449-3873", + "account_credit": 4.05 + }, + { + "id": "176", + "name": "Christopher Santana", + "registered_at": "Fri, 28 Mar 2014 11:26:28 -0700", + "address": "Ap #401-3610 Porta St.", + "city": "Bridgeport", + "state": "Connecticut", + "postal_code": "31517", + "phone": "(916) 183-3805", + "account_credit": 71.54 + }, + { + "id": "177", + "name": "Linus Benjamin", + "registered_at": "Fri, 23 Jan 2015 22:31:42 -0800", + "address": "Ap #480-9547 Morbi Rd.", + "city": "Olathe", + "state": "Kansas", + "postal_code": "85407", + "phone": "(970) 802-1283", + "account_credit": 62.99 + }, + { + "id": "178", + "name": "Abbot Mcclain", + "registered_at": "Tue, 24 Feb 2015 16:47:48 -0800", + "address": "P.O. Box 159, 5873 Auctor Rd.", + "city": "Carson City", + "state": "NV", + "postal_code": "64780", + "phone": "(808) 310-5874", + "account_credit": 13.81 + }, + { + "id": "179", + "name": "Griffin Silva", + "registered_at": "Tue, 14 Oct 2014 10:57:04 -0700", + "address": "6307 Nulla Avenue", + "city": "Juneau", + "state": "AK", + "postal_code": "99838", + "phone": "(679) 747-9281", + "account_credit": 47.03 + }, + { + "id": "180", + "name": "Chloe Shepard", + "registered_at": "Sun, 03 Aug 2014 21:38:38 -0700", + "address": "P.O. Box 198, 4549 Pellentesque Rd.", + "city": "Kapolei", + "state": "HI", + "postal_code": "41472", + "phone": "(130) 324-9334", + "account_credit": 24.78 + }, + { + "id": "181", + "name": "Ori Russo", + "registered_at": "Wed, 11 Mar 2015 03:57:38 -0700", + "address": "Ap #795-182 Commodo Av.", + "city": "Lewiston", + "state": "ME", + "postal_code": "88250", + "phone": "(309) 634-1120", + "account_credit": 46.52 + }, + { + "id": "182", + "name": "Shad Campbell", + "registered_at": "Mon, 20 Oct 2014 11:03:44 -0700", + "address": "8296 Eu, Road", + "city": "Chesapeake", + "state": "VA", + "postal_code": "59563", + "phone": "(109) 812-1478", + "account_credit": 34.45 + }, + { + "id": "183", + "name": "Nomlanga Pugh", + "registered_at": "Sat, 11 Oct 2014 11:44:45 -0700", + "address": "Ap #948-7387 Euismod Street", + "city": "Fort Worth", + "state": "TX", + "postal_code": "54834", + "phone": "(603) 124-9087", + "account_credit": 59.54 + }, + { + "id": "184", + "name": "Damian Nixon", + "registered_at": "Thu, 11 Sep 2014 03:34:13 -0700", + "address": "386-6885 Velit. Rd.", + "city": "Minneapolis", + "state": "MN", + "postal_code": "34740", + "phone": "(996) 763-0457", + "account_credit": 53.6 + }, + { + "id": "185", + "name": "Azalia Bennett", + "registered_at": "Sat, 25 Jan 2014 03:12:08 -0800", + "address": "498-9892 Vehicula Ave", + "city": "Portland", + "state": "ME", + "postal_code": "12829", + "phone": "(233) 218-0724", + "account_credit": 94.45 + }, + { + "id": "186", + "name": "Tyler Sweet", + "registered_at": "Fri, 14 Mar 2014 11:46:41 -0700", + "address": "Ap #558-5634 Semper Rd.", + "city": "Paradise", + "state": "Nevada", + "postal_code": "10272", + "phone": "(401) 227-4119", + "account_credit": 58.12 + }, + { + "id": "187", + "name": "Kyla Sears", + "registered_at": "Sat, 01 Nov 2014 06:22:29 -0700", + "address": "P.O. Box 522, 2866 Lectus St.", + "city": "Casper", + "state": "Wyoming", + "postal_code": "77130", + "phone": "(926) 988-6271", + "account_credit": 40.39 + }, + { + "id": "188", + "name": "Kiona Wagner", + "registered_at": "Wed, 02 Jul 2014 06:16:58 -0700", + "address": "173 Tristique Road", + "city": "Aurora", + "state": "Colorado", + "postal_code": "20338", + "phone": "(976) 299-0296", + "account_credit": 95.61 + }, + { + "id": "189", + "name": "Celeste Hernandez", + "registered_at": "Fri, 13 Jun 2014 03:43:17 -0700", + "address": "4405 Cursus Av.", + "city": "Ketchikan", + "state": "AK", + "postal_code": "99982", + "phone": "(637) 226-8697", + "account_credit": 87.37 + }, + { + "id": "190", + "name": "Stuart Stevenson", + "registered_at": "Sun, 28 Jun 2015 16:34:34 -0700", + "address": "P.O. Box 244, 3411 Urna Road", + "city": "Paradise", + "state": "Nevada", + "postal_code": "54968", + "phone": "(884) 752-9559", + "account_credit": 99.54 + }, + { + "id": "191", + "name": "Yael Potter", + "registered_at": "Thu, 25 Dec 2014 10:43:46 -0800", + "address": "P.O. Box 802, 4280 Tellus. Av.", + "city": "Augusta", + "state": "GA", + "postal_code": "94978", + "phone": "(838) 450-7880", + "account_credit": 89.08 + }, + { + "id": "192", + "name": "Sarah Price", + "registered_at": "Thu, 20 Nov 2014 05:28:59 -0800", + "address": "P.O. Box 695, 4792 Sagittis. Street", + "city": "Jefferson City", + "state": "Missouri", + "postal_code": "68837", + "phone": "(694) 232-5802", + "account_credit": 65.06 + }, + { + "id": "193", + "name": "Keane Schroeder", + "registered_at": "Thu, 26 Mar 2015 19:51:39 -0700", + "address": "3750 Ultrices. St.", + "city": "Wichita", + "state": "KS", + "postal_code": "32895", + "phone": "(771) 777-3480", + "account_credit": 55.08 + }, + { + "id": "194", + "name": "Gloria Cabrera", + "registered_at": "Mon, 17 Feb 2014 11:59:32 -0800", + "address": "Ap #918-2687 Arcu Avenue", + "city": "Reading", + "state": "PA", + "postal_code": "20080", + "phone": "(872) 752-3660", + "account_credit": 37.86 + }, + { + "id": "195", + "name": "Audra Beck", + "registered_at": "Fri, 23 Jan 2015 20:42:53 -0800", + "address": "311-6634 Et St.", + "city": "Bellevue", + "state": "WA", + "postal_code": "81533", + "phone": "(473) 949-2594", + "account_credit": 30.33 + }, + { + "id": "196", + "name": "Dolan Newton", + "registered_at": "Wed, 15 Jan 2014 14:08:05 -0800", + "address": "P.O. Box 588, 3911 Proin Road", + "city": "Auburn", + "state": "ME", + "postal_code": "19968", + "phone": "(214) 790-1643", + "account_credit": 58.03 + }, + { + "id": "197", + "name": "Jolie Ashley", + "registered_at": "Sat, 24 May 2014 19:19:57 -0700", + "address": "901-461 Pharetra St.", + "city": "Jefferson City", + "state": "MO", + "postal_code": "76963", + "phone": "(157) 795-0499", + "account_credit": 50.3 + }, + { + "id": "198", + "name": "Judith Ewing", + "registered_at": "Sun, 06 Apr 2014 15:46:40 -0700", + "address": "P.O. Box 666, 7743 Mauris Road", + "city": "Knoxville", + "state": "TN", + "postal_code": "47671", + "phone": "(200) 706-8284", + "account_credit": 13.91 + }, + { + "id": "199", + "name": "Scarlett Rojas", + "registered_at": "Fri, 06 Feb 2015 11:31:26 -0800", + "address": "P.O. Box 161, 9318 Non, Ave", + "city": "Boise", + "state": "Idaho", + "postal_code": "81837", + "phone": "(669) 244-0896", + "account_credit": 27.69 + }, + { + "id": "200", + "name": "Kane Johnston", + "registered_at": "Fri, 22 May 2015 09:56:42 -0700", + "address": "P.O. Box 940, 1583 At, Street", + "city": "Austin", + "state": "Texas", + "postal_code": "94282", + "phone": "(270) 219-2853", + "account_credit": 62.7 + } +] diff --git a/utils/movies.json b/utils/movies.json new file mode 100644 index 0000000..c11f516 --- /dev/null +++ b/utils/movies.json @@ -0,0 +1,602 @@ +[ + { + "title": "Psycho", + "overview": "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower.", + "release_date": "1960-06-16", + "inventory": 8 + }, + { + "title": "Jaws", + "overview": "An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.", + "release_date": "1975-06-19", + "inventory": 6 + }, + { + "title": "The Exorcist", + "overview": "12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.", + "release_date": "1973-12-26", + "inventory": 7 + }, + { + "title": "North by Northwest", + "overview": "Madison Avenue advertising man Roger Thornhill finds himself thrust into the world of spies when he is mistaken for a man by the name of George Kaplan. Foreign spy Philip Vandamm and his henchman Leonard try to eliminate him but when Thornhill tries to make sense of the case, he is framed for murder. Now on the run from the police, he manages to board the 20th Century Limited bound for Chicago where he meets a beautiful blond, Eve Kendall, who helps him to evade the authorities. His world is turned upside down yet again when he learns that Eve isn't the innocent bystander he thought she was. Not all is as it seems however, leading to a dramatic rescue and escape at the top of Mt. Rushmore.", + "release_date": "1959-07-17", + "inventory": 10 + }, + { + "title": "The Silence of the Lambs", + "overview": "FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.", + "release_date": "1991-02-14", + "inventory": 3 + }, + { + "title": "Alien", + "overview": "During its return to the earth, commercial spaceship Nostromo intercepts a distress signal from a distant planet. When a three-member team of the crew discovers a chamber containing thousands of eggs on the planet, a creature inside one of the eggs attacks an explorer. The entire crew is unaware of the impending nightmare set to descend upon them when the alien parasite planted inside its unfortunate host is birthed.", + "release_date": "1979-05-25", + "inventory": 4 + }, + { + "title": "The Birds", + "overview": "Chic socialite Melanie Daniels enjoys a passing flirtation with an eligible attorney in a San Francisco pet shop and, on an impulse, follows him to his hometown bearing a gift of lovebirds. But upon her arrival, the bird population runs amok. Suddenly, the townsfolk face a massive avian onslaught, with the feathered fiends inexplicably attacking people all over Bodega Bay.", + "release_date": "1963-03-28", + "inventory": 1 + }, + { + "title": "The French Connection", + "overview": "A pair of NYC cops in the Narcotics Bureau stumble onto a drug smuggling job with a French connection.", + "release_date": "1971-10-07", + "inventory": 8 + }, + { + "title": "Rosemary's Baby", + "overview": "A young couple moves into an infamous New York apartment building to start a family. Things become frightening as Rosemary begins to suspect her unborn baby isn't safe around their strange neighbors.", + "release_date": "1968-06-12", + "inventory": 2 + }, + { + "title": "Raiders of the Lost Ark", + "overview": "When Dr. Indiana Jones – the tweed-suited professor who just happens to be a celebrated archaeologist – is hired by the government to locate the legendary Ark of the Covenant, he finds himself up against the entire Nazi regime.", + "release_date": "1981-06-12", + "inventory": 9 + }, + { + "title": "The Godfather", + "overview": "The story spans the years from 1945 to 1955 and chronicles the fictional Italian-American Corleone crime family. When organized crime family patriarch Vito Corleone barely survives an attempt on his life, his youngest son, Michael, steps in to take care of the would-be killers, launching a campaign of bloody revenge.", + "release_date": "1972-03-15", + "inventory": 5 + }, + { + "title": "King Kong", + "overview": "An adventure film about a film crew in search of a monster on a remote island. The crew finds King Kong and decides to take him back to New York as a money making spectacle. The film is a masterpiece of Stop-Motion in filmmaking history and inspired a line of King Kong films.", + "release_date": "1933-03-02", + "inventory": 10 + }, + { + "title": "Bonnie and Clyde", + "overview": "Bonnie and Clyde is based on the true stories of the gangster pair Bonnie Parker and Clyde Barrow who in the 1930s began robbing banks in U.S. cities until they were eventually killed. The film is a major landmark in the aesthetic movement known as the New Hollywood.", + "release_date": "1967-08-04", + "inventory": 4 + }, + { + "title": "Rear Window", + "overview": "Professional photographer L.B. \"Jeff\" Jeffries breaks his leg while getting an action shot at an auto race. Confined to his New York apartment, he spends his time looking out of the rear window observing the neighbors. He begins to suspect that a man across the courtyard may have murdered his wife. Jeff enlists the help of his high society fashion-consultant girlfriend Lisa Freemont and his visiting nurse Stella to investigate.", + "release_date": "1954-08-01", + "inventory": 10 + }, + { + "title": "Deliverance", + "overview": "The Cahulawassee River valley in Northern Georgia is one of the last natural pristine areas of the state, which will soon change with the imminent building of a dam on the river, which in turn will flood much of the surrounding land. As such, four Atlanta city slickers - alpha male Lewis Medlock, generally even-keeled Ed Gentry, slightly condescending Bobby Trippe, and wide-eyed Drew Ballinger - decide to take a multi-day canoe trip on the river, which turns into a trip they'll never forget into the dangerous American back-country.", + "release_date": "1972-07-30", + "inventory": 2 + }, + { + "title": "Chinatown", + "overview": "Private eye Jake Gittes lives off the murky moral climate of sunbaked, pre-World War II Southern California. Hired by a beautiful socialite to investigate her husband's extra-marital affair, Gittes is swept into a maelstrom of double dealings and deadly deceits, uncovering a web of personal and political scandals that come crashing together.", + "release_date": "1974-06-20", + "inventory": 6 + }, + { + "title": "The Manchurian Candidate", + "overview": "The Manchurian Candidate is a political thriller from American director John Frankenheimer. An American soldier is brainwashed into being a killer for the communist Russians during the Korean War.", + "release_date": "1962-10-24", + "inventory": 1 + }, + { + "title": "Vertigo", + "overview": "A retired San Francisco detective suffering from acrophobia investigates the strange activities of an old friend's wife, all the while becoming dangerously obsessed with her.", + "release_date": "1958-05-28", + "inventory": 10 + }, + { + "title": "The Great Escape", + "overview": "The Nazis, exasperated at the number of escapes from their prison camps by a relatively small number of Allied prisoners, relocates them to a high-security \"escape-proof\" camp to sit out the remainder of the war. Undaunted, the prisoners plan one of the most ambitious escape attempts of World War II. Based on a true story.", + "release_date": "1963-07-04", + "inventory": 4 + }, + { + "title": "High Noon", + "overview": "High Noon is about a recently freed leader of a gang of bandits in the desert who is looking to get revenge on the Sheriff who put him in jail. A legendary western film from the Austrian director Fred Zinnemann.", + "release_date": "1952-07-24", + "inventory": 4 + }, + { + "title": "A Clockwork Orange", + "overview": "The head of a gang of toughs, in an insensitive futuristic society, is conditioned to become physically ill at sex and violence during a prison sentence. When he is released, he's brutally beaten by all of his old adversaries.", + "release_date": "1971-12-18", + "inventory": 4 + }, + { + "title": "Taxi Driver", + "overview": "Robert De Niro stars as Travis Bickle in this oppressive psychodrama about a Vietnam veteran who rebels against the decadence and immorality of big city life in New York while working the nightshift as a taxi driver.", + "release_date": "1976-02-08", + "inventory": 4 + }, + { + "title": "Lawrence of Arabia", + "overview": "Lawrence of Arabia is the classic film from David Lean starring Peter O’Toole and based on the autobiography from Thomas Edward Lawrence who during the first World War was on assignment by the British Empire in Arabia. The film would become a cult classic and is known today as a masterpiece.", + "release_date": "1962-12-10", + "inventory": 6 + }, + { + "title": "Double Indemnity", + "overview": "Unsuspecting Mr. Dietrichson becomes increasingly accident prone after his icily calculating wife encourages him to sign a double indemnity policy proposed by a smooth-talking insurance agent. Against a backdrop of distinctly California settings, the partners in crime plan the perfect murder to collect the insurance. Perfect until a claims manager gets a familiar feeling of foul play and pursues the matter relentlessly.", + "release_date": "1944-04-24", + "inventory": 5 + }, + { + "title": "Titanic", + "overview": "84 years later, a 101-year-old woman named Rose DeWitt Bukater tells the story to her granddaughter Lizzy Calvert, Brock Lovett, Lewis Bodine, Bobby Buell and Anatoly Mikailavich on the Keldysh about her life set in April 10th 1912, on a ship called Titanic when young Rose boards the departing ship with the upper-class passengers and her mother, Ruth DeWitt Bukater, and her fiancé, Caledon Hockley. Meanwhile, a drifter and artist named Jack Dawson and his best friend Fabrizio De Rossi win third-class tickets to the ship in a game. And she explains the whole story from departure until the death of Titanic on its first and last voyage April 15th, 1912 at 2:20 in the morning.", + "release_date": "1997-12-19", + "inventory": 5 + }, + { + "title": "The Maltese Falcon", + "overview": "Spade and Archer is the name of a San Francisco detective agency. That's for Sam Spade and Miles Archer. The two men are partners, but Sam doesn't like Miles much. A knockout, who goes by the name of Miss Wanderly, walks into their office; and by that night everything's changed. Miles is dead. And so is a man named Floyd Thursby. It seems Miss Wanderly is surrounded by dangerous men. There's Joel Cairo, who uses gardenia-scented calling cards. There's Kasper Gutman, with his enormous girth and feigned civility. Her only hope of protection comes from Sam, who is suspected by the police of one or the other murder. More murders are yet to come.", + "release_date": "1941-11-18", + "inventory": 2 + }, + { + "title": "Star Wars: Episode IV - A New Hope", + "overview": "Princess Leia is captured and held hostage by the evil Imperial forces in their effort to take over the galactic Empire. Venturesome Luke Skywalker and dashing captain Han Solo team together with the loveable robot duo R2-D2 and C-3PO to rescue the beautiful princess and restore peace and justice in the Empire.", + "release_date": "1977-05-25", + "inventory": 2 + }, + { + "title": "Fatal Attraction", + "overview": "A married man's one night stand comes back to haunt him when that lover begins to stalk him and his family.", + "release_date": "1987-09-11", + "inventory": 8 + }, + { + "title": "The Shining", + "overview": "Jack Torrance accepts a caretaker job at the Overlook Hotel, where he, along with his wife Wendy and their son Danny, must live isolated from the rest of the world for the winter. But they aren't prepared for the madness that lurks within.", + "release_date": "1980-05-22", + "inventory": 3 + }, + { + "title": "The Deer Hunter", + "overview": "A group of working-class friends decides to enlist in the Army during the Vietnam War and finds it to be hellish chaos -- not the noble venture they imagined. Before they left, Steven married his pregnant girlfriend -- and Michael and Nick were in love with the same woman. But all three are different men upon their return.", + "release_date": "1978-12-08", + "inventory": 4 + }, + { + "title": "Close Encounters of the Third Kind", + "overview": "After an encounter with UFOs, a line worker feels undeniably drawn to an isolated area in the wilderness where something spectacular is about to happen.", + "release_date": "1977-11-16", + "inventory": 3 + }, + { + "title": "Strangers on a Train", + "overview": "A psychotic socialite confronts a pro tennis star with a theory on how two complete strangers can get away with murder...a theory that he plans to implement.", + "release_date": "1951-06-30", + "inventory": 9 + }, + { + "title": "The Fugitive", + "overview": "Dr. Richard Kimble, unjustly accused of murdering his wife, must find the real killer while being the target of a nationwide manhunt.", + "release_date": "1993-08-06", + "inventory": 9 + }, + { + "title": "The Night of the Hunter", + "overview": "Harry Powell marries and murders widows for their money, believing he is helping God do away with women who arouse men's carnal instincts. Arrested for auto theft, he shares a cell with condemned killer Ben Harper and tries to get him to reveal the whereabouts of the $10,000 he stole. Only Ben's nine-year-old son, John, and four-year-old daughter, Pearl, know the money is in Pearl's doll; and they have sworn to their father to keep this secret. After Ben is executed, Preacher goes to Cresap's Landing to court Ben's widow, Willa. When he overwhelms her with his Scripture quoting, sermons, and hymns, she agrees to marry him. On their wedding night, he tells her they will never have sex because it is sinful.", + "release_date": "1955-07-26", + "inventory": 9 + }, + { + "title": "Jurassic Park", + "overview": "A wealthy entrepreneur secretly creates a theme park featuring living dinosaurs drawn from prehistoric DNA. Before opening day, he invites a team of experts and his two eager grandchildren to experience the park and help calm anxious investors. However, the park is anything but amusing as the security systems go off-line and the dinosaurs escape.", + "release_date": "1993-06-08", + "inventory": 4 + }, + { + "title": "Bullitt", + "overview": "Bullitt is an American action thriller from director Peter Yates from 1968. Steven Mcqueen plays the leading role as a mafia-chasing police officer who must protect a valuable witness. The film’s ten minute high speed pursuit is legendary.", + "release_date": "1968-10-17", + "inventory": 8 + }, + { + "title": "Casablanca", + "overview": "Casablanca is a classic and one of the most revered films of all time. Starring Humphrey Bogart and Ingrid Bergman in a love triangle in the city of Casablanca which is a refuge for many fleeing foreigners looking for a new life during the war. Political romance with a backdrop of war conflict between democracy and totalitarianism. A landmark in film history.", + "release_date": "1942-11-26", + "inventory": 8 + }, + { + "title": "Notorious", + "overview": "Released shortly after the war, this classic Hitchcock film illustrates the battle between German Nazis and American spies in Rio de Janeiro where a German businessman keeps a wine cellar with uranium ore.", + "release_date": "1946-08-15", + "inventory": 1 + }, + { + "title": "Die Hard", + "overview": "NYPD cop John McClane's plan to reconcile with his estranged wife, Holly, is thrown for a serious loop when minutes after he arrives at her office, the entire building is overtaken by a group of pitiless terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down.", + "release_date": "1988-07-14", + "inventory": 4 + }, + { + "title": "2001: A Space Odyssey", + "overview": "Humanity finds a mysterious object buried beneath the lunar surface and sets off to find its origins with the help of HAL 9000, the world's most advanced super computer.", + "release_date": "1968-04-05", + "inventory": 7 + }, + { + "title": "Dirty Harry", + "overview": "When a madman dubbed the \"Scorpio Killer\" terrorizes San Francisco, hard-boiled cop Harry Callahan -- famous for his take-no-prisoners approach to law enforcement -- is tasked with hunting down the psychopath. Harry eventually collars Scorpio in the process of rescuing a kidnap victim, only to see him walk on technicalities. Now, the maverick detective is determined to nail the maniac himself.", + "release_date": "1971-12-22", + "inventory": 4 + }, + { + "title": "The Terminator", + "overview": "In the post-apocalyptic future, reigning tyrannical supercomputers teleport a cyborg assassin known as the \"Terminator\" back to 1984 to kill Sarah Connor, whose unborn son is destined to lead insurgents against 21st century mechanical hegemony. Meanwhile, the human-resistance movement dispatches a lone warrior to safeguard Sarah. Can he stop the virtually indestructible killing machine?", + "release_date": "1984-10-26", + "inventory": 7 + }, + { + "title": "The Wizard of Oz", + "overview": "One of the most famous musical films and the first film from Hollywood to use color. Young Dorothy finds herself in a magical world where she makes friends with a lion, a scarecrow and a tin man as they make their way along the yellow brick road to talk with the Wizard and ask for the things they miss most in their lives. The Wicked Witch of the West is the only thing that could stop them.", + "release_date": "1939-08-25", + "inventory": 1 + }, + { + "title": "E.T. the Extra-Terrestrial", + "overview": "A science fiction fairytale about an extra-terrestrial who is left behind on Earth and is found by a young boy who befriends him. This heart-warming fantasy from Director Steven Spielberg became one of the most commercially successful films of all time.", + "release_date": "1982-06-11", + "inventory": 2 + }, + { + "title": "Saving Private Ryan", + "overview": "As U.S. troops storm the beaches of Normandy, three brothers lie dead on the battlefield, with a fourth trapped behind enemy lines. Ranger captain John Miller and seven men are tasked with penetrating German-held territory and bringing the boy home.", + "release_date": "1998-07-24", + "inventory": 2 + }, + { + "title": "Carrie", + "overview": "Carrie may be ostracized, but the shy teen has the ability to move objects with her mind. So when the high school \"in crowd\" torments her with a sick joke at the prom, she lashes out with devastating -- and deadly -- power.", + "release_date": "1976-11-03", + "inventory": 3 + }, + { + "title": "Invasion of the Body Snatchers", + "overview": "A small-town doctor learns that the population of his community is being replaced by emotionless alien duplicates.", + "release_date": "1956-02-05", + "inventory": 1 + }, + { + "title": "Dial M for Murder", + "overview": "An ex-tennis pro carries out a plot to have his wife murdered after discovering she is having an affair, and assumes she will soon leave him for the other man anyway. When things go wrong, he improvises a new plan - to frame her for murder instead.", + "release_date": "1954-05-29", + "inventory": 6 + }, + { + "title": "Ben-Hur", + "overview": "Ben-Hur is a 1959 epic film directed by William Wyler, the third film version of Lew Wallace's 1880 novel Ben-Hur: A Tale of the Christ. It premiered at Loew's State Theatre in New York City on November 18, 1959. The film went on to win a record of eleven Academy Awards, including Best Picture, a feat equaled only by Titanic in 1998 and The Lord of the Rings: The Return of the King in 2004. It was also the last film to win the Oscar for both Best Actor and Best Supporting Actor, until nearly 44 years later when Mystic River achieved the same feat.The movie revolves around a Jewish prince who is betrayed and sent into slavery by a Roman friend and how he regains his freedom and comes back for revenge.", + "release_date": "1959-11-18", + "inventory": 5 + }, + { + "title": "Marathon Man", + "overview": "A graduate student and obsessive runner in New York is drawn into a mysterious plot involving his brother, a member of the secretive Division. This film, famous for its excruciating \"Is it safe?\" torture scene by a Nazi dentist, is a spy classic with an all star cast.", + "release_date": "1976-10-06", + "inventory": 1 + }, + { + "title": "Raging Bull", + "overview": "An emotionally self-destructive boxer's journey through life, as the violence and temper that leads him to the top in the ring, destroys his life outside it.", + "release_date": "1980-11-14", + "inventory": 2 + }, + { + "title": "Rocky", + "overview": "When world heavyweight boxing champ Apollo Creed wants to give an unknown fighter a shot at the title as a publicity stunt, his handlers pick palooka Rocky Balboa, an uneducated collector for a Philadelphia loan shark.", + "release_date": "1976-11-21", + "inventory": 10 + }, + { + "title": "Pulp Fiction", + "overview": "A burger-loving hit man, his philosophical partner, a drug-addled gangster's moll and a washed-up boxer converge in this sprawling, comedic crime caper. Their adventures unfurl in three stories that ingeniously trip back and forth in time.", + "release_date": "1994-10-14", + "inventory": 10 + }, + { + "title": "Butch Cassidy and the Sundance Kid", + "overview": "In late 1890s Wyoming, Butch Cassidy is the affable, clever, talkative leader of the outlaw Hole in the Wall Gang. His closest companion is the laconic dead-shot \"Sundance Kid\". As the west rapidly becomes civilized, the law finally catches up to Butch, Sundance and their gang. Chased doggedly by a special posse, the two decide to make their way to South America in hopes of evading their pursuers once and for all.", + "release_date": "1969-09-23", + "inventory": 5 + }, + { + "title": "Wait Until Dark", + "overview": "After a flight back home, Sam Hendrix returns with a doll he innocently acquired along the way. As it turns out, the doll is actually stuffed with heroin, and a group of criminals led by the ruthless Roat has followed Hendrix back to his place to retrieve it. When Hendrix leaves for business, the crooks make their move -- and find his blind wife, Susy, alone in the apartment. Soon, a life-threatening game begins between Susy and the thugs.", + "release_date": "1967-10-26", + "inventory": 6 + }, + { + "title": "Frankenstein", + "overview": "Henry Frankenstein is a doctor who is trying to discover a way to make the dead walk. He succeeds and creates a monster that has to deal with living again.", + "release_date": "1931-11-21", + "inventory": 8 + }, + { + "title": "All the President's Men", + "overview": "In the run-up to the 1972 elections, Washington Post reporter Bob Woodward covers what seems to be a minor break-in at the Democratic Party National headquarters. He is surprised to find top lawyers already on the defense case, and the discovery of names and addresses of Republican fund organizers on the accused further arouses his suspicions. The editor of the Post is prepared to run with the story and assigns Woodward and Carl Bernstein to it. They find the trail leading higher and higher in the Republican Party, and eventually into the White House itself.", + "release_date": "1976-04-04", + "inventory": 4 + }, + { + "title": "The Bridge on the River Kwai", + "overview": "A classic story of English POWs in Burma forced to build a bridge to aid the war effort of their Japanese captors. British and American intelligence officers conspire to blow up the structure, but Col. Nicholson , the commander who supervised the bridge's construction, has acquired a sense of pride in his creation and tries to foil their plans.", + "release_date": "1957-10-02", + "inventory": 9 + }, + { + "title": "Planet of the Apes", + "overview": "Taylor and two other astronauts come out of deep hibernation to find that their ship has crashed. Escaping with little more than clothes they find that they have landed on a planet where men are pre-lingual and uncivilized while apes have learned speech and technology. Taylor is captured and taken to the city of the apes after damaging his throat so that he is silent and cannot communicate with the apes.", + "release_date": "1968-02-07", + "inventory": 10 + }, + { + "title": "The Sixth Sense", + "overview": "A psychological thriller about an eight year old boy named Cole Sear who believes he can see into the world of the dead. A child psychologist named Malcolm Crowe comes to Cole to help him deal with his problem, learning that he really can see ghosts of dead people.", + "release_date": "1999-08-02", + "inventory": 6 + }, + { + "title": "Cape Fear", + "overview": "Sam Bowden, witnesses a rape committed by Max Cady and testifies against him. When released after 8 years in prison, Cady stalks Bowden and his family but is always clever enough not to violate the law. Bowden enlists the aid of a local police chief, a private detective and then hires thugs to harass Cady all to no avail. The film climaxes pitting Bowden and his family against Cady.", + "release_date": "1962-04-12", + "inventory": 3 + }, + { + "title": "Spartacus", + "overview": "Spartacus is a 1960 American historical drama film directed by Stanley Kubrick and based on the novel of the same name by Howard Fast about the historical life of Spartacus and the Third Servile War. The film stars Kirk Douglas as the rebellious slave Spartacus who leads a violent revolt against the decadent Roman empire. The film was awarded four Oscars and stands today as one of the greatest classics of the Sword and Sandal genre.", + "release_date": "1960-10-06", + "inventory": 4 + }, + { + "title": "What Ever Happened to Baby Jane?", + "overview": "Two aging film actresses live as virtual recluses in an old Hollywood mansion. Jane Hudson, a successful child star, cares for her crippled sister Blanche, whose career in later years eclipsed that of Jane. Now the two live together, their relationship affected by simmering subconscious thoughts of mutual envy, hate and revenge.", + "release_date": "1962-10-31", + "inventory": 7 + }, + { + "title": "Touch of Evil", + "overview": "Stark, perverse story of murder, kidnapping, and police corruption in Mexican border town.", + "release_date": "1958-04-23", + "inventory": 5 + }, + { + "title": "The Dirty Dozen", + "overview": "Classic World War II action drama about a group of 12 American military prisoners, who are ordered to infiltrate a well-guarded enemy château and kill the Nazi officers vacationing there. The soldiers, most of whom are facing death sentences for a variety of violent crimes, agree to the mission and the possible commuting of their sentences.", + "release_date": "1967-06-15", + "inventory": 10 + }, + { + "title": "The Matrix", + "overview": "Thomas A. Anderson is a man living two lives. By day he is an average computer programmer and by night a malevolent hacker known as Neo, who finds himself targeted by the police when he is contacted by Morpheus, a legendary computer hacker, who reveals the shocking truth about our reality.", + "release_date": "1999-03-30", + "inventory": 1 + }, + { + "title": "The Treasure of the Sierra Madre", + "overview": "Fred C. Dobbs and Bob Curtin, both down on their luck in Tampico, Mexico in 1925, meet up with a grizzled prospector named Howard and decide to join with him in search of gold in the wilds of central Mexico. Through enormous difficulties, they eventually succeed in finding gold, but bandits, the elements, and most especially greed threaten to turn their success into disaster.", + "release_date": "1948-01-24", + "inventory": 4 + }, + { + "title": "Halloween", + "overview": "A psychotic murderer institutionalized since childhood for the murder of his sister, escapes and stalks a bookish teenage girl and her friends while his doctor chases him through the streets.", + "release_date": "1978-10-25", + "inventory": 4 + }, + { + "title": "The Wild Bunch", + "overview": "Aging outlaw Pike Bishop (William Holden) prepares to retire after one final robbery. Joined by his gang, which includes Dutch Engstrom (Ernest Borgnine) and brothers Lyle (Warren Oates) and Tector Gorch (Ben Johnson), Bishop discovers the heist is a setup orchestrated in part by his old partner, Deke Thornton (Robert Ryan). As the remaining gang takes refuge in Mexican territory, Thornton trails them, resulting in fierce gunfights with plenty of casualties", + "release_date": "1969-06-17", + "inventory": 2 + }, + { + "title": "Dog Day Afternoon", + "overview": "A man robs a bank to pay for his lover's operation; it turns into a hostage situation and a media circus.", + "release_date": "1975-09-21", + "inventory": 9 + }, + { + "title": "Goldfinger", + "overview": "Bond is in Miami on holiday when M tells him to observe Auric Goldfinger. Bond steals Goldfinger's girlfriend, Jill Masterson, but after being knocked out, he awakes to find her dead and covered in gold paint. Upon returning to London, Bond is told to further investigate Goldfinger who is believed to be smuggling gold out of Britain, but warned he will be replaced if he turns the mission into a personal vendetta. After failing to befriend Goldfinger, Bond is caught spying and taken to America as a captive. Bond learns of Goldfinger's plan, codenamed Operation Grand Slam, which involves attacking Fort Knox to increase his gold riches. Can 007 find a way to stop Goldfinger despite being held prisoner? This is the third film from the legendary James Bond series starring Sean Connery as the British super agent.", + "release_date": "1964-09-17", + "inventory": 1 + }, + { + "title": "Platoon", + "overview": "Chris Taylor, a young, naive recruit in Vietnam, faces a moral crisis when confronted with the horrors of war and the duality of man.", + "release_date": "1986-12-18", + "inventory": 1 + }, + { + "title": "Laura", + "overview": "A police detective falls in love with the woman whose murder he's investigating.", + "release_date": "1944-10-11", + "inventory": 5 + }, + { + "title": "Blade Runner", + "overview": "In the smog-choked dystopian Los Angeles of 2019, blade runner Rick Deckard is called out of retirement to kill a quartet of replicants who have escaped to Earth seeking their creator for a way to extend their short life spans.", + "release_date": "1982-06-25", + "inventory": 9 + }, + { + "title": "The Third Man", + "overview": "An American pulp writer arrives in post-WWII Vienna only to find that the friend who waited for him is killed under mysterious circumstances. The ensuing mystery entangles him in his friend's involvement in the black market, with the multinational police, and with his Czech girlfriend.", + "release_date": "1949-08-31", + "inventory": 9 + }, + { + "title": "Thelma & Louise", + "overview": "Whilst on a short weekend getaway, Louise shoots a man who had tried to rape Thelma. Due to the incriminating circumstances, they make a run for it and thus a cross country chase ensues for the two fugitives. Along the way, both women rediscover the strength of their friendship and surprising aspects of their personalities and self-strengths in the trying times.", + "release_date": "1991-05-24", + "inventory": 4 + }, + { + "title": "Terminator 2: Judgment Day", + "overview": "Nearly 10 years have passed since Sarah Connor was targeted for termination by a cyborg from the future. Now her son, John, the future leader of the resistance, is the target for a newer, more deadly terminator. Once again, the resistance has managed to send a protector back to attempt to save John and his mother Sarah.", + "release_date": "1991-07-01", + "inventory": 1 + }, + { + "title": "Gaslight", + "overview": "In the late 19th century, Paula Alquist is studying music in Italy, but ends up abandoning her classes because she's fallen in love with the gallant Gregory Anton. The couple marries and moves to England to live in a home inherited by Paula from her aunt, herself a famous singer, who was mysteriously murdered in the house ten years before. Once they have moved in, Gregory, who is in reality a jewel thief and the murderer of Paula's aunt, launches a campaign of terror designed to drive his new bride insane. Though Paula is certain that she sees the house's gaslights dim every evening and that there are strange noises coming from the attic, Gregory convinces Paula that she's imagining things. Gregory's efforts to make Paula unstable are aided by an impertinent maid, Nancy. Meanwhile, a Scotland Yard inspector, Brian Cameron, becomes suspicious of Gregory and sympathetic to Paula's plight.", + "release_date": "1944-05-04", + "inventory": 8 + }, + { + "title": "The Magnificent Seven", + "overview": "The Magnificent Seven is a western film from John Sturges and a remake of the Akira Kurosawa's film The Seven Samurai from 1954.", + "release_date": "1960-10-23", + "inventory": 10 + }, + { + "title": "Rebecca", + "overview": "A self-conscious bride is tormented by the memory of her husband's dead first wife.", + "release_date": "1940-04-12", + "inventory": 3 + }, + { + "title": "The Omen", + "overview": "Immediately after their miscarriage, the US diplomat Robert Thorn adopts the newborn Damien without the knowledge of his wife. Yet what he doesn’t know is that their new son is the son of the devil. A classic horror film with Gregory Peck from 1976.", + "release_date": "1976-06-25", + "inventory": 1 + }, + { + "title": "The Day the Earth Stood Still", + "overview": "An alien and a robot land on earth after World War II and tell mankind to be peaceful or face destruction. A classic science fiction film from Robert Wise with an exceptional message.", + "release_date": "1951-09-17", + "inventory": 4 + }, + { + "title": "The Phantom of the Opera", + "overview": "A grotesquely disfigured composer known as the \"Phantom\" haunts Paris' opera house, where he's secretly grooming Christine Daae to be an opera diva. Luring her to his underground lair, the Phantom declares his love. But Christine loves Raoul de Chagny and plans to elope with him after her next performance. When the Phantom finds out, he abducts Christine, incurring the wrath of Raoul -- and a horde of rabid Parisians.", + "release_date": "1925-09-06", + "inventory": 4 + }, + { + "title": "Poltergeist", + "overview": "Craig T. Nelson stars as Steve Freeling, the main protagonist, who lives with his wife, Diane, (JoBeth Williams) and their three children, Dana (Dominique Dunne), Robbie (Oliver Robins), and Carol Anne (Heather O'Rourke), in Southern California where he sells houses for the company that built the neighborhood. It starts with just a few odd occurrences, such as broken dishes and furniture moving around by itself. However, a tree comes alive and takes Robbie through his bedroom window, and Carol Anne is abducted by ghosts. Realizing that something evil haunts his home, Steve calls in a team of parapsychologists led by Dr. Lesh (Beatrice Straight) to investigate, hoping to get Carol Anne back, so he can remove his family from the house before it's too late.", + "release_date": "1982-06-04", + "inventory": 4 + }, + { + "title": "Dracula", + "overview": "The legend of vampire Count Dracula begins here with this original 1931 Dracula film from Bela Lugosi.", + "release_date": "1931-02-12", + "inventory": 9 + }, + { + "title": "The Picture of Dorian Gray", + "overview": "Dorian Gray, wishing to remain young and handsome for eternity, essentially sells his soul so that a portrait can age instead of him. Over the course of the years, Dorian commits every sort of sin, heavily influenced by his friend Lord Henry Wotton. But as his life goes on, he slowly realises the emptiness and evil which he has succumbed to.", + "release_date": "1945-03-01", + "inventory": 8 + }, + { + "title": "The Thing from Another World", + "overview": "Scientists and American Air Force officials fend off a blood-thirsty alien organism while at a remote arctic outpost.", + "release_date": "1951-04-29", + "inventory": 10 + }, + { + "title": "12 Angry Men", + "overview": "The defense and the prosecution have rested and the jury is filing into the jury room to decide if a young Spanish-American is guilty or innocent of murdering his father. What begins as an open and shut case soon becomes a mini-drama of each of the jurors' prejudices and preconceptions about the trial, the accused, and each other.", + "release_date": "1957-04-10", + "inventory": 9 + }, + { + "title": "The Guns of Navarone", + "overview": "A team of allied saboteurs are assigned an impossible mission: infiltrate an impregnable Nazi-held island and destroy the two enormous long-range field guns that prevent the rescue of 2,000 trapped British soldiers.", + "release_date": "1961-06-22", + "inventory": 3 + }, + { + "title": "The Poseidon Adventure", + "overview": "The Poseidon Adventure was one of the first Catastrophe films and began the Disaster Film genre. Director Neame tells the story of a group of people that must fight for their lives aboard a sinking ship. Based on the novel by Paul Gallico.", + "release_date": "1972-12-12", + "inventory": 3 + }, + { + "title": "Braveheart", + "overview": "Enraged at the slaughter of Murron, his new bride and childhood love, legendary Scottish warrior William Wallace slays a platoon of the local English lord's soldiers. This leads the village to revolt and, eventually, the entire country to rise up against English rule.", + "release_date": "1995-05-24", + "inventory": 9 + }, + { + "title": "Body Heat", + "overview": "In the midst of a searing Florida heat wave, a woman convinces her lover, a small-town lawyer, to murder her rich husband.", + "release_date": "1981-08-28", + "inventory": 5 + }, + { + "title": "Night of the Living Dead", + "overview": "A group of people try to survive an attack of bloodthirsty zombies while trapped in a rural Pennsylvania farmhouse. Although not the first zombie film, Night of the Living Dead is the progenitor of the contemporary \"zombie apocalypse\" horror film, and it greatly influenced the modern pop-culture zombie archetype.", + "release_date": "1968-10-01", + "inventory": 9 + }, + { + "title": "The China Syndrome", + "overview": "While doing a series of reports on alternative energy sources, an opportunistic reporter Kimberly Wells witnesses an accident at a nuclear power plant. Wells is determined to publicise the incident but soon finds herself entangled in a sinister conspiracy to keep the full impact of the incident a secret.", + "release_date": "1979-03-16", + "inventory": 4 + }, + { + "title": "Full Metal Jacket", + "overview": "A pragmatic U.S. Marine observes the dehumanizing effects the U.S.-Vietnam War has on his fellow recruits from their brutal boot camp training to the bloody street fighting in Hue.", + "release_date": "1987-05-31", + "inventory": 3 + }, + { + "title": "Blue Velvet", + "overview": "The discovery of a severed human ear found in a field leads a young man on an investigation related to a beautiful, mysterious nightclub singer and a group of criminals who have kidnapped her child.", + "release_date": "1986-08-01", + "inventory": 7 + }, + { + "title": "Safety Last!", + "overview": "When a store clerk organizes a contest to climb the outside of a tall building, circumstances force him to make the perilous climb himself.", + "release_date": "1923-04-01", + "inventory": 6 + }, + { + "title": "Blood Simple", + "overview": "A rich but jealous man hires a private investigator to kill his cheating wife and her new man. But, when blood is involved, nothing is simple.", + "release_date": "1984-09-07", + "inventory": 4 + }, + { + "title": "Speed", + "overview": "Los Angeles SWAT cop Jack Traven is up against bomb expert Howard Payne, who's after major ransom money. First it's a rigged elevator in a very tall building. Then it's a rigged bus--if it slows, it will blow, bad enough any day, but a nightmare in LA traffic. And that's still not the end.", + "release_date": "1994-06-09", + "inventory": 10 + }, + { + "title": "The Adventures of Robin Hood", + "overview": "Robin Hood (Errol Flynn) fights nobly for justice against the evil Sir Guy of Gisbourne (Basil Rathbone) while striving to win the hand of the beautiful Maid Marian (Olivia de Havilland).", + "release_date": "1938-05-14", + "inventory": 3 + } +] From 0836ee9df412cf3a7e2dec470dff15f004c60918 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 14:18:24 -0700 Subject: [PATCH 011/189] wrote script to seed movies --- utils/seed.js | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/utils/seed.js b/utils/seed.js index e69de29..2fbf8af 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -0,0 +1,27 @@ +"use strict"; + +var sqlite3 = require('sqlite3').verbose(), + db_env = process.env.DB || 'development', + db = new sqlite3.Database('db/' + db_env + '.db'); + +var movies = require('./movies'); +var movie_statement = db.prepare( + "INSERT INTO movies(title, overview, inventory, release_date) \ + VALUES(?, ?, ?, ?);" +); + +db.serialize(function() { + // loop thru movies + for (var i = 0; i < movies.length; i++) { + var movie = movies[i]; + + // insert each one into the db + movie_statement.run( + movie.title, movie.overview, movie.inventory, movie.release_date + ); + } + + movie_statement.finalize(); +}); + +db.close(); From 988bfc095f9a7ff31bb7220e22faa24873ea28ab Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 14:18:42 -0700 Subject: [PATCH 012/189] updated db with movie data --- customers.json | 2202 --------------------------------------------- db/development.db | Bin 4096 -> 49152 bytes movies.json | 602 ------------- 3 files changed, 2804 deletions(-) delete mode 100644 customers.json delete mode 100644 movies.json diff --git a/customers.json b/customers.json deleted file mode 100644 index a615fdd..0000000 --- a/customers.json +++ /dev/null @@ -1,2202 +0,0 @@ -[ - { - "id": "1", - "name": "Shelley Rocha", - "registered_at": "Wed, 29 Apr 2015 07:54:14 -0700", - "address": "Ap #292-5216 Ipsum Rd.", - "city": "Hillsboro", - "state": "OR", - "postal_code": "24309", - "phone": "(322) 510-8695", - "account_credit": 13.15 - }, - { - "id": "2", - "name": "Curran Stout", - "registered_at": "Wed, 16 Apr 2014 21:40:20 -0700", - "address": "Ap #658-1540 Erat Rd.", - "city": "San Francisco", - "state": "California", - "postal_code": "94267", - "phone": "(908) 949-6758", - "account_credit": 35.66 - }, - { - "id": "3", - "name": "Roanna Robinson", - "registered_at": "Fri, 28 Nov 2014 13:14:08 -0800", - "address": "Ap #561-4214 Eget St.", - "city": "Harrisburg", - "state": "PA", - "postal_code": "15867", - "phone": "(323) 336-1841", - "account_credit": 50.39 - }, - { - "id": "4", - "name": "Carolyn Chandler", - "registered_at": "Fri, 04 Jul 2014 11:05:11 -0700", - "address": "133-8707 Arcu. Avenue", - "city": "Fort Wayne", - "state": "IN", - "postal_code": "73684", - "phone": "(234) 837-2886", - "account_credit": 21.79 - }, - { - "id": "5", - "name": "Aquila Riddle", - "registered_at": "Thu, 27 Aug 2015 08:17:24 -0700", - "address": "Ap #187-9582 Primis St.", - "city": "Tacoma", - "state": "WA", - "postal_code": "73251", - "phone": "(925) 161-2223", - "account_credit": 17.82 - }, - { - "id": "6", - "name": "Phyllis Russell", - "registered_at": "Wed, 02 Apr 2014 21:44:46 -0700", - "address": "746-8511 Ipsum Ave", - "city": "Boise", - "state": "Idaho", - "postal_code": "76759", - "phone": "(961) 964-5158", - "account_credit": 88.67 - }, - { - "id": "7", - "name": "Rajah Riggs", - "registered_at": "Tue, 28 Jan 2014 22:28:45 -0800", - "address": "Ap #881-3920 Malesuada Avenue", - "city": "Norman", - "state": "OK", - "postal_code": "36134", - "phone": "(540) 515-2339", - "account_credit": 30.14 - }, - { - "id": "8", - "name": "Amanda Curtis", - "registered_at": "Tue, 18 Nov 2014 00:43:15 -0800", - "address": "Ap #773-125 Nunc St.", - "city": "Iowa City", - "state": "Iowa", - "postal_code": "18538", - "phone": "(253) 271-5290", - "account_credit": 47.22 - }, - { - "id": "9", - "name": "Jacqueline Perry", - "registered_at": "Thu, 23 Jul 2015 10:18:35 -0700", - "address": "Ap #288-7228 Dis Rd.", - "city": "Anchorage", - "state": "AK", - "postal_code": "99789", - "phone": "(479) 207-8414", - "account_credit": 96.28 - }, - { - "id": "10", - "name": "Quinlan Rich", - "registered_at": "Fri, 10 Jul 2015 15:23:06 -0700", - "address": "Ap #727-9607 Nibh Avenue", - "city": "Hilo", - "state": "HI", - "postal_code": "63747", - "phone": "(521) 124-5753", - "account_credit": 68.41 - }, - { - "id": "11", - "name": "Ciara Summers", - "registered_at": "Thu, 09 Jul 2015 22:12:11 -0700", - "address": "Ap #412-1462 Molestie St.", - "city": "Grand Rapids", - "state": "Michigan", - "postal_code": "44906", - "phone": "(473) 496-4835", - "account_credit": 56.88 - }, - { - "id": "12", - "name": "Alfreda Hines", - "registered_at": "Wed, 19 Aug 2015 23:18:27 -0700", - "address": "P.O. Box 754, 627 Erat Avenue", - "city": "Anchorage", - "state": "Alaska", - "postal_code": "99915", - "phone": "(921) 910-1283", - "account_credit": 55.59 - }, - { - "id": "13", - "name": "Eugenia Roberson", - "registered_at": "Sun, 23 Feb 2014 10:19:11 -0800", - "address": "Ap #781-1953 Suspendisse Road", - "city": "Jackson", - "state": "MS", - "postal_code": "67415", - "phone": "(900) 501-6947", - "account_credit": 22.71 - }, - { - "id": "14", - "name": "Ferris Robles", - "registered_at": "Mon, 16 Mar 2015 16:45:12 -0700", - "address": "P.O. Box 344, 4911 Semper Rd.", - "city": "Independence", - "state": "Missouri", - "postal_code": "46428", - "phone": "(569) 834-1872", - "account_credit": 4.91 - }, - { - "id": "15", - "name": "Sopoline Fisher", - "registered_at": "Sun, 18 May 2014 18:25:58 -0700", - "address": "543-8042 Porttitor Avenue", - "city": "Knoxville", - "state": "TN", - "postal_code": "23142", - "phone": "(603) 919-2974", - "account_credit": 53.63 - }, - { - "id": "16", - "name": "Vivien Justice", - "registered_at": "Mon, 22 Sep 2014 16:07:07 -0700", - "address": "790-3681 Lobortis Rd.", - "city": "Sterling Heights", - "state": "MI", - "postal_code": "54505", - "phone": "(563) 349-0325", - "account_credit": 83.76 - }, - { - "id": "17", - "name": "Ginger Heath", - "registered_at": "Fri, 27 Feb 2015 03:10:39 -0800", - "address": "Ap #395-9452 Quisque St.", - "city": "Billings", - "state": "Montana", - "postal_code": "25054", - "phone": "(572) 140-2058", - "account_credit": 89.69 - }, - { - "id": "18", - "name": "Kieran Calhoun", - "registered_at": "Sun, 24 Aug 2014 03:03:45 -0700", - "address": "Ap #854-9111 Nunc, Road", - "city": "Savannah", - "state": "GA", - "postal_code": "47373", - "phone": "(909) 486-8575", - "account_credit": 61.8 - }, - { - "id": "19", - "name": "Winter Stephenson", - "registered_at": "Fri, 07 Aug 2015 08:09:11 -0700", - "address": "P.O. Box 887, 4257 Lorem Rd.", - "city": "Salt Lake City", - "state": "Utah", - "postal_code": "63684", - "phone": "(466) 617-0803", - "account_credit": 1.41 - }, - { - "id": "20", - "name": "Mallory Weaver", - "registered_at": "Sat, 12 Jul 2014 18:15:55 -0700", - "address": "7297 Tortor, Avenue", - "city": "Houston", - "state": "Texas", - "postal_code": "89807", - "phone": "(727) 342-1336", - "account_credit": 65.24 - }, - { - "id": "21", - "name": "Audra Vance", - "registered_at": "Sat, 01 Nov 2014 01:37:40 -0700", - "address": "P.O. Box 906, 9067 A Street", - "city": "Columbus", - "state": "Ohio", - "postal_code": "43007", - "phone": "(832) 502-4114", - "account_credit": 76.71 - }, - { - "id": "22", - "name": "Aladdin Fowler", - "registered_at": "Mon, 25 May 2015 02:50:55 -0700", - "address": "Ap #548-6390 Ornare Av.", - "city": "Aurora", - "state": "IL", - "postal_code": "92483", - "phone": "(201) 728-7318", - "account_credit": 90.12 - }, - { - "id": "23", - "name": "Dominique Battle", - "registered_at": "Sat, 25 Jan 2014 01:47:14 -0800", - "address": "P.O. Box 753, 5236 At Rd.", - "city": "Gaithersburg", - "state": "MD", - "postal_code": "49893", - "phone": "(385) 326-1715", - "account_credit": 88.51 - }, - { - "id": "24", - "name": "Kimberly Savage", - "registered_at": "Sat, 20 Sep 2014 02:37:33 -0700", - "address": "Ap #888-6281 Aliquam Av.", - "city": "Virginia Beach", - "state": "VA", - "postal_code": "50164", - "phone": "(285) 195-0154", - "account_credit": 41.86 - }, - { - "id": "25", - "name": "Branden Craig", - "registered_at": "Mon, 22 Sep 2014 21:05:52 -0700", - "address": "768-8145 Elit Road", - "city": "Hattiesburg", - "state": "MS", - "postal_code": "99128", - "phone": "(972) 938-4626", - "account_credit": 92.64 - }, - { - "id": "26", - "name": "Hammett Beach", - "registered_at": "Sat, 23 Aug 2014 13:57:12 -0700", - "address": "206-6384 Morbi Road", - "city": "Butte", - "state": "MT", - "postal_code": "54656", - "phone": "(833) 249-0504", - "account_credit": 60.65 - }, - { - "id": "27", - "name": "Dai Meadows", - "registered_at": "Sun, 17 Aug 2014 03:38:21 -0700", - "address": "1083 Enim, St.", - "city": "Sioux City", - "state": "IA", - "postal_code": "63549", - "phone": "(204) 993-4985", - "account_credit": 87.9 - }, - { - "id": "28", - "name": "Grady Chang", - "registered_at": "Mon, 18 May 2015 04:03:19 -0700", - "address": "8819 Nam St.", - "city": "Sacramento", - "state": "CA", - "postal_code": "90337", - "phone": "(306) 153-3636", - "account_credit": 75.94 - }, - { - "id": "29", - "name": "Cody Woodard", - "registered_at": "Tue, 24 Jun 2014 01:42:54 -0700", - "address": "P.O. Box 990, 1927 Quis Ave", - "city": "Gaithersburg", - "state": "Maryland", - "postal_code": "68459", - "phone": "(606) 363-0837", - "account_credit": 97.75 - }, - { - "id": "30", - "name": "Ulysses Whitfield", - "registered_at": "Thu, 20 Nov 2014 19:38:20 -0800", - "address": "906-7966 Adipiscing Street", - "city": "Laramie", - "state": "Wyoming", - "postal_code": "95684", - "phone": "(371) 627-1105", - "account_credit": 93.18 - }, - { - "id": "31", - "name": "Olympia Dyer", - "registered_at": "Wed, 25 Jun 2014 16:02:49 -0700", - "address": "152-525 Odio St.", - "city": "Sandy", - "state": "Utah", - "postal_code": "25061", - "phone": "(124) 172-2031", - "account_credit": 55.17 - }, - { - "id": "32", - "name": "Kristen Snyder", - "registered_at": "Fri, 13 Feb 2015 18:00:19 -0800", - "address": "P.O. Box 610, 7930 Vivamus Av.", - "city": "West Jordan", - "state": "UT", - "postal_code": "50965", - "phone": "(977) 906-9656", - "account_credit": 61.89 - }, - { - "id": "33", - "name": "Mira Stokes", - "registered_at": "Tue, 01 Apr 2014 06:42:52 -0700", - "address": "Ap #630-1483 Luctus Rd.", - "city": "Columbia", - "state": "MD", - "postal_code": "66923", - "phone": "(473) 271-3425", - "account_credit": 95.92 - }, - { - "id": "34", - "name": "Ulla Skinner", - "registered_at": "Mon, 21 Jul 2014 11:28:05 -0700", - "address": "318-7550 Placerat St.", - "city": "Colorado Springs", - "state": "Colorado", - "postal_code": "91540", - "phone": "(718) 770-3057", - "account_credit": 41.64 - }, - { - "id": "35", - "name": "Amelia Brock", - "registered_at": "Thu, 21 May 2015 09:58:26 -0700", - "address": "499-4567 Metus Av.", - "city": "Jackson", - "state": "Mississippi", - "postal_code": "19969", - "phone": "(313) 638-8556", - "account_credit": 29.1 - }, - { - "id": "36", - "name": "Dexter Frank", - "registered_at": "Sat, 01 Aug 2015 20:01:22 -0700", - "address": "P.O. Box 413, 407 Senectus St.", - "city": "Wyoming", - "state": "Wyoming", - "postal_code": "71026", - "phone": "(753) 112-2298", - "account_credit": 83.79 - }, - { - "id": "37", - "name": "Yoshi Willis", - "registered_at": "Sun, 02 Mar 2014 05:18:40 -0800", - "address": "9648 Magna Rd.", - "city": "Sioux City", - "state": "Iowa", - "postal_code": "57062", - "phone": "(592) 873-3593", - "account_credit": 56.74 - }, - { - "id": "38", - "name": "Marah Ballard", - "registered_at": "Sat, 24 Jan 2015 01:05:36 -0800", - "address": "6452 Integer Av.", - "city": "Juneau", - "state": "AK", - "postal_code": "99933", - "phone": "(482) 351-7984", - "account_credit": 68.42 - }, - { - "id": "39", - "name": "Eugenia Cherry", - "registered_at": "Wed, 15 Jul 2015 14:04:05 -0700", - "address": "P.O. Box 749, 4159 Aliquam Rd.", - "city": "Stamford", - "state": "Connecticut", - "postal_code": "29863", - "phone": "(318) 627-4305", - "account_credit": 75.71 - }, - { - "id": "40", - "name": "Porter Mclean", - "registered_at": "Mon, 27 Jan 2014 05:32:30 -0800", - "address": "Ap #450-3061 Turpis St.", - "city": "New Orleans", - "state": "Louisiana", - "postal_code": "70087", - "phone": "(764) 362-7391", - "account_credit": 44.94 - }, - { - "id": "41", - "name": "Philip Patton", - "registered_at": "Tue, 24 Jun 2014 01:28:07 -0700", - "address": "P.O. Box 210, 857 Non, Street", - "city": "Aurora", - "state": "Illinois", - "postal_code": "88138", - "phone": "(188) 787-8862", - "account_credit": 17.53 - }, - { - "id": "42", - "name": "Charlotte Turner", - "registered_at": "Mon, 26 May 2014 21:16:12 -0700", - "address": "8543 Cubilia Avenue", - "city": "Bridgeport", - "state": "CT", - "postal_code": "26116", - "phone": "(629) 711-4885", - "account_credit": 73.15 - }, - { - "id": "43", - "name": "Camden Aguirre", - "registered_at": "Fri, 17 Oct 2014 00:21:57 -0700", - "address": "P.O. Box 100, 8703 Libero Ave", - "city": "Nampa", - "state": "ID", - "postal_code": "13381", - "phone": "(277) 267-0388", - "account_credit": 76.4 - }, - { - "id": "44", - "name": "Samuel Santana", - "registered_at": "Sun, 22 Mar 2015 02:28:48 -0700", - "address": "1605 Quis St.", - "city": "Bellevue", - "state": "Washington", - "postal_code": "67560", - "phone": "(678) 717-4843", - "account_credit": 71.72 - }, - { - "id": "45", - "name": "Sheila Olsen", - "registered_at": "Wed, 18 Feb 2015 17:11:30 -0800", - "address": "2058 Tristique Av.", - "city": "Eugene", - "state": "Oregon", - "postal_code": "63846", - "phone": "(574) 608-9527", - "account_credit": 49.09 - }, - { - "id": "46", - "name": "Acton Gilliam", - "registered_at": "Thu, 26 Feb 2015 20:00:53 -0800", - "address": "Ap #508-8214 Senectus Av.", - "city": "Portland", - "state": "Oregon", - "postal_code": "62594", - "phone": "(903) 973-1984", - "account_credit": 48.64 - }, - { - "id": "47", - "name": "Carla Fox", - "registered_at": "Fri, 16 Jan 2015 21:56:04 -0800", - "address": "4092 Duis St.", - "city": "Biloxi", - "state": "MS", - "postal_code": "67389", - "phone": "(438) 573-5618", - "account_credit": 25.7 - }, - { - "id": "48", - "name": "Ursa Harrell", - "registered_at": "Fri, 21 Nov 2014 23:21:44 -0800", - "address": "8070 Nec Rd.", - "city": "Henderson", - "state": "NV", - "postal_code": "87045", - "phone": "(951) 243-9155", - "account_credit": 41.1 - }, - { - "id": "49", - "name": "Stephanie Foley", - "registered_at": "Mon, 19 May 2014 22:06:51 -0700", - "address": "6806 Volutpat. Street", - "city": "Sioux City", - "state": "IA", - "postal_code": "48520", - "phone": "(562) 674-5565", - "account_credit": 2.94 - }, - { - "id": "50", - "name": "Isabelle Riley", - "registered_at": "Thu, 24 Jul 2014 22:30:47 -0700", - "address": "365-2351 Metus. St.", - "city": "San Antonio", - "state": "Texas", - "postal_code": "42972", - "phone": "(592) 610-6185", - "account_credit": 38.76 - }, - { - "id": "51", - "name": "Olivia Guy", - "registered_at": "Wed, 14 May 2014 08:39:33 -0700", - "address": "8409 Libero Rd.", - "city": "San Francisco", - "state": "California", - "postal_code": "90775", - "phone": "(373) 139-6846", - "account_credit": 44.63 - }, - { - "id": "52", - "name": "Kenneth Rowland", - "registered_at": "Fri, 13 Jun 2014 21:21:50 -0700", - "address": "Ap #862-3617 Cursus Avenue", - "city": "Chattanooga", - "state": "TN", - "postal_code": "54509", - "phone": "(650) 912-9706", - "account_credit": 88.74 - }, - { - "id": "53", - "name": "Zorita Buchanan", - "registered_at": "Sat, 12 Jul 2014 22:22:47 -0700", - "address": "3413 Lectus Avenue", - "city": "Richmond", - "state": "Virginia", - "postal_code": "49611", - "phone": "(109) 544-5498", - "account_credit": 73.2 - }, - { - "id": "54", - "name": "Galvin Daniels", - "registered_at": "Wed, 08 Jan 2014 03:33:40 -0800", - "address": "506-7584 Adipiscing Street", - "city": "Birmingham", - "state": "Alabama", - "postal_code": "36049", - "phone": "(863) 203-7464", - "account_credit": 99.37 - }, - { - "id": "55", - "name": "Hamilton Hunter", - "registered_at": "Tue, 17 Jun 2014 12:08:25 -0700", - "address": "Ap #353-2344 Sodales Street", - "city": "Honolulu", - "state": "Hawaii", - "postal_code": "18980", - "phone": "(531) 196-0181", - "account_credit": 47.93 - }, - { - "id": "56", - "name": "Dieter Frye", - "registered_at": "Mon, 01 Sep 2014 01:11:16 -0700", - "address": "P.O. Box 572, 4852 Nec, Rd.", - "city": "Los Angeles", - "state": "California", - "postal_code": "93004", - "phone": "(843) 603-1249", - "account_credit": 0.19 - }, - { - "id": "57", - "name": "Anne Mclean", - "registered_at": "Sun, 05 Oct 2014 16:05:52 -0700", - "address": "Ap #642-6158 Convallis St.", - "city": "Lawton", - "state": "OK", - "postal_code": "34188", - "phone": "(703) 764-9176", - "account_credit": 52.81 - }, - { - "id": "58", - "name": "Gretchen Gray", - "registered_at": "Fri, 25 Jul 2014 05:15:39 -0700", - "address": "4557 Arcu Ave", - "city": "Virginia Beach", - "state": "VA", - "postal_code": "15836", - "phone": "(629) 782-2033", - "account_credit": 29.02 - }, - { - "id": "59", - "name": "Theodore Ingram", - "registered_at": "Sun, 13 Apr 2014 15:08:45 -0700", - "address": "P.O. Box 362, 9274 Nibh. St.", - "city": "Tucson", - "state": "AZ", - "postal_code": "86869", - "phone": "(227) 651-0229", - "account_credit": 55.08 - }, - { - "id": "60", - "name": "Otto Leblanc", - "registered_at": "Sun, 12 Apr 2015 00:56:48 -0700", - "address": "P.O. Box 210, 6616 Ipsum Ave", - "city": "Detroit", - "state": "Michigan", - "postal_code": "27552", - "phone": "(974) 976-6329", - "account_credit": 38.44 - }, - { - "id": "61", - "name": "Pearl Blackwell", - "registered_at": "Mon, 04 May 2015 20:38:13 -0700", - "address": "797-3332 Nam St.", - "city": "Sterling Heights", - "state": "Michigan", - "postal_code": "51429", - "phone": "(960) 110-2636", - "account_credit": 64.18 - }, - { - "id": "62", - "name": "Caesar Stanley", - "registered_at": "Fri, 31 Jul 2015 01:59:58 -0700", - "address": "Ap #295-1886 Lorem St.", - "city": "Saint Paul", - "state": "MN", - "postal_code": "10029", - "phone": "(841) 157-1769", - "account_credit": 49.14 - }, - { - "id": "63", - "name": "Rebekah Conrad", - "registered_at": "Wed, 01 Jul 2015 10:38:00 -0700", - "address": "112-656 Duis Ave", - "city": "Davenport", - "state": "IA", - "postal_code": "76937", - "phone": "(691) 802-4154", - "account_credit": 67.99 - }, - { - "id": "64", - "name": "Robert Harmon", - "registered_at": "Wed, 08 Apr 2015 21:49:26 -0700", - "address": "333-2529 Duis Road", - "city": "Kaneohe", - "state": "Hawaii", - "postal_code": "58444", - "phone": "(165) 718-1361", - "account_credit": 27.08 - }, - { - "id": "65", - "name": "Maris Puckett", - "registered_at": "Thu, 22 May 2014 19:01:18 -0700", - "address": "Ap #422-3446 A Road", - "city": "Gaithersburg", - "state": "MD", - "postal_code": "39939", - "phone": "(952) 204-5010", - "account_credit": 96.49 - }, - { - "id": "66", - "name": "Lara Ellison", - "registered_at": "Tue, 30 Sep 2014 09:34:25 -0700", - "address": "660-756 Arcu. St.", - "city": "Cedar Rapids", - "state": "Iowa", - "postal_code": "96377", - "phone": "(928) 139-4812", - "account_credit": 60.97 - }, - { - "id": "67", - "name": "Dai Baldwin", - "registered_at": "Thu, 02 Apr 2015 21:28:28 -0700", - "address": "5574 Varius Ave", - "city": "South Bend", - "state": "Indiana", - "postal_code": "27284", - "phone": "(642) 404-1198", - "account_credit": 6.51 - }, - { - "id": "68", - "name": "Mira Lyons", - "registered_at": "Tue, 18 Feb 2014 10:31:37 -0800", - "address": "P.O. Box 176, 9193 Enim Road", - "city": "Topeka", - "state": "KS", - "postal_code": "30606", - "phone": "(355) 309-3105", - "account_credit": 66.25 - }, - { - "id": "69", - "name": "Laurel Diaz", - "registered_at": "Thu, 27 Feb 2014 08:24:02 -0800", - "address": "501 Eu St.", - "city": "Fayetteville", - "state": "Arkansas", - "postal_code": "72463", - "phone": "(382) 883-9819", - "account_credit": 50.13 - }, - { - "id": "70", - "name": "Breanna Kim", - "registered_at": "Fri, 06 Feb 2015 14:42:21 -0800", - "address": "752-6391 Quis Ave", - "city": "Little Rock", - "state": "AR", - "postal_code": "71072", - "phone": "(182) 564-6516", - "account_credit": 58.31 - }, - { - "id": "71", - "name": "Hayes Levine", - "registered_at": "Wed, 13 May 2015 17:46:32 -0700", - "address": "646-9160 Ultrices St.", - "city": "Grand Island", - "state": "NE", - "postal_code": "89643", - "phone": "(624) 302-2419", - "account_credit": 77.3 - }, - { - "id": "72", - "name": "Taylor Spence", - "registered_at": "Wed, 09 Jul 2014 14:10:42 -0700", - "address": "7109 In St.", - "city": "Portland", - "state": "Oregon", - "postal_code": "91240", - "phone": "(993) 724-6663", - "account_credit": 24.11 - }, - { - "id": "73", - "name": "Camille Walton", - "registered_at": "Thu, 19 Mar 2015 01:25:46 -0700", - "address": "718-6981 Libero Road", - "city": "Boise", - "state": "Idaho", - "postal_code": "72346", - "phone": "(332) 249-7842", - "account_credit": 21.88 - }, - { - "id": "74", - "name": "Yardley Mckenzie", - "registered_at": "Mon, 22 Jun 2015 05:10:11 -0700", - "address": "8911 Justo Rd.", - "city": "Huntsville", - "state": "AL", - "postal_code": "36334", - "phone": "(731) 311-1108", - "account_credit": 95.41 - }, - { - "id": "75", - "name": "Rachel Munoz", - "registered_at": "Sun, 04 May 2014 08:20:55 -0700", - "address": "8466 Aliquam Ave", - "city": "Madison", - "state": "Wisconsin", - "postal_code": "56718", - "phone": "(651) 904-9661", - "account_credit": 80.08 - }, - { - "id": "76", - "name": "Bevis Jimenez", - "registered_at": "Sun, 11 May 2014 07:35:02 -0700", - "address": "Ap #222-2891 Magnis St.", - "city": "Columbus", - "state": "Georgia", - "postal_code": "35209", - "phone": "(526) 934-4237", - "account_credit": 25.63 - }, - { - "id": "77", - "name": "Malik Barber", - "registered_at": "Sat, 14 Feb 2015 10:24:50 -0800", - "address": "Ap #364-1684 Quam. St.", - "city": "Waterbury", - "state": "Connecticut", - "postal_code": "75696", - "phone": "(575) 915-7794", - "account_credit": 92.24 - }, - { - "id": "78", - "name": "Nell Bishop", - "registered_at": "Fri, 01 May 2015 18:59:31 -0700", - "address": "7623 Torquent Street", - "city": "Minneapolis", - "state": "MN", - "postal_code": "27078", - "phone": "(819) 107-0728", - "account_credit": 9.35 - }, - { - "id": "79", - "name": "Leigh Anderson", - "registered_at": "Tue, 22 Jul 2014 13:05:46 -0700", - "address": "Ap #149-1154 Cras Rd.", - "city": "Montgomery", - "state": "Alabama", - "postal_code": "36037", - "phone": "(176) 966-1214", - "account_credit": 86.77 - }, - { - "id": "80", - "name": "Chava Kirby", - "registered_at": "Wed, 25 Jun 2014 13:45:50 -0700", - "address": "570-6835 Ac Ave", - "city": "Allentown", - "state": "PA", - "postal_code": "84384", - "phone": "(795) 896-0405", - "account_credit": 5.45 - }, - { - "id": "81", - "name": "Inez Gamble", - "registered_at": "Mon, 09 Feb 2015 17:28:45 -0800", - "address": "471-8542 Et Ave", - "city": "Virginia Beach", - "state": "VA", - "postal_code": "23365", - "phone": "(288) 595-2741", - "account_credit": 32.92 - }, - { - "id": "82", - "name": "Jacob Villarreal", - "registered_at": "Mon, 16 Mar 2015 06:03:28 -0700", - "address": "3480 Amet, Street", - "city": "Grand Island", - "state": "NE", - "postal_code": "53804", - "phone": "(676) 686-4808", - "account_credit": 76.99 - }, - { - "id": "83", - "name": "Velma Mcfadden", - "registered_at": "Wed, 13 Aug 2014 17:48:11 -0700", - "address": "164-557 At St.", - "city": "Juneau", - "state": "AK", - "postal_code": "99806", - "phone": "(520) 661-1866", - "account_credit": 4.31 - }, - { - "id": "84", - "name": "Berk Carroll", - "registered_at": "Mon, 09 Jun 2014 07:18:28 -0700", - "address": "1640 Blandit. Rd.", - "city": "Frankfort", - "state": "Kentucky", - "postal_code": "88958", - "phone": "(937) 237-7054", - "account_credit": 55.15 - }, - { - "id": "85", - "name": "Serina Collins", - "registered_at": "Wed, 12 Aug 2015 11:48:57 -0700", - "address": "6117 Lorem, Avenue", - "city": "South Bend", - "state": "Indiana", - "postal_code": "39108", - "phone": "(216) 221-5456", - "account_credit": 55.52 - }, - { - "id": "86", - "name": "Larissa Soto", - "registered_at": "Wed, 04 Mar 2015 06:32:01 -0800", - "address": "597-5077 Purus St.", - "city": "Tampa", - "state": "Florida", - "postal_code": "19281", - "phone": "(693) 833-8618", - "account_credit": 98.77 - }, - { - "id": "87", - "name": "Erin Mckenzie", - "registered_at": "Fri, 17 Apr 2015 09:24:27 -0700", - "address": "P.O. Box 822, 6254 Etiam Rd.", - "city": "Madison", - "state": "WI", - "postal_code": "94031", - "phone": "(646) 241-7827", - "account_credit": 78.13 - }, - { - "id": "88", - "name": "Katell Lewis", - "registered_at": "Fri, 06 Jun 2014 00:36:28 -0700", - "address": "P.O. Box 794, 8686 Libero St.", - "city": "San Antonio", - "state": "TX", - "postal_code": "90724", - "phone": "(307) 332-5251", - "account_credit": 1.13 - }, - { - "id": "89", - "name": "Yeo Humphrey", - "registered_at": "Mon, 14 Jul 2014 03:21:54 -0700", - "address": "121 Porta Ave", - "city": "Bear", - "state": "DE", - "postal_code": "61381", - "phone": "(770) 120-6205", - "account_credit": 42.14 - }, - { - "id": "90", - "name": "Brynne Stuart", - "registered_at": "Tue, 16 Jun 2015 07:18:47 -0700", - "address": "778-6903 Urna Rd.", - "city": "Jonesboro", - "state": "AR", - "postal_code": "72921", - "phone": "(949) 800-1135", - "account_credit": 84.26 - }, - { - "id": "91", - "name": "Brynne Fuentes", - "registered_at": "Tue, 19 May 2015 01:36:10 -0700", - "address": "8106 Habitant Av.", - "city": "Minneapolis", - "state": "Minnesota", - "postal_code": "23965", - "phone": "(535) 656-2981", - "account_credit": 76.08 - }, - { - "id": "92", - "name": "Giacomo Strong", - "registered_at": "Sat, 13 Dec 2014 10:01:42 -0800", - "address": "1121 Vivamus Av.", - "city": "Madison", - "state": "Wisconsin", - "postal_code": "18820", - "phone": "(938) 428-0683", - "account_credit": 62.64 - }, - { - "id": "93", - "name": "Ruth Nelson", - "registered_at": "Sun, 07 Dec 2014 03:40:07 -0800", - "address": "P.O. Box 324, 7958 Rutrum Avenue", - "city": "Lewiston", - "state": "Maine", - "postal_code": "35597", - "phone": "(821) 465-3951", - "account_credit": 22.11 - }, - { - "id": "94", - "name": "Alexander Brennan", - "registered_at": "Fri, 20 Feb 2015 10:58:42 -0800", - "address": "P.O. Box 778, 9617 Sapien, Avenue", - "city": "San Antonio", - "state": "Texas", - "postal_code": "74395", - "phone": "(452) 676-2428", - "account_credit": 94.6 - }, - { - "id": "95", - "name": "Eagan Lynch", - "registered_at": "Tue, 08 Apr 2014 15:32:50 -0700", - "address": "Ap #209-5829 Gravida St.", - "city": "Dallas", - "state": "Texas", - "postal_code": "45352", - "phone": "(874) 234-9834", - "account_credit": 4.26 - }, - { - "id": "96", - "name": "Charity Buckley", - "registered_at": "Mon, 13 Jul 2015 09:05:22 -0700", - "address": "Ap #822-4239 Aliquam Rd.", - "city": "San Antonio", - "state": "Texas", - "postal_code": "48690", - "phone": "(580) 120-8164", - "account_credit": 5.49 - }, - { - "id": "97", - "name": "Aspen Le", - "registered_at": "Mon, 19 May 2014 22:41:26 -0700", - "address": "Ap #373-9486 A Ave", - "city": "Essex", - "state": "Vermont", - "postal_code": "53433", - "phone": "(179) 428-6526", - "account_credit": 27.07 - }, - { - "id": "98", - "name": "Jana Foster", - "registered_at": "Sat, 31 May 2014 16:18:00 -0700", - "address": "521-938 Odio. Rd.", - "city": "Clarksville", - "state": "TN", - "postal_code": "41791", - "phone": "(828) 240-0643", - "account_credit": 88.61 - }, - { - "id": "99", - "name": "Basia Contreras", - "registered_at": "Sat, 11 Oct 2014 06:25:54 -0700", - "address": "P.O. Box 325, 3668 Donec St.", - "city": "Independence", - "state": "Missouri", - "postal_code": "44890", - "phone": "(847) 205-9126", - "account_credit": 74.62 - }, - { - "id": "100", - "name": "Barbara Jacobson", - "registered_at": "Mon, 03 Nov 2014 07:33:03 -0800", - "address": "489-4471 Commodo Avenue", - "city": "Duluth", - "state": "Minnesota", - "postal_code": "59354", - "phone": "(823) 257-9965", - "account_credit": 12.41 - }, - { - "id": "101", - "name": "Ria Little", - "registered_at": "Wed, 01 Apr 2015 17:10:16 -0700", - "address": "P.O. Box 423, 7795 Aenean St.", - "city": "Athens", - "state": "GA", - "postal_code": "88306", - "phone": "(496) 600-9071", - "account_credit": 0.84 - }, - { - "id": "102", - "name": "Jael Hoover", - "registered_at": "Sun, 12 Apr 2015 04:10:37 -0700", - "address": "P.O. Box 817, 1753 Ac Rd.", - "city": "Seattle", - "state": "Washington", - "postal_code": "17749", - "phone": "(953) 751-2907", - "account_credit": 95.32 - }, - { - "id": "103", - "name": "Howard Meyer", - "registered_at": "Sun, 14 Dec 2014 21:19:41 -0800", - "address": "2813 Pede. Rd.", - "city": "Colchester", - "state": "Vermont", - "postal_code": "11479", - "phone": "(735) 816-9513", - "account_credit": 43.79 - }, - { - "id": "104", - "name": "Brian Yates", - "registered_at": "Mon, 10 Mar 2014 00:26:55 -0700", - "address": "2961 Integer Ave", - "city": "Kearney", - "state": "NE", - "postal_code": "49867", - "phone": "(292) 138-3176", - "account_credit": 9.51 - }, - { - "id": "105", - "name": "Amber Nicholson", - "registered_at": "Thu, 13 Feb 2014 11:15:19 -0800", - "address": "1666 Urna Ave", - "city": "Knoxville", - "state": "Tennessee", - "postal_code": "57653", - "phone": "(154) 850-1394", - "account_credit": 84.42 - }, - { - "id": "106", - "name": "Silas Barton", - "registered_at": "Fri, 06 Feb 2015 00:37:52 -0800", - "address": "Ap #441-4537 Vitae Road", - "city": "Gulfport", - "state": "MS", - "postal_code": "72241", - "phone": "(817) 405-3562", - "account_credit": 5.98 - }, - { - "id": "107", - "name": "Justina Weber", - "registered_at": "Sun, 26 Jul 2015 09:22:06 -0700", - "address": "9004 Dui Rd.", - "city": "Cleveland", - "state": "OH", - "postal_code": "35970", - "phone": "(653) 921-2923", - "account_credit": 35.95 - }, - { - "id": "108", - "name": "Raven Cote", - "registered_at": "Wed, 29 Apr 2015 09:17:30 -0700", - "address": "P.O. Box 944, 5312 Donec Street", - "city": "Savannah", - "state": "GA", - "postal_code": "56882", - "phone": "(212) 164-3612", - "account_credit": 54.27 - }, - { - "id": "109", - "name": "Ahmed Massey", - "registered_at": "Sat, 13 Sep 2014 10:01:23 -0700", - "address": "675-7569 Neque. Rd.", - "city": "Metairie", - "state": "Louisiana", - "postal_code": "74601", - "phone": "(798) 424-7871", - "account_credit": 31.59 - }, - { - "id": "110", - "name": "Thomas Mcbride", - "registered_at": "Sun, 28 Dec 2014 03:52:26 -0800", - "address": "Ap #911-5536 Proin Road", - "city": "Little Rock", - "state": "AR", - "postal_code": "71114", - "phone": "(557) 571-0355", - "account_credit": 62.9 - }, - { - "id": "111", - "name": "April Humphrey", - "registered_at": "Tue, 04 Feb 2014 14:31:31 -0800", - "address": "P.O. Box 153, 5975 Molestie Ave", - "city": "Olathe", - "state": "Kansas", - "postal_code": "84858", - "phone": "(795) 813-1088", - "account_credit": 18.44 - }, - { - "id": "112", - "name": "Sierra Rosa", - "registered_at": "Thu, 15 May 2014 12:18:28 -0700", - "address": "Ap #753-7173 Purus St.", - "city": "Knoxville", - "state": "Tennessee", - "postal_code": "86369", - "phone": "(433) 397-7483", - "account_credit": 12.75 - }, - { - "id": "113", - "name": "Sara Gay", - "registered_at": "Fri, 27 Feb 2015 08:26:18 -0800", - "address": "6311 Felis, Rd.", - "city": "Knoxville", - "state": "Tennessee", - "postal_code": "60949", - "phone": "(239) 940-6734", - "account_credit": 44.11 - }, - { - "id": "114", - "name": "Alexis Ward", - "registered_at": "Mon, 27 Apr 2015 21:02:39 -0700", - "address": "888 Feugiat Rd.", - "city": "Miami", - "state": "Florida", - "postal_code": "65771", - "phone": "(189) 124-7774", - "account_credit": 84.48 - }, - { - "id": "115", - "name": "Justina Dixon", - "registered_at": "Fri, 17 Jul 2015 03:14:57 -0700", - "address": "P.O. Box 279, 5229 Mattis Street", - "city": "Green Bay", - "state": "Wisconsin", - "postal_code": "28463", - "phone": "(488) 172-0802", - "account_credit": 48.41 - }, - { - "id": "116", - "name": "Scott Wise", - "registered_at": "Sat, 20 Dec 2014 10:18:05 -0800", - "address": "P.O. Box 237, 9683 Elit, Road", - "city": "Dover", - "state": "DE", - "postal_code": "80375", - "phone": "(744) 266-9954", - "account_credit": 11.75 - }, - { - "id": "117", - "name": "Cameran Terry", - "registered_at": "Thu, 19 Feb 2015 16:38:52 -0800", - "address": "133-7353 Eu Avenue", - "city": "Rutland", - "state": "VT", - "postal_code": "13964", - "phone": "(232) 667-7186", - "account_credit": 74.33 - }, - { - "id": "118", - "name": "Cooper Suarez", - "registered_at": "Mon, 10 Nov 2014 10:16:37 -0800", - "address": "P.O. Box 632, 4595 Nec Rd.", - "city": "Montpelier", - "state": "Vermont", - "postal_code": "21186", - "phone": "(792) 641-6482", - "account_credit": 20.07 - }, - { - "id": "119", - "name": "Karleigh Ingram", - "registered_at": "Sun, 21 Sep 2014 23:49:59 -0700", - "address": "3480 Nulla Road", - "city": "San Diego", - "state": "CA", - "postal_code": "92064", - "phone": "(819) 878-4232", - "account_credit": 7.66 - }, - { - "id": "120", - "name": "Fiona Santana", - "registered_at": "Thu, 11 Dec 2014 22:20:46 -0800", - "address": "P.O. Box 950, 8105 Gravida. Ave", - "city": "Independence", - "state": "MO", - "postal_code": "64612", - "phone": "(364) 302-8535", - "account_credit": 47.27 - }, - { - "id": "121", - "name": "Cheryl Shelton", - "registered_at": "Mon, 07 Jul 2014 08:34:34 -0700", - "address": "145-5466 Nec Rd.", - "city": "Anchorage", - "state": "AK", - "postal_code": "99971", - "phone": "(666) 421-3975", - "account_credit": 27.65 - }, - { - "id": "122", - "name": "Raya Burgess", - "registered_at": "Fri, 01 May 2015 01:45:27 -0700", - "address": "9695 Lacus. Avenue", - "city": "Owensboro", - "state": "KY", - "postal_code": "72801", - "phone": "(118) 782-5871", - "account_credit": 31.05 - }, - { - "id": "123", - "name": "Hakeem Stokes", - "registered_at": "Fri, 31 Jul 2015 07:26:43 -0700", - "address": "975-799 Sit Street", - "city": "Helena", - "state": "MT", - "postal_code": "67768", - "phone": "(285) 662-1132", - "account_credit": 60.43 - }, - { - "id": "124", - "name": "Macon Crosby", - "registered_at": "Sun, 27 Apr 2014 14:02:28 -0700", - "address": "4714 Aliquet. Road", - "city": "Hartford", - "state": "Connecticut", - "postal_code": "56565", - "phone": "(347) 348-8116", - "account_credit": 66.21 - }, - { - "id": "125", - "name": "Brittany Harris", - "registered_at": "Wed, 19 Mar 2014 05:09:44 -0700", - "address": "183-9407 A Road", - "city": "Bozeman", - "state": "MT", - "postal_code": "56384", - "phone": "(489) 746-9013", - "account_credit": 8.05 - }, - { - "id": "126", - "name": "Galena Ford", - "registered_at": "Fri, 04 Sep 2015 11:09:52 -0700", - "address": "8088 Eget Road", - "city": "Gary", - "state": "IN", - "postal_code": "25479", - "phone": "(538) 724-6020", - "account_credit": 82.15 - }, - { - "id": "127", - "name": "Nehru Smith", - "registered_at": "Sun, 04 Jan 2015 00:43:42 -0800", - "address": "317 Arcu. Avenue", - "city": "Austin", - "state": "TX", - "postal_code": "83794", - "phone": "(127) 566-2347", - "account_credit": 60.36 - }, - { - "id": "128", - "name": "Craig Higgins", - "registered_at": "Mon, 13 Jul 2015 01:16:50 -0700", - "address": "Ap #592-2711 Non, Ave", - "city": "Cambridge", - "state": "Massachusetts", - "postal_code": "50503", - "phone": "(123) 194-5906", - "account_credit": 46.3 - }, - { - "id": "129", - "name": "Ria Goodwin", - "registered_at": "Thu, 29 Jan 2015 07:14:41 -0800", - "address": "860-5993 Vivamus Road", - "city": "Augusta", - "state": "Maine", - "postal_code": "25217", - "phone": "(251) 172-1155", - "account_credit": 88 - }, - { - "id": "130", - "name": "Griffith Key", - "registered_at": "Mon, 10 Feb 2014 02:08:23 -0800", - "address": "152-5468 Ac Road", - "city": "Nampa", - "state": "Idaho", - "postal_code": "51195", - "phone": "(624) 463-6111", - "account_credit": 71.11 - }, - { - "id": "131", - "name": "Kasper Fischer", - "registered_at": "Wed, 13 May 2015 17:02:25 -0700", - "address": "6153 Sed Road", - "city": "Independence", - "state": "Missouri", - "postal_code": "91560", - "phone": "(319) 149-4379", - "account_credit": 40.96 - }, - { - "id": "132", - "name": "Stuart Goodwin", - "registered_at": "Tue, 01 Sep 2015 14:57:31 -0700", - "address": "P.O. Box 689, 2792 Quis, St.", - "city": "Augusta", - "state": "Georgia", - "postal_code": "71303", - "phone": "(538) 387-3287", - "account_credit": 88.19 - }, - { - "id": "133", - "name": "Dawn Carlson", - "registered_at": "Sat, 18 Apr 2015 07:51:41 -0700", - "address": "5366 Id Street", - "city": "Aurora", - "state": "Illinois", - "postal_code": "79365", - "phone": "(994) 905-9769", - "account_credit": 78.41 - }, - { - "id": "134", - "name": "Natalie Schroeder", - "registered_at": "Wed, 24 Jun 2015 01:04:02 -0700", - "address": "392-2462 Luctus Road", - "city": "Boston", - "state": "Massachusetts", - "postal_code": "99200", - "phone": "(891) 649-2871", - "account_credit": 95.95 - }, - { - "id": "135", - "name": "Justine Goodwin", - "registered_at": "Mon, 20 Oct 2014 22:26:35 -0700", - "address": "Ap #406-6268 Morbi Av.", - "city": "Columbus", - "state": "Ohio", - "postal_code": "85028", - "phone": "(155) 830-0119", - "account_credit": 71.42 - }, - { - "id": "136", - "name": "Wilma Velez", - "registered_at": "Sun, 06 Apr 2014 16:31:42 -0700", - "address": "4400 Aliquam Rd.", - "city": "Virginia Beach", - "state": "Virginia", - "postal_code": "36713", - "phone": "(279) 153-9870", - "account_credit": 7.6 - }, - { - "id": "137", - "name": "Chiquita Burks", - "registered_at": "Tue, 18 Feb 2014 20:20:50 -0800", - "address": "Ap #979-8936 Egestas. St.", - "city": "Dover", - "state": "DE", - "postal_code": "48328", - "phone": "(264) 440-3911", - "account_credit": 84.17 - }, - { - "id": "138", - "name": "Christian Mclaughlin", - "registered_at": "Sun, 19 Apr 2015 09:47:16 -0700", - "address": "765 Tristique Avenue", - "city": "Des Moines", - "state": "Iowa", - "postal_code": "35850", - "phone": "(962) 941-9645", - "account_credit": 8.08 - }, - { - "id": "139", - "name": "Aurelia Giles", - "registered_at": "Sun, 07 Dec 2014 21:43:39 -0800", - "address": "P.O. Box 745, 1594 Ante. Rd.", - "city": "Wyoming", - "state": "WY", - "postal_code": "51587", - "phone": "(724) 380-8095", - "account_credit": 62.69 - }, - { - "id": "140", - "name": "Josephine Browning", - "registered_at": "Fri, 12 Dec 2014 06:36:20 -0800", - "address": "459-9737 Donec Rd.", - "city": "Davenport", - "state": "Iowa", - "postal_code": "21255", - "phone": "(436) 817-2557", - "account_credit": 21.97 - }, - { - "id": "141", - "name": "Kasper Morton", - "registered_at": "Tue, 21 Oct 2014 22:31:15 -0700", - "address": "3938 Cursus. Street", - "city": "Philadelphia", - "state": "Pennsylvania", - "postal_code": "56267", - "phone": "(191) 710-5107", - "account_credit": 65.15 - }, - { - "id": "142", - "name": "Renee Higgins", - "registered_at": "Sat, 07 Jun 2014 22:19:01 -0700", - "address": "P.O. Box 523, 9963 Arcu. Road", - "city": "Newport News", - "state": "VA", - "postal_code": "25802", - "phone": "(933) 431-7021", - "account_credit": 67.97 - }, - { - "id": "143", - "name": "Brody Coleman", - "registered_at": "Sat, 22 Feb 2014 06:39:59 -0800", - "address": "Ap #269-5956 Proin Rd.", - "city": "Rutland", - "state": "Vermont", - "postal_code": "72539", - "phone": "(482) 790-5904", - "account_credit": 68.91 - }, - { - "id": "144", - "name": "Jennifer Greer", - "registered_at": "Sun, 12 Jul 2015 08:51:24 -0700", - "address": "923-7286 Dui. Rd.", - "city": "Virginia Beach", - "state": "Virginia", - "postal_code": "97476", - "phone": "(547) 641-6594", - "account_credit": 71.19 - }, - { - "id": "145", - "name": "Gannon Abbott", - "registered_at": "Wed, 24 Sep 2014 14:47:00 -0700", - "address": "Ap #754-9349 Nec Road", - "city": "Rochester", - "state": "Minnesota", - "postal_code": "22689", - "phone": "(363) 394-9351", - "account_credit": 27.97 - }, - { - "id": "146", - "name": "Adrian Nguyen", - "registered_at": "Mon, 28 Apr 2014 10:51:17 -0700", - "address": "956-1243 Libero Av.", - "city": "Fort Smith", - "state": "Arkansas", - "postal_code": "71182", - "phone": "(109) 817-4149", - "account_credit": 92.54 - }, - { - "id": "147", - "name": "Carter Morris", - "registered_at": "Mon, 08 Sep 2014 21:10:38 -0700", - "address": "P.O. Box 304, 5040 Malesuada Rd.", - "city": "Kaneohe", - "state": "Hawaii", - "postal_code": "26814", - "phone": "(450) 765-0057", - "account_credit": 81.11 - }, - { - "id": "148", - "name": "Basia Ratliff", - "registered_at": "Wed, 01 Jan 2014 19:21:29 -0800", - "address": "Ap #907-6837 Diam Ave", - "city": "Knoxville", - "state": "Tennessee", - "postal_code": "80562", - "phone": "(734) 180-1477", - "account_credit": 67.26 - }, - { - "id": "149", - "name": "Genevieve Nieves", - "registered_at": "Tue, 13 May 2014 04:26:45 -0700", - "address": "Ap #864-1195 Sit Street", - "city": "Wichita", - "state": "KS", - "postal_code": "17313", - "phone": "(660) 218-7246", - "account_credit": 38.71 - }, - { - "id": "150", - "name": "Axel Morton", - "registered_at": "Fri, 02 May 2014 02:32:29 -0700", - "address": "459-6656 Ultricies Av.", - "city": "West Jordan", - "state": "Utah", - "postal_code": "99969", - "phone": "(929) 552-4291", - "account_credit": 48.18 - }, - { - "id": "151", - "name": "Montana Wynn", - "registered_at": "Sun, 03 Aug 2014 01:01:44 -0700", - "address": "Ap #236-806 Sem, Av.", - "city": "Springfield", - "state": "Missouri", - "postal_code": "41345", - "phone": "(697) 916-8606", - "account_credit": 33.85 - }, - { - "id": "152", - "name": "Allistair Bradley", - "registered_at": "Fri, 22 May 2015 08:03:48 -0700", - "address": "P.O. Box 384, 7086 At Avenue", - "city": "Juneau", - "state": "Alaska", - "postal_code": "99972", - "phone": "(627) 610-6902", - "account_credit": 68.34 - }, - { - "id": "153", - "name": "Jacob Foley", - "registered_at": "Mon, 17 Mar 2014 17:44:22 -0700", - "address": "785-7522 Duis St.", - "city": "Little Rock", - "state": "AR", - "postal_code": "72550", - "phone": "(310) 834-5542", - "account_credit": 52.03 - }, - { - "id": "154", - "name": "Noelani Burton", - "registered_at": "Sat, 15 Mar 2014 01:00:31 -0700", - "address": "428-8345 Enim. St.", - "city": "Burlington", - "state": "VT", - "postal_code": "83655", - "phone": "(461) 724-9721", - "account_credit": 81.67 - }, - { - "id": "155", - "name": "Abigail Lara", - "registered_at": "Wed, 12 Aug 2015 03:21:43 -0700", - "address": "P.O. Box 388, 1190 Donec St.", - "city": "Shreveport", - "state": "Louisiana", - "postal_code": "41243", - "phone": "(235) 178-3417", - "account_credit": 88.56 - }, - { - "id": "156", - "name": "Driscoll Shepard", - "registered_at": "Sat, 12 Apr 2014 03:01:43 -0700", - "address": "Ap #375-2818 Ac St.", - "city": "Minneapolis", - "state": "MN", - "postal_code": "30682", - "phone": "(433) 449-9825", - "account_credit": 13.79 - }, - { - "id": "157", - "name": "Elaine Carney", - "registered_at": "Thu, 22 May 2014 07:13:57 -0700", - "address": "P.O. Box 495, 1408 Laoreet, Rd.", - "city": "Miami", - "state": "Florida", - "postal_code": "78257", - "phone": "(213) 954-9127", - "account_credit": 82.97 - }, - { - "id": "158", - "name": "Jonas Galloway", - "registered_at": "Sun, 25 Jan 2015 06:05:43 -0800", - "address": "Ap #190-5298 Ornare, Rd.", - "city": "Bloomington", - "state": "MN", - "postal_code": "86280", - "phone": "(113) 365-9867", - "account_credit": 56.1 - }, - { - "id": "159", - "name": "Abel Oneil", - "registered_at": "Sat, 19 Apr 2014 16:26:15 -0700", - "address": "P.O. Box 129, 2669 Arcu. Avenue", - "city": "Colorado Springs", - "state": "CO", - "postal_code": "52301", - "phone": "(857) 528-9424", - "account_credit": 89.69 - }, - { - "id": "160", - "name": "Maia Brock", - "registered_at": "Sat, 13 Jun 2015 04:54:46 -0700", - "address": "Ap #354-4024 Cubilia Road", - "city": "Essex", - "state": "Vermont", - "postal_code": "67149", - "phone": "(392) 863-4448", - "account_credit": 74.13 - }, - { - "id": "161", - "name": "Alden Cabrera", - "registered_at": "Tue, 18 Feb 2014 01:57:47 -0800", - "address": "P.O. Box 904, 6349 Tortor Ave", - "city": "Rutland", - "state": "Vermont", - "postal_code": "96595", - "phone": "(535) 175-9355", - "account_credit": 31.45 - }, - { - "id": "162", - "name": "Kerry Steele", - "registered_at": "Thu, 24 Jul 2014 23:24:08 -0700", - "address": "441-2182 Turpis Av.", - "city": "Anchorage", - "state": "AK", - "postal_code": "99922", - "phone": "(178) 897-7367", - "account_credit": 63.9 - }, - { - "id": "163", - "name": "Charissa Browning", - "registered_at": "Wed, 11 Mar 2015 11:00:37 -0700", - "address": "873-2320 Et, Street", - "city": "Jacksonville", - "state": "Florida", - "postal_code": "14335", - "phone": "(840) 128-0317", - "account_credit": 5.28 - }, - { - "id": "164", - "name": "Darius Mendez", - "registered_at": "Fri, 25 Jul 2014 21:31:44 -0700", - "address": "P.O. Box 505, 730 Nonummy Road", - "city": "Casper", - "state": "WY", - "postal_code": "51369", - "phone": "(335) 359-1497", - "account_credit": 63.72 - }, - { - "id": "165", - "name": "Megan Gates", - "registered_at": "Mon, 09 Mar 2015 05:43:43 -0700", - "address": "955-5227 Nunc Av.", - "city": "Reading", - "state": "PA", - "postal_code": "81062", - "phone": "(443) 918-1564", - "account_credit": 2.86 - }, - { - "id": "166", - "name": "Paloma Horne", - "registered_at": "Mon, 21 Apr 2014 05:04:50 -0700", - "address": "7419 Quis, St.", - "city": "North Las Vegas", - "state": "NV", - "postal_code": "43059", - "phone": "(293) 295-3992", - "account_credit": 55.75 - }, - { - "id": "167", - "name": "Alec Schneider", - "registered_at": "Fri, 05 Sep 2014 06:54:39 -0700", - "address": "958 Arcu. Street", - "city": "Newport News", - "state": "Virginia", - "postal_code": "90428", - "phone": "(378) 745-6478", - "account_credit": 94.93 - }, - { - "id": "168", - "name": "Keegan Porter", - "registered_at": "Tue, 15 Jul 2014 05:47:49 -0700", - "address": "2383 Fusce St.", - "city": "Omaha", - "state": "Nebraska", - "postal_code": "36496", - "phone": "(235) 797-5965", - "account_credit": 83.54 - }, - { - "id": "169", - "name": "Dorian Brooks", - "registered_at": "Thu, 08 Jan 2015 05:35:34 -0800", - "address": "863 Nisi Av.", - "city": "Cedar Rapids", - "state": "Iowa", - "postal_code": "21997", - "phone": "(543) 949-5105", - "account_credit": 85.74 - }, - { - "id": "170", - "name": "Xyla Oneal", - "registered_at": "Wed, 17 Jun 2015 04:22:58 -0700", - "address": "625-1521 Adipiscing Avenue", - "city": "Tuscaloosa", - "state": "Alabama", - "postal_code": "35503", - "phone": "(586) 384-9718", - "account_credit": 92.1 - }, - { - "id": "171", - "name": "Urielle Brock", - "registered_at": "Mon, 11 May 2015 16:37:45 -0700", - "address": "P.O. Box 248, 1197 Adipiscing St.", - "city": "Newport News", - "state": "VA", - "postal_code": "96073", - "phone": "(374) 344-9156", - "account_credit": 97.75 - }, - { - "id": "172", - "name": "Hadley Snow", - "registered_at": "Tue, 04 Feb 2014 06:50:21 -0800", - "address": "Ap #795-8212 Erat. Av.", - "city": "Fort Collins", - "state": "Colorado", - "postal_code": "41558", - "phone": "(290) 857-4604", - "account_credit": 35.67 - }, - { - "id": "173", - "name": "Jenna Conley", - "registered_at": "Wed, 24 Jun 2015 12:00:49 -0700", - "address": "9806 In Rd.", - "city": "South Bend", - "state": "Indiana", - "postal_code": "27537", - "phone": "(965) 898-4616", - "account_credit": 90.28 - }, - { - "id": "174", - "name": "Hermione Combs", - "registered_at": "Thu, 13 Feb 2014 14:01:18 -0800", - "address": "Ap #571-9079 Lobortis Street", - "city": "Cambridge", - "state": "MA", - "postal_code": "77897", - "phone": "(711) 537-2715", - "account_credit": 14.77 - }, - { - "id": "175", - "name": "Scarlet Bridges", - "registered_at": "Tue, 07 Oct 2014 03:48:37 -0700", - "address": "P.O. Box 684, 1366 Cras St.", - "city": "Atlanta", - "state": "GA", - "postal_code": "85419", - "phone": "(303) 449-3873", - "account_credit": 4.05 - }, - { - "id": "176", - "name": "Christopher Santana", - "registered_at": "Fri, 28 Mar 2014 11:26:28 -0700", - "address": "Ap #401-3610 Porta St.", - "city": "Bridgeport", - "state": "Connecticut", - "postal_code": "31517", - "phone": "(916) 183-3805", - "account_credit": 71.54 - }, - { - "id": "177", - "name": "Linus Benjamin", - "registered_at": "Fri, 23 Jan 2015 22:31:42 -0800", - "address": "Ap #480-9547 Morbi Rd.", - "city": "Olathe", - "state": "Kansas", - "postal_code": "85407", - "phone": "(970) 802-1283", - "account_credit": 62.99 - }, - { - "id": "178", - "name": "Abbot Mcclain", - "registered_at": "Tue, 24 Feb 2015 16:47:48 -0800", - "address": "P.O. Box 159, 5873 Auctor Rd.", - "city": "Carson City", - "state": "NV", - "postal_code": "64780", - "phone": "(808) 310-5874", - "account_credit": 13.81 - }, - { - "id": "179", - "name": "Griffin Silva", - "registered_at": "Tue, 14 Oct 2014 10:57:04 -0700", - "address": "6307 Nulla Avenue", - "city": "Juneau", - "state": "AK", - "postal_code": "99838", - "phone": "(679) 747-9281", - "account_credit": 47.03 - }, - { - "id": "180", - "name": "Chloe Shepard", - "registered_at": "Sun, 03 Aug 2014 21:38:38 -0700", - "address": "P.O. Box 198, 4549 Pellentesque Rd.", - "city": "Kapolei", - "state": "HI", - "postal_code": "41472", - "phone": "(130) 324-9334", - "account_credit": 24.78 - }, - { - "id": "181", - "name": "Ori Russo", - "registered_at": "Wed, 11 Mar 2015 03:57:38 -0700", - "address": "Ap #795-182 Commodo Av.", - "city": "Lewiston", - "state": "ME", - "postal_code": "88250", - "phone": "(309) 634-1120", - "account_credit": 46.52 - }, - { - "id": "182", - "name": "Shad Campbell", - "registered_at": "Mon, 20 Oct 2014 11:03:44 -0700", - "address": "8296 Eu, Road", - "city": "Chesapeake", - "state": "VA", - "postal_code": "59563", - "phone": "(109) 812-1478", - "account_credit": 34.45 - }, - { - "id": "183", - "name": "Nomlanga Pugh", - "registered_at": "Sat, 11 Oct 2014 11:44:45 -0700", - "address": "Ap #948-7387 Euismod Street", - "city": "Fort Worth", - "state": "TX", - "postal_code": "54834", - "phone": "(603) 124-9087", - "account_credit": 59.54 - }, - { - "id": "184", - "name": "Damian Nixon", - "registered_at": "Thu, 11 Sep 2014 03:34:13 -0700", - "address": "386-6885 Velit. Rd.", - "city": "Minneapolis", - "state": "MN", - "postal_code": "34740", - "phone": "(996) 763-0457", - "account_credit": 53.6 - }, - { - "id": "185", - "name": "Azalia Bennett", - "registered_at": "Sat, 25 Jan 2014 03:12:08 -0800", - "address": "498-9892 Vehicula Ave", - "city": "Portland", - "state": "ME", - "postal_code": "12829", - "phone": "(233) 218-0724", - "account_credit": 94.45 - }, - { - "id": "186", - "name": "Tyler Sweet", - "registered_at": "Fri, 14 Mar 2014 11:46:41 -0700", - "address": "Ap #558-5634 Semper Rd.", - "city": "Paradise", - "state": "Nevada", - "postal_code": "10272", - "phone": "(401) 227-4119", - "account_credit": 58.12 - }, - { - "id": "187", - "name": "Kyla Sears", - "registered_at": "Sat, 01 Nov 2014 06:22:29 -0700", - "address": "P.O. Box 522, 2866 Lectus St.", - "city": "Casper", - "state": "Wyoming", - "postal_code": "77130", - "phone": "(926) 988-6271", - "account_credit": 40.39 - }, - { - "id": "188", - "name": "Kiona Wagner", - "registered_at": "Wed, 02 Jul 2014 06:16:58 -0700", - "address": "173 Tristique Road", - "city": "Aurora", - "state": "Colorado", - "postal_code": "20338", - "phone": "(976) 299-0296", - "account_credit": 95.61 - }, - { - "id": "189", - "name": "Celeste Hernandez", - "registered_at": "Fri, 13 Jun 2014 03:43:17 -0700", - "address": "4405 Cursus Av.", - "city": "Ketchikan", - "state": "AK", - "postal_code": "99982", - "phone": "(637) 226-8697", - "account_credit": 87.37 - }, - { - "id": "190", - "name": "Stuart Stevenson", - "registered_at": "Sun, 28 Jun 2015 16:34:34 -0700", - "address": "P.O. Box 244, 3411 Urna Road", - "city": "Paradise", - "state": "Nevada", - "postal_code": "54968", - "phone": "(884) 752-9559", - "account_credit": 99.54 - }, - { - "id": "191", - "name": "Yael Potter", - "registered_at": "Thu, 25 Dec 2014 10:43:46 -0800", - "address": "P.O. Box 802, 4280 Tellus. Av.", - "city": "Augusta", - "state": "GA", - "postal_code": "94978", - "phone": "(838) 450-7880", - "account_credit": 89.08 - }, - { - "id": "192", - "name": "Sarah Price", - "registered_at": "Thu, 20 Nov 2014 05:28:59 -0800", - "address": "P.O. Box 695, 4792 Sagittis. Street", - "city": "Jefferson City", - "state": "Missouri", - "postal_code": "68837", - "phone": "(694) 232-5802", - "account_credit": 65.06 - }, - { - "id": "193", - "name": "Keane Schroeder", - "registered_at": "Thu, 26 Mar 2015 19:51:39 -0700", - "address": "3750 Ultrices. St.", - "city": "Wichita", - "state": "KS", - "postal_code": "32895", - "phone": "(771) 777-3480", - "account_credit": 55.08 - }, - { - "id": "194", - "name": "Gloria Cabrera", - "registered_at": "Mon, 17 Feb 2014 11:59:32 -0800", - "address": "Ap #918-2687 Arcu Avenue", - "city": "Reading", - "state": "PA", - "postal_code": "20080", - "phone": "(872) 752-3660", - "account_credit": 37.86 - }, - { - "id": "195", - "name": "Audra Beck", - "registered_at": "Fri, 23 Jan 2015 20:42:53 -0800", - "address": "311-6634 Et St.", - "city": "Bellevue", - "state": "WA", - "postal_code": "81533", - "phone": "(473) 949-2594", - "account_credit": 30.33 - }, - { - "id": "196", - "name": "Dolan Newton", - "registered_at": "Wed, 15 Jan 2014 14:08:05 -0800", - "address": "P.O. Box 588, 3911 Proin Road", - "city": "Auburn", - "state": "ME", - "postal_code": "19968", - "phone": "(214) 790-1643", - "account_credit": 58.03 - }, - { - "id": "197", - "name": "Jolie Ashley", - "registered_at": "Sat, 24 May 2014 19:19:57 -0700", - "address": "901-461 Pharetra St.", - "city": "Jefferson City", - "state": "MO", - "postal_code": "76963", - "phone": "(157) 795-0499", - "account_credit": 50.3 - }, - { - "id": "198", - "name": "Judith Ewing", - "registered_at": "Sun, 06 Apr 2014 15:46:40 -0700", - "address": "P.O. Box 666, 7743 Mauris Road", - "city": "Knoxville", - "state": "TN", - "postal_code": "47671", - "phone": "(200) 706-8284", - "account_credit": 13.91 - }, - { - "id": "199", - "name": "Scarlett Rojas", - "registered_at": "Fri, 06 Feb 2015 11:31:26 -0800", - "address": "P.O. Box 161, 9318 Non, Ave", - "city": "Boise", - "state": "Idaho", - "postal_code": "81837", - "phone": "(669) 244-0896", - "account_credit": 27.69 - }, - { - "id": "200", - "name": "Kane Johnston", - "registered_at": "Fri, 22 May 2015 09:56:42 -0700", - "address": "P.O. Box 940, 1583 At, Street", - "city": "Austin", - "state": "Texas", - "postal_code": "94282", - "phone": "(270) 219-2853", - "account_credit": 62.7 - } -] diff --git a/db/development.db b/db/development.db index c2c1416344796ccdcce9465512d26332b6ab859f..ed78d2bfe74c56e97b5d83c15313cac017d07821 100644 GIT binary patch literal 49152 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%0ANA3 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 delta 58 zcmZo@U~W*DAT21uz`(!)#4sQ-QOB53WMjf|Mn>kz98Aj?nI^AiI>pF1xr(`M5eLU2 G9u@#54hx Date: Thu, 17 Sep 2015 14:29:17 -0700 Subject: [PATCH 013/189] seeded db with customer data --- db/development.db | Bin 49152 -> 73728 bytes utils/seed.js | 32 +++++++++++++++++++++++++++++--- 2 files changed, 29 insertions(+), 3 deletions(-) diff --git a/db/development.db b/db/development.db index ed78d2bfe74c56e97b5d83c15313cac017d07821..ae5a9dcf498218c3b99b2aefc05c6849a8216d26 100644 GIT binary patch delta 24918 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 K$3_00Z~k9s5^WFha); zhB!J1igxSA?cm@br3I0W9UL4T`U9L=sXk|T9_~4ud+s^6dSLhUe9%y+ z6(>D)^JV>5>rg%H9cjP*$-B_D{?62Ng9~iVY=t+djI5!?RTN!8!7^%EM9nWy%X8HF z47EK)u`+63K=FChF^3YfsB;D-r%~4wNXFfUCs3wG~9vZ?>|FSO@=CZ@Ifo|x0l#9Jzc7>32)&Iyr$xnRJ@dm bRWd8E1QjU5Jj}uqcnBpZLKf28PTrb(n2%=q diff --git a/utils/seed.js b/utils/seed.js index 2fbf8af..992f9ff 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -6,8 +6,14 @@ var sqlite3 = require('sqlite3').verbose(), var movies = require('./movies'); var movie_statement = db.prepare( - "INSERT INTO movies(title, overview, inventory, release_date) \ - VALUES(?, ?, ?, ?);" + "INSERT INTO movies (title, overview, inventory, release_date) \ + VALUES (?, ?, ?, ?);" +); + +var customers = require('./customers'); +var customer_statement = db.prepare( + "INSERT INTO customers (name, registered_at, address, city, state, \ + postal_code, phone, account_credit) VALUES (?, ?, ?, ?, ?, ?, ?, ?);" ); db.serialize(function() { @@ -17,11 +23,31 @@ db.serialize(function() { // insert each one into the db movie_statement.run( - movie.title, movie.overview, movie.inventory, movie.release_date + movie.title, + movie.overview, + movie.inventory, + movie.release_date ); } movie_statement.finalize(); + + for (var i = 0; i < customers.length; i++) { + var customer = customers[i]; + + customer_statement.run( + customer.name, + customer.registered_at, + customer.address, + customer.city, + customer.state, + customer.postal_code, + customer.phone, + customer.account_credit * 100 // convert for storage as integer + ); + } + + customer_statement.finalize(); }); db.close(); From a2213ff2a82dc5107762f597af07c90290355ef5 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 17 Sep 2015 14:37:53 -0700 Subject: [PATCH 014/189] removed users routes and references and added /zomg route --- app.js | 2 -- routes/index.js | 4 ++++ routes/users.js | 9 --------- 3 files changed, 4 insertions(+), 11 deletions(-) delete mode 100644 routes/users.js diff --git a/app.js b/app.js index 80a3c36..f0579b1 100644 --- a/app.js +++ b/app.js @@ -6,7 +6,6 @@ var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); var routes = require('./routes/index'); -var users = require('./routes/users'); var app = express(); @@ -23,7 +22,6 @@ app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); app.use('/', routes); -app.use('/users', users); // catch 404 and forward to error handler app.use(function(req, res, next) { diff --git a/routes/index.js b/routes/index.js index ecca96a..254eca5 100644 --- a/routes/index.js +++ b/routes/index.js @@ -6,4 +6,8 @@ router.get('/', function(req, res, next) { res.render('index', { title: 'Express' }); }); +router.get('/zomg', function(req, res, next) { + return res.status(200).json({ message: "it works!" }); +}); + module.exports = router; diff --git a/routes/users.js b/routes/users.js deleted file mode 100644 index 623e430..0000000 --- a/routes/users.js +++ /dev/null @@ -1,9 +0,0 @@ -var express = require('express'); -var router = express.Router(); - -/* GET users listing. */ -router.get('/', function(req, res, next) { - res.send('respond with a resource'); -}); - -module.exports = router; From c5dd50e4a40710976bffa36a7537959018dfd488 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 17 Sep 2015 14:59:23 -0700 Subject: [PATCH 015/189] checkout and checkin endpoints refined --- pseudoRoutes.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/pseudoRoutes.md b/pseudoRoutes.md index bd66899..ea95b5f 100644 --- a/pseudoRoutes.md +++ b/pseudoRoutes.md @@ -50,12 +50,13 @@ Rental - info on availability: boolean - object with list of customers that currently have that movie checked out -### POST '/rental' (checkout) +### POST '/rental/checkout/:customer_id/:movie_id' (checkout) - creates a record of rental movie object -### PUT '/rental' (checkin) +### PUT '/rental/checkin/:customer_id/:movie_id' (checkin) - updates rental record, returned: to true + ```javascript var movies = [ ['title', 'text'], From 94b399f4e04ee9cf134c54c664c19f96a04fa045 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 15:45:28 -0700 Subject: [PATCH 016/189] registered movie_routes --- app.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/app.js b/app.js index f0579b1..7b1a7e5 100644 --- a/app.js +++ b/app.js @@ -5,8 +5,6 @@ var logger = require('morgan'); var cookieParser = require('cookie-parser'); var bodyParser = require('body-parser'); -var routes = require('./routes/index'); - var app = express(); // view engine setup @@ -14,15 +12,19 @@ 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(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'))); +var routes = require('./routes/index'); app.use('/', routes); +var movie_routes = require('./routes/movies'); +app.use('/movies', movie_routes); + // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); From 33b07c206cb3b7c203c17047e8c2b8ebbf7a8a3c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 15:45:47 -0700 Subject: [PATCH 017/189] added /movies route -- IT WORKS --- routes/movies.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 routes/movies.js diff --git a/routes/movies.js b/routes/movies.js new file mode 100644 index 0000000..d15ac37 --- /dev/null +++ b/routes/movies.js @@ -0,0 +1,22 @@ +var express = require('express'); +var router = express.Router(); + +// open a connection to the db +var sqlite3 = require('sqlite3').verbose(), + db_env = process.env.DB || 'development', + db = new sqlite3.Database('db/' + db_env + '.db'); +// run a SQL statement to retrieve the data + +// serve that data as json at that endpoint + +/* GET list of movies */ +router.get('/', function(req, res, next) { + db.all("SELECT title FROM movies;", function(err, rows) { + rows.forEach(function(row) { + console.log(row.title); + }) + }); + return res.status(200).json({ message: "all the movies!" }); +}); + +module.exports = router; \ No newline at end of file From d096d0b87a817862d894301c97ca0a5958c88158 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 16:12:18 -0700 Subject: [PATCH 018/189] working /movies route that returns list of all movies --- routes/movies.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index d15ac37..3de269b 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -5,18 +5,16 @@ var router = express.Router(); var sqlite3 = require('sqlite3').verbose(), db_env = process.env.DB || 'development', db = new sqlite3.Database('db/' + db_env + '.db'); -// run a SQL statement to retrieve the data - -// serve that data as json at that endpoint /* GET list of movies */ router.get('/', function(req, res, next) { + // run a SQL statement to retrieve the data db.all("SELECT title FROM movies;", function(err, rows) { - rows.forEach(function(row) { - console.log(row.title); - }) + // serve that data as json at that endpoint + res.status(200).json({ movies: rows }); + + db.close(); }); - return res.status(200).json({ message: "all the movies!" }); }); -module.exports = router; \ No newline at end of file +module.exports = router; From 3ae537b9a093e56e870e8b81140c5e625fca95b9 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 16:12:46 -0700 Subject: [PATCH 019/189] added example code to movie_tests --- tests/movie_tests.js | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 tests/movie_tests.js diff --git a/tests/movie_tests.js b/tests/movie_tests.js new file mode 100644 index 0000000..8fa3bf7 --- /dev/null +++ b/tests/movie_tests.js @@ -0,0 +1,41 @@ +// var assert = require('assert'); +// var moviesController = require('../controllers/movies_controller.js'); + +// describe("Database", function() { +// var db; +// var database_path = "db/test.db"; + +// beforeEach(function() { +// db = new Database(database_path); +// }); + +// it("can be instantiated", function() { +// // assert.equal(db instanceof Database, true); +// assert.equal(Object.getPrototypeOf(db), Database.prototype); +// }); + +// it("has a `test` property that is a function", function() { +// assert.equal(typeof db.test, "function"); +// }); + +// it("holds onto the `path` to the database", function() { +// assert.equal(db.path, database_path); +// }); + +// describe("User queries", function() { +// before(function() { +// // create a users table +// db.query("CREATE TABLE IF NOT EXISTS users (name TEXT);"); +// // insert some users + +// }) + +// it("has a users table", function(done) { +// var table_exists = "SELECT count(*) AS table_count FROM sqlite_master WHERE type='table' AND name='users';"; +// db.query(table_exists, function(result) { +// assert.equal(result[0].table_count, 1); +// done(); +// }); +// }) +// }) +// }) From 8205495d7fce0c58222a67c14d9adb9f6027810f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 17 Sep 2015 16:22:56 -0700 Subject: [PATCH 020/189] added notes re: registered routes --- app.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/app.js b/app.js index 7b1a7e5..fc4a87d 100644 --- a/app.js +++ b/app.js @@ -19,9 +19,12 @@ app.use(bodyParser.urlencoded({ extended: false })); app.use(cookieParser()); app.use(express.static(path.join(__dirname, 'public'))); +// Are we going to use this?? +// register root routes var routes = require('./routes/index'); app.use('/', routes); +// register movies routes var movie_routes = require('./routes/movies'); app.use('/movies', movie_routes); From 4249b92718cb836d7fb54a4c32831df4646d5996 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 17 Sep 2015 16:27:51 -0700 Subject: [PATCH 021/189] added /customers endpoint to retrieve customer data in json --- app.js | 4 ++++ routes/customers.js | 21 +++++++++++++++++++++ routes/movies.js | 2 +- 3 files changed, 26 insertions(+), 1 deletion(-) create mode 100644 routes/customers.js diff --git a/app.js b/app.js index fc4a87d..0ed6ea4 100644 --- a/app.js +++ b/app.js @@ -28,6 +28,10 @@ app.use('/', routes); var movie_routes = require('./routes/movies'); app.use('/movies', movie_routes); +// register customer routes +var customer_routes = require('./routes/customers'); +app.use('/customers', customer_routes); + // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); diff --git a/routes/customers.js b/routes/customers.js new file mode 100644 index 0000000..4f64746 --- /dev/null +++ b/routes/customers.js @@ -0,0 +1,21 @@ +var express = require('express'); +var router = express.Router(); + +// open a connection to the db +var sqlite3 = require('sqlite3').verbose(), + db_env = process.env.DB || 'development', + db = new sqlite3.Database('db/' + db_env + '.db'); + +/* GET list of movies */ +router.get('/', function(req, res, next) { + // run a SQL statement to retrieve the data + db.all("SELECT name, registered_at, address, city, state, \ + postal_code, phone, account_credit FROM customers;", function(err, rows) { + // serve that data as json at that endpoint + res.status(200).json({ customers: rows }); + + db.close(); + }); +}); + +module.exports = router; diff --git a/routes/movies.js b/routes/movies.js index 3de269b..102b471 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -9,7 +9,7 @@ var sqlite3 = require('sqlite3').verbose(), /* GET list of movies */ router.get('/', function(req, res, next) { // run a SQL statement to retrieve the data - db.all("SELECT title FROM movies;", function(err, rows) { + db.all("SELECT title, overview, release_date, inventory FROM movies;", function(err, rows) { // serve that data as json at that endpoint res.status(200).json({ movies: rows }); From e5ce4b9126b828dc122dbe3decc4a749273e043d Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 10:29:56 -0700 Subject: [PATCH 022/189] made pnm start command use nodemon --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 286d1a9..8d92328 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "node ./bin/www" + "start": "nodemon ./bin/www" }, "dependencies": { "body-parser": "~1.13.2", From 6e710f8e22b9fc43c66bd4d1dad53bd935b5fc5f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 10:30:21 -0700 Subject: [PATCH 023/189] created adapter to talk to database and perform CRUD operations --- database_adapter.js | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) create mode 100644 database_adapter.js diff --git a/database_adapter.js b/database_adapter.js new file mode 100644 index 0000000..ffa9fa7 --- /dev/null +++ b/database_adapter.js @@ -0,0 +1,22 @@ +"use strict"; + +var sqlite3 = require('sqlite3').verbose(), + db_env = process.env.DB || 'development'; + +module.exports = { + find_all: function(callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + var statement = "SELECT * FROM " + this.table_name; + + db.all(statement, function(err, res) { + if (callback) { callback(err, res); } + db.close(); + }); + } + + // find_by: { + + // } + + // get resources/:sort_by/:number/:offset +} From 4c8d4def4f7cca782eb7c9db53c3aaa5781387a7 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 10:31:01 -0700 Subject: [PATCH 024/189] created models for movie and customer that use the database-adapter --- models/customer.js | 9 +++++++++ models/movie.js | 9 +++++++++ 2 files changed, 18 insertions(+) create mode 100644 models/customer.js create mode 100644 models/movie.js diff --git a/models/customer.js b/models/customer.js new file mode 100644 index 0000000..746bdbc --- /dev/null +++ b/models/customer.js @@ -0,0 +1,9 @@ +"use strict"; + +function Customer() { + this.table_name = "customers"; +} + +Customer.prototype = require('../database_adapter'); + +module.exports = Customer; diff --git a/models/movie.js b/models/movie.js new file mode 100644 index 0000000..12d7431 --- /dev/null +++ b/models/movie.js @@ -0,0 +1,9 @@ +"use strict"; + +function Movie() { + this.table_name = "movies"; +} + +Movie.prototype = require('../database_adapter'); + +module.exports = Movie; From faefd463aafdf6e5d1f07cea700f27866c2dbcf1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 10:31:44 -0700 Subject: [PATCH 025/189] modified routes to use models and functions as defined in the database apater; removed SQL statements --- routes/customers.js | 14 +++----------- routes/movies.js | 13 +++---------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 4f64746..da24b22 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -1,20 +1,12 @@ var express = require('express'); var router = express.Router(); -// open a connection to the db -var sqlite3 = require('sqlite3').verbose(), - db_env = process.env.DB || 'development', - db = new sqlite3.Database('db/' + db_env + '.db'); +var Customer = require('../models/customer'), + customer = new Customer(); -/* GET list of movies */ router.get('/', function(req, res, next) { - // run a SQL statement to retrieve the data - db.all("SELECT name, registered_at, address, city, state, \ - postal_code, phone, account_credit FROM customers;", function(err, rows) { - // serve that data as json at that endpoint + customer.find_all(function(err, rows) { res.status(200).json({ customers: rows }); - - db.close(); }); }); diff --git a/routes/movies.js b/routes/movies.js index 102b471..edca988 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -1,19 +1,12 @@ var express = require('express'); var router = express.Router(); -// open a connection to the db -var sqlite3 = require('sqlite3').verbose(), - db_env = process.env.DB || 'development', - db = new sqlite3.Database('db/' + db_env + '.db'); +var Movie = require('../models/movie'), + movie = new Movie(); -/* GET list of movies */ router.get('/', function(req, res, next) { - // run a SQL statement to retrieve the data - db.all("SELECT title, overview, release_date, inventory FROM movies;", function(err, rows) { - // serve that data as json at that endpoint + movie.find_all(function(err, rows) { res.status(200).json({ movies: rows }); - - db.close(); }); }); From f2ea1519361eba57c18b9df816b4df59bf31e393 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 18 Sep 2015 10:50:49 -0700 Subject: [PATCH 026/189] added find_by method in database adapter, working for customer find_by :id, returns a record of a single customer --- database_adapter.js | 13 ++++++++++--- routes/customers.js | 8 ++++++++ 2 files changed, 18 insertions(+), 3 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index ffa9fa7..daa62a5 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -12,11 +12,18 @@ module.exports = { if (callback) { callback(err, res); } db.close(); }); - } + }, - // find_by: { + find_by: function(column, value, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " = ?"; - // } + // get returns one record, making this emulate Active Record's find_by + db.get(statement, value, function(err, res) { + if (callback) { callback(err, res); } + db.close(); + }); + } // get resources/:sort_by/:number/:offset } diff --git a/routes/customers.js b/routes/customers.js index da24b22..cf49327 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -10,4 +10,12 @@ router.get('/', function(req, res, next) { }); }); +router.get('/:id', function(req, res, next) { + var id = req.params.id; + + customer.find_by('id', id, function(err, row) { + res.status(200).json({ customer: row} ); + }); +}); + module.exports = router; From 460a7df7360769af09a09c465810e69ccde801a2 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 18 Sep 2015 10:57:59 -0700 Subject: [PATCH 027/189] added find_by movie title endpoint --- routes/movies.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/routes/movies.js b/routes/movies.js index edca988..86d92e9 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -10,4 +10,12 @@ router.get('/', function(req, res, next) { }); }); +router.get('/:title', function(req, res, next) { + var title = req.params.title; + + movie.find_by('title', title, function(err, row) { + res.status(200).json({ movie: row} ); + }); +}); + module.exports = router; From 7b67adc38a56f40e4658f655cb2dc09e5ce1d7e3 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 11:41:25 -0700 Subject: [PATCH 028/189] added where function --- database_adapter.js | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/database_adapter.js b/database_adapter.js index daa62a5..4c12cdf 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -14,15 +14,35 @@ module.exports = { }); }, + // get returns one record, making this emulate Active Record's find_by find_by: function(column, value, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " = ?"; - // get returns one record, making this emulate Active Record's find_by db.get(statement, value, function(err, res) { if (callback) { callback(err, res); } db.close(); }); + }, + + // returns array of records + where: function(columns, values, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + var where_statements = []; + + // where_statements => ["city = ?", "state = ?"] + for (var i = 0; i < columns.length; i++) { + where_statements.push(columns[i] + " = ?"); + } + // where_statement => "city = ? AND state = ?" + var where_statement = where_statements.join(" AND "); + + var statement = "SELECT * FROM " + this.table_name + " WHERE " + where_statement; + + db.all(statement, values, function(err, res) { + if (callback) { callback(err, res); } + db.close(); + }); } // get resources/:sort_by/:number/:offset From 47fdf74a239a076af92e6774bb38bf06763199d8 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 11:42:50 -0700 Subject: [PATCH 029/189] added debugger route to test function of database-adapter --- routes/customers.js | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/routes/customers.js b/routes/customers.js index cf49327..64b3f1b 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -18,4 +18,17 @@ router.get('/:id', function(req, res, next) { }); }); +// DEBUGGER ROUTE + +// router.get('/:city', function(req, res, next) { +// var values = []; +// values.push(req.params.city); +// console.log(values); + +// customer.where(['city'], values, function(err, rows) { +// console.log(values); +// res.status(200).json({ customers: rows} ); +// }); +// }); + module.exports = router; From 0c3df756493f6ac42e8ad79f284161e27a6e7245 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 18 Sep 2015 13:11:37 -0700 Subject: [PATCH 030/189] changed test folder name and added movie model test file --- test/models/movie.js | 86 ++++++++++++++++++++++++++++++++++++++++++++ tests/movie_tests.js | 41 --------------------- 2 files changed, 86 insertions(+), 41 deletions(-) create mode 100644 test/models/movie.js delete mode 100644 tests/movie_tests.js diff --git a/test/models/movie.js b/test/models/movie.js new file mode 100644 index 0000000..d202c96 --- /dev/null +++ b/test/models/movie.js @@ -0,0 +1,86 @@ +// var assert = require('assert'), +// Movie = require('../../models/movie'), +// sqlite3 = require('sqlite3').verbose(); + +// describe("Movie", function() { +// var movie, db_cleaner + +// beforeEach(function(done) { +// movie = new Movie(); + +// db_cleaner = new sqlite3.Database('db/test.db'); +// db_cleaner.serialize(function() { +// db_cleaner.exec( +// "BEGIN; \ +// DELETE FROM movies; \ +// INSERT INTO movies(title, overview, release_date, inventory) \ +// VALUES('Jaws', 'Shark!', 'Yesterday', 10), \ +// ('Maws', 'Worm!', 'Yesterday', 11); \ +// COMMIT;" +// , function(err) { +// db_cleaner.close(); +// done(); +// } +// ); +// }); +// }) + +// it("can be instantiated", function() { +// assert(movie instanceof Movie); +// }) + +// describe("instance methods", function() { +// it("can find a movie by id", function(done){ +// movie.find_by("id", 1, function(err, res) { +// assert.equal(err, undefined); +// assert(res instanceof Array); +// assert.equal(res.length, 1); +// assert.equal(res[0].id, 1); +// done(); +// }) +// }) + +// it("can find a movie by title", function(done) { +// movie.find_by("title", "Jaws", function(err, res) { +// assert.equal(err, undefined); +// assert(res instanceof Array); +// assert.equal(res.length, 1); +// assert.equal(res[0].title, 'Jaws'); +// done(); +// }) +// }) + +// it("can save changes to a movie", function(done) { +// movie.find_by("title", "Jaws", function(err, res) { +// var original_title = res[0].title; +// var id = res[0].id; +// movie.save({title: "Jaws 2: Jawsier", id: id}, function(err, res) { +// assert.equal(err, undefined); +// assert.equal(res.inserted_id, 0); //it didn't insert any records +// assert.equal(res.changed, 1); //it updated one record +// done(); +// }) +// }) +// }); + +// it("can save a new movie to the database", function(done) { +// var data = { +// title: "RoboJaws", +// overview: "Jaws is hunted by RoboJaws", +// release_date: "Tomorrow", +// inventory: 10 +// } + +// movie.create(data, function(err, res) { +// assert.equal(res.inserted_id, 3); //it inserted a new record +// assert.equal(res.changed, 1); //one record was changed + +// movie.find_by("title", "RoboJaws", function(err, res) { +// assert.equal(res.length, 1); +// assert.equal(res[0].title, 'RoboJaws'); //we found our new movie +// done(); +// }) +// }) +// }); +// }) +// }) diff --git a/tests/movie_tests.js b/tests/movie_tests.js deleted file mode 100644 index 8fa3bf7..0000000 --- a/tests/movie_tests.js +++ /dev/null @@ -1,41 +0,0 @@ -// var assert = require('assert'); -// var moviesController = require('../controllers/movies_controller.js'); - -// describe("Database", function() { -// var db; -// var database_path = "db/test.db"; - -// beforeEach(function() { -// db = new Database(database_path); -// }); - -// it("can be instantiated", function() { -// // assert.equal(db instanceof Database, true); -// assert.equal(Object.getPrototypeOf(db), Database.prototype); -// }); - -// it("has a `test` property that is a function", function() { -// assert.equal(typeof db.test, "function"); -// }); - -// it("holds onto the `path` to the database", function() { -// assert.equal(db.path, database_path); -// }); - -// describe("User queries", function() { -// before(function() { -// // create a users table -// db.query("CREATE TABLE IF NOT EXISTS users (name TEXT);"); -// // insert some users - -// }) - -// it("has a users table", function(done) { -// var table_exists = "SELECT count(*) AS table_count FROM sqlite_master WHERE type='table' AND name='users';"; -// db.query(table_exists, function(result) { -// assert.equal(result[0].table_count, 1); -// done(); -// }); -// }) -// }) -// }) From 562010c726bc9ddeafa5c85167f56af3d56c87ea Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 18 Sep 2015 13:12:08 -0700 Subject: [PATCH 031/189] changed find_by query to use LIKE to take account for casing --- database_adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database_adapter.js b/database_adapter.js index 4c12cdf..12bdcbe 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -17,7 +17,7 @@ module.exports = { // get returns one record, making this emulate Active Record's find_by find_by: function(column, value, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " = ?"; + var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " LIKE ?"; db.get(statement, value, function(err, res) { if (callback) { callback(err, res); } From b4a3edd1d372410846978494500758aa85d954a6 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 18 Sep 2015 14:11:30 -0700 Subject: [PATCH 032/189] WIP limit function --- database_adapter.js | 14 ++++ routes/movies.js | 13 ++++ test/models/movie.js | 152 +++++++++++++++++++++---------------------- 3 files changed, 103 insertions(+), 76 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 12bdcbe..050d355 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -39,6 +39,20 @@ module.exports = { var statement = "SELECT * FROM " + this.table_name + " WHERE " + where_statement; + db.all(statement, values, function(err, res) { + if (callback) { callback(err, res); } + db.close(); + }); + }, + + limit: function(column, queries, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + var limit = queries[0]; + var offset = queries[1]; + + var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column + " LIMIT " + limit + " OFFSET " + offset; + console.log(statement); + db.all(statement, values, function(err, res) { if (callback) { callback(err, res); } db.close(); diff --git a/routes/movies.js b/routes/movies.js index 86d92e9..fe52f86 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -18,4 +18,17 @@ router.get('/:title', function(req, res, next) { }); }); +router.get(':sort_by/:limit/:offset', function(req, res, next) { + var queries = []; + queries.push(req.params.limit); + queries.push(req.params.offset); + var column = req.params.sorty_by + + console.log(queries); + + movie.limit(column, queries, function(err, rows) { + res.status(200).json({ movies: rows} ); + }); +}); + module.exports = router; diff --git a/test/models/movie.js b/test/models/movie.js index d202c96..d49c787 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -1,86 +1,86 @@ -// var assert = require('assert'), -// Movie = require('../../models/movie'), -// sqlite3 = require('sqlite3').verbose(); +var assert = require('assert'), + Movie = require('../../models/movie'), + sqlite3 = require('sqlite3').verbose(); -// describe("Movie", function() { -// var movie, db_cleaner +describe("Movie", function() { + var movie, db_cleaner; -// beforeEach(function(done) { -// movie = new Movie(); + beforeEach(function(done) { + movie = new Movie(); -// db_cleaner = new sqlite3.Database('db/test.db'); -// db_cleaner.serialize(function() { -// db_cleaner.exec( -// "BEGIN; \ -// DELETE FROM movies; \ -// INSERT INTO movies(title, overview, release_date, inventory) \ -// VALUES('Jaws', 'Shark!', 'Yesterday', 10), \ -// ('Maws', 'Worm!', 'Yesterday', 11); \ -// COMMIT;" -// , function(err) { -// db_cleaner.close(); -// done(); -// } -// ); -// }); -// }) + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM movies; \ + INSERT INTO movies(title, overview, release_date, inventory) \ + VALUES('Jaws', 'Shark!', 'Yesterday', 10), \ + ('Maws', 'Worm!', 'Yesterday', 11); \ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }) -// it("can be instantiated", function() { -// assert(movie instanceof Movie); -// }) + it("can be instantiated", function() { + assert(movie instanceof Movie); + }) -// describe("instance methods", function() { -// it("can find a movie by id", function(done){ -// movie.find_by("id", 1, function(err, res) { -// assert.equal(err, undefined); -// assert(res instanceof Array); -// assert.equal(res.length, 1); -// assert.equal(res[0].id, 1); -// done(); -// }) -// }) + describe("instance methods", function() { + it("can find a movie by id", function(done){ + movie.find_by("id", 1, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res.length, 1); + assert.equal(res[0].id, 1); + done(); + }) + }) -// it("can find a movie by title", function(done) { -// movie.find_by("title", "Jaws", function(err, res) { -// assert.equal(err, undefined); -// assert(res instanceof Array); -// assert.equal(res.length, 1); -// assert.equal(res[0].title, 'Jaws'); -// done(); -// }) -// }) + // it("can find a movie by title", function(done) { + // movie.find_by("title", "Jaws", function(err, res) { + // assert.equal(err, undefined); + // assert(res instanceof Array); + // assert.equal(res.length, 1); + // assert.equal(res[0].title, 'Jaws'); + // done(); + // }) + // }) -// it("can save changes to a movie", function(done) { -// movie.find_by("title", "Jaws", function(err, res) { -// var original_title = res[0].title; -// var id = res[0].id; -// movie.save({title: "Jaws 2: Jawsier", id: id}, function(err, res) { -// assert.equal(err, undefined); -// assert.equal(res.inserted_id, 0); //it didn't insert any records -// assert.equal(res.changed, 1); //it updated one record -// done(); -// }) -// }) -// }); + // it("can save changes to a movie", function(done) { + // movie.find_by("title", "Jaws", function(err, res) { + // var original_title = res[0].title; + // var id = res[0].id; + // movie.save({title: "Jaws 2: Jawsier", id: id}, function(err, res) { + // assert.equal(err, undefined); + // assert.equal(res.inserted_id, 0); //it didn't insert any records + // assert.equal(res.changed, 1); //it updated one record + // done(); + // }) + // }) + // }); -// it("can save a new movie to the database", function(done) { -// var data = { -// title: "RoboJaws", -// overview: "Jaws is hunted by RoboJaws", -// release_date: "Tomorrow", -// inventory: 10 -// } + // it("can save a new movie to the database", function(done) { + // var data = { + // title: "RoboJaws", + // overview: "Jaws is hunted by RoboJaws", + // release_date: "Tomorrow", + // inventory: 10 + // } -// movie.create(data, function(err, res) { -// assert.equal(res.inserted_id, 3); //it inserted a new record -// assert.equal(res.changed, 1); //one record was changed + // movie.create(data, function(err, res) { + // assert.equal(res.inserted_id, 3); //it inserted a new record + // assert.equal(res.changed, 1); //one record was changed -// movie.find_by("title", "RoboJaws", function(err, res) { -// assert.equal(res.length, 1); -// assert.equal(res[0].title, 'RoboJaws'); //we found our new movie -// done(); -// }) -// }) -// }); -// }) -// }) + // movie.find_by("title", "RoboJaws", function(err, res) { + // assert.equal(res.length, 1); + // assert.equal(res[0].title, 'RoboJaws'); //we found our new movie + // done(); + // }) + // }) + // }); + }) +}) From d40c3aebaffc774e026d3c10caa5c6c8cdee6195 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 18 Sep 2015 14:26:13 -0700 Subject: [PATCH 033/189] added subset function to obtain movies sorted by, limit, and offset --- database_adapter.js | 8 +++----- routes/movies.js | 6 +++--- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 050d355..49185d2 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -45,15 +45,13 @@ module.exports = { }); }, - limit: function(column, queries, callback) { + subset: function(column, queries, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - var limit = queries[0]; - var offset = queries[1]; - var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column + " LIMIT " + limit + " OFFSET " + offset; + var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column + " LIMIT ? OFFSET ?"; console.log(statement); - db.all(statement, values, function(err, res) { + db.all(statement, queries, function(err, res) { if (callback) { callback(err, res); } db.close(); }); diff --git a/routes/movies.js b/routes/movies.js index fe52f86..bfdfaa0 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -18,15 +18,15 @@ router.get('/:title', function(req, res, next) { }); }); -router.get(':sort_by/:limit/:offset', function(req, res, next) { +router.get('/:sort_by/:limit/:offset', function(req, res, next) { var queries = []; queries.push(req.params.limit); queries.push(req.params.offset); - var column = req.params.sorty_by + var column = req.params.sort_by; console.log(queries); - movie.limit(column, queries, function(err, rows) { + movie.subset(column, queries, function(err, rows) { res.status(200).json({ movies: rows} ); }); }); From 4db59eadea2730882518569126c8342eb76eb0e0 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 14:46:53 -0700 Subject: [PATCH 034/189] removed comment --- routes/movies.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index bfdfaa0..d5a1907 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -24,8 +24,6 @@ router.get('/:sort_by/:limit/:offset', function(req, res, next) { queries.push(req.params.offset); var column = req.params.sort_by; - console.log(queries); - movie.subset(column, queries, function(err, rows) { res.status(200).json({ movies: rows} ); }); From f308653b8a2c4ee9e6b640fbf5b096e9538979c9 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 14:47:10 -0700 Subject: [PATCH 035/189] added subset endpoint --- routes/customers.js | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/routes/customers.js b/routes/customers.js index 64b3f1b..5bcffd0 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -18,6 +18,17 @@ router.get('/:id', function(req, res, next) { }); }); +router.get('/:sort_by/:limit/:offset', function(req, res, next) { + var queries = []; + queries.push(req.params.limit); + queries.push(req.params.offset); + var column = req.params.sort_by; + + customer.subset(column, queries, function(err, rows) { + res.status(200).json({ customers: rows} ); + }); +}); + // DEBUGGER ROUTE // router.get('/:city', function(req, res, next) { From 26dc95baaa93f3a37db244b2aae3e9ec3a549221 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 14:47:33 -0700 Subject: [PATCH 036/189] added subset function --- database_adapter.js | 1 - 1 file changed, 1 deletion(-) diff --git a/database_adapter.js b/database_adapter.js index 49185d2..4b408c7 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -57,5 +57,4 @@ module.exports = { }); } - // get resources/:sort_by/:number/:offset } From 1a12821ca851e3d892de2c882fe6d9b8398578ae Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 18 Sep 2015 16:33:24 -0700 Subject: [PATCH 037/189] debugging movie test file --- db/test.db | Bin 0 -> 4096 bytes npm-debug.log | 25 +++++++++++++++++++++++++ package.json | 3 ++- test/models/movie.js | 6 +++--- 4 files changed, 30 insertions(+), 4 deletions(-) create mode 100644 db/test.db create mode 100644 npm-debug.log diff --git a/db/test.db b/db/test.db new file mode 100644 index 0000000000000000000000000000000000000000..c2c1416344796ccdcce9465512d26332b6ab859f GIT binary patch literal 4096 zcmeH`K~KUk6vw*_f@{ok*BFV8~`48I8(5x|$IhAazRVT=%J=vmXV7{B*c@#CMhfi6Bz zPW1uDK0?mIUhBn-su4)foO-j}wpJY=uOX8x1`?`#soi*Pf8^p(|9a@++=j(eCU3Pi-DuMhAT*o4U*j>Md^l7~(ieHRJ%0nyJ7*a!4&;HbTKSpGB9q!0PD$$4y2QzKGlIa6hyk|u~l!jT2?yAO3C=B&DSm!vGMJ%062t2 zE-`0Pb6(^kB?}o*>?cni&-L93x!el*?#)t{SM6;YJ%)fGa4-U<{||=N1U3XJPr&ql N<*&#HGz1Pt;0uxOwrT(X literal 0 HcmV?d00001 diff --git a/npm-debug.log b/npm-debug.log new file mode 100644 index 0000000..fbd43e8 --- /dev/null +++ b/npm-debug.log @@ -0,0 +1,25 @@ +0 info it worked if it ends with ok +1 verbose cli [ 'node', '/usr/local/bin/npm', 'run', 'db:schema' ] +2 info using npm@2.10.1 +3 info using node@v0.12.4 +4 verbose node symlink /usr/local/bin/node +5 verbose stack Error: missing script: db:schema +5 verbose stack at run (/usr/local/lib/node_modules/npm/lib/run-script.js:142:19) +5 verbose stack at /usr/local/lib/node_modules/npm/lib/run-script.js:58:5 +5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:345:5 +5 verbose stack at checkBinReferences_ (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:309:45) +5 verbose stack at final (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:343:3) +5 verbose stack at then (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:113:5) +5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:300:12 +5 verbose stack at evalmachine.:334:14 +5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:102:5 +5 verbose stack at FSReqWrap.oncomplete (evalmachine.:95:15) +6 verbose cwd /Users/arhx/projects/Ada/project-forks/C3Projects--VideoStoreAPI +7 error Darwin 14.5.0 +8 error argv "node" "/usr/local/bin/npm" "run" "db:schema" +9 error node v0.12.4 +10 error npm v2.10.1 +11 error missing script: db:schema +12 error If you need help, you may report this error at: +12 error +13 verbose exit [ 1, true ] diff --git a/package.json b/package.json index 8d92328..ababf9c 100644 --- a/package.json +++ b/package.json @@ -3,7 +3,8 @@ "version": "0.0.0", "private": true, "scripts": { - "start": "nodemon ./bin/www" + "start": "nodemon ./bin/www", + "test": "clear; DB=test mocha --recursive" }, "dependencies": { "body-parser": "~1.13.2", diff --git a/test/models/movie.js b/test/models/movie.js index d49c787..cbb09ed 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -33,9 +33,9 @@ describe("Movie", function() { it("can find a movie by id", function(done){ movie.find_by("id", 1, function(err, res) { assert.equal(err, undefined); - assert(res instanceof Array); - assert.equal(res.length, 1); - assert.equal(res[0].id, 1); + assert(res instanceof Object); + // assert.equal(res.length, 1); + assert.equal(res.id, 1); done(); }) }) From a6debf3523de04cc086d69db775bbe72177c950d Mon Sep 17 00:00:00 2001 From: Anita Date: Sat, 19 Sep 2015 19:27:07 -0700 Subject: [PATCH 038/189] added go -b --- db/test.db | Bin 4096 -> 4096 bytes npm-debug.log | 25 ------------------------- package.json | 5 ++++- 3 files changed, 4 insertions(+), 26 deletions(-) delete mode 100644 npm-debug.log diff --git a/db/test.db b/db/test.db index c2c1416344796ccdcce9465512d26332b6ab859f..21f695013f1c4cf135156d44a0b4a8ebbdec9bee 100644 GIT binary patch delta 90 zcmZorXi%6S%_uQZ#+gxKW5N<<4kqT449riMPi_`u*~@G$$;8GWDlX6Hn^;~Po?n!! k7@1mJl3J9KSjjEL2$YhPXY>L}1!p7{Wh3Oc7O`*u08maDE&u=k delta 25 hcmZorXi%6S%_uTa#+gxMW5N>V%`6;$*cb7z003Qm2QmNv diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index fbd43e8..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,25 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ 'node', '/usr/local/bin/npm', 'run', 'db:schema' ] -2 info using npm@2.10.1 -3 info using node@v0.12.4 -4 verbose node symlink /usr/local/bin/node -5 verbose stack Error: missing script: db:schema -5 verbose stack at run (/usr/local/lib/node_modules/npm/lib/run-script.js:142:19) -5 verbose stack at /usr/local/lib/node_modules/npm/lib/run-script.js:58:5 -5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:345:5 -5 verbose stack at checkBinReferences_ (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:309:45) -5 verbose stack at final (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:343:3) -5 verbose stack at then (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:113:5) -5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:300:12 -5 verbose stack at evalmachine.:334:14 -5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:102:5 -5 verbose stack at FSReqWrap.oncomplete (evalmachine.:95:15) -6 verbose cwd /Users/arhx/projects/Ada/project-forks/C3Projects--VideoStoreAPI -7 error Darwin 14.5.0 -8 error argv "node" "/usr/local/bin/npm" "run" "db:schema" -9 error node v0.12.4 -10 error npm v2.10.1 -11 error missing script: db:schema -12 error If you need help, you may report this error at: -12 error -13 verbose exit [ 1, true ] diff --git a/package.json b/package.json index ababf9c..b466582 100644 --- a/package.json +++ b/package.json @@ -4,7 +4,10 @@ "private": true, "scripts": { "start": "nodemon ./bin/www", - "test": "clear; DB=test mocha --recursive" + "test": "DB=test mocha --recursive", + "db:schema": "node ./utils/schema", + "db:seed": "node ./utils/seed", + "db:setup": "npm run db:schema; npm run db:seed" }, "dependencies": { "body-parser": "~1.13.2", From 725400b5cce00b6036375f4f55fa0b9a8df9384d Mon Sep 17 00:00:00 2001 From: Anita Date: Sat, 19 Sep 2015 20:04:17 -0700 Subject: [PATCH 039/189] testing for customers model WIP --- db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 89 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+) create mode 100644 test/models/customer.js diff --git a/db/test.db b/db/test.db index 21f695013f1c4cf135156d44a0b4a8ebbdec9bee..7cdae1182266ebdf71ec91c451598c76c96b8002 100644 GIT binary patch delta 258 zcmXBOO-jQ+7{>8@fu%ba>Y@s7BSHgBn0Ygkubo!Auu8-%y3}Zb4NNmNO+Z)n0)k#a zynuKUPvnT(2mbt?4Q$|Tpxf{J6W#v0{oLvqrmdN;rv1Hb?V2x@(btAEcQD*@jH!Hr z%T5$!Gi|CdPy*+j03?(HW5a=aYRWx zLJ~OOW9+gRBmL-6?`wy%vx6N)o#u58*?o5-#Phr?6c)hos`OfHd delta 25 hcmZorXi%6S%_uQZ#+gxKW5N>l%`7~Bm>2P|003Sk2R;A* diff --git a/test/models/customer.js b/test/models/customer.js new file mode 100644 index 0000000..976cded --- /dev/null +++ b/test/models/customer.js @@ -0,0 +1,89 @@ +var assert = require('assert'), + Customer = require('../../models/customer'), + sqlite3 = require('sqlite3').verbose(); + +describe("Customer", function() { + var customer, db_cleaner; + + beforeEach(function(done) { + customer = new Customer(); + + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM customers; \ + INSERT INTO customers (name, registered_at, address, city, state, \ + postal_code, phone, account_credit) \ + VALUES ('Dana Scully', 'Wed, 16 Apr 2014 21:40:20 -0700', \ + 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ + '(371) 627-1105', 1234), \ + ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }) + + it("can be instantiated", function() { + assert(customer instanceof Customer); + }) + + describe("instance methods", function() { + it("can find a customer by id", function(done){ + customer.find_by("id", 1, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Object); + assert.equal(res.id, 1); + done(); + }) + }) + + // it("can find a customer by title", function(done) { + // customer.find_by("title", "Jaws", function(err, res) { + // assert.equal(err, undefined); + // assert(res instanceof Array); + // assert.equal(res.length, 1); + // assert.equal(res[0].title, 'Jaws'); + // done(); + // }) + // }) + + // it("can save changes to a customer", function(done) { + // customer.find_by("title", "Jaws", function(err, res) { + // var original_title = res[0].title; + // var id = res[0].id; + // customer.save({title: "Jaws 2: Jawsier", id: id}, function(err, res) { + // assert.equal(err, undefined); + // assert.equal(res.inserted_id, 0); //it didn't insert any records + // assert.equal(res.changed, 1); //it updated one record + // done(); + // }) + // }) + // }); + + // it("can save a new customer to the database", function(done) { + // var data = { + // title: "RoboJaws", + // overview: "Jaws is hunted by RoboJaws", + // release_date: "Tomorrow", + // inventory: 10 + // } + + // customer.create(data, function(err, res) { + // assert.equal(res.inserted_id, 3); //it inserted a new record + // assert.equal(res.changed, 1); //one record was changed + + // customer.find_by("title", "RoboJaws", function(err, res) { + // assert.equal(res.length, 1); + // assert.equal(res[0].title, 'RoboJaws'); //we found our new customer + // done(); + // }) + // }) + // }); + }) +}) From f9214094dca8363b6d6a238928c397cb923a3e43 Mon Sep 17 00:00:00 2001 From: Anita Date: Sat, 19 Sep 2015 21:55:56 -0700 Subject: [PATCH 040/189] testing for customers find_all --- db/test.db | Bin 4096 -> 4096 bytes package.json | 3 +++ test/models/customer.js | 24 +++++++++++------------- 3 files changed, 14 insertions(+), 13 deletions(-) diff --git a/db/test.db b/db/test.db index 7cdae1182266ebdf71ec91c451598c76c96b8002..659edc8db9c28483fd4dc2a2329f538f2aa7d1f9 100644 GIT binary patch delta 17 YcmZorXi%6S%@{dR#+fm4W5NP{04}ZtPyhe` delta 17 YcmZorXi%6S&8Rd{#+gxRW5NP{04sF_;s5{u diff --git a/package.json b/package.json index b466582..d339874 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,8 @@ "morgan": "~1.6.1", "serve-favicon": "~2.3.0", "sqlite3": "^3.1.0" + }, + "devDependencies": { + "should": "^7.1.0" } } diff --git a/test/models/customer.js b/test/models/customer.js index 976cded..eadfd4c 100644 --- a/test/models/customer.js +++ b/test/models/customer.js @@ -16,10 +16,10 @@ describe("Customer", function() { INSERT INTO customers (name, registered_at, address, city, state, \ postal_code, phone, account_credit) \ VALUES ('Dana Scully', 'Wed, 16 Apr 2014 21:40:20 -0700', \ - 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ - '(371) 627-1105', 1234), \ + 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ + '(371) 627-1105', 1234), \ ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ - 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ COMMIT;" , function(err) { db_cleaner.close(); @@ -34,6 +34,14 @@ describe("Customer", function() { }) describe("instance methods", function() { + it("can find all customers", function(done){ + customer.find_all(function(err, res){ + assert.equal(err, undefined); + assert.equal(res.length, 2); + done(); + }); + }); + it("can find a customer by id", function(done){ customer.find_by("id", 1, function(err, res) { assert.equal(err, undefined); @@ -43,16 +51,6 @@ describe("Customer", function() { }) }) - // it("can find a customer by title", function(done) { - // customer.find_by("title", "Jaws", function(err, res) { - // assert.equal(err, undefined); - // assert(res instanceof Array); - // assert.equal(res.length, 1); - // assert.equal(res[0].title, 'Jaws'); - // done(); - // }) - // }) - // it("can save changes to a customer", function(done) { // customer.find_by("title", "Jaws", function(err, res) { // var original_title = res[0].title; From 1b4a126e8e15a5ead92ec845fea801c5d38348dd Mon Sep 17 00:00:00 2001 From: Anita Date: Sun, 20 Sep 2015 23:12:09 -0700 Subject: [PATCH 041/189] added testing for customers.subset and removed console.log from subset method --- database_adapter.js | 1 - db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 45 ++++++++++++++++++++++++++++++++++------ 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 4b408c7..251f7b0 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -49,7 +49,6 @@ module.exports = { var db = new sqlite3.Database('db/' + db_env + '.db'); var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column + " LIMIT ? OFFSET ?"; - console.log(statement); db.all(statement, queries, function(err, res) { if (callback) { callback(err, res); } diff --git a/db/test.db b/db/test.db index 659edc8db9c28483fd4dc2a2329f538f2aa7d1f9..1c8e8cd0b7444b16faeacaa9e268e86c69b09fc1 100644 GIT binary patch delta 17 YcmZorXi%6S&3JI4j5FiGjR_0*0W`)2AOHXW delta 17 YcmZorXi%6S%@{dR#+fm4W5NP{04}ZtPyhe` diff --git a/test/models/customer.js b/test/models/customer.js index eadfd4c..ffa329e 100644 --- a/test/models/customer.js +++ b/test/models/customer.js @@ -48,14 +48,47 @@ describe("Customer", function() { assert(res instanceof Object); assert.equal(res.id, 1); done(); - }) - }) + }); + }); + + it("can return a subset of customers sorted by name", function(done){ + var queries = [1, 0] + customer.subset("name", queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 1); + assert.equal(res[0].name, "Dana Scully") + done(); + }); + }); + + it("can return a subset of customers sorted by registered_at", function(done){ + var queries = [1, 0] + customer.subset("registered_at", queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 2); + assert.equal(res[0].name, "Fox Mulder") + done(); + }); + }); + + it("can return a subset of customers sorted by postal_code", function(done){ + var queries = [1, 1] + customer.subset("postal_code", queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 2); + assert.equal(res[0].name, "Fox Mulder") + done(); + }); + }); // it("can save changes to a customer", function(done) { - // customer.find_by("title", "Jaws", function(err, res) { - // var original_title = res[0].title; - // var id = res[0].id; - // customer.save({title: "Jaws 2: Jawsier", id: id}, function(err, res) { + // customer.find_by("name", "Fox Mulder", function(err, res) { + // var original_name = res.name; + // var id = res.id; + // customer.save({name: "Foxy Mulder", id: id}, function(err, res) { // assert.equal(err, undefined); // assert.equal(res.inserted_id, 0); //it didn't insert any records // assert.equal(res.changed, 1); //it updated one record From 13fb4224ee827654e798db809d393fc87e7b3a50 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 09:16:58 -0700 Subject: [PATCH 042/189] added first test for --- db/test.db | Bin 4096 -> 4096 bytes npm-debug.log | 25 ------------------------- test/models/movie.js | 28 ++++++++++++++++++---------- 3 files changed, 18 insertions(+), 35 deletions(-) delete mode 100644 npm-debug.log diff --git a/db/test.db b/db/test.db index c2c1416344796ccdcce9465512d26332b6ab859f..700cb0dd922fc20e54e60f65ed5b38d6bb47f452 100644 GIT binary patch delta 90 zcmZorXi%6S&6qn;#+fm9W5N<<4kqT449riMPi_`u*~@G$$;8GWDlX6Hn^;~Po?n!! k7@1mJl3J9KSjjEL2$YhPXY>L}1!p7{Wh3Oc7O`*u0ENRD*Z=?k delta 25 hcmZorXi%6S%_uTa#+gxMW5N>V%`6;$*cb7z003Qm2QmNv diff --git a/npm-debug.log b/npm-debug.log deleted file mode 100644 index fbd43e8..0000000 --- a/npm-debug.log +++ /dev/null @@ -1,25 +0,0 @@ -0 info it worked if it ends with ok -1 verbose cli [ 'node', '/usr/local/bin/npm', 'run', 'db:schema' ] -2 info using npm@2.10.1 -3 info using node@v0.12.4 -4 verbose node symlink /usr/local/bin/node -5 verbose stack Error: missing script: db:schema -5 verbose stack at run (/usr/local/lib/node_modules/npm/lib/run-script.js:142:19) -5 verbose stack at /usr/local/lib/node_modules/npm/lib/run-script.js:58:5 -5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:345:5 -5 verbose stack at checkBinReferences_ (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:309:45) -5 verbose stack at final (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:343:3) -5 verbose stack at then (/usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:113:5) -5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/read-package-json/read-json.js:300:12 -5 verbose stack at evalmachine.:334:14 -5 verbose stack at /usr/local/lib/node_modules/npm/node_modules/graceful-fs/graceful-fs.js:102:5 -5 verbose stack at FSReqWrap.oncomplete (evalmachine.:95:15) -6 verbose cwd /Users/arhx/projects/Ada/project-forks/C3Projects--VideoStoreAPI -7 error Darwin 14.5.0 -8 error argv "node" "/usr/local/bin/npm" "run" "db:schema" -9 error node v0.12.4 -10 error npm v2.10.1 -11 error missing script: db:schema -12 error If you need help, you may report this error at: -12 error -13 verbose exit [ 1, true ] diff --git a/test/models/movie.js b/test/models/movie.js index cbb09ed..47c91ce 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -34,21 +34,29 @@ describe("Movie", function() { movie.find_by("id", 1, function(err, res) { assert.equal(err, undefined); assert(res instanceof Object); - // assert.equal(res.length, 1); assert.equal(res.id, 1); done(); }) }) - // it("can find a movie by title", function(done) { - // movie.find_by("title", "Jaws", function(err, res) { - // assert.equal(err, undefined); - // assert(res instanceof Array); - // assert.equal(res.length, 1); - // assert.equal(res[0].title, 'Jaws'); - // done(); - // }) - // }) + it("can find a movie by title", function(done) { + movie.find_by("title", "Jaws", function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Object); + assert.equal(res.title, 'Jaws'); + done(); + }) + }) + + it("can find all movies where a column has a particular value", function(done) { + movie.where(["title"], ["Jaws"], function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Object); // Why is this breaking? + assert.equal(res.length, 1); + assert.equal(res[0].title, "Jaws"); + done(); + }) + }) // it("can save changes to a movie", function(done) { // movie.find_by("title", "Jaws", function(err, res) { From a550937b29568ec8e164f732df5a663bea0ca457 Mon Sep 17 00:00:00 2001 From: Anita Date: Mon, 21 Sep 2015 10:23:50 -0700 Subject: [PATCH 043/189] WIP customers create function --- database_adapter.js | 18 +++++- db/test.db | Bin 4096 -> 4096 bytes routes/customers.js | 24 ++++++-- test/models/customer.js | 127 ++++++++++++++++++++++++++++++++++++++++ 4 files changed, 163 insertions(+), 6 deletions(-) create mode 100644 test/models/customer.js diff --git a/database_adapter.js b/database_adapter.js index 4b408c7..44827c4 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -49,12 +49,26 @@ module.exports = { var db = new sqlite3.Database('db/' + db_env + '.db'); var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column + " LIMIT ? OFFSET ?"; - console.log(statement); db.all(statement, queries, function(err, res) { if (callback) { callback(err, res); } db.close(); }); - } + }, + + // customers/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone + create: function(columns, values, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + var column_names = columns.join(', '); + var question_marks = Array(values.length + 1).join('?').split('').join(', '); + var statement = + "INSERT INTO " + this.table_name + " (" + column_names + ") \ + VALUES (" + question_marks + ");"; + + db.run(statement, values, function(err, res) { + if (callback) { callback(err, { inserted_id: this.lastID }); } + db.close(); + }); + } } diff --git a/db/test.db b/db/test.db index 21f695013f1c4cf135156d44a0b4a8ebbdec9bee..0ba2e23ff33125a1487b641789607e1e97447569 100644 GIT binary patch delta 258 zcmZorXi%6S&8Rg|#+gxTW5N=44kl(L2IgL7rOkpYV$AiKOk50#-n!C?;+jlu`4tMj zr8z07MQ%lzItqpc3SOl-3PuKorV56pRz}8F24)Jn2IdAp0V7>gBU1(cl+1jE;1a#y z)WnjKoYe5d;*89^^pgBMOAA8-OAR9fGff3!BTHQqOCt+L)j~!t24!zoSy7->E{S=G z3c<;x@i{q_;i)M=%ghuU3yMINnJ5?;TA3JF85uw<3()h|Q*Z)0&BDT5N5RC%)Lg+Q vzbG|VAt*)9IX|Z~H>tGPKO-~W#2Bbq!`R$VQ^Cy0T-VUhz?9|EA`TV+;Br7= delta 25 hcmZorXi%6S%_uQZ#+gxKW5N>l%`7~Bm>2P|003Sk2R;A* diff --git a/routes/customers.js b/routes/customers.js index 5bcffd0..50b0a15 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -19,16 +19,32 @@ router.get('/:id', function(req, res, next) { }); router.get('/:sort_by/:limit/:offset', function(req, res, next) { - var queries = []; - queries.push(req.params.limit); - queries.push(req.params.offset); + var values = []; + values.push(req.params.limit); + values.push(req.params.offset); var column = req.params.sort_by; - customer.subset(column, queries, function(err, rows) { + customer.subset(column, values, function(err, rows) { res.status(200).json({ customers: rows} ); }); }); +router.post('/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone', function(req, res, next) { + var values = []; + values.push(req.params.name); + values.push(req.params.registered_at); + values.push(req.params.address); + values.push(req.params.city); + values.push(req.params.state); + values.push(req.params.postal_code); + values.push(req.params.phone); + var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone'] + + customer.create(columns, values, function(err, pineapple) { + res.status(200).json(pineapple); + }); +}); + // DEBUGGER ROUTE // router.get('/:city', function(req, res, next) { diff --git a/test/models/customer.js b/test/models/customer.js new file mode 100644 index 0000000..7843efd --- /dev/null +++ b/test/models/customer.js @@ -0,0 +1,127 @@ +var assert = require('assert'), + Customer = require('../../models/customer'), + sqlite3 = require('sqlite3').verbose(); + +describe("Customer", function() { + var customer, db_cleaner; + + beforeEach(function(done) { + customer = new Customer(); + + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM customers; \ + INSERT INTO customers (name, registered_at, address, city, state, \ + postal_code, phone, account_credit) \ + VALUES ('Dana Scully', 'Wed, 16 Apr 2014 21:40:20 -0700', \ + 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ + '(371) 627-1105', 1234), \ + ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }) + + it("can be instantiated", function() { + assert(customer instanceof Customer); + }) + + describe("instance methods", function() { + it("can find all customers", function(done){ + customer.find_all(function(err, res){ + assert.equal(err, undefined); + assert.equal(res.length, 2); + done(); + }); + }); + + it("can find a customer by id", function(done){ + customer.find_by("id", 1, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Object); + assert.equal(res.id, 1); + done(); + }); + }); + + it("can return a subset of customers sorted by name", function(done){ + var queries = [1, 0] + customer.subset("name", queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 1); + assert.equal(res[0].name, "Dana Scully") + done(); + }); + }); + + it("can return a subset of customers sorted by registered_at", function(done){ + var queries = [1, 0] + customer.subset("registered_at", queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 2); + assert.equal(res[0].name, "Fox Mulder") + done(); + }); + }); + + it("can return a subset of customers sorted by postal_code", function(done){ + var queries = [1, 1] + customer.subset("postal_code", queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 2); + assert.equal(res[0].name, "Fox Mulder") + done(); + }); + }); + }); // end of describe instance methods + + describe("class methods", function() { + it("can create a new customer in the database", function(done) { + var data = { + name: "Ratboy", + registered_at: "Wed, 24 Feb 2012 18:22:18 -0700", + address: "55 Skinner Ave.", + city: "Vancouver", + state: "BC", + postal_code: "93840", + phone: "(385) 948-9282", + account_credit: 9900 + } + + customer.create(columns, values, function(err, res) { + assert.equal(res.inserted_id, 3); //it inserted a new record + // assert.equal(res.changed, 1); //one record was changed + + // customer.find_by("title", "RoboJaws", function(err, res) { + // assert.equal(res.length, 1); + // assert.equal(res[0].title, 'RoboJaws'); //we found our new customer + // done(); + // }) + }); + }); + }); + + // it("can save changes to a customer", function(done) { + // customer.find_by("name", "Fox Mulder", function(err, res) { + // var original_name = res.name; + // var id = res.id; + // customer.save({name: "Foxy Mulder", id: id}, function(err, res) { + // assert.equal(err, undefined); + // assert.equal(res.inserted_id, 0); //it didn't insert any records + // assert.equal(res.changed, 1); //it updated one record + // done(); + // }) + // }) + // }); + +}) From b03cc7b5ec4f4ba937226756cdb7922a2d5947fb Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 10:32:19 -0700 Subject: [PATCH 044/189] got test working --- database_adapter.js | 8 ++++---- db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 25 +++++++++++++++---------- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 44827c4..7d70add 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -60,11 +60,11 @@ module.exports = { create: function(columns, values, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); var column_names = columns.join(', '); - var question_marks = Array(values.length + 1).join('?').split('').join(', '); + var question_marks = Array(columns.length + 1).join('?').split('').join(', '); - var statement = - "INSERT INTO " + this.table_name + " (" + column_names + ") \ - VALUES (" + question_marks + ");"; + var statement = "INSERT INTO " + this.table_name + " (" + column_names + ") VALUES (" + question_marks + ");"; + + console.log(statement); db.run(statement, values, function(err, res) { if (callback) { callback(err, { inserted_id: this.lastID }); } diff --git a/db/test.db b/db/test.db index 0ba2e23ff33125a1487b641789607e1e97447569..dd74e797dbd06c5feadff8b9c1202dda4ac677e8 100644 GIT binary patch delta 133 zcmZorXi%6S&6qS%#+fl`W5N=4E@q}949vaEN=!#K3$kouii=_9VvzLKmKPM)WC%(u zNy@JbPfgKLFfvhaOHEQRGB7k!Fto5TGO{wXP|!6nH!v_YRS3?`%*#tHQgAFw)eB3^ lOU^GXOD%G8wluadG0-r!Fx6DBG_laNG_o+-ti*kf1pxnhBC`Mh delta 36 scmZorXi%6S&8Rg|#+gxTW5N=44kl(L2IgL7rOkpYV$7SBxbLw50HfXrbpQYW diff --git a/test/models/customer.js b/test/models/customer.js index df25318..e1f7304 100644 --- a/test/models/customer.js +++ b/test/models/customer.js @@ -87,16 +87,20 @@ describe("Customer", function() { describe("class methods", function() { it("can create a new customer in the database", function(done) { - var data = { - name: "Ratboy", - registered_at: "Wed, 24 Feb 2012 18:22:18 -0700", - address: "55 Skinner Ave.", - city: "Vancouver", - state: "BC", - postal_code: "93840", - phone: "(385) 948-9282", - account_credit: 9900 - } + // var data = { + // name: "Ratboy", + // registered_at: "Wed, 24 Feb 2012 18:22:18 -0700", + // address: "55 Skinner Ave.", + // city: "Vancouver", + // state: "BC", + // postal_code: "93840", + // phone: "(385) 948-9282", + // account_credit: 9900 + // } + + var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone']; + var values = ["Ratboy", "Wed, 24 Feb 2012 18:22:18 -0700", "55 Skinner Ave.", + "Vancouver", "BC", "93840", "(385) 948-9282"]; customer.create(columns, values, function(err, res) { assert.equal(res.inserted_id, 3); //it inserted a new record @@ -107,6 +111,7 @@ describe("Customer", function() { // assert.equal(res[0].title, 'RoboJaws'); //we found our new customer // done(); // }) + done(); }); }); }); From dafad209de7761ce908c6eae8239832639d8cfbf Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 10:41:50 -0700 Subject: [PATCH 045/189] removed comments in function --- database_adapter.js | 6 +++--- db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 22 ++++------------------ 3 files changed, 7 insertions(+), 21 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 7d70add..0afa110 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -56,15 +56,15 @@ module.exports = { }); }, + // Example route: // customers/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone create: function(columns, values, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); var column_names = columns.join(', '); var question_marks = Array(columns.length + 1).join('?').split('').join(', '); - var statement = "INSERT INTO " + this.table_name + " (" + column_names + ") VALUES (" + question_marks + ");"; - - console.log(statement); + var statement = "INSERT INTO " + this.table_name + " (" + column_names + ") \ + VALUES (" + question_marks + ");"; db.run(statement, values, function(err, res) { if (callback) { callback(err, { inserted_id: this.lastID }); } diff --git a/db/test.db b/db/test.db index dd74e797dbd06c5feadff8b9c1202dda4ac677e8..eabd0f05ff003ad650af7e43f9d41e8bce7f4641 100644 GIT binary patch delta 24 fcmZorXi%6S&Db?j#+k8eV?r_)W9;T5TsEu#V0{OW delta 24 fcmZorXi%6S&6qS%#+fl`V?r_)Bg5t+TsEu#S;q$B diff --git a/test/models/customer.js b/test/models/customer.js index e1f7304..c894c25 100644 --- a/test/models/customer.js +++ b/test/models/customer.js @@ -87,31 +87,17 @@ describe("Customer", function() { describe("class methods", function() { it("can create a new customer in the database", function(done) { - // var data = { - // name: "Ratboy", - // registered_at: "Wed, 24 Feb 2012 18:22:18 -0700", - // address: "55 Skinner Ave.", - // city: "Vancouver", - // state: "BC", - // postal_code: "93840", - // phone: "(385) 948-9282", - // account_credit: 9900 - // } - var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone']; var values = ["Ratboy", "Wed, 24 Feb 2012 18:22:18 -0700", "55 Skinner Ave.", "Vancouver", "BC", "93840", "(385) 948-9282"]; customer.create(columns, values, function(err, res) { assert.equal(res.inserted_id, 3); //it inserted a new record - // assert.equal(res.changed, 1); //one record was changed - // customer.find_by("title", "RoboJaws", function(err, res) { - // assert.equal(res.length, 1); - // assert.equal(res[0].title, 'RoboJaws'); //we found our new customer - // done(); - // }) - done(); + customer.find_by("name", "Ratboy", function(err, res) { + assert.equal(res.name, 'Ratboy'); //we found our new customer + done(); + }); }); }); }); From 58438980cea7f4b0479c5956b68d472a05e22be9 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 11:07:09 -0700 Subject: [PATCH 046/189] got test and function working for update --- database_adapter.js | 21 +++++++++++++++++++++ db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 19 +++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/database_adapter.js b/database_adapter.js index 0afa110..5545313 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -70,5 +70,26 @@ module.exports = { if (callback) { callback(err, { inserted_id: this.lastID }); } db.close(); }); + }, + + // Example route: + // customers/update/:id?name=name&city=city&state=state + update: function(id, columns, values, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + // "column1 = ?, column2 = ?, column3 = ?" + var columnsQueries = []; + + for (var i = 0; i < columns.length; i++) { + columnsQueries.push(columns[i] + " = ?"); + }; + + var update_statement = columnsQueries.join(', '); + + var statement = "UPDATE " + this.table_name + " SET " + update_statement + "WHERE id = " + id + ";"; + + db.run(statement, values, function(err, res) { + if (callback) { callback(err, { changes: this.changes }); } + db.close(); + }); } } diff --git a/db/test.db b/db/test.db index eabd0f05ff003ad650af7e43f9d41e8bce7f4641..b3dfefb4d22f7c014693df941fc7166dc16d26db 100644 GIT binary patch delta 76 zcmZorXi%6S#l*-vQN{^KZcJFh&c(#6!NArpbr7QU#KkxEPeZb!7#` fHJRM Date: Mon, 21 Sep 2015 11:12:44 -0700 Subject: [PATCH 047/189] added Rental model --- models/rental.js | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 models/rental.js diff --git a/models/rental.js b/models/rental.js new file mode 100644 index 0000000..6753719 --- /dev/null +++ b/models/rental.js @@ -0,0 +1,9 @@ +"use strict"; + +function Rental() { + this.table_name = "rentals"; +} + +Rental.prototype = require('../database_adapter'); + +module.exports = Rental; From 5686f852dcbc4f8c72d2c401bd39c0e23e45af61 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 11:30:23 -0700 Subject: [PATCH 048/189] added checkout route and pseudocode for inventory check --- routes/rentals.js | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 routes/rentals.js diff --git a/routes/rentals.js b/routes/rentals.js new file mode 100644 index 0000000..5d5498d --- /dev/null +++ b/routes/rentals.js @@ -0,0 +1,35 @@ +var express = require('express'); +var router = express.Router(); + +var Rental = require('../models/rental'), + rental = new Rental(); + +var RENTAL_PERIOD = 5; // 5 days + +router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { + // add check for if there is an available movie for checkout + // query db to count # of rentals with that movie id + // check movie record to get inventory + // compare # of rentals with inventory + // if inventory <= rentals, return message NO + // else proceed with checkout + + var values = []; + values.push(req.params.customer_id); + values.push(req.params.movie_id); + + var checkout_date = new Date(); + var return_date = new Date(); + return_date.setDate(return_date.getDate() + RENTAL_PERIOD); + + var defaults = [checkout_date, return_date, "false"]; + + values = values + defaults; + var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; + + rental.create(columns, values, function(err, res) { + res.status(200).json(res); + }); +}); + +module.exports = router; From e1eecc82240e204ae980d8641db167d9f70e386d Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 11:30:45 -0700 Subject: [PATCH 049/189] changed variable name from pineapple to res --- routes/customers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 50b0a15..6df4a31 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -40,8 +40,8 @@ router.post('/create/:name/:registered_at/:address/:city/:state/:postal_code/:ph values.push(req.params.phone); var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone'] - customer.create(columns, values, function(err, pineapple) { - res.status(200).json(pineapple); + customer.create(columns, values, function(err, res) { + res.status(200).json(res); }); }); From fa98a3467ec06ce2f551d06360014d0bd621e491 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 11:41:03 -0700 Subject: [PATCH 050/189] added where to namespace debugger where route --- routes/customers.js | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 6df4a31..e92bd74 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -47,15 +47,15 @@ router.post('/create/:name/:registered_at/:address/:city/:state/:postal_code/:ph // DEBUGGER ROUTE -// router.get('/:city', function(req, res, next) { -// var values = []; -// values.push(req.params.city); -// console.log(values); - -// customer.where(['city'], values, function(err, rows) { -// console.log(values); -// res.status(200).json({ customers: rows} ); -// }); -// }); +router.get('/where/:city', function(req, res, next) { + var values = []; + values.push(req.params.city); + console.log(values); + + customer.where(['city'], values, function(err, rows) { + console.log(rows.length); + res.status(200).json({ customers: rows} ); + }); +}); module.exports = router; From cb18c02623874500c8f8a6e29ec8ac37d01b5e50 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 11:41:40 -0700 Subject: [PATCH 051/189] added rental_movies_count to checkout route --- routes/rentals.js | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 5d5498d..287b5fa 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -4,19 +4,29 @@ var router = express.Router(); var Rental = require('../models/rental'), rental = new Rental(); +var Movie = require('../models/movie'), + movie = new Movie(); + var RENTAL_PERIOD = 5; // 5 days router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { - // add check for if there is an available movie for checkout + // add check for if there is an available movie for checkout: // query db to count # of rentals with that movie id // check movie record to get inventory // compare # of rentals with inventory // if inventory <= rentals, return message NO // else proceed with checkout + var movie_id = req.params.movie_id; + var rented_movies_count = movie.where(['id'], movie_id, function(err, rows) { + return rows.length; + }); + + + var values = []; values.push(req.params.customer_id); - values.push(req.params.movie_id); + values.push(movie_id); var checkout_date = new Date(); var return_date = new Date(); From c905a1208b2d063f1fa9fca3c08d11de904d6810 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 13:23:38 -0700 Subject: [PATCH 052/189] added unit tests for subset, create, and update --- db/test.db | Bin 0 -> 4096 bytes test/models/movie.js | 97 +++++++++++++++++++++++++++---------------- 2 files changed, 61 insertions(+), 36 deletions(-) create mode 100644 db/test.db diff --git a/db/test.db b/db/test.db new file mode 100644 index 0000000000000000000000000000000000000000..5d40bc2ede6a0ea154dd46e4ba728b8f8bd24cdb GIT binary patch literal 4096 zcmeHJ&2HL25cUrxQlcIzH9{zgn5eA;Dn|BVgW*(2AtfYD3Q^NYm5{Nwu!`}f_L_tv zxmUg9F?!7#^a=V7?Q?YbOG2x(*C=77-JKne_nY}Vv+L%&9l|htqJGa}kQE|=C|m9wK#k5kNHASeyu#_2D0=>kWZy=d|I@-#=!8oycAno6VDUOYP;CS z9<$tFIz=`cmC`{44oc;n3QU!dBo5Tx9#pm}4cKqgc1w*Ts8^2CV21&tJ?yu*0r42_ zU_T8#+9!BUV|THAOheXkES`Q0pRqLGn}xpjw+1_7gVgYiv=mDu#PinJ%^6Z~CCGEG zUa4<)*0Xxo;2jb$9=p@xg)ni*avUEA!E|L4HkgV5yY~8o@|D}NsWaQ^q)WY-Y}qyq zJ=U`M#)QonNe!doQY;=9hn;aKV}63kD9r^i(cK;aBg~y)(LVM$&!JP3Q8P%pFUkdV1`BMIR*AjE#&w_ym#XwPx3R~K$c+kc0L8%fK2SuooPM04^ zTvZME35iP?DJs-re^}Mv(DJw$g)(*t?&Cv#r*9xtHCN(dR9KC#i`&*|(Ck|NF;{Db zT0rXZr2dnF{6$Vm-yam$i(u~w10UsOAzpu(coItq4U4tu;1D}$Ksr=$8+fWC(99x2 zMa=|7&8wQs$C>w*$1iDqd6qW|SyNY&S<^^CK{u5GG7*uMg^jw+$7gkA zonuHn1^+_5u6}Cfn1Z03_6j8RQ<|aUzffNH7u;&m8O_q62Y<~L^ivyXO zT1X-_mx3%RC^|rSH4a!@+)M<6;Nt*EO-q)tHgGkX~* z(=#y5d>V9Q Date: Mon, 21 Sep 2015 14:20:23 -0700 Subject: [PATCH 053/189] registered rentals routes --- app.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/app.js b/app.js index 0ed6ea4..d50b4f4 100644 --- a/app.js +++ b/app.js @@ -32,6 +32,10 @@ app.use('/movies', movie_routes); var customer_routes = require('./routes/customers'); app.use('/customers', customer_routes); +// register rental routes +var rental_routes = require('./routes/rentals'); +app.use('/rentals', rental_routes); + // catch 404 and forward to error handler app.use(function(req, res, next) { var err = new Error('Not Found'); From ee62581cf649d16eeb0e09d24899b54c3520561d Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 14:20:48 -0700 Subject: [PATCH 054/189] clarified comment purpose --- database_adapter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/database_adapter.js b/database_adapter.js index 5545313..337c216 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -76,7 +76,7 @@ module.exports = { // customers/update/:id?name=name&city=city&state=state update: function(id, columns, values, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - // "column1 = ?, column2 = ?, column3 = ?" + // eg. "column1 = ?, column2 = ?, column3 = ?" var columnsQueries = []; for (var i = 0; i < columns.length; i++) { From 37b5b4835549e0966824c42e7ca794e699759d8f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 14:21:06 -0700 Subject: [PATCH 055/189] WIP; fixing logic on checkout route --- routes/rentals.js | 61 ++++++++++++++++++++++++++++------------------- 1 file changed, 36 insertions(+), 25 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 287b5fa..7763a85 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -10,36 +10,47 @@ var Movie = require('../models/movie'), var RENTAL_PERIOD = 5; // 5 days router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { - // add check for if there is an available movie for checkout: + // Add check for if there is an available movie for checkout: // query db to count # of rentals with that movie id - // check movie record to get inventory - // compare # of rentals with inventory - // if inventory <= rentals, return message NO - // else proceed with checkout + // TODO: check only returned = false var movie_id = req.params.movie_id; - var rented_movies_count = movie.where(['id'], movie_id, function(err, rows) { - return rows.length; + var rented_movies_count = movie.where(['id', 'returned'], [movie_id, 'false'], function(err, rows) { + rows.length; }); - - - - var values = []; - values.push(req.params.customer_id); - values.push(movie_id); - - var checkout_date = new Date(); - var return_date = new Date(); - return_date.setDate(return_date.getDate() + RENTAL_PERIOD); - - var defaults = [checkout_date, return_date, "false"]; - - values = values + defaults; - var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; - - rental.create(columns, values, function(err, res) { - res.status(200).json(res); + // check movie record to get inventory + var relevant_movie = movie.find_by('id', movie_id, function(err, row) { + row; }); + + var inventory = relevant_movie[0].inventory; + console.log(inventory); + // compare # of rentals with inventory + if (rented_movies_count >= inventory) { + // if inventory <= rentals, return message NO + res.status(403).json({ error: "There are no available copies of that movie for rental." }) + } else { + // else proceed with checkout + var values = []; + values.push(req.params.customer_id); + values.push(movie_id); + + var checkout_date = new Date(); + var return_date = new Date(); + return_date.setDate(return_date.getDate() + RENTAL_PERIOD); + + var defaults = [checkout_date, return_date, "false"]; + + for (var i = 0; i < defaults.length; i++) { + values.push(defaults[i]); + } + + var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; + + rental.create(columns, values, function(err, res) { + res.status(200).json(res); + }); + } }); module.exports = router; From bd2edbacd56e45cd85dd9002d0dbed1cb3e62dd5 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 14:26:50 -0700 Subject: [PATCH 056/189] used concat function in place of loop to add arrays --- routes/rentals.js | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 7763a85..854c66b 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -40,10 +40,7 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { return_date.setDate(return_date.getDate() + RENTAL_PERIOD); var defaults = [checkout_date, return_date, "false"]; - - for (var i = 0; i < defaults.length; i++) { - values.push(defaults[i]); - } + values = values.concat(defaults); var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; From 6c747f64b85a723e34c28a10695943daf1a71d9a Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 15:01:01 -0700 Subject: [PATCH 057/189] WIP; figuring out callbacks --- routes/rentals.js | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 854c66b..56cb3fc 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -13,10 +13,21 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { // Add check for if there is an available movie for checkout: // query db to count # of rentals with that movie id // TODO: check only returned = false + + // countCheckoutMovies = function() + // compareWithInventory + // respondToCall + // -> either send error message or execute checkout based on answer + + // + var movie_id = req.params.movie_id; - var rented_movies_count = movie.where(['id', 'returned'], [movie_id, 'false'], function(err, rows) { - rows.length; - }); + + var rented_movies = function(next) { + movie.where(['id', 'returned'], [movie_id, 'false'], function(err, rows) { + next(rows); + }); + } // check movie record to get inventory var relevant_movie = movie.find_by('id', movie_id, function(err, row) { @@ -48,6 +59,8 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { res.status(200).json(res); }); } + + async.series([rented_movies, ]) }); module.exports = router; From 77092d99a5d531754b32a7673e3f91e2171e0530 Mon Sep 17 00:00:00 2001 From: Anita Date: Mon, 21 Sep 2015 15:12:54 -0700 Subject: [PATCH 058/189] WIP rentals post action --- routes/rentals.js | 82 ++++++++++++++++++++++++++--------------------- 1 file changed, 46 insertions(+), 36 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 56cb3fc..8110338 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -14,7 +14,6 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { // query db to count # of rentals with that movie id // TODO: check only returned = false - // countCheckoutMovies = function() // compareWithInventory // respondToCall // -> either send error message or execute checkout based on answer @@ -23,44 +22,55 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { var movie_id = req.params.movie_id; - var rented_movies = function(next) { - movie.where(['id', 'returned'], [movie_id, 'false'], function(err, rows) { - next(rows); - }); - } - - // check movie record to get inventory - var relevant_movie = movie.find_by('id', movie_id, function(err, row) { - row; - }); - - var inventory = relevant_movie[0].inventory; - console.log(inventory); - // compare # of rentals with inventory - if (rented_movies_count >= inventory) { - // if inventory <= rentals, return message NO - res.status(403).json({ error: "There are no available copies of that movie for rental." }) - } else { - // else proceed with checkout - var values = []; - values.push(req.params.customer_id); - values.push(movie_id); - - var checkout_date = new Date(); - var return_date = new Date(); - return_date.setDate(return_date.getDate() + RENTAL_PERIOD); - - var defaults = [checkout_date, return_date, "false"]; - values = values.concat(defaults); - - var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; - - rental.create(columns, values, function(err, res) { - res.status(200).json(res); + function countCheckedOutMovies(movie_id) { + var count; + rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { + console.log(rows); + count = rows.length; }); + return count; } - async.series([rented_movies, ]) + console.log(countCheckedOutMovies(movie_id)); + + // var rented_movies = function(next) { + // movie.where(['id', 'returned'], [movie_id, 'false'], function(err, rows) { + // next(rows); + // }); + // } + + // // check movie record to get inventory + // var relevant_movie = movie.find_by('id', movie_id, function(err, row) { + // row; + // }); + + // var inventory = relevant_movie[0].inventory; + // console.log(inventory); + // // compare # of rentals with inventory + // if (rented_movies_count >= inventory) { + // // if inventory <= rentals, return message NO + // res.status(403).json({ error: "There are no available copies of that movie for rental." }) + // } else { + // // else proceed with checkout + // var values = []; + // values.push(req.params.customer_id); + // values.push(movie_id); + + // var checkout_date = new Date(); + // var return_date = new Date(); + // return_date.setDate(return_date.getDate() + RENTAL_PERIOD); + + // var defaults = [checkout_date, return_date, "false"]; + // values = values.concat(defaults); + + // var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; + + // rental.create(columns, values, function(err, res) { + // res.status(200).json(res); + // }); + // } + + // async.series([rented_movies, ]) }); module.exports = router; From 0659edb3c3e903cfc40ed52ae0f729885a14bc38 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 15:48:35 -0700 Subject: [PATCH 059/189] added async to packages --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index d339874..c734139 100644 --- a/package.json +++ b/package.json @@ -10,6 +10,7 @@ "db:setup": "npm run db:schema; npm run db:seed" }, "dependencies": { + "async": "^1.4.2", "body-parser": "~1.13.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", From f99afd49cd95a057ed289a59d0cecf4c174b6efd Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 15:49:04 -0700 Subject: [PATCH 060/189] WIP; working on getting functions to execute synchronously --- routes/rentals.js | 98 +++++++++++++++++++++++------------------------ 1 file changed, 49 insertions(+), 49 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 8110338..69d4f4e 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -1,3 +1,4 @@ +var async = require('async'); var express = require('express'); var router = express.Router(); @@ -22,55 +23,54 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { var movie_id = req.params.movie_id; - function countCheckedOutMovies(movie_id) { - var count; - rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { - console.log(rows); - count = rows.length; - }); - return count; - } - - console.log(countCheckedOutMovies(movie_id)); - - // var rented_movies = function(next) { - // movie.where(['id', 'returned'], [movie_id, 'false'], function(err, rows) { - // next(rows); - // }); - // } - - // // check movie record to get inventory - // var relevant_movie = movie.find_by('id', movie_id, function(err, row) { - // row; - // }); - - // var inventory = relevant_movie[0].inventory; - // console.log(inventory); - // // compare # of rentals with inventory - // if (rented_movies_count >= inventory) { - // // if inventory <= rentals, return message NO - // res.status(403).json({ error: "There are no available copies of that movie for rental." }) - // } else { - // // else proceed with checkout - // var values = []; - // values.push(req.params.customer_id); - // values.push(movie_id); - - // var checkout_date = new Date(); - // var return_date = new Date(); - // return_date.setDate(return_date.getDate() + RENTAL_PERIOD); - - // var defaults = [checkout_date, return_date, "false"]; - // values = values.concat(defaults); - - // var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; - - // rental.create(columns, values, function(err, res) { - // res.status(200).json(res); - // }); - // } - - // async.series([rented_movies, ]) + var count; + var inventory; + + async.series([ + function countCheckedOutMovies(movie_id, callback) { + rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { + count = rows.length; + callback(null, count); + }); + }, + + function retrieveInventory(movie_id, callback) { + movie.find_by('id', movie_id, function(err, row) { + inventory = row.inventory; + callback(null, inventory); + }) + } + ], + + function compareCountInventory(err, results) { + console.log(results); + + count = results[0]; + inventory = results[1]; + + if (count >= inventory) { + // if inventory <= rentals, return message NO + res.status(403).json({ error: "There are no available copies of that movie for rental." }) + } else { + // proceed with checkout + var values = []; + values.push(req.params.customer_id); + values.push(movie_id); + + var checkout_date = new Date(); + var return_date = new Date(); + return_date.setDate(return_date.getDate() + RENTAL_PERIOD); + + var defaults = [checkout_date, return_date, "false"]; + values = values.concat(defaults); + + var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; + + rental.create(columns, values, function(err, results) { + res.status(200).json({ success: "Yay! You checked out a movie." }); + }); + } + }); }); module.exports = router; From 05804166b9a8bd104c0a149066313756ca7e29e0 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Mon, 21 Sep 2015 21:37:23 -0700 Subject: [PATCH 061/189] got the checkout route operational --- routes/rentals.js | 87 ++++++++++++++++++++++------------------------- 1 file changed, 40 insertions(+), 47 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 69d4f4e..0cae3ef 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -11,66 +11,59 @@ var Movie = require('../models/movie'), var RENTAL_PERIOD = 5; // 5 days router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { - // Add check for if there is an available movie for checkout: - // query db to count # of rentals with that movie id - // TODO: check only returned = false - - // compareWithInventory - // respondToCall - // -> either send error message or execute checkout based on answer - - // - var movie_id = req.params.movie_id; + var count, inventory, enoughInventory; - var count; - var inventory; - - async.series([ - function countCheckedOutMovies(movie_id, callback) { + async.waterfall([ + function(callback) { rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { count = rows.length; + // console.log(count, rows, typeof(count)); callback(null, count); - }); + }) }, - - function retrieveInventory(movie_id, callback) { + function(movieCount, callback) { movie.find_by('id', movie_id, function(err, row) { + // don't need inventory, could call row.inventory on line 29 inventory = row.inventory; - callback(null, inventory); + enoughInventory = (movieCount < inventory) ? true : false; + // console.log(row, inventory, typeof(inventory)); + callback(null, enoughInventory); }) } - ], - - function compareCountInventory(err, results) { - console.log(results); - - count = results[0]; - inventory = results[1]; - - if (count >= inventory) { - // if inventory <= rentals, return message NO - res.status(403).json({ error: "There are no available copies of that movie for rental." }) - } else { - // proceed with checkout - var values = []; - values.push(req.params.customer_id); - values.push(movie_id); - - var checkout_date = new Date(); - var return_date = new Date(); - return_date.setDate(return_date.getDate() + RENTAL_PERIOD); + ], function(err, result) { + // if result, which equals enoughInventory, is false, return message NO + if (result == false) { + res.status(403).json({ error: "There are no available copies of that movie for rental." }) + } else { // proceed with checkout + var values = []; + values.push(req.params.customer_id); + values.push(movie_id); + + var checkout_date = new Date(); + var return_date = new Date(); + return_date.setDate(return_date.getDate() + RENTAL_PERIOD); + + var defaults = [checkout_date, return_date, "false"]; + values = values.concat(defaults); + + var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; + + rental.create(columns, values, function(err, results) { + res.status(200).json({ success: "Yay! You checked out a movie." }); + }); + } + }); - var defaults = [checkout_date, return_date, "false"]; - values = values.concat(defaults); + // countCheckedOutMovies( + // retrieveCompareInventory( + // createRental( + // ) + // ) + // ); - var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; + // retrieveCompareInventory(createRental()); - rental.create(columns, values, function(err, results) { - res.status(200).json({ success: "Yay! You checked out a movie." }); - }); - } - }); }); module.exports = router; From 2fd914a038e0d1747a74fb8172b7295a5b3928f9 Mon Sep 17 00:00:00 2001 From: Anita Date: Mon, 21 Sep 2015 22:03:31 -0700 Subject: [PATCH 062/189] added comments and removed extraneous code --- db/development.db | Bin 73728 -> 73728 bytes routes/rentals.js | 14 ++------------ 2 files changed, 2 insertions(+), 12 deletions(-) diff --git a/db/development.db b/db/development.db index ae5a9dcf498218c3b99b2aefc05c6849a8216d26..d29298c54c61d811d8cd934bba19afbd311e9375 100644 GIT binary patch delta 273 zcmZoTz|wGlWr8%L%|sbzMw^WZOSt)1ndKOmuP`rXu449KmfI}I!^2#!!^+OU$f&I? z&ctbGVq#=rX<=w;Vrp)oX8`0H8yg$IxM_(w#i=?hFx9Lu)g~rpCMF2gP%c=tHZwZ| zC&+Aeh+=ayOEUu_W2j;yOCUEH%!jCEf~sbMt2Qz)g&7S}4dH?nYcT>9a{`TqskJaP Tx3EN*4CR8=HVG^fU=#oV8UQ#D delta 38 ucmZoTz|wGlWr8%L`9v9KM)QpcOSqXBShfqwFtRdFHsJZ%B(O|?Q2+qna0+Aq diff --git a/routes/rentals.js b/routes/rentals.js index 0cae3ef..25294f2 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -15,19 +15,19 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { var count, inventory, enoughInventory; async.waterfall([ + // count total # of checked out copies of movie with id, movie_id function(callback) { rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { count = rows.length; - // console.log(count, rows, typeof(count)); callback(null, count); }) }, + // check if enough inventory of movie is available (true/false) function(movieCount, callback) { movie.find_by('id', movie_id, function(err, row) { // don't need inventory, could call row.inventory on line 29 inventory = row.inventory; enoughInventory = (movieCount < inventory) ? true : false; - // console.log(row, inventory, typeof(inventory)); callback(null, enoughInventory); }) } @@ -54,16 +54,6 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { }); } }); - - // countCheckedOutMovies( - // retrieveCompareInventory( - // createRental( - // ) - // ) - // ); - - // retrieveCompareInventory(createRental()); - }); module.exports = router; From 27cc703803d8ce47aa125a40aa0003c95af55bcd Mon Sep 17 00:00:00 2001 From: Anita Date: Tue, 22 Sep 2015 14:20:03 -0700 Subject: [PATCH 063/189] added rentals seed data --- db/development.db | Bin 73728 -> 76800 bytes routes/rentals.js | 4 +- utils/rentals.json | 233 +++++++++++++++++++++++++++++++++++++++++++++ utils/seed.js | 20 ++++ 4 files changed, 255 insertions(+), 2 deletions(-) create mode 100644 utils/rentals.json diff --git a/db/development.db b/db/development.db index d29298c54c61d811d8cd934bba19afbd311e9375..7ed09c2ae6396dac63b8dd995cb122c79689ca96 100644 GIT binary patch delta 3726 zcmeH}O>7%Q9K~mLW@9_C9VfA~`EZg=nlx#fw7a&~aom*HiPKM|pf(jnil9+qgrJBD zQUvA0H9`oa9$L8)oDj$=y&%!Xhr)@RP(VoBP!ByI!2ux-2%!jxD)9c^O%qX!?3@$n z{Z^jre`ogX%$vEqA}`;SS38>32xII7wDI@hwc&`OMsA)Mv6EIM4_5^#b88KqgPfuv4tNQ5#MYx6Lwjk++VtZ3gL<(t1+d%+)Y|jlx>(2 z^SGFYTUJO^@?<_&{vey4(7VOlP8s!CwIi0xuF^!chL9f(*;F0Xks($1kyLTB2a{wQ zZbW6d)(TZL1773|Otg(zLuN#UQ&o!>F~u&@YOx|a!Cg%Ccwj|EC$RE-I#3_*fr@Bl z;tIgn5$G^91<_JYLn&w+qR^ta8iod;T@WP@E$Rk{f`Za50a3P5ti%|ihLV6HjuMVi zW(1;)+Y1drlsN+sXr%Pwl#mq4bPq+|F^C>cNmdR{T&Z1_`qkh0`>j3vm*t>z7iGUJN?rB` z*enxYiuc5<=-J6IL{YW#bSJ}{px+4foea~rTJf(8>;C^OfB6TA^*HXV$FD^}%wav= zQ;N!SI8&_g5`T?nxQ~6uuGnXaskrWJy9u@0DQoY#JUM)Wv_{M+GSdJ!5q_1XD>J>EaxN=i8*aJojmwbjdb8j zcTgdAo5A*KJZUd?lh#s?Z^x51=iM%~)Z|HAqcbEL+|4EtSrf^T$WS=sJp)2P?Tr!uV0~$ye0XYg4R#hMI9Hb zOsw8%3UgHy4DT0-c<;tnzJ02eS6aSBd-@;f_H*tosdImeq70z76||nibrt#(`WAz} skLx0ISKg2u*8~)XF36iw@<36>@MB5dkwH$+I#16UM$;>J`p|vx5AYz=%>V!Z delta 885 zcmYMxKTH!*90%}w_kP#A!hwa>QfjFM3lv&Qd%d<-C|WBT644m{Bn%{CKqpL0)Wk4Y z&Nw(QNV+&UnAF(C#6Oo<2M0!D92^)N9UP2taBy%S;`jBBH2Hnr{oZ}^d+*YXFSM~u zkAnSjQIe#2ROeUTN*J=(a1V+HXFz^q7gF)aO1pNWf=LZM8pw|O>dV#J3w;O0Kpb~I#1qOHpO7o7c z-RG54b`H&)orEXtF<7?4@PsXfmTWQWxGhE;y9Z|PfZ`2MSOr;eL*)`kh>sr^UwdR4 zgbgq#zQQMN?Ge}P7MJVNdZ5C?65rub#OrREe>8d_Z=mP1CRnRyu2D z^Hws2Hj~MuI_>qVYqzc?sFPMYY17P^=6<@}Hq&vgN^UV*ZH4o>LM~-w+F_%BcBR?3 z(sDa3|4$pKY-hAcx7ucSk|FHI=uXy3=dHs2qcKO=~ zBXa1rObwUL{_-0A!rKJOLY4FyEn;0mJwUxfeL#IfEl{083=e3G1rn z&`m~;a(A!0Mw=M)1iR0$`-*9fvc0F)=o5B!@a8*K6BR=hQOl@@xYc8s9M=nRsn6K? ciu#G#^)$%Gn5J^S#5cJg|6&)f`n^B?0oJLVyZ`_I diff --git a/routes/rentals.js b/routes/rentals.js index 25294f2..be98919 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -29,12 +29,12 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { inventory = row.inventory; enoughInventory = (movieCount < inventory) ? true : false; callback(null, enoughInventory); - }) + }); } ], function(err, result) { // if result, which equals enoughInventory, is false, return message NO if (result == false) { - res.status(403).json({ error: "There are no available copies of that movie for rental." }) + res.status(403).json({ error: "There are no available copies of that movie for rental." }); } else { // proceed with checkout var values = []; values.push(req.params.customer_id); diff --git a/utils/rentals.json b/utils/rentals.json new file mode 100644 index 0000000..08c201b --- /dev/null +++ b/utils/rentals.json @@ -0,0 +1,233 @@ +[ + { + "customer_id": 1, + "movie_id": 1, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 1, + "checkout_date": "01 Nov 2004 06:19:02", + "return_date": "06 Nov 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 1, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + }, + { + "customer_id": 1, + "movie_id": 1, + "checkout_date": "10 May 2011 02:58:43", + "return_date": "15 May 2011 02:58:43", + "returned": "true" + }, + { + "customer_id": 1, + "movie_id": 1, + "checkout_date": "03 Oct 2012 00:25:08", + "return_date": "11 Oct 2012 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 2, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 3, + "checkout_date": "01 Nov 2004 06:19:02", + "return_date": "06 Nov 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 2, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + }, + { + "customer_id": 1, + "movie_id": 3, + "checkout_date": "10 May 2011 02:58:43", + "return_date": "15 May 2011 02:58:43", + "returned": "true" + }, + { + "customer_id": 2, + "movie_id": 2, + "checkout_date": "03 Oct 2012 00:25:08", + "return_date": "11 Oct 2012 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 2, + "movie_id": 4, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 2, + "movie_id": 4, + "checkout_date": "01 Nov 2004 06:19:02", + "return_date": "06 Nov 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 34, + "movie_id": 89, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + }, + { + "customer_id": 10, + "movie_id": 7, + "checkout_date": "10 May 2011 02:58:43", + "return_date": "15 May 2011 02:58:43", + "returned": "false" + }, + { + "customer_id": 100, + "movie_id": 5, + "checkout_date": "03 Oct 2012 00:25:08", + "return_date": "11 Oct 2012 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 134, + "movie_id": 71, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 14, + "checkout_date": "01 Nov 2004 06:19:02", + "return_date": "06 Nov 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 1, + "movie_id": 16, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + }, + { + "customer_id": 14, + "movie_id": 13, + "checkout_date": "10 May 2011 02:58:43", + "return_date": "15 May 2011 02:58:43", + "returned": "true" + }, + { + "customer_id": 94, + "movie_id": 7, + "checkout_date": "03 Oct 2012 00:25:08", + "return_date": "11 Oct 2012 07:54:14 -0700", + "returned": "true" + }, + { + "customer_id": 2, + "movie_id": 4, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 165, + "movie_id": 5, + "checkout_date": "01 Nov 2004 06:19:02", + "return_date": "06 Nov 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 198, + "movie_id": 54, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + }, + { + "customer_id": 122, + "movie_id": 19, + "checkout_date": "10 May 2011 02:58:43", + "return_date": "15 May 2011 02:58:43", + "returned": "true" + }, + { + "customer_id": 64, + "movie_id": 87, + "checkout_date": "03 Oct 2012 00:25:08", + "return_date": "11 Oct 2012 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 39, + "movie_id": 25, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 28, + "movie_id": 99, + "checkout_date": "19 Sep 2015 06:19:02", + "return_date": "24 Sep 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 32, + "movie_id": 85, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + }, + { + "customer_id": 13, + "movie_id": 13, + "checkout_date": "10 May 2011 02:58:43", + "return_date": "15 May 2011 02:58:43", + "returned": "true" + }, + { + "customer_id": 14, + "movie_id": 14, + "checkout_date": "03 Oct 2012 00:25:08", + "return_date": "11 Oct 2012 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 12, + "movie_id": 29, + "checkout_date": "29 Apr 2015 07:54:14 -0700", + "return_date": "3 May 2015 07:54:14 -0700", + "returned": "false" + }, + { + "customer_id": 56, + "movie_id": 5, + "checkout_date": "01 Nov 2004 06:19:02", + "return_date": "06 Nov 2004 18:19:02", + "returned": "false" + }, + { + "customer_id": 177, + "movie_id": 82, + "checkout_date": "03 Dec 2009 02:58:43", + "return_date": "08 Dec 2009 06:19:02", + "returned": "true" + } +] diff --git a/utils/seed.js b/utils/seed.js index 992f9ff..ba83048 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -16,6 +16,12 @@ var customer_statement = db.prepare( postal_code, phone, account_credit) VALUES (?, ?, ?, ?, ?, ?, ?, ?);" ); +var rentals = require('./rentals'); +var rental_statement = db.prepare( + "INSERT INTO rentals(customer_id, movie_id, checkout_date, return_date, returned) \ + VALUES (?, ?, ?, ?, ?);" + ); + db.serialize(function() { // loop thru movies for (var i = 0; i < movies.length; i++) { @@ -48,6 +54,20 @@ db.serialize(function() { } customer_statement.finalize(); + + for (var i = 0; i < rentals.length; i++) { + var rental = rentals[i]; + + rental_statement.run( + rental.customer_id, + rental.movie_id, + rental.checkout_date, + rental.return_date, + rental.returned // boolean + ); + } + + rental_statement.finalize(); }); db.close(); From 21c72df7981bd16156cba332a8467c597bf4f19a Mon Sep 17 00:00:00 2001 From: Anita Date: Tue, 22 Sep 2015 14:22:09 -0700 Subject: [PATCH 064/189] added rentals seed data --- db/development.db | Bin 76800 -> 76800 bytes utils/rentals.json | 4 ++-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/db/development.db b/db/development.db index 7ed09c2ae6396dac63b8dd995cb122c79689ca96..1ce3fdeae9eb429f5e9bf388998dcf77b2d83ba7 100644 GIT binary patch delta 1106 zcmXw%OGs2v7=Z7&=gc_jsN;KlkMH+;d~3en6_N%*LP9Pg3R+ZzMB@b)K`zt@Y0)B@ z$`(Q86b7|u(Ly4kMGK)8EnKuHXi?EZwC`Uu@O^XUznA~~k6GF^OS@(@JH@?WS=J={ z|GZeMX|mlL&*nFk@`pY4LzNkRV!u-v;YGcs>Z4v$szaS;czx_N>YYOqvnb;v@=v3j z6DaREDm;ctBz@@^DjPx7L#TED)%Bsq9u(|CtsSVn4JEc9Un9zDK%@1@Ta8jHQFFQ6 zIb4DQMW~?=wdJAsY*e0wYW%1r1NEn(0UsJnL?d1l7mE_yD8?X{c45B`Vapx$damfu z5l3q6aE{<{rxoWrb$G}r!#z$uPIBaeWJmI*IFc^&I?BC_iY}nE1(Yt;7R;b38AOwG z-qndFn^3lNR4g6zNy(K`sK?`q=gZcAuvHQDdVlDc?f~al-&UG2AzNoydIedQ)F*Qr z2dPPhD-%tEWJrNb$ORdej8ZO716fHgOh7tFJ}DvxWSj*cmC2+_K{~I3kgTE>WFWF7 zX(R}(&AV=qp$6oyAPsgyAM{I~GQ&ZT z9Z7N-VjLvMIT}dbvm?guiI@@-F#(u`zwis@;5*E~R}(cKmDzUXszV($6}E}GcMo*L zeB$9_cn?#s!;5d_>1}!X#%vm+2)#zGmxqL&^U@6>W6DHaPl-N~=zXF?aMx^`3bn7d z?ihaEf<9P<6_|%*Sb}SC6s|%$TqNgtx%ljX-ZW`sH{GycN_^I|rFZnYKBe>R&-Ok0 zoZYN`t1Y#t29?+PVBNH)!~LG>@Jz$99Y_qTreHL&@s%ClnjB*()zXqla4Mm8J;)XN sw%K<3)d55JCb!kd>8Av}1S95>c|gMvvq$Fv#bkpVJQDdrYd%{02d_G-4*&oF delta 1109 zcmXw%Jxo(k6oB7-_ZAAYrTi2M@>8@xks?r9#Zd4*S@JY%0rBJWeQ@~>D-`Hw$eZF-)=a2B5AM|5emsxrd zS=K&~LWe;D55XYxfwWT^8HYyL0n!^uA@QYb>3bJQ*X5E)kg}xr(t5da3p7h_c0vrK z1N9&ikjf)a3o?RjAXAXbNP!`kfDsq~`3y=y8qfhUT4{j{vI@#UCRPkZPzX|JlU!V8 zC!b3iWB}tJ!KJVNM#@^_MnY?L)&xz~guPi4WsMlu9I%a>v$3h8L2KI5?{r4b>RS7Y zowZNdN%dQ~>at2JzxB~tw5Bsd-gsu}`+^+^T>p`D{p&C7{8Uk{m8Vjv@<3+N-*Ww@ zSus_L;GbX(9>7f!T~o&Oyxr1SbBvunh(Quwz&H59sZ}ZG^QK-gUJ3F6-oR^k1q<*L z9>IM$4R_%d+<+yRASspDQ=9xJ&i+r^JkRkdc|FJ3h(bo0=O(5$^pmfK7{6eQ?Na4+&7BSX7wAZ> AGynhq diff --git a/utils/rentals.json b/utils/rentals.json index 08c201b..2be880b 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -112,7 +112,7 @@ "returned": "false" }, { - "customer_id": 1, + "customer_id": 32, "movie_id": 14, "checkout_date": "01 Nov 2004 06:19:02", "return_date": "06 Nov 2004 18:19:02", @@ -203,7 +203,7 @@ "returned": "true" }, { - "customer_id": 14, + "customer_id": 32, "movie_id": 14, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", From d78cc1d997f69dc4919cc98ebf9af08d0dd6176c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 14:53:32 -0700 Subject: [PATCH 065/189] added rentals/:title route --- routes/rentals.js | 85 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 77 insertions(+), 8 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 25294f2..fdb0f12 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -8,19 +8,88 @@ var Rental = require('../models/rental'), var Movie = require('../models/movie'), movie = new Movie(); +var Customer = require('../models/customer'), + customer = new Customer(); + var RENTAL_PERIOD = 5; // 5 days -router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { - var movie_id = req.params.movie_id; +router.get('/:title', function(request, response, next) { + var title = request.params.title; + var rentedCount, inventory; + var customerIdList = []; + var movieObject = {}; + + async.waterfall([ + // query db for movie + function(callback) { + movie.find_by('title', title, function(error, row) { + movieObject.movie = row; + inventory = row.inventory; + callback(null, inventory, movieObject); + }); + }, + // retrieve customer_ids from rentals for that movie + function(movieInventory, movieObject, callback) { + rental.where('customer_id', ['movie_id', 'returned'], + [movieObject.movie.id, 'false'], function(error, rows) { + console.log(rows); // 1 + callback(null, movieInventory, rows, movieObject); + }); + }, + // get count of rentals + function(movieInventory, customerIDs, movieObject, callback) { + // check how many copies of that movie are checked out + rentedCount = customerIDs.length; + console.log(customerIDs); // 2 + callback(null, movieInventory, rentedCount, customerIDs, movieObject); + }, + // calculate availability + function(movieInventory, rentedCount, customerIDs, movieObject, callback) { + var availableBool = (rentedCount < movieInventory) ? true : false; + var availableCount = (rentedCount < movieInventory) ? (movieInventory - rentedCount) : 0; + movieObject.availability = { + available: availableBool, + copiesAvailable: availableCount + }; + console.log(customerIDs); // 3 + callback(null, customerIDs, movieObject); + }, + // turn object of customerIDs into array of ids + function(customerIDs, movieObject, callback) { + console.log(customerIDs); // 4 + for (var i = 0; i < customerIDs.length; i++) { + console.log(customerIDs[i]); // 5 + customerIdList.push(customerIDs[i].customer_id); + } + console.log(customerIdList); // 6 + callback(null, customerIdList, movieObject); + }, + // query DB for full customer data + // parameter is movieObject with movie and availability objects + function(customerIDs, movieObject, callback) { + console.log(customerIDs); // 7 + customer.where_in('id', customerIDs, function(error, rows) { + console.log(rows); + movieObject.currentRenters = rows; + callback(null, movieObject); + }); + } + ], function(error, result) { + response.status(200).json(result); + }); +}); + +router.post('/checkout/:customer_id/:movie_id', function(request, response, next) { + var movie_id = request.params.movie_id; var count, inventory, enoughInventory; async.waterfall([ // count total # of checked out copies of movie with id, movie_id function(callback) { - rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { + rental.where(['*', 'movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { count = rows.length; callback(null, count); - }) + }); }, // check if enough inventory of movie is available (true/false) function(movieCount, callback) { @@ -29,15 +98,15 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { inventory = row.inventory; enoughInventory = (movieCount < inventory) ? true : false; callback(null, enoughInventory); - }) + }); } ], function(err, result) { // if result, which equals enoughInventory, is false, return message NO if (result == false) { - res.status(403).json({ error: "There are no available copies of that movie for rental." }) + response.status(403).json({ error: "There are no available copies of that movie for rental." }); } else { // proceed with checkout var values = []; - values.push(req.params.customer_id); + values.push(request.params.customer_id); values.push(movie_id); var checkout_date = new Date(); @@ -50,7 +119,7 @@ router.post('/checkout/:customer_id/:movie_id', function(req, res, next) { var columns = ['customer_id', 'movie_id', 'checkout_date', 'return_date', 'returned']; rental.create(columns, values, function(err, results) { - res.status(200).json({ success: "Yay! You checked out a movie." }); + response.status(200).json({ success: "Yay! You checked out a movie." }); }); } }); From 70156548b20f063edd43a88801067daa0de94e13 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 14:53:53 -0700 Subject: [PATCH 066/189] added where_in function --- database_adapter.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 337c216..b85bd71 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -26,18 +26,18 @@ module.exports = { }, // returns array of records - where: function(columns, values, callback) { + where: function(desiredColumns, queriedColumns, values, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); var where_statements = []; // where_statements => ["city = ?", "state = ?"] - for (var i = 0; i < columns.length; i++) { - where_statements.push(columns[i] + " = ?"); + for (var i = 0; i < queriedColumns.length; i++) { + where_statements.push(queriedColumns[i] + " = ?"); } // where_statement => "city = ? AND state = ?" var where_statement = where_statements.join(" AND "); - var statement = "SELECT * FROM " + this.table_name + " WHERE " + where_statement; + var statement = "SELECT " + desiredColumns + " FROM " + this.table_name + " WHERE " + where_statement; db.all(statement, values, function(err, res) { if (callback) { callback(err, res); } @@ -45,6 +45,19 @@ module.exports = { }); }, + where_in: function(column, valueList, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + console.log("value list: ", valueList); + var questionMarks = Array(valueList.length + 1).join('?').split('').join(', '); + + var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " IN (" + questionMarks + ");"; + console.log(statement, valueList); + db.all(statement, valueList, function(error, result) { + if (callback) { callback(error, result); } + db.close(); + }); + }, + subset: function(column, queries, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); From acfa0d64607ced5f7b4232ebf179112d0bd78649 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 14:54:11 -0700 Subject: [PATCH 067/189] added necessary parameter to movie tests --- test/models/movie.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models/movie.js b/test/models/movie.js index 2c00f0c..9c0e944 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -49,7 +49,7 @@ describe("Movie", function() { }) it("can find all movies where a column has a particular value", function(done) { - movie.where(["title"], ["Jaws"], function(err, res) { + movie.where('*', ["title"], ["Jaws"], function(err, res) { assert.equal(err, undefined); assert(res instanceof Object); // Why is this breaking? assert.equal(res.length, 1); From 3c79cd0be4699be9ca2e00f60c4f4496394e0ba5 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 15:16:13 -0700 Subject: [PATCH 068/189] changed where function back to selecting * --- database_adapter.js | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index b85bd71..b1e61a0 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -26,18 +26,18 @@ module.exports = { }, // returns array of records - where: function(desiredColumns, queriedColumns, values, callback) { + where: function(columns, values, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); var where_statements = []; // where_statements => ["city = ?", "state = ?"] - for (var i = 0; i < queriedColumns.length; i++) { - where_statements.push(queriedColumns[i] + " = ?"); + for (var i = 0; i < columns.length; i++) { + where_statements.push(columns[i] + " = ?"); } // where_statement => "city = ? AND state = ?" var where_statement = where_statements.join(" AND "); - var statement = "SELECT " + desiredColumns + " FROM " + this.table_name + " WHERE " + where_statement; + var statement = "SELECT * FROM " + this.table_name + " WHERE " + where_statement; db.all(statement, values, function(err, res) { if (callback) { callback(err, res); } @@ -47,11 +47,10 @@ module.exports = { where_in: function(column, valueList, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - console.log("value list: ", valueList); var questionMarks = Array(valueList.length + 1).join('?').split('').join(', '); var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " IN (" + questionMarks + ");"; - console.log(statement, valueList); + db.all(statement, valueList, function(error, result) { if (callback) { callback(error, result); } db.close(); From 7a4a8a0eb2bb3b753bd45fdccb387f0d55af6e15 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 15:16:41 -0700 Subject: [PATCH 069/189] added space before curly brace --- routes/customers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/customers.js b/routes/customers.js index e92bd74..6fb3d64 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -14,7 +14,7 @@ router.get('/:id', function(req, res, next) { var id = req.params.id; customer.find_by('id', id, function(err, row) { - res.status(200).json({ customer: row} ); + res.status(200).json({ customer: row } ); }); }); From cf8ec8cdce3de6dc16d6a4fa1152a6f091131ff1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 15:17:11 -0700 Subject: [PATCH 070/189] changed where test back to not taking desiredColumns parameter --- test/models/movie.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models/movie.js b/test/models/movie.js index 9c0e944..2c00f0c 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -49,7 +49,7 @@ describe("Movie", function() { }) it("can find all movies where a column has a particular value", function(done) { - movie.where('*', ["title"], ["Jaws"], function(err, res) { + movie.where(["title"], ["Jaws"], function(err, res) { assert.equal(err, undefined); assert(res instanceof Object); // Why is this breaking? assert.equal(res.length, 1); From 7805ed7f6777084b84a3449ad2a6f6a89c79e56c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 15:17:34 -0700 Subject: [PATCH 071/189] got rentals/:title route working --- routes/rentals.js | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index fdb0f12..b3d8ef0 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -28,48 +28,40 @@ router.get('/:title', function(request, response, next) { callback(null, inventory, movieObject); }); }, - // retrieve customer_ids from rentals for that movie + // retrieve rental records for that movie function(movieInventory, movieObject, callback) { - rental.where('customer_id', ['movie_id', 'returned'], + rental.where(['movie_id', 'returned'], [movieObject.movie.id, 'false'], function(error, rows) { - console.log(rows); // 1 callback(null, movieInventory, rows, movieObject); }); }, // get count of rentals - function(movieInventory, customerIDs, movieObject, callback) { + function(movieInventory, rentals, movieObject, callback) { // check how many copies of that movie are checked out - rentedCount = customerIDs.length; - console.log(customerIDs); // 2 - callback(null, movieInventory, rentedCount, customerIDs, movieObject); + rentedCount = rentals.length; + callback(null, movieInventory, rentedCount, rentals, movieObject); }, // calculate availability - function(movieInventory, rentedCount, customerIDs, movieObject, callback) { + function(movieInventory, rentedCount, rentals, movieObject, callback) { var availableBool = (rentedCount < movieInventory) ? true : false; var availableCount = (rentedCount < movieInventory) ? (movieInventory - rentedCount) : 0; movieObject.availability = { available: availableBool, copiesAvailable: availableCount }; - console.log(customerIDs); // 3 - callback(null, customerIDs, movieObject); + callback(null, rentals, movieObject); }, - // turn object of customerIDs into array of ids - function(customerIDs, movieObject, callback) { - console.log(customerIDs); // 4 - for (var i = 0; i < customerIDs.length; i++) { - console.log(customerIDs[i]); // 5 - customerIdList.push(customerIDs[i].customer_id); + // turn object of rentals into array of ids + function(rentals, movieObject, callback) { + for (var i = 0; i < rentals.length; i++) { + customerIdList.push(rentals[i].customer_id); } - console.log(customerIdList); // 6 callback(null, customerIdList, movieObject); }, // query DB for full customer data // parameter is movieObject with movie and availability objects function(customerIDs, movieObject, callback) { - console.log(customerIDs); // 7 customer.where_in('id', customerIDs, function(error, rows) { - console.log(rows); movieObject.currentRenters = rows; callback(null, movieObject); }); @@ -86,7 +78,7 @@ router.post('/checkout/:customer_id/:movie_id', function(request, response, next async.waterfall([ // count total # of checked out copies of movie with id, movie_id function(callback) { - rental.where(['*', 'movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { + rental.where(['movie_id', 'returned'], [movie_id, 'false'], function(err, rows) { count = rows.length; callback(null, count); }); From 162c184754a9efbdf63a7476bf2662028b32b64c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 15:17:45 -0700 Subject: [PATCH 072/189] modifications to dev db --- db/development.db | Bin 76800 -> 76800 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/db/development.db b/db/development.db index 1ce3fdeae9eb429f5e9bf388998dcf77b2d83ba7..8923a6bb75c8ae60584fe8a57b3bc47d2e54258b 100644 GIT binary patch delta 1035 zcmXw%IcOAN97lI%zU*$yCfVGZdvkB@`@S~G=2j7nkRo8f6c!2=Dk5SsU}2FWAr=-E z!m6kOY$5zqSGy8*8xOKzXw4z?f)Hth?=b4^!4uzJ`^dbtMMHy#M z-)Yoy61AT|E!w_$1~pEhngpsIM-_2YI*cNND8C=g^`e<>G|-M(+t5fWiZ`OFdQ?=W zGv}*OMs)P@b_?}hMQxW*=L#xRv|S6RR)r{5 z=A#3sz5@*^qe^8ktdL_0G#E@t<7PX*u&==jg}ythnNgmPh10R^w3n)?Qbu7CIzfd|HKsu|)6q($50r2hs0T{BS+!9Ilzk1T`ifd*F9rp# zfaYKn)NUoI)~SX{GY(atE~yl1x@yn><&X!tpr)2U0c3*`tj|RHRT7}$&w_p!Z61Sv zE!DFZ&D*z=CTx->5=@$E?on7Yp80JX&;RqtNtz`_zQF=~fsba}lvq5(n6{^BpN<^Q zJhhCMvipYxr}*|B-oZV1%L1bXZ{Rh&f;%t+&*2F?gajKtu+5G?W*s;$?;D2hLL4?= z9hTuXtieq<4%b=Mr_(PZ|3$@ofg^KyGee4RMMG`OJY+bcNWMZ7pMU7IkfrZe%p-#I Y%)W-A)=?m7x|kl+^v`C;gsns8FB{~UZ~y=R delta 1033 zcmXw%IZPB$7=UNyy>?gbWDV7c#mxi2+FF`*!lL<$Q{EYuidTqd!wpnzbA zg@wr)u`p2?2^1C<7RFduSWsA4P*`YUVT=Vqzn{cSzHevV%=_Pe%<6$&J<#jLdHyZK zFy`U^Z+9c!Zuz%fEpMA-Rgs+)FwNt2Z0yT}H<^*aRLY)JsyASpDpzJObXhTJm^a!_GR*Cso&U$d5-f#r42^7P7mw^wN6?pWT-V{7?Pj# zZ5AXaX|8lM2XY|~3ZWFFS<*^5JP0z95txGlka&_r2}nCDKr)j~*ML;s07)4|6G%g3 zN>WHCbVD!5G^Ht0j7(!1q;~1OjH3f4LB1QW2p+h^st=*e*jy{7}F#QGz#diAb8xobUEo{r1<&ttW%9h0rssWf6D ZZL%w79;uzLn)P2W!*bBHJ^lDd{R22fnbH6N From 31c5aa205d342c32f654131439332507270ad387 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 20:09:27 -0700 Subject: [PATCH 073/189] refactored /:title route to take advantage of hoisted variables --- routes/rentals.js | 47 ++++++++++++++++++++--------------------------- 1 file changed, 20 insertions(+), 27 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index b3d8ef0..95578df 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -15,53 +15,46 @@ var RENTAL_PERIOD = 5; // 5 days router.get('/:title', function(request, response, next) { var title = request.params.title; - var rentedCount, inventory; + var rentedCount; var customerIdList = []; var movieObject = {}; async.waterfall([ - // query db for movie + // query db for movie and get inventory function(callback) { movie.find_by('title', title, function(error, row) { - movieObject.movie = row; - inventory = row.inventory; - callback(null, inventory, movieObject); + movieObject.movie_data = row; + callback(null); }); }, // retrieve rental records for that movie - function(movieInventory, movieObject, callback) { + function(callback) { rental.where(['movie_id', 'returned'], - [movieObject.movie.id, 'false'], function(error, rows) { - callback(null, movieInventory, rows, movieObject); + [movieObject.movie_data.id, 'false'], function(error, rows) { + // turn object of rentals into array of ids + for (var i = 0; i < rows.length; i++) { + customerIdList.push(rows[i].customer_id); + } + callback(null); }); }, // get count of rentals - function(movieInventory, rentals, movieObject, callback) { + function(callback) { // check how many copies of that movie are checked out - rentedCount = rentals.length; - callback(null, movieInventory, rentedCount, rentals, movieObject); - }, - // calculate availability - function(movieInventory, rentedCount, rentals, movieObject, callback) { - var availableBool = (rentedCount < movieInventory) ? true : false; - var availableCount = (rentedCount < movieInventory) ? (movieInventory - rentedCount) : 0; + rentedCount = customerIdList.length; + var inventory = movieObject.movie_data.inventory; + + var availableBool = (rentedCount < inventory) ? true : false; + var availableCount = (rentedCount < inventory) ? (inventory - rentedCount) : 0; movieObject.availability = { available: availableBool, copiesAvailable: availableCount }; - callback(null, rentals, movieObject); - }, - // turn object of rentals into array of ids - function(rentals, movieObject, callback) { - for (var i = 0; i < rentals.length; i++) { - customerIdList.push(rentals[i].customer_id); - } - callback(null, customerIdList, movieObject); + callback(null); }, // query DB for full customer data - // parameter is movieObject with movie and availability objects - function(customerIDs, movieObject, callback) { - customer.where_in('id', customerIDs, function(error, rows) { + function(callback) { + customer.where_in('id', customerIdList, function(error, rows) { movieObject.currentRenters = rows; callback(null, movieObject); }); From ba87dc5ab7ae405953384e82ed5ff52270928d8b Mon Sep 17 00:00:00 2001 From: Anita Date: Tue, 22 Sep 2015 20:17:27 -0700 Subject: [PATCH 074/189] added movies rented (current and past) to customers/:id endpoint --- routes/customers.js | 58 ++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 6fb3d64..c757839 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -1,9 +1,16 @@ var express = require('express'); -var router = express.Router(); +var router = express.Router(); +var async = require('async'); var Customer = require('../models/customer'), customer = new Customer(); +var Rental = require('../models/rental'), + rental = new Rental(); + +var Movie = require('../models/movie'), + movie = new Movie(); + router.get('/', function(req, res, next) { customer.find_all(function(err, rows) { res.status(200).json({ customers: rows }); @@ -12,12 +19,57 @@ router.get('/', function(req, res, next) { router.get('/:id', function(req, res, next) { var id = req.params.id; + var current_rentals = []; + var past_rentals = []; + var customer_info; - customer.find_by('id', id, function(err, row) { - res.status(200).json({ customer: row } ); + async.waterfall([ + // get current movie rentals + function(callback) { + rental.where(['customer_id', 'returned'], [id, "false"], function(err, rows) { + for (var i = 0; i < rows.length; i++) { + movie.find_by('id', rows[i].movie_id, function(err, movie) { + current_rentals.push(movie); + }); + } + callback(null); + }); + }, + // get past movie rentals + function(callback) { + rental.where(['customer_id', 'returned'], [id, "true"], function(err, rows) { + for (var i = 0; i < rows.length; i++) { + movie.find_by('id', rows[i].movie_id, function(err, movie) { + past_rentals.push(movie); + }); + } + callback(null); + }); + }, + // get customer data + function(callback) { + customer.find_by('id', id, function(err, row) { + customer_info = row; + callback(null); + }); + }, + // putting the json data all together for customers/:id + ], function(error, result) { + res.status(200).json({ customer_data: customer_info, rentals: { current_movies: current_rentals, past_movies: past_rentals } }); }); }); + // json returned in the following format + // { customer_data: { + // name: "Joe", + // city: "Dallas" + // }, + // rentals: { + // current movie objects: [ { movie object }, { movie object } ], + // past movie objects: [ { movie object }, { movie object } ] + // } + // } + router.get('/:sort_by/:limit/:offset', function(req, res, next) { var values = []; values.push(req.params.limit); From 1f56626b828a92fee42c8cdceab1001d245aebd1 Mon Sep 17 00:00:00 2001 From: Anita Date: Tue, 22 Sep 2015 20:32:38 -0700 Subject: [PATCH 075/189] edited rentals seed data --- db/development.db | Bin 76800 -> 76800 bytes utils/rentals.json | 78 ++++++++++++++++++++++----------------------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/db/development.db b/db/development.db index 8923a6bb75c8ae60584fe8a57b3bc47d2e54258b..3557003ec0a206f458814553bb9fe23d129e11e4 100644 GIT binary patch delta 1678 zcmds$-D_KQ7{`BaNpntKmZUG~OWLMgyQW)`zU8DjNnesJ+q&+BI4iC)u&@e(dZ#c{ zYy$(msIcaDQOJBEySKgeiDYWXJ>&FLtpDEjlIj`((*KVc`48IX`~C z=XuWae1DsJYI9Fr?+u%`7-MIl*6-1FVp^EDK3&`4d`Nr5hdib~7T@wg{i@vNeU49! z%8l_W*gpI$Fn<~FUjj}(1++g2oW2MIF94bIz!Zf~Edj|>z(@%gIu7&~fUbF9DG%gq zU||+GYyoGdfaytKZUQJC1186T#j%rMd<4i21KmTwL_g5m3v~7X9o;~*3m9kz&IAEF z03>{XVE~r%XWQFy<4}c)ic}WBP$dJNs-(aZl_TKs$^bZ4p-A2e1(>b4!I?LJo>zeM zOF(`dh*2v7E5Imy@iKj4AqO0t27FZdAeCC8+Kx~~9*=7be?snq?3nyV?u(zr4e^|q z;D7Tk_*Guu2K#|&R@OyN+*=H`G0uyN5!tWTd_^H*VF(`+mjBO;2Ey6!i431{MZGT`T9dLi(EnRm4@gImSO73?t6s_|xZ zt~a;24B1>+!uF&g9=}DVkR)jqIK84k7qX=`@KNCyUL zUDORPL?)PlXq0KF52F5&O=#rg844ML$P6^&(-1Y4hD2kWV#rUEOhTg&8HV~#PN5=} zA#x>+h^AkF4ns6Nn%Eq46e>bw!$l|#k%O`j8Indx?j++4LY+_t6on!QAPkY=$wp@& z@;I$ia57lKiS+EmLcfKF%S?VH-;__tzW$~(AsOHkzZ{x||bgeS2=;Je;N}sngT>(`()XbW0WyDG|ss=2Rw9QTd7tf}v@ z6zBiS&x2ec!n;DLJ51hjLhtX&?Xt&f4YfY%B5rV^dJ|#pLpQPc6U29wk@78!Mtvp_ zGhWBjmsG}s14RECJKur6L6#U2JMI-qdK*iBKnV-HF%h>cho&WWb{12=4961KnvS+TLvaGE;=I^V`gG>OO&Y4 zM2$vFq^}pd@Ipnc7famsnrw+Ca%G5F)C*%s^uk1Ayzs&cx0p$a-=`EW{1+toet4gA zPM`CfbH2~&wp!g*Z-xD~dyKJ@(Ei`;_2jUy-MfCF#(9Tf7a#Gk@rn3~hm2*p&f})8 zdgV&#F)VL+1kld|v*!Ts1Au!T7(EN*P60>m2L>p8Y7Xcx1HCgq&lJ#A06Hgt_G3WX zQQ*V~FqZ|!jsSy0z~mrM=m!oQ0>XVI@MI4#+zrIKfIuhE8U`XEAlMH0+klxCAnFB< zyMd!RplQIkdB^sqTya&XC|_j~ELU>ibY%dXsvHE1l_;34P^M&s67*H9pz|eQhi^xPy+E9|H~z1IMWJZYp(xYD-W>cDtny|Af2?vcvLkc~|@_-V;xX z46pM|{vt1NH~XGlVGBmlp46wjHYRv6A7ro28rNcBW78dVj(cp3^K3D=Xfb#>?aa9w zaW?3%8ToR;`}m_5pIyqj_67sp4;rUSDTm%%Bb2f3NjZy7ijf#`Gq3TP%fSU@bYwIe z(|9%;kVu#`2HhGaPM4C#lKXjW%z{Y`+tX4ltr}4_Kr6Mh+>fwY%ZR-wNLy-oP7$_j zZrHklEAYetht~xP*~a7=z!-%-h#qPhqKhp;r)L>5Uy^!oJVvk)1B zuAQE76r#t@KxDK5hW%6cAe+(4_d;YbdNJ}=2Sg7?1)YHM5P6y&nEXlpp(idt2OzQ{ z*?^o)?|&GIK>?^0BIib+AmoR9bP^9l{Xi{3#ybvCS5Wc<)bK5Rn{nT-{_X`PzmTuX z1sVI_+9p~}s13CR{h>@X%9UxE+m$_DHqYditjdRERQw>`M@yyo9e#r^^J%WLuh|=H z9xc`H%*C6XFlr%N8f!C}&^!Naf^QJU-LQ7XaF^`D<$|wMTBO-bapP1e$0Noor4i8= z+W(PbJk*#k1`E~l1Yb5L%PBnR1hREWMs_d@|_*|4+e8ODgXcg diff --git a/utils/rentals.json b/utils/rentals.json index 2be880b..a414688 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -1,35 +1,35 @@ [ { "customer_id": 1, - "movie_id": 1, + "movie_id": 5, "checkout_date": "29 Apr 2015 07:54:14 -0700", "return_date": "3 May 2015 07:54:14 -0700", "returned": "false" }, { "customer_id": 1, - "movie_id": 1, + "movie_id": 49, "checkout_date": "01 Nov 2004 06:19:02", "return_date": "06 Nov 2004 18:19:02", "returned": "false" }, { "customer_id": 1, - "movie_id": 1, + "movie_id": 72, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", "returned": "true" }, { "customer_id": 1, - "movie_id": 1, + "movie_id": 100, "checkout_date": "10 May 2011 02:58:43", "return_date": "15 May 2011 02:58:43", "returned": "true" }, { "customer_id": 1, - "movie_id": 1, + "movie_id": 99, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", "returned": "false" @@ -50,181 +50,181 @@ }, { "customer_id": 1, - "movie_id": 2, + "movie_id": 39, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", "returned": "true" }, { "customer_id": 1, - "movie_id": 3, + "movie_id": 68, "checkout_date": "10 May 2011 02:58:43", "return_date": "15 May 2011 02:58:43", "returned": "true" }, { "customer_id": 2, - "movie_id": 2, + "movie_id": 28, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", "returned": "false" }, { "customer_id": 2, - "movie_id": 4, + "movie_id": 44, "checkout_date": "29 Apr 2015 07:54:14 -0700", "return_date": "3 May 2015 07:54:14 -0700", "returned": "false" }, { "customer_id": 2, - "movie_id": 4, + "movie_id": 41, "checkout_date": "01 Nov 2004 06:19:02", "return_date": "06 Nov 2004 18:19:02", "returned": "false" }, { - "customer_id": 34, + "customer_id": 2, "movie_id": 89, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", "returned": "true" }, { - "customer_id": 10, - "movie_id": 7, + "customer_id": 2, + "movie_id": 50, "checkout_date": "10 May 2011 02:58:43", "return_date": "15 May 2011 02:58:43", "returned": "false" }, { - "customer_id": 100, - "movie_id": 5, + "customer_id": 2, + "movie_id": 51, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", "returned": "false" }, { - "customer_id": 134, - "movie_id": 71, + "customer_id": 3, + "movie_id": 29, "checkout_date": "29 Apr 2015 07:54:14 -0700", "return_date": "3 May 2015 07:54:14 -0700", "returned": "false" }, { - "customer_id": 32, - "movie_id": 14, + "customer_id": 3, + "movie_id": 5, "checkout_date": "01 Nov 2004 06:19:02", "return_date": "06 Nov 2004 18:19:02", "returned": "false" }, { - "customer_id": 1, + "customer_id": 3, "movie_id": 16, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", "returned": "true" }, { - "customer_id": 14, - "movie_id": 13, + "customer_id": 3, + "movie_id": 68, "checkout_date": "10 May 2011 02:58:43", "return_date": "15 May 2011 02:58:43", "returned": "true" }, { - "customer_id": 94, - "movie_id": 7, + "customer_id": 3, + "movie_id": 89, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", "returned": "true" }, { - "customer_id": 2, - "movie_id": 4, + "customer_id": 4, + "movie_id": 89, "checkout_date": "29 Apr 2015 07:54:14 -0700", "return_date": "3 May 2015 07:54:14 -0700", "returned": "false" }, { - "customer_id": 165, - "movie_id": 5, + "customer_id": 4, + "movie_id": 74, "checkout_date": "01 Nov 2004 06:19:02", "return_date": "06 Nov 2004 18:19:02", "returned": "false" }, { - "customer_id": 198, + "customer_id": 4, "movie_id": 54, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", "returned": "true" }, { - "customer_id": 122, + "customer_id": 4, "movie_id": 19, "checkout_date": "10 May 2011 02:58:43", "return_date": "15 May 2011 02:58:43", "returned": "true" }, { - "customer_id": 64, + "customer_id": 4, "movie_id": 87, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", "returned": "false" }, { - "customer_id": 39, + "customer_id": 4, "movie_id": 25, "checkout_date": "29 Apr 2015 07:54:14 -0700", "return_date": "3 May 2015 07:54:14 -0700", "returned": "false" }, { - "customer_id": 28, + "customer_id": 4, "movie_id": 99, "checkout_date": "19 Sep 2015 06:19:02", "return_date": "24 Sep 2004 18:19:02", "returned": "false" }, { - "customer_id": 32, + "customer_id": 4, "movie_id": 85, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", "returned": "true" }, { - "customer_id": 13, + "customer_id": 4, "movie_id": 13, "checkout_date": "10 May 2011 02:58:43", "return_date": "15 May 2011 02:58:43", "returned": "true" }, { - "customer_id": 32, + "customer_id": 4, "movie_id": 14, "checkout_date": "03 Oct 2012 00:25:08", "return_date": "11 Oct 2012 07:54:14 -0700", "returned": "false" }, { - "customer_id": 12, + "customer_id": 4, "movie_id": 29, "checkout_date": "29 Apr 2015 07:54:14 -0700", "return_date": "3 May 2015 07:54:14 -0700", "returned": "false" }, { - "customer_id": 56, + "customer_id": 4, "movie_id": 5, "checkout_date": "01 Nov 2004 06:19:02", "return_date": "06 Nov 2004 18:19:02", "returned": "false" }, { - "customer_id": 177, + "customer_id": 4, "movie_id": 82, "checkout_date": "03 Dec 2009 02:58:43", "return_date": "08 Dec 2009 06:19:02", From c6260e56d79efdba2c8efaacf61640265cca96bd Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 21:03:58 -0700 Subject: [PATCH 076/189] adding customers object to movies/:title route; WIP --- routes/movies.js | 31 ++++++++++++++++++++++++++++++- 1 file changed, 30 insertions(+), 1 deletion(-) diff --git a/routes/movies.js b/routes/movies.js index d5a1907..473ef62 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -1,9 +1,17 @@ +var async = require('async'); + var express = require('express'); var router = express.Router(); var Movie = require('../models/movie'), movie = new Movie(); +var Customer = require('../models/customer'), + customer = new Customer(); + + var Rental = require('../models/rental'), + rental = new Rental(); + router.get('/', function(req, res, next) { movie.find_all(function(err, rows) { res.status(200).json({ movies: rows }); @@ -12,9 +20,30 @@ router.get('/', function(req, res, next) { router.get('/:title', function(req, res, next) { var title = req.params.title; + var currentRentersArray = []; + var pastRentersArray = []; + + var movieObject = { + movie_data: undefined, + customers: { currentRenters: currentRentersArray, pastRenters: pastRentersArray } + }; + var movieId; movie.find_by('title', title, function(err, row) { - res.status(200).json({ movie: row} ); + movieObject.movie_data = row; + movieId = row.id; + + rental.where(['movie_id'], [movieId], function(err, rows) { + for (var i = 0; i < rows.length; i++) { + if (rows[i].returned == "false") { + movieObject.customers.currentRenters.push(rows[i]); + } else { + movieObject.customers.pastRenters.push(rows[i]); + } + } + + res.status(200).json(movieObject); + }); }); }); From a8079aa7f66d7cc984e199c7317fe1af8c5a9f54 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Tue, 22 Sep 2015 21:14:55 -0700 Subject: [PATCH 077/189] added current and past renters to customers object --- routes/movies.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index 473ef62..7d3817e 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -20,12 +20,12 @@ router.get('/', function(req, res, next) { router.get('/:title', function(req, res, next) { var title = req.params.title; - var currentRentersArray = []; - var pastRentersArray = []; + // var currentRentersArray = []; + // var pastRentersArray = []; var movieObject = { movie_data: undefined, - customers: { currentRenters: currentRentersArray, pastRenters: pastRentersArray } + customers: { currentRenters: undefined, pastRenters: undefined } }; var movieId; @@ -34,15 +34,26 @@ router.get('/:title', function(req, res, next) { movieId = row.id; rental.where(['movie_id'], [movieId], function(err, rows) { + var currentRentersIds = []; + var pastRentersIds = []; + for (var i = 0; i < rows.length; i++) { if (rows[i].returned == "false") { - movieObject.customers.currentRenters.push(rows[i]); + currentRentersIds.push(rows[i].customer_id); } else { - movieObject.customers.pastRenters.push(rows[i]); + pastRentersIds.push(rows[i].customer_id); } } - res.status(200).json(movieObject); + customer.where_in(['id'], currentRentersIds, function(err, rows) { + movieObject.customers.currentRenters = rows; + + customer.where_in(['id'], pastRentersIds, function(err, rows) { + movieObject.customers.pastRenters = rows; + + res.status(200).json(movieObject); + }); + }); }); }); }); From 9cff1faf0b72a00651996e3163a979db44d6a446 Mon Sep 17 00:00:00 2001 From: Anita Date: Tue, 22 Sep 2015 22:29:37 -0700 Subject: [PATCH 078/189] refactoring of customers to use only callbacks, no async --- database_adapter.js | 11 +++++++ routes/customers.js | 76 ++++++++++++++++++--------------------------- 2 files changed, 42 insertions(+), 45 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index b1e61a0..bdb63e1 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -68,6 +68,17 @@ module.exports = { }); }, + order_by: function(column, callback) { + var db = new sqlite3.Database('db/' + db_env + '.db'); + + var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column; + + db.all(statement, function(err, res) { + if (callback) { callback(err, res); } + db.close(); + }); + }, + // Example route: // customers/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone create: function(columns, values, callback) { diff --git a/routes/customers.js b/routes/customers.js index c757839..95936b3 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -1,6 +1,6 @@ var express = require('express'); var router = express.Router(); -var async = require('async'); +// var async = require('async'); var Customer = require('../models/customer'), customer = new Customer(); @@ -19,57 +19,43 @@ router.get('/', function(req, res, next) { router.get('/:id', function(req, res, next) { var id = req.params.id; - var current_rentals = []; - var past_rentals = []; var customer_info; - async.waterfall([ - // get current movie rentals - function(callback) { - rental.where(['customer_id', 'returned'], [id, "false"], function(err, rows) { - for (var i = 0; i < rows.length; i++) { - movie.find_by('id', rows[i].movie_id, function(err, movie) { - current_rentals.push(movie); - }); - } - callback(null); - }); - }, - // get past movie rentals - function(callback) { - rental.where(['customer_id', 'returned'], [id, "true"], function(err, rows) { - for (var i = 0; i < rows.length; i++) { - movie.find_by('id', rows[i].movie_id, function(err, movie) { - past_rentals.push(movie); - }); + var customerObject = { + customer_data: undefined, + rentals: { current_rentals: undefined, past_rentals: undefined } + } + + customer.find_by('id', id, function(err, row) { + customerObject.customer_data = row; + + rental.where(['customer_id'], [id], function(err, rows) { + var currentMoviesIDs = []; + var pastMoviesIDs = []; + + for (var i = 0; i < rows.length; i++) { + // currently checked out movies + if (rows[i].returned == "false") { + currentMoviesIDs.push(rows[i].movie_id); + // returned movies + } else { + pastMoviesIDs.push(rows[i].movie_id); } - callback(null); - }); - }, - // get customer data - function(callback) { - customer.find_by('id', id, function(err, row) { - customer_info = row; - callback(null); + } + + movie.where_in(['id'], currentMoviesIDs, function(err, rows) { + customerObject.rentals.currentRenters = rows; + + movie.where_in(['id'], pastMoviesIDs, function(err, rows) { + customerObject.rentals.pastRenters = rows; + + res.status(200).json(customerObject); + }); }); - }, - // putting the json data all together for customers/:id - ], function(error, result) { - res.status(200).json({ customer_data: customer_info, rentals: { current_movies: current_rentals, past_movies: past_rentals } }); + }); }); }); - // json returned in the following format - // { customer_data: { - // name: "Joe", - // city: "Dallas" - // }, - // rentals: { - // current movie objects: [ { movie object }, { movie object } ], - // past movie objects: [ { movie object }, { movie object } ] - // } - // } - router.get('/:sort_by/:limit/:offset', function(req, res, next) { var values = []; values.push(req.params.limit); From 5e6df69ab762847d2e6d9f020ff3ded89dc7c9e8 Mon Sep 17 00:00:00 2001 From: Anita Date: Wed, 23 Sep 2015 09:01:18 -0700 Subject: [PATCH 079/189] removing async from customers.js and adding order_by adapter function --- database_adapter.js | 4 ++-- routes/customers.js | 2 ++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index bdb63e1..dc1b8ab 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -68,10 +68,10 @@ module.exports = { }); }, - order_by: function(column, callback) { + order_by: function(condition, column, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - var statement = "SELECT * FROM " + this.table_name + " ORDER BY " + column; + var statement = "SELECT * FROM " + this.table_name + " WHERE " + condition + " ORDER BY " + column; db.all(statement, function(err, res) { if (callback) { callback(err, res); } diff --git a/routes/customers.js b/routes/customers.js index 95936b3..dcff6aa 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -48,6 +48,8 @@ router.get('/:id', function(req, res, next) { movie.where_in(['id'], pastMoviesIDs, function(err, rows) { customerObject.rentals.pastRenters = rows; + + res.status(200).json(customerObject); }); From 9ad14b80585a5071c02926f190a1133e89f8986c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 09:33:32 -0700 Subject: [PATCH 080/189] changed schema of rentals table changed return_date column to due_date to reflect usage. changed returned boolean to returned_date to allow sorting. updated seed data to reflect change --- db/development.db | Bin 76800 -> 76800 bytes db/test.db | Bin 4096 -> 76800 bytes utils/rentals.json | 132 ++++++++++++++++++++++----------------------- utils/schema.js | 4 +- utils/seed.js | 6 +-- 5 files changed, 71 insertions(+), 71 deletions(-) diff --git a/db/development.db b/db/development.db index 3557003ec0a206f458814553bb9fe23d129e11e4..bb1efc4ea8905e74517987c385527c761fa4c07c 100644 GIT binary patch delta 2362 zcmeH{O>7%Q6vuaVX5)|b#&+T)b`mF>q)8m-qqgIZ#Br0ju@g5Te3T+JqM}r>B@Td4 zm6TEniBVN?=poi}0Eq)qKyau^6&HmAhe~ijh)RGs3UMe>52!+F)bM}yTJ+%D zIbiAkv*-EkyqVemyv;qaxhJ;Tn;bKeBrQSahXqO_5f7rHzpENzT;>vgUA`{!vO8B| z_Ts>xrLCibz0+qn<+u9t>xHxVb87{Ct#EN|L_c3xTR;D5A^&e|sF)itK9|2^{l+C; zViRSD=;s@ORZJZ^3#88gsnfvHb3os-!1PHV`6SS~4ESkzJvrdWJTR64!pDL5EZ{l@ zG*1E9NkB^gy)j@Y40MD5=TRUt40I0xjzOv!JOV8C0*yU@?gysY0iO>T_X3GlV6GXM zcLDB3pv?i;Z9r24U=e`A70}B!K&heZuwLLBu_CQiElz_Y#W*-w90N}j2f(gk7uZ>( z0-hqx+ftk=K-Qj$`tQ@l-a@9ZKk#!m1t#g(me-JQ}HPca&ys$y1k+Hu~4-GI%t;}K#*=B*OH21pXQR)t0&^709&;uCy(pcaT6N_M7~ zJplzEy29jhdg&>Md_h*}gUEkm7P>xEgKSQ2A@`3$8)QnlDRGF*vjCChvk)}^x?Xfk z$Y&jp6Cw*|Ale4qhafZyEkgYe8Cr+vRz{)9jlwtCjW#$4k&WkQe{@gWP#Z*(4?}cF zP4v60yYI@|!fTy&;c5OgFYzU={O{)fh?{*ox)9sqH1s$07jy=?2b~gS@vAJ#4L=<4 zU8R#9@UjTdc<&M47C$57I`lpCH1sX>4fH;ATYM@6!{c8uv8{Y5%F3++Jn}9gIf~pA z7JgOYclgz^`?E`2&GwiLNSr*p0qJG~5(;&LosWg+b>ec+EPO`3C*P3Yl%woVc8gtL zbJD)_g>+e(E~UL{s@rT;;<1+4Wi~9)SZRq_e{BUCwGMy1j+N~+bByI|ux{rFcT_Vp z<4QKDrrK$Q&LMoYhGk3mDj8|bILL-S7^U-IAq+iSD)s^z#2ZJA+rHAgdkTnO%bB*d-= zuzkMsp};GDk32I=p4oyou0bzCSD;P&dl^1ao*-{sq`Zko`1KmaUM9=D1Sff58IgkW vPzc&b&`ZHTpb_Xk0uBnSiBI6WZE+U?omtBwDvR9)E2Bw&VPaQtv4{L0%kPxU delta 2183 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 G!kfP}^@cM5 diff --git a/utils/rentals.json b/utils/rentals.json index a414688..baeee60 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -3,231 +3,231 @@ "customer_id": 1, "movie_id": 5, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 1, "movie_id": 49, "checkout_date": "01 Nov 2004 06:19:02", - "return_date": "06 Nov 2004 18:19:02", - "returned": "false" + "due_date": "06 Nov 2004 18:19:02", + "returned_date": "" }, { "customer_id": 1, "movie_id": 72, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" }, { "customer_id": 1, "movie_id": 100, "checkout_date": "10 May 2011 02:58:43", - "return_date": "15 May 2011 02:58:43", - "returned": "true" + "due_date": "15 May 2011 02:58:43", + "returned_date": "14 May 2011 02:58:43" }, { "customer_id": 1, "movie_id": 99, "checkout_date": "03 Oct 2012 00:25:08", - "return_date": "11 Oct 2012 07:54:14 -0700", - "returned": "false" + "due_date": "11 Oct 2012 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 1, "movie_id": 2, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 1, "movie_id": 3, "checkout_date": "01 Nov 2004 06:19:02", - "return_date": "06 Nov 2004 18:19:02", - "returned": "false" + "due_date": "06 Nov 2004 18:19:02", + "returned_date": "" }, { "customer_id": 1, "movie_id": 39, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" }, { "customer_id": 1, "movie_id": 68, "checkout_date": "10 May 2011 02:58:43", - "return_date": "15 May 2011 02:58:43", - "returned": "true" + "due_date": "15 May 2011 02:58:43", + "returned_date": "14 May 2011 02:58:43" }, { "customer_id": 2, "movie_id": 28, "checkout_date": "03 Oct 2012 00:25:08", - "return_date": "11 Oct 2012 07:54:14 -0700", - "returned": "false" + "due_date": "11 Oct 2012 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 2, "movie_id": 44, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 2, "movie_id": 41, "checkout_date": "01 Nov 2004 06:19:02", - "return_date": "06 Nov 2004 18:19:02", - "returned": "false" + "due_date": "06 Nov 2004 18:19:02", + "returned_date": "" }, { "customer_id": 2, "movie_id": 89, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" }, { "customer_id": 2, "movie_id": 50, "checkout_date": "10 May 2011 02:58:43", - "return_date": "15 May 2011 02:58:43", - "returned": "false" + "due_date": "15 May 2011 02:58:43", + "returned_date": "" }, { "customer_id": 2, "movie_id": 51, "checkout_date": "03 Oct 2012 00:25:08", - "return_date": "11 Oct 2012 07:54:14 -0700", - "returned": "false" + "due_date": "11 Oct 2012 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 3, "movie_id": 29, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 3, "movie_id": 5, "checkout_date": "01 Nov 2004 06:19:02", - "return_date": "06 Nov 2004 18:19:02", - "returned": "false" + "due_date": "06 Nov 2004 18:19:02", + "returned_date": "" }, { "customer_id": 3, "movie_id": 16, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" }, { "customer_id": 3, "movie_id": 68, "checkout_date": "10 May 2011 02:58:43", - "return_date": "15 May 2011 02:58:43", - "returned": "true" + "due_date": "15 May 2011 02:58:43", + "returned_date": "14 May 2011 02:58:43" }, { "customer_id": 3, "movie_id": 89, "checkout_date": "03 Oct 2012 00:25:08", - "return_date": "11 Oct 2012 07:54:14 -0700", - "returned": "true" + "due_date": "11 Oct 2012 07:54:14 -0700", + "returned_date": "10 Oct 2012 07:54:14 -0700" }, { "customer_id": 4, "movie_id": 89, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 4, "movie_id": 74, "checkout_date": "01 Nov 2004 06:19:02", - "return_date": "06 Nov 2004 18:19:02", - "returned": "false" + "due_date": "06 Nov 2004 18:19:02", + "returned_date": "" }, { "customer_id": 4, "movie_id": 54, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" }, { "customer_id": 4, "movie_id": 19, "checkout_date": "10 May 2011 02:58:43", - "return_date": "15 May 2011 02:58:43", - "returned": "true" + "due_date": "15 May 2011 02:58:43", + "returned_date": "14 May 2011 02:58:43" }, { "customer_id": 4, "movie_id": 87, "checkout_date": "03 Oct 2012 00:25:08", - "return_date": "11 Oct 2012 07:54:14 -0700", - "returned": "false" + "due_date": "11 Oct 2012 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 4, "movie_id": 25, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 4, "movie_id": 99, "checkout_date": "19 Sep 2015 06:19:02", - "return_date": "24 Sep 2004 18:19:02", - "returned": "false" + "due_date": "24 Sep 2004 18:19:02", + "returned_date": "" }, { "customer_id": 4, "movie_id": 85, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" }, { "customer_id": 4, "movie_id": 13, "checkout_date": "10 May 2011 02:58:43", - "return_date": "15 May 2011 02:58:43", - "returned": "true" + "due_date": "15 May 2011 02:58:43", + "returned_date": "14 May 2011 02:58:43" }, { "customer_id": 4, "movie_id": 14, "checkout_date": "03 Oct 2012 00:25:08", - "return_date": "11 Oct 2012 07:54:14 -0700", - "returned": "false" + "due_date": "11 Oct 2012 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 4, "movie_id": 29, "checkout_date": "29 Apr 2015 07:54:14 -0700", - "return_date": "3 May 2015 07:54:14 -0700", - "returned": "false" + "due_date": "3 May 2015 07:54:14 -0700", + "returned_date": "" }, { "customer_id": 4, "movie_id": 5, "checkout_date": "01 Nov 2004 06:19:02", - "return_date": "06 Nov 2004 18:19:02", - "returned": "false" + "due_date": "06 Nov 2004 18:19:02", + "returned_date": "" }, { "customer_id": 4, "movie_id": 82, "checkout_date": "03 Dec 2009 02:58:43", - "return_date": "08 Dec 2009 06:19:02", - "returned": "true" + "due_date": "08 Dec 2009 06:19:02", + "returned_date": "07 Dec 2009 06:19:02" } ] diff --git a/utils/schema.js b/utils/schema.js index 7a021fc..47c2a2c 100644 --- a/utils/schema.js +++ b/utils/schema.js @@ -26,8 +26,8 @@ var rental_fields = [ ['customer_id', 'integer'], ['movie_id', 'integer'], ['checkout_date', 'text'], - ['return_date', 'text'], - ['returned', 'text'] // boolean + ['due_date', 'text'], + ['returned_date', 'text'] ]; function reset(table_name, table_fields) { diff --git a/utils/seed.js b/utils/seed.js index ba83048..3765f0f 100644 --- a/utils/seed.js +++ b/utils/seed.js @@ -18,7 +18,7 @@ var customer_statement = db.prepare( var rentals = require('./rentals'); var rental_statement = db.prepare( - "INSERT INTO rentals(customer_id, movie_id, checkout_date, return_date, returned) \ + "INSERT INTO rentals(customer_id, movie_id, checkout_date, due_date, returned_date) \ VALUES (?, ?, ?, ?, ?);" ); @@ -62,8 +62,8 @@ db.serialize(function() { rental.customer_id, rental.movie_id, rental.checkout_date, - rental.return_date, - rental.returned // boolean + rental.due_date, + rental.returned_date ); } From bdf149842cfb47fe40c0dfb233ba7a9da5590561 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 09:44:17 -0700 Subject: [PATCH 081/189] updated routes and database adapter to use new rentals schema --- database_adapter.js | 1 + db/test.db | Bin 76800 -> 76800 bytes routes/customers.js | 2 +- routes/movies.js | 2 +- routes/rentals.js | 14 +++++++------- 5 files changed, 10 insertions(+), 9 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index dc1b8ab..562e02d 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -68,6 +68,7 @@ module.exports = { }); }, + // order_by: function(condition, column, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); diff --git a/db/test.db b/db/test.db index aee8ec4b5f4fff7a2856b69fc574876508462355..0e2a3ae657dcbaf94ddc8b119595d15df31b7e3f 100644 GIT binary patch delta 720 zcmZ9~&u$Vy90%}S7O_H$Q9(qCowe33mc`v+7k2S4f4Y?t(?m@1;K2nZvgwwM3yX51 z#AK{YeEWc~N9<>Lye}HLKS4^rz{~bc& zg!h6J`f(gz`WBi!7ouFcwY7F3mE)e+p(#?)&~wDp4B4axbwW{2Z1oV=TXGhAge>pPlspdH zKJzW#$$ZrSXOhSM9Z?ODth?mm*vC^@3Clg zh{AbDLIwzIKn@B}1Ox8E19%8ksKH`=1Gd3}9e4yy*oDPcI0F$l3ri4#*)qc7J>qZ? zE!Y=B|~6js4}8RQHIOJKGDvN;gUflLUdv%t>)Zwk0RnBW-N z0b^;9wn0j9h!As89S)&CI&>n0Nr;TU@o>LK?5l=cL9?&Gd_ap|# zci`w2)UUxo57fG#%KuPlg5^W7xC8S1vKfBLBxfJz#M05PZV-CdY7q Date: Wed, 23 Sep 2015 09:57:10 -0700 Subject: [PATCH 082/189] modified seed data to allow more meaningful testing --- db/development.db | Bin 76800 -> 76800 bytes db/test.db | Bin 76800 -> 76800 bytes utils/rentals.json | 6 +++--- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/db/development.db b/db/development.db index bb1efc4ea8905e74517987c385527c761fa4c07c..d7c51e60e44d40c2e32d65c43512914f0d103ee3 100644 GIT binary patch delta 1104 zcmaiyJ!lhg7>9Fr|HNpM7~7`Cw%W6{nzT{VG_`5$N2;-{Rz=i82f;!W926W>M8x#K z!NEa^gM)*RiVlJwC)B~g!9m2q!J&hLLk9;32N6NBKEL8_;CXVq_ul{BkDFUGbBpFy zbA7ZH2m~hK-_IJkoypnJ+OwGlmeo}a*^jJr^@;t?N>#5ox2*$y#B@59u36ICPNMP& zw00V$r%?Mb6g`Ue9Y*m(XqS%fnLs=fyUd>#AcM+h(?;x&JCzJi4sj{e*+qbqf89dMbPTiXj=%aGAQH( zanh;aK+unbFFBQZPqj9B!+5>73$OEb;4yD2-s^3`{hnUX>*?GLo{rmn4Y?Ol>>P@m zLM^Jc;W+BhAcocXXc2Yi(2zPxs)J1`xl@IP!@)ZKZ083KZ1*D(*G?4NY_8Z>DCT>! z1-E>9*3D(Jh3aUm!7BJuv3aY~+D7u4cy#5-rhs$PQFZmu2Cx~sAgx91Xdfy-ooa|%K>ZKGC}^=MD1g?j z^=dSED1pYTPh%XmgT5aPYy>nZeG^)D0@Pr-6=^H`L0?h^G)5iX2`f9-weKdD?3#(2 znn{Lhro;HgP5o!U?awSfH2ue^nV&rN9ZtYkI1ZoTgIO@GmTmk{YT5CFi_7GGXb~QSQ;>z<1d|+Qz9=uFyl;de b%DZ45P-e|65pXSLmggd@$S1mvTfd#ZuidH$ delta 1060 zcmXYvIcOA77{_;J-flL@Z}xrPoAYGQi7g6~I zG;kjEoJHAZP?44|okA58sBsLnjG&Gol-iFndeL|{O6o*q?Wm>&6*QxiCNx%uN@|c> ztvzci&`cRhE=7?d)SHj;^3bVV)R~P&GtfjTN=rsLE=q_;=^+$nP|ykDTqlMDA>R$( zaboSBYEAS8aJ|=oyS+v{?N#AouNW74+91=@x>=r<%YT5HZlm1mXmAO&s@kbJ)SyO8 z>g4@BsHznW=|pWh!H7z(Q=#E-Fp-Dt{K0`r-*qGQ`o@h`|5EaX6<1wCFg|rR)0mj; zWCxrT6bPtgdaEAP$Z0q(l4mAlf!d>9YNsxUg6>~U9)>fadX7`lvF7=jt71a&h4`Xt)m_&Ry&!_Wb% zK|LJR`E*HXkONx04iX?;|NThXfxT&R!@jAAo^-Hk$MQpwBgZ$VE#n6d|2doHr`a}z zmf194;K2Cig;GzHdPL+Skwr!N6p0dPgSYSlzQH~-zS?Fl6t<3-@|n;Fcn|MLJ=Du@ z^zthrJ8%u2lXwUrg`1%sevx*SzNIQ7RJm=KuxFyyp|ktlFy%MdDP=RQqd4C@J9Pd7wEv`u diff --git a/db/test.db b/db/test.db index 0e2a3ae657dcbaf94ddc8b119595d15df31b7e3f..1eb65be0c0c0ad775e30565f85c310ca7b15dddd 100644 GIT binary patch delta 131 zcmZp;!P0PpWrDPzIRgWOHxP3Iu{#huP1G@FG~bx8l#!8hG8@whMvlqrnNBgXPp)F_ zVq##~ESONrJaIxR8!u2TPVOcFb^%7W%^V6mi~>MqAS?*Pk{~V3DvH}x6dCVu0RWNA B8)*Ol delta 919 zcmaKpPiWI%7{-&lwbQE52}8;p{Ys~6T{FLYN!Fxu;9Bk6svE9z6C7yPhBewHnkAd{ zV1*%wBL3;Yi-IDG;=w;d1TS88(SrxQ4AhIDUc7kO#fxthJnZ1%{qd1}@B2LO^POJ_ zoL>oCYi}hS#}%+PVC}`~zMhhK^6dD1o)0#H!b5&tZogr6~bkaPSpgz*Sg< zpYQ{|!x#7rEARo{!5dhH*YFDeK845d0PeyqxCuAl3S5LmI0rTGz=0EB!f`kX6L1I) zz#wFyA2g7mr_maSFD-^23w3nSUqbX9Lu959`VmC>Frv4JP{$C;2!b6%NKOBAKVnxN zAvV`YWf9$b5Ig%3i9SS^j@XgLnGoa#r8a)NVv-|b-m02&8IreVDjxAFW}W1H&v(s% z9wEpLZC!J1h)fzb-g8LStXk&0IqA5wF-EDjF~SGAwnzs*Y%I(bD~5X#KT9gr84Ybl zWdRZ#hLI4K{~O+uFg${La2vC`4wvBq)G?WCy}CZcbrsZT+t#EoFl*RlgXDbIv*yNq zGesngj5zZI^%O#BMv*g;N<^wrI&g}_(`i|hm`X-`yF`j!&ycf#-IiBt9wbebwFFb; zBw=YuRGCha~WXzhG`76dWGHlp?#Td&lEu;JsTk4G6;p1HEC#~JKJ-y%&@s;Z=T(z0#SB?I$j&xB!@9Dm+) zvpHSX6q=AVHA!?u6LqFBO9*kXLJ1i!h#gIfdFM=x9Q3PY)6Kh9s*&qz&r2%9WmGa+ zww&hD6IRJ{T+6_bnnd*kqrFKYGhI}0CcphO-yFBEqnYns!!}5< Date: Wed, 23 Sep 2015 09:57:32 -0700 Subject: [PATCH 083/189] changed rental.where to rental.order_by to return ordered results --- routes/customers.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/routes/customers.js b/routes/customers.js index 3558fe6..782ced6 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -29,7 +29,11 @@ router.get('/:id', function(req, res, next) { customer.find_by('id', id, function(err, row) { customerObject.customer_data = row; - rental.where(['customer_id'], [id], function(err, rows) { + var condition = "customer_id = " + id; + + // order_by returns a collection of records matching the condition, + // ordered by the column + rental.order_by(condition, "checkout_date", function(err, rows) { var currentMoviesIDs = []; var pastMoviesIDs = []; From 9ce205ccc9ca3f253e148f7b864a851d90c8c94e Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 10:27:51 -0700 Subject: [PATCH 084/189] added returned_date to pastRental movie objects --- routes/customers.js | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 782ced6..bd59731 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -20,10 +20,11 @@ router.get('/', function(req, res, next) { router.get('/:id', function(req, res, next) { var id = req.params.id; var customer_info; + var pastRentalsArray = []; var customerObject = { customer_data: undefined, - rentals: { current_rentals: undefined, past_rentals: undefined } + movies: { pastRentals: pastRentalsArray } } customer.find_by('id', id, function(err, row) { @@ -36,6 +37,7 @@ router.get('/:id', function(req, res, next) { rental.order_by(condition, "checkout_date", function(err, rows) { var currentMoviesIDs = []; var pastMoviesIDs = []; + var pastMoviesObject = {}; for (var i = 0; i < rows.length; i++) { // currently checked out movies @@ -43,16 +45,30 @@ router.get('/:id', function(req, res, next) { currentMoviesIDs.push(rows[i].movie_id); // returned movies } else { - pastMoviesIDs.push(rows[i].movie_id); + pastMoviesObject[rows[i].movie_id] = rows[i].returned_date; + // pastMoviesIDs.push(rows[i].movie_id); } } + console.log(pastMoviesObject); + pastMoviesIDs = Object.keys(pastMoviesObject); + console.log(pastMoviesIDs); movie.where_in(['id'], currentMoviesIDs, function(err, rows) { - customerObject.rentals.currentRenters = rows; + customerObject.movies.currentRentals = rows; // no returned_date movie.where_in(['id'], pastMoviesIDs, function(err, rows) { - customerObject.rentals.pastRenters = rows; - + console.log(rows); + for (var i = 0; i < rows.length; i++) { + var movieObject = {}; + movieObject.movieData = rows[i]; + movieObject.returnedDate = pastMoviesObject[rows[i].id]; + pastRentalsArray.push(movieObject); + } + // customerObject.movies.pastRentals = rows; + // add returned_date to each rental + + // brute force: iterate through each movie object, + // run a query on the rentals table, get returned_date for that movie res.status(200).json(customerObject); From fa94f990ae8cb101d6d1f8ebe844f3996a380fd1 Mon Sep 17 00:00:00 2001 From: Anita Date: Wed, 23 Sep 2015 11:04:01 -0700 Subject: [PATCH 085/189] WIP adding sorting to movie endpoint --- db/development.db | Bin 76800 -> 76800 bytes routes/movies.js | 12 ++++++++++-- utils/rentals.json | 10 +++++----- 3 files changed, 15 insertions(+), 7 deletions(-) diff --git a/db/development.db b/db/development.db index d7c51e60e44d40c2e32d65c43512914f0d103ee3..933655926b141931b772ed76ed1e603018fb3e85 100644 GIT binary patch delta 1124 zcmYk4J4{ni7{~A9^Z^uFpg?(F9)&_%xGgPx@G9?@uP7QwNF;&5L4yMtV~ph{4h{^E z>)_yEQVk3yDp#X}gM))H4h#$oY8;4haL~jU2Lk^8i7__${d#)tchC7AUELF_dt$w+ z#O;tIX&U_f$mcdfQN`_ey6{kz!=_!?l0)WW<((Wfud5sKxaAUlHQTa?@Ys21Xda5s zLV>f8eg^724Naeb(#N549$z~FHH<-#5vY3z@?@aVKB%z=YD+=x1XLe~+9S}E4wZC5 zbwSA22KBY_&R{dt-w2g9K-IO7s|wO8p&lPpSq_brLd71aq6qT3p!__j#tu0IWK(Uh zPtC%T-Eujvs@Yb9xpo=-aDmYchl~z5WwgMPMjc#c@PaCX=XM%AZr~;qy#h^Kf-*}` zlG!%RKpkvEAuAtAL;ff<$cl{RKam^Y+4c&NRn&4xU4ta46?6f<8v<YE!~hdx!JUnV%fDrH7908 zPW%Qx!94f|X255#BVLFaSrIvVKv?!YhVKeXJd%ZFdw+yqrx5fOya9K?Yq2SWjKwSP z5Q5UVw=7Pz{_`&N114IFoj zzpgPh$%xC0xcEcqQReh6?d0N$7D=U2ny#m#@wA?dME=`Lq~o!4B&LP+gsw;Qe@{$( zc{e96AbBs7?*&Uh2M5^naq}w(f$!LGabrb17cz6%KTdV&|?Byv}oZXqD6}qLJwL*v}jQf(L${67m@INbNrvfIsfxJH@|4|i{@Hw zSu6;JLObE#pEWw0?y+ORqnW#w)#gX+IVJou4?=;k)h!+dk~iUL7u^Vz2F7 zT?6Hn@z~!rl_BSfqdv-@9IBuc)c*u1&<&ti6mtU9@eXJM1)>f0EURD*s3}FOBesAt zRAZZ=QPURYvL#kX+ zB~Rr7oP$$v9FD;>Ou_-!%X!T@FUugV!7msvca6pwNW(WXZ(K_opZ@LKGYN~uESNV* aYsq>1(XiwPM^D*iK2mNiuPB(?OU@s8nyStK diff --git a/routes/movies.js b/routes/movies.js index a73b375..401ff30 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -18,8 +18,10 @@ router.get('/', function(req, res, next) { }); }); -router.get('/:title', function(req, res, next) { +router.get('/:title/:order', function(req, res, next) { var title = req.params.title; + var order = req.params.order; + // sort by customer_id, customer name, and checkout_date // var currentRentersArray = []; // var pastRentersArray = []; @@ -33,7 +35,13 @@ router.get('/:title', function(req, res, next) { movieObject.movie_data = row; movieId = row.id; - rental.where(['movie_id'], [movieId], function(err, rows) { + var condition = "movie_id = " + movieId; + + if (order = "customer_name") { + order = "id" + } + + rental.order_by(condition, order, function(err, rows) { var currentRentersIds = []; var pastRentersIds = []; diff --git a/utils/rentals.json b/utils/rentals.json index 2746c78..7101ad2 100644 --- a/utils/rentals.json +++ b/utils/rentals.json @@ -84,7 +84,7 @@ "returned_date": "" }, { - "customer_id": 2, + "customer_id": 3, "movie_id": 89, "checkout_date": "03 Dec 2009 02:58:43", "due_date": "08 Dec 2009 06:19:02", @@ -133,11 +133,11 @@ "returned_date": "14 May 2011 02:58:43" }, { - "customer_id": 3, + "customer_id": 2, "movie_id": 89, - "checkout_date": "03 Oct 2012 00:25:08", - "due_date": "11 Oct 2012 07:54:14 -0700", - "returned_date": "10 Oct 2012 07:54:14 -0700" + "checkout_date": "03 Oct 1999 00:25:08", + "due_date": "11 Oct 1999 07:54:14 -0700", + "returned_date": "10 Oct 1999 07:54:14 -0700" }, { "customer_id": 4, From bc6ac1609ce0ef75cc65f05c6bb299831e6ef2bb Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 13:41:26 -0700 Subject: [PATCH 086/189] refactored statement in order_by function --- database_adapter.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 562e02d..1ffd9ff 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -68,11 +68,14 @@ module.exports = { }); }, - // + // if 'none' is passed in, no sort is performed order_by: function(condition, column, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - var statement = "SELECT * FROM " + this.table_name + " WHERE " + condition + " ORDER BY " + column; + var statement; + statement = (column == "none") ? + "SELECT * FROM " + this.table_name + " WHERE " + condition + : "SELECT * FROM " + this.table_name + " WHERE " + condition + " ORDER BY " + column; db.all(statement, function(err, res) { if (callback) { callback(err, res); } From 82db4b00aed61ff878ce1e4283141d0e82f1e414 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 13:42:07 -0700 Subject: [PATCH 087/189] modified seed data to make debugging easier --- db/development.db | Bin 76800 -> 76800 bytes utils/customers.json | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/db/development.db b/db/development.db index 933655926b141931b772ed76ed1e603018fb3e85..cf108715b631042242ffe3911c0517d93222f899 100644 GIT binary patch delta 1102 zcmZvaOGs2v7{~9u=gc_jsN?t=-{W(9JC5)7`&|)bAS5JZ5SUO<5Rr}-TC{MXO+Zch2grUftE}d0x+= zVHnf!?`JM;)P*e1;?wy}(+ozO*0$Lgd2GEi8zR@$hS?W$>k1XFJ;&p|GpJ||d1q10 zDO7wCrJX?4$I$3ekZFmSHy!XJ=JB}*zk9u}r zQ@R5Kunuc54>w^IZom<^1|7V5Nm^c%MP1NaI#W9KzybtepQ2BSU!V?tki>0DxGRTh bGrqz-p7EQmsBYmuS3KpX1GS?)=Dzw1cIl{X delta 1097 zcmZ9KOGs2v7=Z8N%tIZWaU6Agk2>Rw&iH=6^8K!evTz|JCDEdwpdi8=FSKakLYt@- zEdq^P1eLe2MT-_e5iMG@aM7ZLixvhgB7#KwerVOe_s!2e=brOF?$Wke+Ey!tey>Z@ zv?=)a(@(7?nhdY&`P?I2uT43P4Ly;1YJAY+sq5ydK4yDV#7tJ5WqZqMG&qY|XHe`U zYB+&SyEh(VcI)pQ`ZVgO=A0i-4lPcvqh{FI#gJr%l zyCRUGNkc;*pNfoF3Y3p!2pCJLmQ9ck0g%IMAsvb(wnN!FhOL5z@-J%UZ8Ko38_oJV zeOBAm7E{@QbM_7Q-Ty~kwzHg7+{7JrIKycm?0! z3v4S}eKypV)2;8DYw9D9-ohJr4L9KhJcA9kUeJ~8SU)gr^+2LK2fVYw+6*ki5-h+q zxWxYRhO(XWa`G%shG80xk#Sfu?kDg`@SD9Ix_ar*<-`V_B;W_j9$CJkwp2)$G!+}R a95MZmx%pMG@{ Date: Wed, 23 Sep 2015 13:42:36 -0700 Subject: [PATCH 088/189] added sort by customer name to /:title/:order route --- routes/movies.js | 21 +++++++++++++++++---- 1 file changed, 17 insertions(+), 4 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index 401ff30..06b6ff8 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -20,7 +20,8 @@ router.get('/', function(req, res, next) { router.get('/:title/:order', function(req, res, next) { var title = req.params.title; - var order = req.params.order; + var originalOrder = req.params.order; + console.log(originalOrder); // sort by customer_id, customer name, and checkout_date // var currentRentersArray = []; // var pastRentersArray = []; @@ -34,18 +35,25 @@ router.get('/:title/:order', function(req, res, next) { movie.find_by('title', title, function(err, row) { movieObject.movie_data = row; movieId = row.id; + var sortOrder; var condition = "movie_id = " + movieId; - if (order = "customer_name") { - order = "id" + // don't bother sorting rentals if customers should be sorted by customer name + if (originalOrder == "customer_name") { + sortOrder = "none" + } else { + sortOrder = originalOrder; } + console.log(sortOrder); - rental.order_by(condition, order, function(err, rows) { + rental.order_by(condition, sortOrder, function(err, rows) { var currentRentersIds = []; var pastRentersIds = []; + console.log(rows); for (var i = 0; i < rows.length; i++) { + if (rows[i].returned_date == "") { currentRentersIds.push(rows[i].customer_id); } else { @@ -57,6 +65,11 @@ router.get('/:title/:order', function(req, res, next) { movieObject.customers.currentRenters = rows; customer.where_in(['id'], pastRentersIds, function(err, rows) { + if (originalOrder == "customer_name") { + rows.sort(function(a, b) { + return a.name.localeCompare(b.name); // this is a good way to sort strings! + }); // sort customers by names ASC + } movieObject.customers.pastRenters = rows; res.status(200).json(movieObject); From cf7db1b49d274f1d1ec85e5d26e73ceaf6835324 Mon Sep 17 00:00:00 2001 From: Anita Date: Wed, 23 Sep 2015 14:23:30 -0700 Subject: [PATCH 089/189] starting overdue for rentals, removed console.logs in movies --- routes/movies.js | 3 --- routes/rentals.js | 12 ++++++++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index 06b6ff8..91ad30c 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -21,7 +21,6 @@ router.get('/', function(req, res, next) { router.get('/:title/:order', function(req, res, next) { var title = req.params.title; var originalOrder = req.params.order; - console.log(originalOrder); // sort by customer_id, customer name, and checkout_date // var currentRentersArray = []; // var pastRentersArray = []; @@ -45,13 +44,11 @@ router.get('/:title/:order', function(req, res, next) { } else { sortOrder = originalOrder; } - console.log(sortOrder); rental.order_by(condition, sortOrder, function(err, rows) { var currentRentersIds = []; var pastRentersIds = []; - console.log(rows); for (var i = 0; i < rows.length; i++) { if (rows[i].returned_date == "") { diff --git a/routes/rentals.js b/routes/rentals.js index d029a14..11c3297 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -110,4 +110,16 @@ router.post('/checkout/:customer_id/:movie_id', function(request, response, next }); }); +router.get('/overdue', function(req, res, next) { + var today = new Date(); + var overdues = []; + rentals.where('due_date', condition, function(err, rows) { + for (var i = 0; i < rows.length; i++) { + if (rows[i].due_date > today) { + response.status(200).json({ overdue_customers: overdues }) + } + } + }); +}); + module.exports = router; From 31b4c99bb042572b91adad758ee106f2497f3d1e Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 14:42:06 -0700 Subject: [PATCH 090/189] added /overdue route, moved to top of file to avoid collisions --- routes/rentals.js | 29 ++++++++++++++++++----------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 11c3297..e39212c 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -13,6 +13,24 @@ var Customer = require('../models/customer'), var RENTAL_PERIOD = 5; // 5 days +router.get('/overdue', function(req, res, next) { + var today = new Date(); + var overdueCustomerIds = []; + + rental.where(['returned_date'], [''], function(err, rows) { + for (var i = 0; i < rows.length; i++) { + var dueDate = new Date(rows[i].due_date); + if (dueDate < today) { // overdue! + overdueCustomerIds.push(rows[i].customer_id); + } + } + + customer.where_in("id", overdueCustomerIds, function(err, rows) { + res.status(200).json({ overdue_customers: rows }); + }); + }); +}); + router.get('/:title', function(request, response, next) { var title = request.params.title; var rentedCount; @@ -110,16 +128,5 @@ router.post('/checkout/:customer_id/:movie_id', function(request, response, next }); }); -router.get('/overdue', function(req, res, next) { - var today = new Date(); - var overdues = []; - rentals.where('due_date', condition, function(err, rows) { - for (var i = 0; i < rows.length; i++) { - if (rows[i].due_date > today) { - response.status(200).json({ overdue_customers: overdues }) - } - } - }); -}); module.exports = router; From 520612443d8b840384418c66e5286c20e8b3070c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 15:09:20 -0700 Subject: [PATCH 091/189] added /checkin route --- routes/rentals.js | 29 ++++++++++++++++++++++++++++- 1 file changed, 28 insertions(+), 1 deletion(-) diff --git a/routes/rentals.js b/routes/rentals.js index e39212c..c735ebb 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -13,8 +13,9 @@ var Customer = require('../models/customer'), var RENTAL_PERIOD = 5; // 5 days +var today = new Date(); + router.get('/overdue', function(req, res, next) { - var today = new Date(); var overdueCustomerIds = []; rental.where(['returned_date'], [''], function(err, rows) { @@ -128,5 +129,31 @@ router.post('/checkout/:customer_id/:movie_id', function(request, response, next }); }); +router.put('/checkin/:customer_id/:movie_title', function(req, res, next) { + var customerId = req.params.customer_id; + var movieTitle = req.params.movie_title; + var movieId; + + // retrieve rental record which corresponds to customer id and movie title, + // AND which is not already returned + + // translate movie title to movie id + movie.find_by("title", movieTitle, function(err, row) { + movieId = row.id; + var columns = ["customer_id", "movie_id", "returned_date"]; + var values = [customerId, movieId, ""]; + + rental.where(columns, values, function(err, rows) { + var rentalId = rows[0].id; + + var message = "Congratulations, you have checked in: "; + + rental.update(rentalId, ["returned_date"], [today], function(err, result) { + res.status(200).json(message + movieTitle); + }) + }); + }); +}); + module.exports = router; From e57f827fe33b6a7d6a5b30c60ffc32871e0dc405 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 15:11:40 -0700 Subject: [PATCH 092/189] checked in movie, which changed db --- db/development.db | Bin 76800 -> 76800 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/db/development.db b/db/development.db index cf108715b631042242ffe3911c0517d93222f899..6e4619f5d136e4a6d8b49beaf743a5a03e42b171 100644 GIT binary patch delta 100 zcmZp;!P0PpWr8$g&O{k!#+;1_%lwV>8JN#9w=vr@ygn*aU#s1dtm6Ympp70c){frcWR~00Yefh66tW>;kR=djd28?E$m_b^${G l`~bB8d;mU?K^U`fPz3=AF&hT}0Rc5N4U;%fDzkP`irU+77oh+E From 5501e7d2c8dd815fe78a0125b19388a64d06f8c5 Mon Sep 17 00:00:00 2001 From: Anita Date: Wed, 23 Sep 2015 15:36:19 -0700 Subject: [PATCH 093/189] removing extraneous comments, console.logs, and brackets in where_in function call --- routes/customers.js | 64 +++++++++++++++------------------------------ routes/movies.js | 11 +++----- 2 files changed, 25 insertions(+), 50 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index bd59731..848fac3 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -5,11 +5,11 @@ var router = express.Router(); var Customer = require('../models/customer'), customer = new Customer(); -var Rental = require('../models/rental'), - rental = new Rental(); +var Rental = require('../models/rental'), + rental = new Rental(); -var Movie = require('../models/movie'), - movie = new Movie(); +var Movie = require('../models/movie'), + movie = new Movie(); router.get('/', function(req, res, next) { customer.find_all(function(err, rows) { @@ -49,28 +49,19 @@ router.get('/:id', function(req, res, next) { // pastMoviesIDs.push(rows[i].movie_id); } } - console.log(pastMoviesObject); pastMoviesIDs = Object.keys(pastMoviesObject); - console.log(pastMoviesIDs); - movie.where_in(['id'], currentMoviesIDs, function(err, rows) { + movie.where_in('id', currentMoviesIDs, function(err, rows) { customerObject.movies.currentRentals = rows; // no returned_date - movie.where_in(['id'], pastMoviesIDs, function(err, rows) { - console.log(rows); + movie.where_in('id', pastMoviesIDs, function(err, rows) { for (var i = 0; i < rows.length; i++) { var movieObject = {}; movieObject.movieData = rows[i]; movieObject.returnedDate = pastMoviesObject[rows[i].id]; pastRentalsArray.push(movieObject); } - // customerObject.movies.pastRentals = rows; - // add returned_date to each rental - // brute force: iterate through each movie object, - // run a query on the rentals table, get returned_date for that movie - - res.status(200).json(customerObject); }); }); @@ -89,33 +80,20 @@ router.get('/:sort_by/:limit/:offset', function(req, res, next) { }); }); -router.post('/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone', function(req, res, next) { - var values = []; - values.push(req.params.name); - values.push(req.params.registered_at); - values.push(req.params.address); - values.push(req.params.city); - values.push(req.params.state); - values.push(req.params.postal_code); - values.push(req.params.phone); - var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone'] - - customer.create(columns, values, function(err, res) { - res.status(200).json(res); - }); -}); - -// DEBUGGER ROUTE - -router.get('/where/:city', function(req, res, next) { - var values = []; - values.push(req.params.city); - console.log(values); - - customer.where(['city'], values, function(err, rows) { - console.log(rows.length); - res.status(200).json({ customers: rows} ); - }); -}); +// router.post('/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone', function(req, res, next) { +// var values = []; +// values.push(req.params.name); +// values.push(req.params.registered_at); +// values.push(req.params.address); +// values.push(req.params.city); +// values.push(req.params.state); +// values.push(req.params.postal_code); +// values.push(req.params.phone); +// var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone'] + +// customer.create(columns, values, function(err, res) { +// res.status(200).json(res); +// }); +// }); module.exports = router; diff --git a/routes/movies.js b/routes/movies.js index 91ad30c..26f08a7 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -1,7 +1,7 @@ var async = require('async'); var express = require('express'); -var router = express.Router(); +var router = express.Router(); var Movie = require('../models/movie'), movie = new Movie(); @@ -9,7 +9,7 @@ var Movie = require('../models/movie'), var Customer = require('../models/customer'), customer = new Customer(); - var Rental = require('../models/rental'), +var Rental = require('../models/rental'), rental = new Rental(); router.get('/', function(req, res, next) { @@ -21,9 +21,6 @@ router.get('/', function(req, res, next) { router.get('/:title/:order', function(req, res, next) { var title = req.params.title; var originalOrder = req.params.order; - // sort by customer_id, customer name, and checkout_date - // var currentRentersArray = []; - // var pastRentersArray = []; var movieObject = { movie_data: undefined, @@ -58,10 +55,10 @@ router.get('/:title/:order', function(req, res, next) { } } - customer.where_in(['id'], currentRentersIds, function(err, rows) { + customer.where_in('id', currentRentersIds, function(err, rows) { movieObject.customers.currentRenters = rows; - customer.where_in(['id'], pastRentersIds, function(err, rows) { + customer.where_in('id', pastRentersIds, function(err, rows) { if (originalOrder == "customer_name") { rows.sort(function(a, b) { return a.name.localeCompare(b.name); // this is a good way to sort strings! From a30ea3ad7a11c4af99fb883e36600582fdb9eaa1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 16:05:44 -0700 Subject: [PATCH 094/189] wrote test for GET /customers --- db/test.db | Bin 76800 -> 76800 bytes test/routes/customers.js | 46 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 46 insertions(+) create mode 100644 test/routes/customers.js diff --git a/db/test.db b/db/test.db index 1eb65be0c0c0ad775e30565f85c310ca7b15dddd..f8c09a1f65b347e8099bc421f2fc8993cc75b080 100644 GIT binary patch delta 449 zcmZ9G&ui0Q9LC=trC?SM6-%i)_U(q)U^CwLO|mAz%T~=;i-=aNf(PGjFH2aKV476t zWm9$%L?wTN;!Q;6U*O53r-5hx58tzg&*kBH9zG}MwUhJOhbx!pDMDzhxuDtBJo(rc zgr0tT_6g%gRVQEYQuUSm!bbIqzBLFvL-a2_qwl{rYp>~XKOl7KT8EmN}Rtq)F^24rR%vHg z=$O0A7tFY*6$xEM^c`I#KefaUa{QDUs58E~(rlaPfh=a((NyjAK{ybq8R)41?gc^w z+yjdZ7;{~i9K>m=a@bs`^+z(@&B}$!w}!s$Ijm=Ut_i;5S-$W@ObpZ=TUWbnlZ4qz zxLYQBDi8Cx51hfMOsdh1%hm9H^OllDk*KMhM{&AeWU23Q=Jy2KFu@kS<>)tj{W&(! z+W5|LOW)m=sf5XHnIuP5e{H4u6I|;Kv!pznmGgU1oH@3Z@7V)x!iE@FoHMuf`%U9> G1H(TE%`80IS$G)#$O8a8Nf1^5 diff --git a/test/routes/customers.js b/test/routes/customers.js new file mode 100644 index 0000000..7b862fc --- /dev/null +++ b/test/routes/customers.js @@ -0,0 +1,46 @@ +var request = require('supertest'), + assert = require('assert'), + app = require('../../app'), + sqlite3 = require('sqlite3').verbose(), + agent = request.agent(app); + +describe("customers routes", function() { + var db_cleaner; + + beforeEach(function(done) { + db_cleaner = new sqlite3.Database('db/test.db'); + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM customers; \ + INSERT INTO customers (name, registered_at, address, city, state, \ + postal_code, phone, account_credit) \ + VALUES ('Dana Scully', 'Wed, 16 Apr 2014 21:40:20 -0700', \ + 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ + '(371) 627-1105', 1234), \ + ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }); + + describe("GET /", function(){ + it("responds with json", function(done) { + agent.get('/customers').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var customers = response.body.customers; + assert.equal(error, undefined); + assert(customers instanceof Array); + assert.equal(customers.length, 2); + assert.equal(customers[0].name, "Dana Scully"); + done(); + }); + }); + }); +}); From 65244f3fb4f44b8993c9399d507825a6e0918b61 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 16:05:52 -0700 Subject: [PATCH 095/189] added Supertest --- package.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/package.json b/package.json index c734139..2b01b0e 100644 --- a/package.json +++ b/package.json @@ -19,7 +19,8 @@ "mocha": "^2.3.2", "morgan": "~1.6.1", "serve-favicon": "~2.3.0", - "sqlite3": "^3.1.0" + "sqlite3": "^3.1.0", + "supertest": "^1.1.0" }, "devDependencies": { "should": "^7.1.0" From bd4eed2ccc3ea5d938bd17f5f7cb37f5fa0d01c2 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 16:16:40 -0700 Subject: [PATCH 096/189] added more tests for /customers endpoint --- db/test.db | Bin 76800 -> 76800 bytes test/routes/customers.js | 48 +++++++++++++++++++++++++++++++++++---- 2 files changed, 44 insertions(+), 4 deletions(-) diff --git a/db/test.db b/db/test.db index f8c09a1f65b347e8099bc421f2fc8993cc75b080..33c42eadeb7409d84ad66d779eb0d0fce1c82f90 100644 GIT binary patch delta 22 ecmZp;!P0PpWr8&0oQX2djB^?jwk9wx&;|fxW(ZIK delta 22 dcmZp;!P0PpWr8$g%S0Jx#+Jr}tqF_^v;ksn2p|9e diff --git a/test/routes/customers.js b/test/routes/customers.js index 7b862fc..72723d8 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -29,18 +29,58 @@ describe("customers routes", function() { }); }); - describe("GET /", function(){ + describe("GET /customers", function() { it("responds with json", function(done) { agent.get('/customers').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - var customers = response.body.customers; assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of objects", function(done) { + agent.get('/customers').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var customers = response.body.customers; + assert(customers instanceof Array); + done(); + }); + }); + + it("returns as many customers as there are in the table: 2", function(done) { + agent.get('/customers').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var customers = response.body.customers; + assert.equal(customers.length, 2); - assert.equal(customers[0].name, "Dana Scully"); done(); - }); + }); + }); + + it("the customer objects contain customer data", function(done) { + agent.get('/customers').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var customer = response.body.customers[0]; + + assert.equal(customer.name, "Dana Scully"); + assert.equal(customer.registered_at, 'Wed, 16 Apr 2014 21:40:20 -0700'); + assert.equal(customer.address, 'P.O. Box 887, 4257 Lorem Rd.'); + assert.equal(customer.city, "Columbus"); + assert.equal(customer.state, "Ohio"); + assert.equal(customer.postal_code, "43201"); + assert.equal(customer.phone, "(371) 627-1105"); + assert.equal(customer.account_credit, 1234); + done(); + }); }); }); + + // describe("GET /customers/:id", function() { + // it("res") + // }); }); From 89958a3de70f569332900bed7fe7fc7be7164fd6 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 17:16:10 -0700 Subject: [PATCH 097/189] fixed db_cleaner in routes/customers tests --- db/test.db | Bin 76800 -> 76800 bytes routes/customers.js | 3 --- test/routes/customers.js | 31 +++++++++++++++++++++++++------ 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/db/test.db b/db/test.db index 33c42eadeb7409d84ad66d779eb0d0fce1c82f90..fb717e72edf70b375c69b1937306791b7854ce3d 100644 GIT binary patch delta 280 zcmZp;!P0PpWr7qFOT|PPCm^{oVHq>W0tV)b%nO+NHw*GKGEeSj7tGUVVq?%Z7G?BQ z2v5u_Q7Fk*a7xX|Of5?-PEF3wOHrsu%gjkFR>;jS%S<&gFtA|JWn^Q}H56rZ%S_Jz zs?SJOa4Rh-ElN$xEGjNRQEq5yX~D$Hz`(%7tjNIJ!>q`3WV0a4Hm1o(xMC+Oac4^u zF>*1edb`Ssifb}C=A>3Aco$VBXQXCN)=`$9e3;vji<$W_1M_R Date: Wed, 23 Sep 2015 18:41:53 -0700 Subject: [PATCH 098/189] db setup --- db/development.db | Bin 76800 -> 76800 bytes db/test.db | Bin 76800 -> 76800 bytes 2 files changed, 0 insertions(+), 0 deletions(-) diff --git a/db/development.db b/db/development.db index 6e4619f5d136e4a6d8b49beaf743a5a03e42b171..0cf518e0878d1fdd35e5c7f6711318e8a79eb73d 100644 GIT binary patch delta 1097 zcmXYvJ4{ny7>3V({=YXU&_aQ7FZTlF($Ye?7btf%sF*O2NFsxSCYmTQN-QTK#(@|} z9UL4?DuKax;b7|E;NW14CJYV?4h{?skT@7)B7*Om*yMS7dd}DH|1M{FPc84Mwc=d& zuBK^I;QvRgtOr86d-v7+h7j#ZtG*>d$rt)Z5lr5e>mti^s#=+-y@c@Wi_q{KR6h&V zU4X*pp~yMNe+HU54Rtep!8lYl3U$OG*AO%kgBtpviXN!33(D<;yb-7=2=%u?rLE9J z6Exlc#p`)ya}Cs61yxl-lVwm}F;r3nIlYjt0CML+g)YdG4HY|~3tAn7%-SOWH4RqE)=~9RbPb$7oag# z+cpCQIfxu~UfvDWgrFgIl*bN6S#k>twc9P3_|oMsSgSOh&O>P{s=&3wwe3+Vq00hI zu0oo|adCLP z9S{p00jxgXhO~}vko*d8*^ym5=JuD8zj#w1K+L88JThjX12fgO? zX^U_KOKh4Dkw{iDI^Ae4o_&BqJ|O3Ne-kr#_QiAE<9;22wyt#9NgYF}29K1y6 z7N0-m@p1fmB2?Pq7k}jTV+*1mGCGFHHLwci!3tOgOW+i^1)|^@xPly)b(OYy1dr@x z@&zVu!^0!A?q%!WK>+-~4JU8hP#X%>seOw|JAC4=&9sJ(<)*Up;a8PbE^#FP0SJ7p AUjP6A delta 1119 zcmXYvJ4{ni9Eb0@=d=_lw7ko^K!F0KE%X-3yS$$oqnI#|2$8`75>1pCHI|zg<3J3g z4h{|`NMJCcUJ@J}92|_%#KD2V!GVDR5(i_967cs!Z}NTj+;h)8|HrwDJ8E%9Ef;3F z=QK?l1OG2EzY=KD-E%Le*MtZs?fQlYB{%gCBAC1>S45ZPR8=xje+kPy7opNAC~Fd` zy8xA)hg|2N+B49=X~@m(n}?ysL8zo3%Ik&N;?P(p6mEz7tx&WDGNMp*BQz9-YC=$7 zJ(N)k_0%wCl@CgHLn#WfOB?Kw z30SjPPRD{w6r0So(CmV9%w{;>48oaaH9TmR!UZM+w42=5YjQj19jNF!lsyl1&O)Qi zwqgP*XCpdTd2buk&;<3fqG47r!jyeX)ZwtD;ik)TdgXOV^#TZ_kwY72=>*wDi#=gR+ie;m1Tc+Bv;iV z%-jd>mEl5A`AOcB-TJ=%T)(9o;y`SP1uY~(+Mc$lT}7CGSG*`i6CxU|Pma&jxf%^4 z5;mf-Xrwg~4u-9+X`8SXW*#7$4s7j5K!X8aGvFSczVc~@PhXIggIRq9@4#E|2HXW( z;04&gCv#Y2dkP*a%l7bCT56e_OmdSYtXagG+XC-y9AoARW-fzSFa`SYc7p5A9?5m( zW5BrDR&HTaR_d=m_#&p(6sN;j8Q?zOkFnB;k-Da3VJh-9>oP=_L|^b1l5gNQ#E1s6_|)6SvO8JNt3 z)J>~P5me>|x>4MTh~7Y5b*CT{yaaE;6I{7?HZR}z@bVs?myXX%Zp`A&+=64 z%5;+bcW$~aCkv_}p>;%G(>nRCN_-U(yhL0bB8r--f4pCaKp8@BpRyw#&UhB zNxWnRck*Z~QZJP)Fd6LR5fuLQ#iD<&wjqKni^L$9gfiaClGx=Ya~l?0Z-Q;PhNEnF zEyWsI^KV_%m2Wc=Gw{>HQ7HC{*0t5*cW Date: Wed, 23 Sep 2015 19:04:11 -0700 Subject: [PATCH 099/189] WIP customers/:id endpoint testing --- db/test.db | Bin 76800 -> 76800 bytes test/routes/customers.js | 39 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 39 insertions(+) diff --git a/db/test.db b/db/test.db index 0c37d5be4838f6fe46547d6c04054f18c262c94e..092f0ede90ec3617e2184eb3695b93894b2e4cda 100644 GIT binary patch delta 497 zcmY+A&uSA<7{%}0J4PBPB-Ej_M*0OQCYUjI?#wiI0$nu05gkPQgXzMBljOE@>2wC> zPe@m-t_796Ko{a(L|>r3fPzqP23Ic5w>X^d$Kjk^>SvewyG?xM_xr{`-A^w+ zkSZqUh5)tlk-^?f+<6`* zleC(!LphWyc}uNn%3U!GW4Vgbl5fAReXMDXzty{b5C8xG delta 68 zcmZp;!P0PpWr7qFOaDX}Cm^{oVF@!61IuPXo=waXCwQ>&G5`TCZj-<=0Y(`BlE)F3 diff --git a/test/routes/customers.js b/test/routes/customers.js index 2fc1425..2ac9ca6 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -101,5 +101,44 @@ describe("customers routes", function() { done(); }); }); + + it("returns an object with customer data and movies", function(done) { + agent.get('/customers/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var result = response.body; + + assert(result instanceof Object); + done(); + }); + }); + + it("object returned has customer_data and movies", function(done) { + agent.get('/customers/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var result = response.body; + var keys = Object.keys(result); + + assert.equal(keys.length, 2); + assert.equal(keys[0], "customer_data"); + assert.equal(keys[1], "movies") + done(); + }); + }); + + it("object returned has customer_data and movies", function(done) { + agent.get('/customers/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var result = response.body; + var keys = Object.keys(result); + + assert.equal(keys.length, 2); + assert.equal(keys[0], "customer_data"); + assert.equal(keys[1], "movies") + done(); + }); + }); }); }); From ac4731bb37ae2e2f6ea621aedf4fe5d84ecc5af3 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 19:06:28 -0700 Subject: [PATCH 100/189] added tests for /movies route --- db/test.db | Bin 76800 -> 76800 bytes test/routes/movies.js | 102 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) create mode 100644 test/routes/movies.js diff --git a/db/test.db b/db/test.db index fb717e72edf70b375c69b1937306791b7854ce3d..2a02924b6be01159f5be1449cd5e9ff5d11a6200 100644 GIT binary patch delta 24 ecmZp;!P0PpWr7qFtIR|hCm`9Fur+~kfi?hQGY47# delta 24 ecmZp;!P0PpWr7qFOT|PPCm`9Fur+~kfi?hY0|*cR diff --git a/test/routes/movies.js b/test/routes/movies.js new file mode 100644 index 0000000..be199fc --- /dev/null +++ b/test/routes/movies.js @@ -0,0 +1,102 @@ +var request = require('supertest'), + assert = require('assert'), + app = require('../../app'), + sqlite3 = require('sqlite3').verbose(), + agent = request.agent(app); + +describe("movies routes", function() { + var db_cleaner; + + beforeEach(function(done) { + db_cleaner = new sqlite3.Database('db/test.db'); + + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM customers; \ + INSERT INTO customers (name, registered_at, address, city, state, \ + postal_code, phone, account_credit) \ + VALUES ('Alex Krychek', 'Wed, 16 Apr 2014 21:40:20 -0700', \ + 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ + '(371) 627-1105', 1234), \ + ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ + DELETE FROM movies; \ + INSERT INTO movies (title, overview, release_date, inventory) \ + VALUES ('Fight the Future', 'first xfiles movie', '1998', 2), \ + ('I Want to Believe', 'second xfiles movie', '2008', 4); \ + DELETE FROM rentals; \ + INSERT INTO rentals (customer_id, movie_id, checkout_date, due_date, \ + returned_date) \ + VALUES (1, 1, '2012', '2013', '2013'), \ + (1, 2, '2008', '2009', '2009'), \ + (1, 2, '2014', '2015', ''); \ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }); + + describe("GET /movies", function() { + + it("responds with json", function(done) { + agent.get('/movies').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of objects", function(done) { + agent.get('/movies').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var movies = response.body.movies; + + assert(movies instanceof Array); + done(); + }); + }); + + it("returns as many movies as there are in the table: 2", function(done) { + agent.get('/movies').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var movies = response.body.movies; + + assert.equal(movies.length, 2); + done(); + }); + }); + + it("the movie objects contain movie data", function(done) { + agent.get('/movies').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var movie = response.body.movies[0]; + + // 'Fight the Future', 'first xfiles movie', '1998', 2 + assert.equal(movie.title, "Fight the Future"); + assert.equal(movie.overview, 'first xfiles movie'); + assert.equal(movie.release_date, '1998'); + assert.equal(movie.inventory, 2); + done(); + }); + }); + }); + + // describe("GET /customers/:id", function() { + // it("responds with json", function(done) { + // agent.get('/customers/1').set('Accept', 'application/json') + // .expect('Content-Type', /application\/json/) + // .expect(200, function(error, response) { + // assert.equal(error, undefined); + // done(); + // }); + // }); + // }); +}); From fd1a5cdd2d4caef527c28e90d9b83908bc6f8824 Mon Sep 17 00:00:00 2001 From: Anita Date: Wed, 23 Sep 2015 19:39:47 -0700 Subject: [PATCH 101/189] refactored customers subset unit test --- db/test.db | Bin 76800 -> 76800 bytes test/models/customer.js | 59 ++++++++++----------------------------- test/routes/customers.js | 47 +++++++++++++++++++++++++++---- 3 files changed, 56 insertions(+), 50 deletions(-) diff --git a/db/test.db b/db/test.db index 092f0ede90ec3617e2184eb3695b93894b2e4cda..5309c889d25e2e292414a5c281550fb32be31160 100644 GIT binary patch delta 24 ecmZp;!P0PpWr7qF$McCYPC&9TVQT{80&M_u?FjY& delta 24 ecmZp;!P0PpWr7qF>w}3hPC&9TVQT{80&M_u3kc!> diff --git a/test/models/customer.js b/test/models/customer.js index 9be6dad..3c6d9cd 100644 --- a/test/models/customer.js +++ b/test/models/customer.js @@ -51,38 +51,22 @@ describe("Customer", function() { }); }); - it("can return a subset of customers sorted by name", function(done){ - var queries = [1, 0] - customer.subset("name", queries, function(err, res) { - assert.equal(err, undefined); - assert(res instanceof Array); - assert.equal(res[0].id, 1); - assert.equal(res[0].name, "Dana Scully") - done(); - }); - }); - - it("can return a subset of customers sorted by registered_at", function(done){ - var queries = [1, 0] - customer.subset("registered_at", queries, function(err, res) { - assert.equal(err, undefined); - assert(res instanceof Array); - assert.equal(res[0].id, 2); - assert.equal(res[0].name, "Fox Mulder") - done(); - }); - }); - - it("can return a subset of customers sorted by postal_code", function(done){ - var queries = [1, 1] - customer.subset("postal_code", queries, function(err, res) { - assert.equal(err, undefined); - assert(res instanceof Array); - assert.equal(res[0].id, 2); - assert.equal(res[0].name, "Fox Mulder") - done(); + var sorted_by = ["name", "registered_at", "postal_code"]; + + for (var i = 0; i < sorted_by.length; i++) { + var column = sorted_by[i]; + + it("can return a subset of customers sorted by " + column, function(done) { + var queries = [1, 0]; + customer.subset(column, queries, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res[0].id, 1); + assert.equal(res[0].name, "Dana Scully") + done(); + }); }); - }); + } }); // end of describe instance methods describe("class methods", function() { @@ -121,17 +105,4 @@ describe("Customer", function() { }); }); - // it("can save changes to a customer", function(done) { - // customer.find_by("name", "Fox Mulder", function(err, res) { - // var original_name = res.name; - // var id = res.id; - // customer.save({name: "Foxy Mulder", id: id}, function(err, res) { - // assert.equal(err, undefined); - // assert.equal(res.inserted_id, 0); //it didn't insert any records - // assert.equal(res.changed, 1); //it updated one record - // done(); - // }) - // }) - // }); - }); diff --git a/test/routes/customers.js b/test/routes/customers.js index 2ac9ca6..d534885 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -127,16 +127,51 @@ describe("customers routes", function() { }); }); - it("object returned has customer_data and movies", function(done) { + it("returns a list of movies currently checked out", function(done) { agent.get('/customers/1').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - var result = response.body; - var keys = Object.keys(result); + var currentRentals = response.body.movies.currentRentals; + var movie = currentRentals[0]; + + assert.equal(currentRentals.length, 1); + assert.equal(movie.title, "I Want to Believe"); + assert.equal(movie.overview, "second xfiles movie"); + assert.equal(movie.release_date, "2008"); + assert.equal(movie.inventory, 4); + done(); + }); + }); - assert.equal(keys.length, 2); - assert.equal(keys[0], "customer_data"); - assert.equal(keys[1], "movies") + it("returns a list of past rentals", function(done) { + agent.get('/customers/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var pastRentals = response.body.movies.pastRentals; + var movie = pastRentals[0].movieData; + + assert.equal(pastRentals.length, 2); + assert.equal(movie.title, "Fight the Future"); + assert.equal(movie.overview, "first xfiles movie"); + assert.equal(movie.release_date, "1998"); + assert.equal(movie.inventory, 2); + done(); + }); + }); + + it("sorts past rentals by checkout date"); + + it("includes return date for past rentals", function(done) { + agent.get('/customers/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + var pastRentals = response.body.movies.pastRentals; + var movie1ReturnDate = pastRentals[0].returnedDate; + var movie2ReturnDate = pastRentals[1].returnedDate; + console.log(movie1ReturnDate) + + assert.equal(movie1ReturnDate, 2013); + assert.equal(movie2ReturnDate, 2009); done(); }); }); From 667a6155c392f1b0627f1f053eb4f949f53e4181 Mon Sep 17 00:00:00 2001 From: Anita Date: Wed, 23 Sep 2015 19:40:52 -0700 Subject: [PATCH 102/189] removed extraneous comment --- routes/customers.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index bdb539c..aebcd55 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -61,12 +61,6 @@ router.get('/:id', function(req, res, next) { movieObject.returnedDate = pastMoviesObject[rows[i].id]; pastRentalsArray.push(movieObject); } - // customerObject.movies.pastRentals = rows; - // add returned_date to each rental - - // brute force: iterate through each movie object, - // run a query on the rentals table, get returned_date for that movie - res.status(200).json(customerObject); }); From c85bc7bc674dcc01b154c84f26d25e5ba4de718c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Wed, 23 Sep 2015 19:41:20 -0700 Subject: [PATCH 103/189] added tests /movies/:sort_by/:number/:offset --- db/test.db | Bin 76800 -> 76800 bytes test/routes/movies.js | 118 +++++++++++++++++++++++++++++++++++++----- 2 files changed, 104 insertions(+), 14 deletions(-) diff --git a/db/test.db b/db/test.db index 2a02924b6be01159f5be1449cd5e9ff5d11a6200..6b56793639e7d608b95c02994f21d7be2979cee3 100644 GIT binary patch delta 91 zcmZp;!P0PpWr7qF`@e}YPC#;F!V+#iR_56Z%&(cRG9PAM%RGCtAWtW=h5#!&10$!X kC@+(dfuSi7n~AVML_~oi20#%5GZ1b*%)k9GKclS-0Ed|t7ytkO delta 50 zcmZp;!P0PpWr7qFtIR|hCm^{oVF@=EGxK2v=GV+unGbIkWT|7GtiWR4e3*axVSYwi F832W=4<-Nr diff --git a/test/routes/movies.js b/test/routes/movies.js index be199fc..d529799 100644 --- a/test/routes/movies.js +++ b/test/routes/movies.js @@ -30,7 +30,9 @@ describe("movies routes", function() { returned_date) \ VALUES (1, 1, '2012', '2013', '2013'), \ (1, 2, '2008', '2009', '2009'), \ - (1, 2, '2014', '2015', ''); \ + (1, 2, '2014', '2015', ''), \ + (2, 1, '2005', '2006', '2006'), \ + (2, 1, '2015', '2016', ''); \ COMMIT;" , function(err) { db_cleaner.close(); @@ -53,7 +55,6 @@ describe("movies routes", function() { it("returns an array of objects", function(done) { agent.get('/movies').set('Accept', 'application/json') - .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var movies = response.body.movies; @@ -64,7 +65,6 @@ describe("movies routes", function() { it("returns as many movies as there are in the table: 2", function(done) { agent.get('/movies').set('Accept', 'application/json') - .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var movies = response.body.movies; @@ -75,7 +75,6 @@ describe("movies routes", function() { it("the movie objects contain movie data", function(done) { agent.get('/movies').set('Accept', 'application/json') - .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var movie = response.body.movies[0]; @@ -89,14 +88,105 @@ describe("movies routes", function() { }); }); - // describe("GET /customers/:id", function() { - // it("responds with json", function(done) { - // agent.get('/customers/1').set('Accept', 'application/json') - // .expect('Content-Type', /application\/json/) - // .expect(200, function(error, response) { - // assert.equal(error, undefined); - // done(); - // }); - // }); - // }); + describe("GET /movies/:title/:order", function() { + it("responds with json", function(done) { + agent.get('/movies/Fight the Future/customer_id').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an object", function(done) { + agent.get('/movies/Fight the Future/customer_id').set('Accept', 'application/json') + .expect(200, function(error, response) { + var movie = response.body; + + assert(movie instanceof Object); + done(); + }); + }); + + it("returns the movie with the title from the url", function(done) { + agent.get('/movies/Fight the Future/customer_id').set('Accept', 'application/json') + .expect(200, function(error, response) { + var movieData = response.body.movie_data; + + assert.equal(movieData.title, 'Fight the Future'); + done(); + }); + }); + + it("returns a currentRenters object with a list of current renters", function(done) { + agent.get('/movies/Fight the Future/customer_id').set('Accept', 'application/json') + .expect(200, function(error, response) { + var currentRenters = response.body.customers.currentRenters; + + assert(currentRenters[0].name, 'Fox Mulder'); + done(); + }); + }); + + it("returns a pastRenters object with a list of past renters sorted by the order variable", function(done) { + agent.get('/movies/Fight the Future/customer_id').set('Accept', 'application/json') + .expect(200, function(error, response) { + var pastRenters = response.body.customers.pastRenters; + + assert(pastRenters[0].name, 'Alex Krychek'); + done(); + }); + }); + }); + +describe("GET /movies/:sort_by/:number/:offset", function() { + it("responds with json", function(done) { + agent.get('/movies/title/1/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an object", function(done) { + agent.get('/movies/title/2/0').set('Accept', 'application/json') + .expect(200, function(error, response) { + var movies = response.body; + console.log(movies); + assert(movies instanceof Object); + done(); + }); + }); + + // it("returns the number of movies in the number parameter", function(done) { + // agent.get('/movies/title/2/0').set('Accept', 'application/json') + // .expect(200, function(error, response) { + // var movieData = response.body.movie_data; + + // assert.equal(movieData.title, 'Fight the Future'); + // done(); + // }); + // }); + + // it("returns a currentRenters object with a list of current renters", function(done) { + // agent.get('/movies/title/5/5').set('Accept', 'application/json') + // .expect(200, function(error, response) { + // var currentRenters = response.body.customers.currentRenters; + + // assert(currentRenters[0].name, 'Fox Mulder'); + // done(); + // }); + // }); + + // it("returns a pastRenters object with a list of past renters sorted by the order variable", function(done) { + // agent.get('/movies/title/5/5').set('Accept', 'application/json') + // .expect(200, function(error, response) { + // var pastRenters = response.body.customers.pastRenters; + + // assert(pastRenters[0].name, 'Alex Krychek'); + // done(); + // }); + // }); + }); }); From e8078a74fd812c8d31849d72072cc7de6683e809 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 08:49:01 -0700 Subject: [PATCH 104/189] ran latest tests --- db/test.db | Bin 76800 -> 76800 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/db/test.db b/db/test.db index 6b56793639e7d608b95c02994f21d7be2979cee3..cae0878b91152ecfb062b42e90d2b525f7db65f5 100644 GIT binary patch delta 24 ecmZp;!P0PpWr7qFhx$YrCm`9Fur+~kfi?hRZ3lJ$ delta 24 ecmZp;!P0PpWr7qF`@e}YPC&9TVQT{80&M_w&j}&` From eff81e71b56a5ed1b0b6b2f12ce492aa6e1c0338 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 09:21:42 -0700 Subject: [PATCH 105/189] added remaining tests for GET /movies/:sort_by/:number/:offset --- db/test.db | Bin 76800 -> 76800 bytes test/routes/movies.js | 71 ++++++++++++++++++++++-------------------- 2 files changed, 37 insertions(+), 34 deletions(-) diff --git a/db/test.db b/db/test.db index cae0878b91152ecfb062b42e90d2b525f7db65f5..f7564065ff9a5069ff569ad26ccdfcf3c8f21358 100644 GIT binary patch delta 76 zcmZp;!P0PpWr7qFr{qK#Cm^{oVF@!AGjlTo^F`(b%*~qxSxT8@rJ30nq~%2!9Tj}@ f%Q91o^K(-b3UcyGj0_AcnVT1|Z(qR9n4kgx4g?f} delta 67 zcmZp;!P0PpWr7qFhx$YrCm^{oVF@!A6Y~NF=8Mb=nEN*?@>DTT3}6?uVrFA-Hxy+I W$w*a*&~?kqX Date: Thu, 24 Sep 2015 09:23:54 -0700 Subject: [PATCH 106/189] removed console.log --- test/routes/movies.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/routes/movies.js b/test/routes/movies.js index 0436744..83247e1 100644 --- a/test/routes/movies.js +++ b/test/routes/movies.js @@ -184,7 +184,6 @@ describe("GET /movies/:sort_by/:number/:offset", function() { agent.get('/movies/title/1/1').set('Accept', 'application/json') .expect(200, function(error, response) { var movies = response.body.movies; - console.log(movies); // this is the second movie alphabetically assert(movies[0].title, "Fight the Future"); From 63a8e5bdf1fde5ebd16d8cf0911f9f5ca2e1441c Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 09:36:45 -0700 Subject: [PATCH 107/189] wrote integration tests for GET /rentals/overdue --- db/test.db | Bin 76800 -> 76800 bytes test/routes/rentals.js | 82 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 82 insertions(+) create mode 100644 test/routes/rentals.js diff --git a/db/test.db b/db/test.db index cae0878b91152ecfb062b42e90d2b525f7db65f5..95d917a17c259da536ca6fd6184da796738e4cf0 100644 GIT binary patch delta 218 zcmZp;!P0PpWr7qFr`ALnCm^{oVF^1IGt(Xh<{oB6rahYlS=KShCNpy}D0{1m%Zh6< zxg_Q#Dg-B&=Hyhm6=muu7)`e2mee;gHc<%3EJ!U<2rkhJDa|QP^v}*o%*fA8G&V6c zGt)3KFw;~pHnP+;u{5$^zc5*m`>_ZIa{>eNYv!xWhnd$h&t~pmE@Msr+ULP+EyBUh zz{n{oD#~nVX=w<=Mj%>%ot=S`QB;(d$S-|8~Q delta 167 zcmZp;!P0PpWr7qFhx$YrCm^{oVF^1I6SE=%a}Tp3(~-@BEZdl3W0<)ZB)zre1;sTP zf)Y!T@+-qrQ*;!JOcdNwlN5{$42={FEv$@;tPCv_bPdc63`|WGg0nO8@=}Ww9LrMm z!V>e6^GnN8i=3P-jV(+JG>k1wH5DvPEOaf6EG8>*Kjvd)p3T7gn)xd8Vdk~Wvw^nO SF;5KOZl2A*eKtR1stf=Dk1U-4 diff --git a/test/routes/rentals.js b/test/routes/rentals.js new file mode 100644 index 0000000..9e8806e --- /dev/null +++ b/test/routes/rentals.js @@ -0,0 +1,82 @@ +var request = require('supertest'), + assert = require('assert'), + app = require('../../app'), + sqlite3 = require('sqlite3').verbose(), + agent = request.agent(app); + +describe("rentals routes", function() { + var db_cleaner; + + beforeEach(function(done) { + db_cleaner = new sqlite3.Database('db/test.db'); + + db_cleaner.serialize(function() { + db_cleaner.exec( + "BEGIN; \ + DELETE FROM customers; \ + INSERT INTO customers (name, registered_at, address, city, state, \ + postal_code, phone, account_credit) \ + VALUES ('Alex Krychek', 'Wed, 16 Apr 2014 21:40:20 -0700', \ + 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ + '(371) 627-1105', 1234), \ + ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293), \ + ('Dana Scully', 'Fri, 20 Jul 2015 15:23:06 -0700', '234 Piper St.', \ + 'Tulsa', 'Oklahoma', '34566', '(206) 329-4928', 2000); \ + DELETE FROM movies; \ + INSERT INTO movies (title, overview, release_date, inventory) \ + VALUES ('Fight the Future', 'first xfiles movie', '1998', 2), \ + ('I Want to Believe', 'second xfiles movie', '2008', 4); \ + DELETE FROM rentals; \ + INSERT INTO rentals (customer_id, movie_id, checkout_date, due_date, \ + returned_date) \ + VALUES (1, 1, '2012', '2013', '2013'), \ + (1, 2, '2008', '2009', '2009'), \ + (1, 2, '2014', '2015', ''), \ + (2, 1, '2005', '2006', '2006'), \ + (2, 1, '2015', '2016', ''), \ + (2, 3, '2013', '2014', ''), \ + (1, 2, '1989', '1990', ''), \ + (3, 1, '1991', '1992', '1991'); \ + COMMIT;" + , function(err) { + db_cleaner.close(); + done(); + } + ); + }); + }); + + describe("GET /rentals/overdue", function() { + + it("responds with json", function(done) { + agent.get('/rentals/overdue').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an array of objects", function(done) { + agent.get('/rentals/overdue').set('Accept', 'application/json') + .expect(200, function(error, response) { + var overdueCustomers = response.body.overdue_customers; + + assert(overdueCustomers instanceof Array); + done(); + }); + }); + + it("returns a list of the customers with overdue books", function(done) { + agent.get('/rentals/overdue').set('Accept', 'application/json') + .expect(200, function(error, response) { + var overdueCustomers = response.body.overdue_customers; + + // only two of the three customers with rental records have overdue + assert.equal(overdueCustomers.length, 2); + done(); + }); + }); + }); +}); From b4922b6ed0ca31156670cc3ce81ecc9d5d603c6a Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 09:45:23 -0700 Subject: [PATCH 108/189] debugging customer sorting tests --- db/test.db | Bin 76800 -> 76800 bytes routes/customers.js | 1 - test/routes/customers.js | 20 +++++++++++++++----- 3 files changed, 15 insertions(+), 6 deletions(-) diff --git a/db/test.db b/db/test.db index cae0878b91152ecfb062b42e90d2b525f7db65f5..aca4ba6c7de0a436efcd3e11a700923308976d62 100644 GIT binary patch delta 1175 zcmYk*TWkzb7zgkLc?v2GEG%Sd>T@E{`MfrO+F9y}m|2NDkwg8$J3oBTGD|939moRb-uU?UUk z)QsX_wW28P;DHrzY_!fG!JFGJ5mM}U)hi_ATvwlvBIgi25u|iLq0i|!9dJV|Lu0kn zt3-8;bS%&IWCr-2zJ1vYkLS9x{ayUP&VQL9bU~eQUk|2f)Tx~EwqQ)5AL&bapI)V7 zNRQCb_5Q{pk535@O)FF}BLQX!LlV$5O;4pPNJ(KjIZUG%qJtqhFQ?TG;|=6*IRqgD zMNkhmq#y|f=pY~lbx;d6FdrgN1#@8z%!XM|0p(BzrBDLJFck`6cnbdfkbp*zN4pwU z!Ag*gErT{#3N7G;CRhxMKwe2D%z!Wyz;uw;(+bV71RB7CI4p#y?0p^{ILrhMra=IF zV8Q}mZY1_ptwO&$}L5G{LoRWccm>4wSI4)%8Pjk$%Z`u1aXHg`}y z=$09`Y78?T%%c=^^a4A-y}@UClRSckP#$E3WrqLY_httEb8lUc-0$+HM~>l7H71z(Tz4zqFG!RwuzZ>Vez(1Csq@d z)6!HzEO&F$b&_ZIm|vx(3Oz|nodUi+AWvJ~Uc$}s^Xl2sTJqsm*uz}U-CxvYw^inP zZ~UZrc8y(T5yD(n@q^wf_p-eA3Q8AbX&fa^Se~6jc}&hYBjd+NPN7sGODEwt9EA~t zh1Kn7tOJ#SwMMSQ&1JO3E!DJcm;FefcHw^0WAgSH{y4evPN`Rj0r=geRN5 z{#u+QHH0!zYagR+!TOlar`@_NFFJlQFCXu~UMaV!belgrAhl?AmpO8bb(c{!OzT+} zRh5uRLy=lltqnzJP^ngw%1V0VRLn4#MfVJ{@}rs&H3tTnwRc}lMI@}0R75HRv?d%0 z)~FF)kn-L)CE?F_89&GO@YLo@aZ1u_(_C%|c``FoWq3vjGw2~LdYHv@+QoWfMx5Fv)w;EQn?i{V_v^7}%%%n#qW#Q@n}(*x>=CNPY23Cn zqnA-O$P7CU-94JFQyUIdH=~+Pw`&&DsM$jsm}&Jg+Z-~=X(OD{X%jYC&=7SB{j0J= z3K4N!b#O`A^$YvpL&UEhc)5>udR%aq1l*2IZ^>S-RMb>mT#y}bbDF)DAm2%Xd<1J? zl{jQYhCy#PFef=5WVxMB&hB;sxft=OS=Bj_H-j9q^i7s=J0H#2i4=ZwDVNv1Sxk^c z81NK4fgz8@kOvz$LGD5_2W~@pL!{S5dJU3sa2Z?#qhJ`=pdaX<8+1Tdo9Jp4T?Zj) zgk--+!Xi;%RVG#?VwDf|SKuo+Nft;6TF3K+$VC=h6#c=oBp;Dkk|Qn|2 Date: Thu, 24 Sep 2015 09:45:42 -0700 Subject: [PATCH 109/189] started creating tests for GET /rentals/:title; WIP --- test/routes/rentals.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 9e8806e..15f3d56 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -79,4 +79,8 @@ describe("rentals routes", function() { }); }); }); + + // describe('GET /rentals/:title', function() { + + // }); }); From e4a3474ad1a465c9b5e65e7d6bdaab5462845da6 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 09:46:28 -0700 Subject: [PATCH 110/189] fixing merge conflict --- db/test.db | Bin 76800 -> 76800 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/db/test.db b/db/test.db index 95d917a17c259da536ca6fd6184da796738e4cf0..cc5992952657d6d6c3760cffc6d4c99388502677 100644 GIT binary patch delta 22 dcmZp;!P0PpWr8$g*hCp;#<0eOtqF_^v;khI2gCpX delta 22 dcmZp;!P0PpWr8%L) Date: Thu, 24 Sep 2015 10:16:43 -0700 Subject: [PATCH 111/189] fixed /customers/:id route to return movies sorted by checkout date; order_by's sorting was being overridden by a later query --- routes/customers.js | 36 ++++++++++++++++++++++-------------- 1 file changed, 22 insertions(+), 14 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index f0c3b36..d1de55b 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -20,11 +20,11 @@ router.get('/', function(req, res, next) { router.get('/:id', function(req, res, next) { var id = req.params.id; var customer_info; - var pastRentalsArray = []; + // var pastRentalsObject = {}; var customerObject = { customer_data: undefined, - movies: { pastRentals: pastRentalsArray } + movies: {} } customer.find_by('id', id, function(err, row) { @@ -32,12 +32,11 @@ router.get('/:id', function(req, res, next) { var condition = "customer_id = " + id; - // order_by returns a collection of records matching the condition, - // ordered by the column - rental.order_by(condition, "checkout_date", function(err, rows) { + // use where to pull all records that meet the condition + rental.where(["customer_id"], [id], function(err, rows) { var currentMoviesIDs = []; var pastMoviesIDs = []; - var pastMoviesObject = {}; + var pastMovies = {}; for (var i = 0; i < rows.length; i++) { // currently checked out movies @@ -45,23 +44,32 @@ router.get('/:id', function(req, res, next) { currentMoviesIDs.push(rows[i].movie_id); // returned movies } else { - pastMoviesObject[rows[i].movie_id] = rows[i].returned_date; - // pastMoviesIDs.push(rows[i].movie_id); + pastMovies[rows[i].movie_id] = { + dates: { + returned_date: rows[i].returned_date, + checkout_date: rows[i].checkout_date + } + }; + + pastMoviesIDs.push(rows[i].movie_id); } } - pastMoviesIDs = Object.keys(pastMoviesObject); movie.where_in('id', currentMoviesIDs, function(err, rows) { customerObject.movies.currentRentals = rows; // no returned_date + pastMoviesArray = []; - movie.where_in('id', pastMoviesIDs, function(err, rows) { + movie.where_in('id', pastMoviesIDs, function(err, rows) { // unsorted for (var i = 0; i < rows.length; i++) { - var movieObject = {}; - movieObject.movieData = rows[i]; - movieObject.returnedDate = pastMoviesObject[rows[i].id]; - pastRentalsArray.push(movieObject); + pastMovies[rows[i].id].movie_data = rows[i]; + pastMoviesArray.push(pastMovies[rows[i].id]); } + + pastMoviesArray.sort(function(a, b) { + return a.dates.checkout_date.localeCompare(b.dates.checkout_date); // this is a good way to sort strings! + }); + customerObject.movies.pastRentals = pastMoviesArray; res.status(200).json(customerObject); }); }); From ace430b07ce8c37ac3774dce2a05b8566db26191 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 10:49:55 -0700 Subject: [PATCH 112/189] removed unused condition variable --- routes/customers.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index d1de55b..1192360 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -30,8 +30,6 @@ router.get('/:id', function(req, res, next) { customer.find_by('id', id, function(err, row) { customerObject.customer_data = row; - var condition = "customer_id = " + id; - // use where to pull all records that meet the condition rental.where(["customer_id"], [id], function(err, rows) { var currentMoviesIDs = []; From 547b360d9f1fdd2f4a552e4abfc01af5a75617a8 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 10:50:12 -0700 Subject: [PATCH 113/189] fixed /movies/:title/:order route to return sorted data --- routes/movies.js | 62 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 43 insertions(+), 19 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index 26f08a7..f6664b3 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -20,53 +20,77 @@ router.get('/', function(req, res, next) { router.get('/:title/:order', function(req, res, next) { var title = req.params.title; - var originalOrder = req.params.order; + var order = req.params.order; var movieObject = { movie_data: undefined, - customers: { currentRenters: undefined, pastRenters: undefined } + customers: { } }; + var movieId; movie.find_by('title', title, function(err, row) { movieObject.movie_data = row; movieId = row.id; - var sortOrder; - - var condition = "movie_id = " + movieId; - // don't bother sorting rentals if customers should be sorted by customer name - if (originalOrder == "customer_name") { - sortOrder = "none" - } else { - sortOrder = originalOrder; - } - - rental.order_by(condition, sortOrder, function(err, rows) { + rental.where(["movie_id"], [movieId], function(err, rows) { var currentRentersIds = []; var pastRentersIds = []; + var pastRenters = {}; for (var i = 0; i < rows.length; i++) { if (rows[i].returned_date == "") { currentRentersIds.push(rows[i].customer_id); } else { + var checkoutDate = new Date(rows[i].checkout_date); + pastRenters[rows[i].customer_id] = { + dates: { + checkout_date: checkoutDate + } + }; + pastRentersIds.push(rows[i].customer_id); } } + console.log(pastRenters); customer.where_in('id', currentRentersIds, function(err, rows) { movieObject.customers.currentRenters = rows; + var pastRentersArray = []; customer.where_in('id', pastRentersIds, function(err, rows) { - if (originalOrder == "customer_name") { - rows.sort(function(a, b) { - return a.name.localeCompare(b.name); // this is a good way to sort strings! - }); // sort customers by names ASC + for (var i = 0; i < rows.length; i++) { + console.log(rows[i].id); + pastRenters[rows[i].id].customer_data = rows[i]; + pastRentersArray.push(pastRenters[rows[i].id]); } - movieObject.customers.pastRenters = rows; + + // now sort the array by name, id or checkout date + if (order == "name") { + pastRentersArray.sort(function(a, b) { + return a.customer_data.name + .localeCompare(b.customer_data.name); + }); + } else if (order == "id") { + pastRentersArray.sort(function(a, b) { + return a.customer_data.id - b.customer_data.id; + }); + } else if (order == "checkout_date") { + pastRentersArray.sort(function(a, b) { + return a.dates.checkout_date - b.dates.checkout_date; + }); + } else { + var error_message = "You cannot sort by: " + order; + } + + movieObject.customers.pastRenters = pastRentersArray; - res.status(200).json(movieObject); + if (error_message) { + res.status(400).json(error_message); + } else { + res.status(200).json(movieObject); + } }); }); }); From d256703b9d5e12d34a44e33c78e87eb0d46542f0 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 10:50:48 -0700 Subject: [PATCH 114/189] removed unused order_by function --- database_adapter.js | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index 1ffd9ff..b1e61a0 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -68,21 +68,6 @@ module.exports = { }); }, - // if 'none' is passed in, no sort is performed - order_by: function(condition, column, callback) { - var db = new sqlite3.Database('db/' + db_env + '.db'); - - var statement; - statement = (column == "none") ? - "SELECT * FROM " + this.table_name + " WHERE " + condition - : "SELECT * FROM " + this.table_name + " WHERE " + condition + " ORDER BY " + column; - - db.all(statement, function(err, res) { - if (callback) { callback(err, res); } - db.close(); - }); - }, - // Example route: // customers/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone create: function(columns, values, callback) { From 81f8aaef2de4178ff4d8bc6307a3f3fda14b9b86 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 11:55:24 -0700 Subject: [PATCH 115/189] WIP customers testing --- db/test.db | Bin 0 -> 76800 bytes test/routes/customers.js | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) create mode 100644 db/test.db diff --git a/db/test.db b/db/test.db new file mode 100644 index 0000000000000000000000000000000000000000..622ffb4d2a0cc4001f8dcbc655eb2a051c8b00f7 GIT binary patch literal 76800 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 Date: Thu, 24 Sep 2015 11:59:18 -0700 Subject: [PATCH 116/189] updated url parameter to be allowed sort order --- db/test.db | Bin 76800 -> 76800 bytes test/routes/movies.js | 10 +++++----- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/db/test.db b/db/test.db index f7564065ff9a5069ff569ad26ccdfcf3c8f21358..62bfb9812a145f7ba5a2a995ca922a7941dfb78d 100644 GIT binary patch delta 22 ecmZp;!P0PpWr8&0+=(*IjB^_kwk9wx&;|fxdk9hh delta 22 dcmZp;!P0PpWr8%L Date: Thu, 24 Sep 2015 12:06:07 -0700 Subject: [PATCH 117/189] WIP fixing customers tests after changes to routes code --- db/test.db | Bin 76800 -> 76800 bytes test/routes/customers.js | 14 +++++++------- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/db/test.db b/db/test.db index 622ffb4d2a0cc4001f8dcbc655eb2a051c8b00f7..f0c8975247e296cc2ab48f470535e1562eca9cc5 100644 GIT binary patch delta 24 ecmZp;!P0PpWr7qFi_JtCCm`9Fur+~kfi?hS+Xt8c delta 24 ecmZp;!P0PpWr7qFbNfUYCm`9Fur+~kfi?hZH3%#K diff --git a/test/routes/customers.js b/test/routes/customers.js index 026712a..f0234fe 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -24,7 +24,7 @@ describe("customers routes", function() { DELETE FROM movies; \ INSERT INTO movies (title, overview, release_date, inventory) \ VALUES ('Fight the Future', 'first xfiles movie', '1998', 2), \ - ('I Want to Believe', 'second xfiles movie', '2008', 4), \ + ('I Want to Believe', 'second xfiles movie', '2008', 4); \ DELETE FROM rentals; \ INSERT INTO rentals (customer_id, movie_id, checkout_date, due_date, \ returned_date) \ @@ -73,7 +73,7 @@ describe("customers routes", function() { }); }); - it.only("the customer objects contain customer data", function(done) { + it("the customer objects contain customer data", function(done) { agent.get('/customers').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { @@ -148,13 +148,13 @@ describe("customers routes", function() { .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var pastRentals = response.body.movies.pastRentals; - var movie = pastRentals[0].movieData; + var movie = pastRentals[0].movie_data; assert.equal(pastRentals.length, 2); - assert.equal(movie.title, "Fight the Future"); - assert.equal(movie.overview, "first xfiles movie"); - assert.equal(movie.release_date, "1998"); - assert.equal(movie.inventory, 2); + assert.equal(movie.title, "I Want to Believe"); + assert.equal(movie.overview, "second xfiles movie"); + assert.equal(movie.release_date, "2008"); + assert.equal(movie.inventory, 4); done(); }); }); From b98594497a961d7a8f632181e903c0f15f1285b5 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 12:09:51 -0700 Subject: [PATCH 118/189] fixed customers testing --- test/routes/customers.js | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/test/routes/customers.js b/test/routes/customers.js index f0234fe..4b672ab 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -166,8 +166,8 @@ describe("customers routes", function() { var pastRental1 = response.body.movies.pastRentals[0].movie_data; var pastRental2 = response.body.movies.pastRentals[1].movie_data; - assert.equal(pastRental1.title, "Fight the Future"); - assert.equal(pastRental2.title, "I Want to Believe"); + assert.equal(pastRental1.title, "I Want to Believe"); + assert.equal(pastRental2.title, "Fight the Future"); done(); }); }); @@ -177,11 +177,11 @@ describe("customers routes", function() { .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var pastRentals = response.body.movies.pastRentals; - var movie1ReturnDate = pastRentals[0].returnedDate; - var movie2ReturnDate = pastRentals[1].returnedDate; + var movie1ReturnDate = pastRentals[0].dates.returned_date; + var movie2ReturnDate = pastRentals[1].dates.returned_date; - assert.equal(movie1ReturnDate, 2013); - assert.equal(movie2ReturnDate, 2009); + assert.equal(movie1ReturnDate, 2009); + assert.equal(movie2ReturnDate, 2013); done(); }); }); From 6f257f9d95b9bdfc7155600ac1ff7a250206f7f6 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 12:13:13 -0700 Subject: [PATCH 119/189] removed console.log from movies routes files and fixed test for movies routes on line 132. --- db/test.db | Bin 0 -> 4096 bytes routes/movies.js | 2 -- test/routes/movies.js | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) create mode 100644 db/test.db diff --git a/db/test.db b/db/test.db new file mode 100644 index 0000000000000000000000000000000000000000..ed12a75d4baba6b3ccf02ad0e80007f1831f4421 GIT binary patch literal 4096 zcmeHJ-EQMV6drrBjkai|MKp@42=!EGQ6u84J+>1&SEN+}B`sajifSdK$hD`*sE(%^ zkF)J%ms{R|8y*0j0$u-aN&_AbI#}E`Of*0Ig`_`j+mry$;C8~ zV51V!H1sI|LfQ#J%6%AH|M0bkM~_)*595#bo~g%J#|XdCe^g5`{$C2*eT>W1T1|WV zkqjAndUS4!=C>ebyVotKs2scla6xz1Iy0vsCga z6(beE5=qBYG+@eSjIJT!goal+>^xnX0$=<_{r<(-R6}_NimP%E9G*Sm)kx~#vf~M)x3z@uKnyGxq`FRP|4| zj=3bJ>EoCB26|~%v_m)#64jSD?9-Uh8BJ-(lL&4uSxnPKi&ZapB}3alhE>t}Y&=o% z6AJxIby9lCL@L+9E#LR_{QT>97vb;luKvrrExceW6!Y}LUgzTqe$?S;@b(ThRv!-}Hn#`FdT;#U1rx|&yG zwV-<~axw>q)p5)YF&AX7nkP-zSE+eky8#Yy+i=7Mox(6`9`HDuUS#RXgmK4KFYnoH zs}3#FHZ03@OTXpk{|Wvc;Xm>3_-Fi+GK*0tP$=-@v rA*MpiRz9EOGJ2{l Date: Thu, 24 Sep 2015 13:30:20 -0700 Subject: [PATCH 120/189] added where and where_in unit tests for customers --- database_adapter.js | 6 +++--- db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 32 +++++++++++++++++++++++++++++--- 3 files changed, 32 insertions(+), 6 deletions(-) diff --git a/database_adapter.js b/database_adapter.js index b1e61a0..4af12c7 100644 --- a/database_adapter.js +++ b/database_adapter.js @@ -45,13 +45,13 @@ module.exports = { }); }, - where_in: function(column, valueList, callback) { + where_in: function(column, values, callback) { var db = new sqlite3.Database('db/' + db_env + '.db'); - var questionMarks = Array(valueList.length + 1).join('?').split('').join(', '); + var questionMarks = Array(values.length + 1).join('?').split('').join(', '); var statement = "SELECT * FROM " + this.table_name + " WHERE " + column + " IN (" + questionMarks + ");"; - db.all(statement, valueList, function(error, result) { + db.all(statement, values, function(error, result) { if (callback) { callback(error, result); } db.close(); }); diff --git a/db/test.db b/db/test.db index ed12a75d4baba6b3ccf02ad0e80007f1831f4421..c67d546fbd73f412b127a9f8710a4836481b5ca3 100644 GIT binary patch delta 105 zcmZorXi%6SCB&q`z`(!)#4w;eQOAghNn>NeQbtC$$!tt37+EK;XFA2mvbl Date: Thu, 24 Sep 2015 13:38:18 -0700 Subject: [PATCH 121/189] added where_in method test for movies --- db/test.db | Bin 4096 -> 4096 bytes test/models/customer.js | 4 ++-- test/models/movie.js | 42 ++++++++++++++++++++++++++-------------- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/db/test.db b/db/test.db index c67d546fbd73f412b127a9f8710a4836481b5ca3..e305ecb2590524b98f9a8e17ec1a85f63e683efb 100644 GIT binary patch delta 44 zcmZorXi%6S&A54@j5FirjS1_RnV6e43$mm!^IEa6F}NFwGKOTNDp+l9X0PP{03SCC A+5i9m delta 27 icmZorXi%6S&8RU^#+gxLW5PP-&5Asw%$u9pYdHXKtq2ML diff --git a/test/models/customer.js b/test/models/customer.js index bf53862..3e62206 100644 --- a/test/models/customer.js +++ b/test/models/customer.js @@ -65,9 +65,9 @@ describe("Customer", function() { }); it("can find all customers with specified column=value(s)", function(done) { - var city = 'city'; + var column = 'city'; var values = ['Seattle']; - customer.where_in(city, values, function(err, res) { + customer.where_in(column, values, function(err, res) { assert.equal(err, undefined); assert(res instanceof Array); assert.equal(res.length, 2); diff --git a/test/models/movie.js b/test/models/movie.js index 2c00f0c..bae12cd 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -14,8 +14,9 @@ describe("Movie", function() { "BEGIN; \ DELETE FROM movies; \ INSERT INTO movies(title, overview, release_date, inventory) \ - VALUES('Jaws', 'Shark!', '20150920', 10), \ - ('Maws', 'Worm!', '20150111', 11); \ + VALUES('Jaws', 'Shark!', '2015', 10), \ + ('Paws', 'Cat!', '1989', 10), \ + ('Maws', 'Worm!', '2009', 11); \ COMMIT;" , function(err) { db_cleaner.close(); @@ -23,11 +24,11 @@ describe("Movie", function() { } ); }); - }) + }); it("can be instantiated", function() { assert(movie instanceof Movie); - }) + }); describe("instance methods", function() { it("can find a movie by id", function(done){ @@ -36,8 +37,8 @@ describe("Movie", function() { assert(res instanceof Object); assert.equal(res.id, 1); done(); - }) - }) + }); + }); it("can find a movie by title", function(done) { movie.find_by("title", "Jaws", function(err, res) { @@ -45,18 +46,31 @@ describe("Movie", function() { assert(res instanceof Object); assert.equal(res.title, 'Jaws'); done(); - }) - }) + }); + }); it("can find all movies where a column has a particular value", function(done) { movie.where(["title"], ["Jaws"], function(err, res) { assert.equal(err, undefined); - assert(res instanceof Object); // Why is this breaking? + assert(res instanceof Object); assert.equal(res.length, 1); assert.equal(res[0].title, "Jaws"); done(); - }) - }) + }); + }); + + it("can find all movies with specified column=value(s)", function(done) { + var column = 'inventory'; + var values = ['10']; + movie.where_in(column, values, function(err, res) { + assert.equal(err, undefined); + assert(res instanceof Array); + assert.equal(res.length, 2); + assert.equal(res[0].title, 'Jaws'); + assert.equal(res[1].title, 'Paws'); + done(); + }); + }); it("can return a subset of movies sorted by title", function(done){ var queries = [1, 0] // number, offset @@ -75,7 +89,7 @@ describe("Movie", function() { assert.equal(err, undefined); assert(res instanceof Array); assert.equal(res[0].id, 2); - assert.equal(res[0].release_date, "20150111"); + assert.equal(res[0].release_date, "1989"); done(); }); }); @@ -88,7 +102,7 @@ describe("Movie", function() { '1998', 3]; movie.create(columns, values, function(err, res) { - assert.equal(res.inserted_id, 3); //it inserted a new record + assert.equal(res.inserted_id, 4); //it inserted a new record movie.find_by("title", "The X-Files: Fight the Future", function(err, res) { assert.equal(res.title, "The X-Files: Fight the Future"); //we found our new movie @@ -98,7 +112,7 @@ describe("Movie", function() { }); it("can update a movie record", function(done) { - var id = 2; + var id = 1; var columns = ['title', 'release_date']; var values = ['The X-Files: I Want to Believe', '2008']; From a3efd09dd036e51c096d568b193532e18ecb283b Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 13:40:37 -0700 Subject: [PATCH 122/189] added find_all test for movies --- db/test.db | Bin 4096 -> 4096 bytes test/models/movie.js | 8 ++++++++ 2 files changed, 8 insertions(+) diff --git a/db/test.db b/db/test.db index e305ecb2590524b98f9a8e17ec1a85f63e683efb..36c94de36bfed96c76c8286b095cbcc5d029da77 100644 GIT binary patch delta 19 ZcmZorXi%6S#l$Q+QN{^KZcJFf4*)O51kL~e delta 19 ZcmZorXi%6S#l*CEqKp%e+?cR{9{@R&1_%HE diff --git a/test/models/movie.js b/test/models/movie.js index bae12cd..7f0c6d2 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -31,6 +31,14 @@ describe("Movie", function() { }); describe("instance methods", function() { + it("can find all movies", function(done){ + movie.find_all(function(err, res){ + assert.equal(err, undefined); + assert.equal(res.length, 3); + done(); + }); + }); + it("can find a movie by id", function(done){ movie.find_by("id", 1, function(err, res) { assert.equal(err, undefined); From 1a84622deae2c134390118ff10b6b29e1627112e Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 13:47:36 -0700 Subject: [PATCH 123/189] fixed test typo --- db/test.db | Bin 4096 -> 4096 bytes test/models/movie.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/db/test.db b/db/test.db index 36c94de36bfed96c76c8286b095cbcc5d029da77..3dbceaa00bf8caf6ef2148246f7aae416f9abad0 100644 GIT binary patch delta 17 YcmZorXi%6S&6qV&#+fl|W5NP{057ctasU7T delta 17 YcmZorXi%6S%_uri#+gxcW5NP{04lNs$N&HU diff --git a/test/models/movie.js b/test/models/movie.js index 7f0c6d2..6e1b950 100644 --- a/test/models/movie.js +++ b/test/models/movie.js @@ -120,7 +120,7 @@ describe("Movie", function() { }); it("can update a movie record", function(done) { - var id = 1; + var id = 3; var columns = ['title', 'release_date']; var values = ['The X-Files: I Want to Believe', '2008']; From b860301f3c4d2bd00f745371d71f5af6cbaae772 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 14:55:32 -0700 Subject: [PATCH 124/189] added additional tests for GET /rentals/:title --- db/test.db | Bin 76800 -> 76800 bytes test/routes/rentals.js | 57 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/db/test.db b/db/test.db index cc5992952657d6d6c3760cffc6d4c99388502677..7c2ba2fe3cdf1305fed2965abbf9a78c92de6013 100644 GIT binary patch delta 184 zcmZp;!P0PpWr7qFclAUWCm^{oVJ$OrGjr2sL6#zBIV)*qHU?>VQAS4v-~6)7)Z+Zy zRE2_^{1PJr154(~3)u6Rn8JZd-I-EjShyG@y|v{9#Wfj%5=)ZuE5lP$bQFwC6x>pi z6pRcEjT8(mtc;AT3@sFN4a^M;OidMnvorJZQi~KE%To2i67!PtOUqJ=oSZFS-^0b|q6h%4voIR~ delta 67 zcmZp;!P0PpWr7qFXV^p;Cm^{oVJ$Ob|7O92Qs#*PJc3rtYz*#(qKqLKsR|LgZkaig W7qI7T7Gzn+)Vzml`yMVv7exTAaTEOj diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 15f3d56..1d20658 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -48,7 +48,6 @@ describe("rentals routes", function() { }); describe("GET /rentals/overdue", function() { - it("responds with json", function(done) { agent.get('/rentals/overdue').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) @@ -65,7 +64,7 @@ describe("rentals routes", function() { assert(overdueCustomers instanceof Array); done(); - }); + }); }); it("returns a list of the customers with overdue books", function(done) { @@ -76,11 +75,59 @@ describe("rentals routes", function() { // only two of the three customers with rental records have overdue assert.equal(overdueCustomers.length, 2); done(); - }); + }); }); }); - // describe('GET /rentals/:title', function() { + describe('GET /rentals/:title', function() { + it("responds with json", function(done) { + agent.get('/rentals/Fight the Future').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an object", function(done) { + agent.get('/rentals/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + assert(response.body instanceof Object); + done(); + }); + }); + + it("returns movie info: overview, release_date, inventory", function(done) { + agent.get('/rentals/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + assert.equal(response.body.movie_data.overview, "first xfiles movie"); + assert.equal(response.body.movie_data.release_date, "1998"); + assert.equal(response.body.movie_data.inventory, 2); + done(); + }); + }); + + it("returns availability info: yes/no, and copies available", function(done) { + agent.get('/rentals/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + assert.equal(response.body.availability.available, true); + assert.equal(response.body.availability.copiesAvailable, 1); + done(); + }); + }); - // }); + it("returns a list of customers who have currently rented the movie", function(done) { + agent.get('/rentals/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + assert(response.body.currentRenters instanceof Object); + assert.equal(response.body.currentRenters[0].name, "Fox Mulder"); + done(); + }); + }); + }); }); + + + + + From 4bd9677cd2f0a5624e29b4c0b4d0752e4c55f68b Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 15:10:20 -0700 Subject: [PATCH 125/189] added tests for /customers/:sort_by/:number/:offset --- db/test.db | Bin 4096 -> 4096 bytes test/routes/customers.js | 62 ++++++++++++++++++++++++++++++++++++--- 2 files changed, 58 insertions(+), 4 deletions(-) diff --git a/db/test.db b/db/test.db index 3dbceaa00bf8caf6ef2148246f7aae416f9abad0..ac78bfc0910327573bc8c272014ae03f1f2f0ef3 100644 GIT binary patch delta 143 zcmZorXi%6S#l*5`qKp%e+?cSIop}dS_+~*Ccc#hVT#1?K%v=nb-r9y zMGC>$nR$7sMQ%lzItqpc3SOl-3PuJ71`39zRz}8F24)Jn2Id9^CZ=WzE}2EC$tC$k s3O;$^iNzV2dFdtjc`nWdhDOFF8bGY6U}|QrYhh_%$iHB-BKLh301J>ODgXcg delta 63 zcmZorXi%6S#l)O7QN{^KZcJFq&b*Z=e6t{nJJaNFu0&A=Rc~EsMR83g$DGs(1@EHD S!W4n-#h5vj6}crV)w& diff --git a/test/routes/customers.js b/test/routes/customers.js index 4b672ab..41b5901 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -19,8 +19,10 @@ describe("customers routes", function() { VALUES ('Alex Krychek', 'Wed, 16 Apr 2014 21:40:20 -0700', \ 'P.O. Box 887, 4257 Lorem Rd.', 'Columbus', 'Ohio', '43201', \ '(371) 627-1105', 1234), \ - ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ - 'Seattle', 'Washington', '98109', '(206) 329-4928', 293); \ + ('Fox Mulder', 'Fri, 10 Jul 2015 15:23:06 -0700', '152-525 Odio St.', \ + 'Seattle', 'Washington', '98109', '(206) 329-4928', 293), \ + ('Walter Skinner', 'Fri, 10 Jul 2000 15:23:06 -0700', '456 Director Ln', \ + 'Washington', 'DC', '01234', '(234) 567-8901', 4000); \ DELETE FROM movies; \ INSERT INTO movies (title, overview, release_date, inventory) \ VALUES ('Fight the Future', 'first xfiles movie', '1998', 2), \ @@ -62,13 +64,13 @@ describe("customers routes", function() { }); }); - it("returns as many customers as there are in the table: 2", function(done) { + it("returns as many customers as there are in the table: 3", function(done) { agent.get('/customers').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var customers = response.body.customers; - assert.equal(customers.length, 2); + assert.equal(customers.length, 3); done(); }); }); @@ -186,4 +188,56 @@ describe("customers routes", function() { }); }); }); + + describe("GET /customers/:sort_by/:number/:offset", function() { + it("responds with json", function(done) { + agent.get('/customers/name/1/1').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns an object", function(done) { + agent.get('/customers/name/1/1').set('Accept', 'application/json') + .expect(200, function(error, response) { + var customers = response.body; + assert(customers instanceof Object); + done(); + }); + }); + + it("returns the number of customers in the number parameter", function(done) { + agent.get('/customers/name/2/0').set('Accept', 'application/json') + .expect(200, function(error, response) { + var customers = response.body.customers; + + assert.equal(customers.length, 2); + done(); + }); + }); + + it("returns customers ordered, here by registered_at (date)", function(done) { + agent.get('/customers/registered_at/2/0').set('Accept', 'application/json') + .expect(200, function(error, response) { + var customers = response.body.customers; + + // this is the third movie by id, but the first by registered_at + assert(customers[0].name, "Walter Skinner"); + done(); + }); + }); + + it("returns customers starting from the id listed in the offset", function(done) { + agent.get('/customers/registered_at/1/1').set('Accept', 'application/json') + .expect(200, function(error, response) { + var customers = response.body.customers; + + // this is the second movie alphabetically + assert(customers[0].name, "Alex Krychek"); + done(); + }); + }); + }); }); From aaecf854068a6d687b03ee9fd78c52691c148138 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 15:10:56 -0700 Subject: [PATCH 126/189] removed unused (practice) endpoint for POST create --- routes/customers.js | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 1192360..598816d 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -86,20 +86,4 @@ router.get('/:sort_by/:limit/:offset', function(req, res, next) { }); }); -router.post('/create/:name/:registered_at/:address/:city/:state/:postal_code/:phone', function(req, res, next) { - var values = []; - values.push(req.params.name); - values.push(req.params.registered_at); - values.push(req.params.address); - values.push(req.params.city); - values.push(req.params.state); - values.push(req.params.postal_code); - values.push(req.params.phone); - var columns = ['name', 'registered_at', 'address', 'city', 'state', 'postal_code', 'phone'] - - customer.create(columns, values, function(err, res) { - res.status(200).json(res); - }); -}); - module.exports = router; From 4d9db4a526350f34d68bd89c1d6d88a235b3abfb Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 15:15:14 -0700 Subject: [PATCH 127/189] fixed comments in /customers/:sort_by/:number/:offset --- test/routes/customers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/routes/customers.js b/test/routes/customers.js index 41b5901..1e4e4c4 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -223,7 +223,7 @@ describe("customers routes", function() { .expect(200, function(error, response) { var customers = response.body.customers; - // this is the third movie by id, but the first by registered_at + // this is the third customer by id, but the first by registered_at assert(customers[0].name, "Walter Skinner"); done(); }); @@ -234,7 +234,7 @@ describe("customers routes", function() { .expect(200, function(error, response) { var customers = response.body.customers; - // this is the second movie alphabetically + // this is the second customer by registered_at assert(customers[0].name, "Alex Krychek"); done(); }); From ac1ae37bfbe1aba7c6a6936652aebfc6179bf508 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 15:21:02 -0700 Subject: [PATCH 128/189] fixed checkout endpoint to take movie_title instead of movie_id --- db/development.db | Bin 76800 -> 76800 bytes db/test.db | Bin 4096 -> 4096 bytes routes/rentals.js | 12 +++++++++--- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/db/development.db b/db/development.db index 0cf518e0878d1fdd35e5c7f6711318e8a79eb73d..b1fec446a5f5a6cc29abbc6bef4f132abfa4e7ff 100644 GIT binary patch delta 81 zcmZp;!P0PpWr8&0#fdV`j2Aa1EUD*WW{zWEKFi$39Jg7pA%Iy!O^Ka>lTllnH`&m{ d#Msc-*wDh*+{j$d0K_#lGlg+Cw>4L-0079@783vf delta 42 ycmZp;!P0PpWr8&0g^4oGj2AX0EUD*UVs2w#KFi#;S+K#Ed2#@U?&h}UsuciJLl2+; diff --git a/db/test.db b/db/test.db index 3dbceaa00bf8caf6ef2148246f7aae416f9abad0..bd7e19ec6f13fd30046bf69a07bddd3673714f89 100644 GIT binary patch delta 17 YcmZorXi%6S%{Y6aj5FixjR_0*0WypQ)Bpeg delta 17 YcmZorXi%6S&6qV&#+fl|W5NP{057ctasU7T diff --git a/routes/rentals.js b/routes/rentals.js index c735ebb..80956d8 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -83,11 +83,17 @@ router.get('/:title', function(request, response, next) { }); }); -router.post('/checkout/:customer_id/:movie_id', function(request, response, next) { - var movie_id = request.params.movie_id; - var count, inventory, enoughInventory; +router.post('/checkout/:customer_id/:movie_title', function(request, response, next) { + var movie_title = request.params.movie_title; + var count, inventory, enoughInventory, movie_id; async.waterfall([ + function(callback) { + movie.find_by('title', movie_title, function(err, row) { + movie_id = row.id; + callback(null); + }); + }, // count total # of checked out copies of movie with id, movie_id function(callback) { rental.where(['movie_id', 'returned_date'], [movie_id, ''], function(err, rows) { From 3311c347d78e3616196ba19a07137a5d606d823f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 15:36:58 -0700 Subject: [PATCH 129/189] merge conflicts in test.db --- db/test.db | Bin 4096 -> 4096 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/db/test.db b/db/test.db index ac78bfc0910327573bc8c272014ae03f1f2f0ef3..0140685b032ef81fdbf883027249705b9ff2c9bf 100644 GIT binary patch delta 237 zcmZorXi%6S&G=xVj5FhdjR{Mbd6<|NFfd8G9cOGt(Xh<{oB6 zraesIn*~|inI?yGrOGBVb1^7;tBcEuYcjbc<|QfwCzs~rRJs*q>L?gZw&j-8H!?O+ z2*@l*Em8xrbSi zX$Mm{P}H4iayVCNs;0NLqM*1YQ+Q%dNotWoaCT;1UTTqBQKpW9p@D)|X^w)Cfq{X7 zp{bRTv6X?Dg06wNfq{vsnSx7ZQEGBYevyJtUU*`0MrK}mNq(M-vw@+Jv55u{YbuzU qnd@3u8W{2~n5@YCn2(itHUsl(=Bvzynb$JU2D@wG1eM9N`BMP^K{f0E From c5180a7770d14bb090b9bf63efe0cd98338ffdeb Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 16:17:20 -0700 Subject: [PATCH 130/189] removed async from rentals/:title endpoint --- routes/rentals.js | 50 ++++++++++++++--------------------------------- 1 file changed, 15 insertions(+), 35 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 80956d8..fcc0b46 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -1,4 +1,4 @@ -var async = require('async'); +// var async = require('async'); var express = require('express'); var router = express.Router(); @@ -38,48 +38,28 @@ router.get('/:title', function(request, response, next) { var customerIdList = []; var movieObject = {}; - async.waterfall([ - // query db for movie and get inventory - function(callback) { - movie.find_by('title', title, function(error, row) { - movieObject.movie_data = row; - callback(null); - }); - }, + // query db for movie and get inventory + movie.find_by('title', title, function(error, row) { + movieObject.movie_data = row; + // retrieve rental records for that movie - function(callback) { - rental.where(['movie_id', 'returned_date'], - [movieObject.movie_data.id, ''], function(error, rows) { - // turn object of rentals into array of ids - for (var i = 0; i < rows.length; i++) { - customerIdList.push(rows[i].customer_id); - } - callback(null); - }); - }, - // get count of rentals - function(callback) { - // check how many copies of that movie are checked out + rental.where(['movie_id', 'returned_date'], [movieObject.movie_data.id, ''], function(error, rows) { + // turn object of rentals into array of ids + for (var i = 0; i < rows.length; i++) { + customerIdList.push(rows[i].customer_id); + } + rentedCount = customerIdList.length; var inventory = movieObject.movie_data.inventory; - var availableBool = (rentedCount < inventory) ? true : false; var availableCount = (rentedCount < inventory) ? (inventory - rentedCount) : 0; - movieObject.availability = { - available: availableBool, - copiesAvailable: availableCount - }; - callback(null); - }, - // query DB for full customer data - function(callback) { + movieObject.availability = { available: availableBool, copiesAvailable: availableCount } + customer.where_in('id', customerIdList, function(error, rows) { movieObject.currentRenters = rows; - callback(null, movieObject); + response.status(200).json(movieObject); }); - } - ], function(error, result) { - response.status(200).json(result); + }); }); }); From 4453a72ff9d9f8b3d5f72f8b2b40f201e392fa61 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 16:29:39 -0700 Subject: [PATCH 131/189] removed async from rentals/checkout endpoint --- db/development.db | Bin 76800 -> 76800 bytes routes/rentals.js | 70 ++++++++++++++++++++-------------------------- 2 files changed, 30 insertions(+), 40 deletions(-) diff --git a/db/development.db b/db/development.db index b1fec446a5f5a6cc29abbc6bef4f132abfa4e7ff..840a0ff844e637156761fef63687755d458f9b2c 100644 GIT binary patch delta 83 zcmZp;!P0PpWr8&0rHL}mjF&bhEUD*VVK!r6KFi$39LH?7S+GHkSwl^koq>~4Tbnn; f(8R>p(AeD2($K=pP|pCwH8rz@aW}^`FIoWr*EALN delta 44 zcmZp;!P0PpWr8&0#fdV`j2Aa1EUD*WW{zWEKFi$39Jg7pL6v!O0EhPGxaLJG0B9%= Av;Y7A diff --git a/routes/rentals.js b/routes/rentals.js index fcc0b46..cd0d150 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -1,4 +1,3 @@ -// var async = require('async'); var express = require('express'); var router = express.Router(); @@ -67,51 +66,42 @@ router.post('/checkout/:customer_id/:movie_title', function(request, response, n var movie_title = request.params.movie_title; var count, inventory, enoughInventory, movie_id; - async.waterfall([ - function(callback) { - movie.find_by('title', movie_title, function(err, row) { - movie_id = row.id; - callback(null); - }); - }, + movie.find_by('title', movie_title, function(err, row) { + movie_id = row.id; + // count total # of checked out copies of movie with id, movie_id - function(callback) { - rental.where(['movie_id', 'returned_date'], [movie_id, ''], function(err, rows) { - count = rows.length; - callback(null, count); - }); - }, - // check if enough inventory of movie is available (true/false) - function(movieCount, callback) { + rental.where(['movie_id', 'returned_date'], [movie_id, ''], function(err, rows) { + movieCount = rows.length; + + // check if enough inventory of movie is available (true/false) movie.find_by('id', movie_id, function(err, row) { // don't need inventory, could call row.inventory on line 29 inventory = row.inventory; enoughInventory = (movieCount < inventory) ? true : false; - callback(null, enoughInventory); + + // if result, which equals enoughInventory, is false, return message NO + if (enoughInventory == false) { + response.status(403).json({ error: "There are no available copies of that movie for rental." }); + } else { // proceed with checkout + var values = []; + values.push(request.params.customer_id); + values.push(movie_id); + + var checkout_date = new Date(); + var due_date = new Date(); + due_date.setDate(due_date.getDate() + RENTAL_PERIOD); + + var defaults = [checkout_date, due_date, ""]; + values = values.concat(defaults); + + var columns = ['customer_id', 'movie_id', 'checkout_date', 'due_date', 'returned_date']; + + rental.create(columns, values, function(err, results) { + response.status(200).json({ success: "Yay! You checked out a movie." }); + }); + } }); - } - ], function(err, result) { - // if result, which equals enoughInventory, is false, return message NO - if (result == false) { - response.status(403).json({ error: "There are no available copies of that movie for rental." }); - } else { // proceed with checkout - var values = []; - values.push(request.params.customer_id); - values.push(movie_id); - - var checkout_date = new Date(); - var due_date = new Date(); - due_date.setDate(due_date.getDate() + RENTAL_PERIOD); - - var defaults = [checkout_date, due_date, ""]; - values = values.concat(defaults); - - var columns = ['customer_id', 'movie_id', 'checkout_date', 'due_date', 'returned_date']; - - rental.create(columns, values, function(err, results) { - response.status(200).json({ success: "Yay! You checked out a movie." }); - }); - } + }); }); }); From 822f51230939d037d4288ab3fff32bde881ea995 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 16:31:57 -0700 Subject: [PATCH 132/189] uninstalled async --- package.json | 1 - 1 file changed, 1 deletion(-) diff --git a/package.json b/package.json index 2b01b0e..bb0c0bd 100644 --- a/package.json +++ b/package.json @@ -10,7 +10,6 @@ "db:setup": "npm run db:schema; npm run db:seed" }, "dependencies": { - "async": "^1.4.2", "body-parser": "~1.13.2", "cookie-parser": "~1.3.5", "debug": "~2.2.0", From 0bc3d379c08bdf3079bbec186de2b31e9931f018 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 16:33:05 -0700 Subject: [PATCH 133/189] removed async requirement from movies routes file --- routes/movies.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index 0000196..d9c6858 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -1,5 +1,3 @@ -var async = require('async'); - var express = require('express'); var router = express.Router(); From 43f4dda86c412c08f3157c98a635237cf8de180a Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Thu, 24 Sep 2015 16:38:57 -0700 Subject: [PATCH 134/189] added tests for PUT /rentals/checkin endpoint --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 52 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 52 insertions(+) diff --git a/db/test.db b/db/test.db index 0140685b032ef81fdbf883027249705b9ff2c9bf..583bbc03e56483854cc7a6ae85d0b8bbdc1518c4 100644 GIT binary patch delta 95 zcmZorXi%6S#l$5)QN{^KZcJFnEzUfffrHtef%!G_Rp!IYYnkntJDAIu6E+L7s52|d wv$8WVa*B#-GZ`5engX$zp^1sHp|P2ziHW75k)FZi1b%B41_lP9$@BRW0q^q@_W%F@ delta 61 zcmZorXi%6S#l-SpqKp%e+?cSCTbzM`frB}Lf%!G_Rp!IYYnf*=cQBVRCu|mE@nD{u Qz;DeWz{<`rc|Lz401?0tH~;_u diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 1d20658..ee8deb3 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -125,6 +125,58 @@ describe("rentals routes", function() { }); }); }); + + describe("PUT /rentals/checkin/:customer_id/:movie_title", function() { + it("responds with json", function(done) { + agent.put('/rentals/checkin/2/Fight the Future').set('Accept', 'application/json') + .expect('Content-Type', /application\/json/) + .expect(200, function(error, response) { + assert.equal(error, undefined); + done(); + }); + }); + + it("returns a message that you checked in that movie", function(done) { + agent.put('/rentals/checkin/2/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + assert.equal(response.body, "Congratulations, you have checked in: Fight the Future"); + done(); + }); + }); + + it("updates the rental record with the returned_date", function(done) { + var statement = + "SELECT * FROM rentals JOIN movies \ + ON rentals.movie_id = movies.id \ + WHERE movies.title = ? \ + AND rentals.customer_id = ? \ + AND rentals.returned_date = '';"; + + var values = ['Fight the Future', 2]; + var rentalsBeforeCheckin, + rentalsAfterCheckin; + + var db = new sqlite3.Database('db/test.db'); + + db.all(statement, values, function(err, rows) { + rentalsBeforeCheckin = rows; + db.close(); + + agent.put('/rentals/checkin/2/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + var db = new sqlite3.Database('db/test.db'); + + db.all(statement, values, function(err, rows) { + rentalsAfterCheckin = rows; + db.close(); + + assert(rentalsBeforeCheckin.length > rentalsAfterCheckin.length); + done(); + }); + }); + }); + }); + }); }); From 6b5fa92b52d2769e52df8387d1c1ce535a1cb823 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 21:37:50 -0700 Subject: [PATCH 135/189] added message display test for post method --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 33 insertions(+), 1 deletion(-) diff --git a/db/test.db b/db/test.db index 583bbc03e56483854cc7a6ae85d0b8bbdc1518c4..c317aaf3756060e7349783c213f1879cf684067f 100644 GIT binary patch delta 99 zcmZorXi%6S&6qz?#+fmHW5PmiNd^W6PG(C6=GV+unGZ9sWuDF4!Cc0iz-+l$kVT$Z xRh5&Sfs<2Po7d39#Msc()WXEj+`?4P0K_%5Fo$p_$MM^;2(Yp Date: Thu, 24 Sep 2015 21:52:24 -0700 Subject: [PATCH 136/189] updated POST checkout method to charge per rental --- db/development.db | Bin 76800 -> 76800 bytes routes/rentals.js | 11 +++++++++-- test/routes/rentals.js | 2 ++ 3 files changed, 11 insertions(+), 2 deletions(-) diff --git a/db/development.db b/db/development.db index 840a0ff844e637156761fef63687755d458f9b2c..bd60a77341726ff5ae02a3d11e3d3a542e747429 100644 GIT binary patch delta 93 zcmZp;!P0PpWr8&0m5DOWj8`@$ILR@}Z(b~yn8?S<%*()hmbr~Nj@gWvce9|uZzfH3 p6?O(jMs00gmJmY|6JtYDGczM&Q%eIq0}$8L!UD$KY}R~g1pu)D7x@4H delta 55 zcmV-70LcG<*aU#s1dtm6(vciP0n)KxLLQT%3f;4RABA8H1Oqkz1I+`516~6*vk@=@ N1Cvk)BeOPx%BU~=65jv- diff --git a/routes/rentals.js b/routes/rentals.js index cd0d150..6a545f6 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -63,8 +63,9 @@ router.get('/:title', function(request, response, next) { }); router.post('/checkout/:customer_id/:movie_title', function(request, response, next) { + var customer_id = request.params.customer_id; var movie_title = request.params.movie_title; - var count, inventory, enoughInventory, movie_id; + var count, inventory, enoughInventory, movie_id, account_credit; movie.find_by('title', movie_title, function(err, row) { movie_id = row.id; @@ -97,7 +98,13 @@ router.post('/checkout/:customer_id/:movie_title', function(request, response, n var columns = ['customer_id', 'movie_id', 'checkout_date', 'due_date', 'returned_date']; rental.create(columns, values, function(err, results) { - response.status(200).json({ success: "Yay! You checked out a movie." }); + customer.find_by('id', customer_id, function(err, row) { + account_credit = row.account_credit; + var new_credit = account_credit - 100; + customer.update(customer_id, ['account_credit'], [new_credit], function(err, results) { + response.status(200).json({ success: "Yay! You checked out " + movie_title }); + }); + }); }); } }); diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 47c2dda..22fe17d 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -185,6 +185,8 @@ describe("rentals routes", function() { .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var result = response.body; + var movie = request.params.movie_title; + console.log(movie); assert.equal(error, undefined); assert.equal(result.success, 'Yay! You checked out a movie.') From fd2b41ea511f19741508c6f44c6a699a9a694121 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 21:54:44 -0700 Subject: [PATCH 137/189] updated post checkout message return test --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 6 ++---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/db/test.db b/db/test.db index c317aaf3756060e7349783c213f1879cf684067f..0e3772ffc819cd45e6a717452977e57a270e03df 100644 GIT binary patch delta 50 zcmZorXi%6S&Dc0m#+k8kW5RrH#=K2D9?W897A7VprY3p@h9)M)rWO_u?&LWBMF3-B B4N3q2 delta 50 zcmZorXi%6S&6qz?#+fmHW5RrH#!H)cJeb8yEldo}Ell+c3{6aoO)bnJ+{tnLivVhG B4Uhl; diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 22fe17d..8d02c04 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -180,16 +180,14 @@ describe("rentals routes", function() { describe("POST /rentals/checkout/:customer_id/:movie_title", function() { - it.only("returns a message that you checked out a movie", function(done) { + it("returns a message that you checked out a movie", function(done) { agent.post('/rentals/checkout/1/Fight the Future').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { var result = response.body; - var movie = request.params.movie_title; - console.log(movie); assert.equal(error, undefined); - assert.equal(result.success, 'Yay! You checked out a movie.') + assert.equal(result.success, 'Yay! You checked out Fight the Future') done(); }); }); From 8e36f58f6cfb1c30d4c4a2153159d42e1ef1e50a Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 22:22:51 -0700 Subject: [PATCH 138/189] edited POST checkout test --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 29 ++++++++++++----------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/db/test.db b/db/test.db index 0e3772ffc819cd45e6a717452977e57a270e03df..b86e6776b84a189a2b4b79a746031a120e8a8d62 100644 GIT binary patch delta 46 wcmZorXi%6S#l$T)QN{^KZcKQ=CuU)4YG7z=sb^qlVq$D+X#n9)j^keh010XfT>t<8 delta 46 wcmZorXi%6S#l+P(QN{^KZcKQ=CuU}0Vq#)yqGw=eVq$D+VFBSzj^keh03{#{G5`Po diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 8d02c04..84947e3 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -4,11 +4,16 @@ var request = require('supertest'), sqlite3 = require('sqlite3').verbose(), agent = request.agent(app); +var Rental = require('../../models/rental'), + Customer = require('../../models/customer'); + describe("rentals routes", function() { - var db_cleaner; + var db_cleaner, rental, customer; beforeEach(function(done) { db_cleaner = new sqlite3.Database('db/test.db'); + rental = new Rental(); + customer = new Customer(); db_cleaner.serialize(function() { db_cleaner.exec( @@ -178,7 +183,6 @@ describe("rentals routes", function() { }); }); - describe("POST /rentals/checkout/:customer_id/:movie_title", function() { it("returns a message that you checked out a movie", function(done) { agent.post('/rentals/checkout/1/Fight the Future').set('Accept', 'application/json') @@ -192,25 +196,16 @@ describe("rentals routes", function() { }); }); - it.only("adds a rental record to the rentals table", function(done) { + it("adds a rental record to the rentals table", function(done) { agent.post('/rentals/checkout/1/Fight the Future').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - // var statement = - // "SELECT * FROM rentals JOIN movies \ - // ON rentals.movie_id = movies.id \ - // WHERE movies.title = ? \ - // AND rentals.customer_id = ? \ - // AND rentals.returned_date = '';"; - - // var values = ['Fight the Future', 2]; - // var rentalsBeforeCheckin, - // rentalsAfterCheckin; - - // var db = new sqlite3.Database('db/test.db'); - // db.all() - done(); + rental.find_by("id", 9, function(err, res) { + assert.equal(res.movie_id, 1); + assert.equal(res.customer_id, 1); + done(); + }); }); }); }); From 5b234d4a74a87567cee0021f8b6965537c0b72a4 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 22:23:51 -0700 Subject: [PATCH 139/189] removed customer from rental routes testing --- test/routes/rentals.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 84947e3..7ffa8e9 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -4,8 +4,7 @@ var request = require('supertest'), sqlite3 = require('sqlite3').verbose(), agent = request.agent(app); -var Rental = require('../../models/rental'), - Customer = require('../../models/customer'); +var Rental = require('../../models/rental'); describe("rentals routes", function() { var db_cleaner, rental, customer; @@ -13,7 +12,6 @@ describe("rentals routes", function() { beforeEach(function(done) { db_cleaner = new sqlite3.Database('db/test.db'); rental = new Rental(); - customer = new Customer(); db_cleaner.serialize(function() { db_cleaner.exec( From 07cee3f9ff5177fcf97a944e4b6194c0d1944a9d Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 22:24:43 -0700 Subject: [PATCH 140/189] removed customer variable --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/db/test.db b/db/test.db index b86e6776b84a189a2b4b79a746031a120e8a8d62..0709b465eb64293752f36f96a16ae98297143323 100644 GIT binary patch delta 43 ucmZorXi%6S&6qJ!#+fl=W5P>5Q8N<@a|;7K149!NV^d252zPQE{~`bjG7Gl= delta 43 ucmZorXi%6S%_uif#+gxWW5P>5QBzX`Lt{%l149!NV^d252zPQE{~`ePcMA^y diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 7ffa8e9..1991029 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -7,7 +7,7 @@ var request = require('supertest'), var Rental = require('../../models/rental'); describe("rentals routes", function() { - var db_cleaner, rental, customer; + var db_cleaner, rental; beforeEach(function(done) { db_cleaner = new sqlite3.Database('db/test.db'); From 722f37015812d7989e3b07b605d21b55965817b2 Mon Sep 17 00:00:00 2001 From: Anita Date: Thu, 24 Sep 2015 22:29:22 -0700 Subject: [PATCH 141/189] ignore test.db --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 83c46df..20124a7 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,5 @@ # Let package.json handle dependencies /node_modules + +db/test.db From d29ea5063cf1ec1862711fc5bd8a9e5a73a898b7 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:13:46 -0700 Subject: [PATCH 142/189] added comments to PUT checkin route --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 9 +++++++-- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/db/test.db b/db/test.db index 0709b465eb64293752f36f96a16ae98297143323..79f67d6ed6e3f1a82e9fa441afb96e77649636b0 100644 GIT binary patch delta 47 xcmZorXi%6S#l+(_QN{^KZcKR2CvItOY-nm|WUgmmXkub)W@HKBPLAVW1OOk%3*rC( delta 47 xcmZorXi%6S#l)R4QN{^KZcKR2CvIwCW@2G(VW4MVXkub)YH0xBPLAVW1OO^(3_1V+ diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 1991029..cd398e2 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -148,8 +148,11 @@ describe("rentals routes", function() { }); it("updates the rental record with the returned_date", function(done) { + // this joins movies and rentals on the movie_id + // and selects all those records with the customer ID and movie title + // from the URI, which have *not* been returned var statement = - "SELECT * FROM rentals JOIN movies \ + "SELECT * FROM rentals INNER JOIN movies \ ON rentals.movie_id = movies.id \ WHERE movies.title = ? \ AND rentals.customer_id = ? \ @@ -173,7 +176,8 @@ describe("rentals routes", function() { rentalsAfterCheckin = rows; db.close(); - assert(rentalsBeforeCheckin.length > rentalsAfterCheckin.length); + // check to make sure the number of un-returned movies has decreased by 1 + assert(rentalsBeforeCheckin.length - rentalsAfterCheckin.length == 1); done(); }); }); @@ -199,6 +203,7 @@ describe("rentals routes", function() { .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { + // there were 8 rental records seeded prior to creating the new rental rental.find_by("id", 9, function(err, res) { assert.equal(res.movie_id, 1); assert.equal(res.customer_id, 1); From 9511821a2666bf66393bb93197091c53c9dfc455 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:15:53 -0700 Subject: [PATCH 143/189] created skeleton of endpoint-readme --- endpoint-readme.md | 10 ++++++++++ 1 file changed, 10 insertions(+) create mode 100644 endpoint-readme.md diff --git a/endpoint-readme.md b/endpoint-readme.md new file mode 100644 index 0000000..194848b --- /dev/null +++ b/endpoint-readme.md @@ -0,0 +1,10 @@ +Anita & Alice's Video Store +--------------------------- + +**Endpoints** + +*Customers* + +*Movies* + +*Rentals* \ No newline at end of file From 09f38c3d0f6a6f1071fec68064be3ba91afeea08 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:19:53 -0700 Subject: [PATCH 144/189] added all endpoints --- endpoint-readme.md | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 194848b..b7d77ad 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -3,8 +3,31 @@ Anita & Alice's Video Store **Endpoints** +See below for the available endpoints for this API. + *Customers* +*GET '/customers'* + +GET '/customers/:id' + +GET '/customers/:sort_by/:limit/:offset' + + *Movies* -*Rentals* \ No newline at end of file +GET '/movies' + +GET '/movies/:title/:order' + +GET '/movies/:sort_by/:limit/:offset' + +*Rentals* + +GET '/rentals/overdue' + +GET '/rentals/:title' + +POST '/rentals/checkout/:customer_id/:movie_title' + +PUT '/rentals/checkin/:customer_id/:movie_title' From c113199b3fba44eb924e21151f780763ce7539f6 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:25:12 -0700 Subject: [PATCH 145/189] added get_customers sample to endpoint-readme --- endpoint-readme.md | 8 ++++++-- samples/get_customers.json | 1 + 2 files changed, 7 insertions(+), 2 deletions(-) create mode 100644 samples/get_customers.json diff --git a/endpoint-readme.md b/endpoint-readme.md index b7d77ad..3a88540 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -5,9 +5,13 @@ Anita & Alice's Video Store See below for the available endpoints for this API. -*Customers* +**Customers** -*GET '/customers'* +GET '/customers' + +- Returns list of all customers. +- Includes the following properties: name, registered_at (date of registration), address, city, state, postal_code, phone, account_credit (in cents). +- [Sample](./samples/get_customers.json). GET '/customers/:id' diff --git a/samples/get_customers.json b/samples/get_customers.json new file mode 100644 index 0000000..31f8587 --- /dev/null +++ b/samples/get_customers.json @@ -0,0 +1 @@ +{"customers":[{"id":1,"name":"Shelley Rocha","registered_at":"Wed, 29 Apr 2015 07:54:14 -0700","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":1315},{"id":2,"name":"XCurran Stout","registered_at":"Wed, 16 Apr 2014 21:40:20 -0700","address":"Ap #658-1540 Erat Rd.","city":"San Francisco","state":"California","postal_code":"94267","phone":"(908) 949-6758","account_credit":3565.9999999999995},{"id":3,"name":"Roanna Robinson","registered_at":"Fri, 28 Nov 2014 13:14:08 -0800","address":"Ap #561-4214 Eget St.","city":"Harrisburg","state":"PA","postal_code":"15867","phone":"(323) 336-1841","account_credit":5039},{"id":4,"name":"Carolyn Chandler","registered_at":"Fri, 04 Jul 2014 11:05:11 -0700","address":"133-8707 Arcu. Avenue","city":"Fort Wayne","state":"IN","postal_code":"73684","phone":"(234) 837-2886","account_credit":2079},{"id":5,"name":"Aquila Riddle","registered_at":"Thu, 27 Aug 2015 08:17:24 -0700","address":"Ap #187-9582 Primis St.","city":"Tacoma","state":"WA","postal_code":"73251","phone":"(925) 161-2223","account_credit":1782}]} \ No newline at end of file From 53346c8e55be6e77d8c9296defa866729e2f0672 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:29:00 -0700 Subject: [PATCH 146/189] changed casing on json object from camel to snake --- routes/customers.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/customers.js b/routes/customers.js index 598816d..1834147 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -54,7 +54,7 @@ router.get('/:id', function(req, res, next) { } movie.where_in('id', currentMoviesIDs, function(err, rows) { - customerObject.movies.currentRentals = rows; // no returned_date + customerObject.movies.current_rentals = rows; // no returned_date pastMoviesArray = []; movie.where_in('id', pastMoviesIDs, function(err, rows) { // unsorted @@ -67,7 +67,7 @@ router.get('/:id', function(req, res, next) { return a.dates.checkout_date.localeCompare(b.dates.checkout_date); // this is a good way to sort strings! }); - customerObject.movies.pastRentals = pastMoviesArray; + customerObject.movies.past_rentals = pastMoviesArray; res.status(200).json(customerObject); }); }); From a559090de8f9681994020f24f8ee1317d57ea3e1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:32:44 -0700 Subject: [PATCH 147/189] added sample for GET 'customers/id' --- endpoint-readme.md | 10 +++++++++- samples/get_customer_id.json | 1 + 2 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 samples/get_customer_id.json diff --git a/endpoint-readme.md b/endpoint-readme.md index 3a88540..dc02005 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -11,10 +11,18 @@ GET '/customers' - Returns list of all customers. - Includes the following properties: name, registered_at (date of registration), address, city, state, postal_code, phone, account_credit (in cents). -- [Sample](./samples/get_customers.json). +- [Sample: GET '/customers'](./samples/get_customers.json) GET '/customers/:id' +- Returns data about the customer identified by the id passed in the URI. +- Includes customer_data and rentals. + - customer_data includes the following properties: name, registered_at (date of registration), address, city, state, postal_code, phone, account_credit (in cents). + - rentals includes: current_rentals and past_rentals. + - current_rentals and past_rentals are lists of movies rented by the customer. + - Each movie object includes the following propeties: title, overview, release_date, inventory. +- [Sample: GET '/customers/1'](./samples/get_customers_id.json) + GET '/customers/:sort_by/:limit/:offset' diff --git a/samples/get_customer_id.json b/samples/get_customer_id.json new file mode 100644 index 0000000..dd01545 --- /dev/null +++ b/samples/get_customer_id.json @@ -0,0 +1 @@ +{"customer_data":{"id":1,"name":"Shelley Rocha","registered_at":"Wed, 29 Apr 2015 07:54:14 -0700","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":1315},"movies":{"current_rentals":[{"id":2,"title":"Jaws","overview":"An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.","release_date":"1975-06-19","inventory":6},{"id":3,"title":"The Exorcist","overview":"12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.","release_date":"1973-12-26","inventory":7},{"id":5,"title":"The Silence of the Lambs","overview":"FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.","release_date":"1991-02-14","inventory":3},{"id":49,"title":"Ben-Hur","overview":"Ben-Hur is a 1959 epic film directed by William Wyler, the third film version of Lew Wallace's 1880 novel Ben-Hur: A Tale of the Christ. It premiered at Loew's State Theatre in New York City on November 18, 1959. The film went on to win a record of eleven Academy Awards, including Best Picture, a feat equaled only by Titanic in 1998 and The Lord of the Rings: The Return of the King in 2004. It was also the last film to win the Oscar for both Best Actor and Best Supporting Actor, until nearly 44 years later when Mystic River achieved the same feat.The movie revolves around a Jewish prince who is betrayed and sent into slavery by a Roman friend and how he regains his freedom and comes back for revenge.","release_date":"1959-11-18","inventory":5},{"id":84,"title":"Poltergeist","overview":"Craig T. Nelson stars as Steve Freeling, the main protagonist, who lives with his wife, Diane, (JoBeth Williams) and their three children, Dana (Dominique Dunne), Robbie (Oliver Robins), and Carol Anne (Heather O'Rourke), in Southern California where he sells houses for the company that built the neighborhood. It starts with just a few odd occurrences, such as broken dishes and furniture moving around by itself. However, a tree comes alive and takes Robbie through his bedroom window, and Carol Anne is abducted by ghosts. Realizing that something evil haunts his home, Steve calls in a team of parapsychologists led by Dr. Lesh (Beatrice Straight) to investigate, hoping to get Carol Anne back, so he can remove his family from the house before it's too late.","release_date":"1982-06-04","inventory":4},{"id":99,"title":"Speed","overview":"Los Angeles SWAT cop Jack Traven is up against bomb expert Howard Payne, who's after major ransom money. First it's a rigged elevator in a very tall building. Then it's a rigged bus--if it slows, it will blow, bad enough any day, but a nightmare in LA traffic. And that's still not the end.","release_date":"1994-06-09","inventory":10}],"past_rentals":[{"dates":{"returned_date":"07 Dec 2008 06:19:02","checkout_date":"03 Dec 2008 02:58:43"},"movie_data":{"id":39,"title":"Die Hard","overview":"NYPD cop John McClane's plan to reconcile with his estranged wife, Holly, is thrown for a serious loop when minutes after he arrives at her office, the entire building is overtaken by a group of pitiless terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down.","release_date":"1988-07-14","inventory":4}},{"dates":{"returned_date":"07 Dec 2009 06:19:02","checkout_date":"03 Dec 2009 02:58:43"},"movie_data":{"id":72,"title":"Platoon","overview":"Chris Taylor, a young, naive recruit in Vietnam, faces a moral crisis when confronted with the horrors of war and the duality of man.","release_date":"1986-12-18","inventory":1}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":68,"title":"Halloween","overview":"A psychotic murderer institutionalized since childhood for the murder of his sister, escapes and stalks a bookish teenage girl and her friends while his doctor chases him through the streets.","release_date":"1978-10-25","inventory":4}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":100,"title":"The Adventures of Robin Hood","overview":"Robin Hood (Errol Flynn) fights nobly for justice against the evil Sir Guy of Gisbourne (Basil Rathbone) while striving to win the hand of the beautiful Maid Marian (Olivia de Havilland).","release_date":"1938-05-14","inventory":3}}]}} \ No newline at end of file From 42bc7f33503df4fa08f433b66373b98e5979a9bd Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:33:52 -0700 Subject: [PATCH 148/189] fixed typo in file name --- samples/get_customer_id.json | 1 - 1 file changed, 1 deletion(-) delete mode 100644 samples/get_customer_id.json diff --git a/samples/get_customer_id.json b/samples/get_customer_id.json deleted file mode 100644 index dd01545..0000000 --- a/samples/get_customer_id.json +++ /dev/null @@ -1 +0,0 @@ -{"customer_data":{"id":1,"name":"Shelley Rocha","registered_at":"Wed, 29 Apr 2015 07:54:14 -0700","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":1315},"movies":{"current_rentals":[{"id":2,"title":"Jaws","overview":"An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.","release_date":"1975-06-19","inventory":6},{"id":3,"title":"The Exorcist","overview":"12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.","release_date":"1973-12-26","inventory":7},{"id":5,"title":"The Silence of the Lambs","overview":"FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.","release_date":"1991-02-14","inventory":3},{"id":49,"title":"Ben-Hur","overview":"Ben-Hur is a 1959 epic film directed by William Wyler, the third film version of Lew Wallace's 1880 novel Ben-Hur: A Tale of the Christ. It premiered at Loew's State Theatre in New York City on November 18, 1959. The film went on to win a record of eleven Academy Awards, including Best Picture, a feat equaled only by Titanic in 1998 and The Lord of the Rings: The Return of the King in 2004. It was also the last film to win the Oscar for both Best Actor and Best Supporting Actor, until nearly 44 years later when Mystic River achieved the same feat.The movie revolves around a Jewish prince who is betrayed and sent into slavery by a Roman friend and how he regains his freedom and comes back for revenge.","release_date":"1959-11-18","inventory":5},{"id":84,"title":"Poltergeist","overview":"Craig T. Nelson stars as Steve Freeling, the main protagonist, who lives with his wife, Diane, (JoBeth Williams) and their three children, Dana (Dominique Dunne), Robbie (Oliver Robins), and Carol Anne (Heather O'Rourke), in Southern California where he sells houses for the company that built the neighborhood. It starts with just a few odd occurrences, such as broken dishes and furniture moving around by itself. However, a tree comes alive and takes Robbie through his bedroom window, and Carol Anne is abducted by ghosts. Realizing that something evil haunts his home, Steve calls in a team of parapsychologists led by Dr. Lesh (Beatrice Straight) to investigate, hoping to get Carol Anne back, so he can remove his family from the house before it's too late.","release_date":"1982-06-04","inventory":4},{"id":99,"title":"Speed","overview":"Los Angeles SWAT cop Jack Traven is up against bomb expert Howard Payne, who's after major ransom money. First it's a rigged elevator in a very tall building. Then it's a rigged bus--if it slows, it will blow, bad enough any day, but a nightmare in LA traffic. And that's still not the end.","release_date":"1994-06-09","inventory":10}],"past_rentals":[{"dates":{"returned_date":"07 Dec 2008 06:19:02","checkout_date":"03 Dec 2008 02:58:43"},"movie_data":{"id":39,"title":"Die Hard","overview":"NYPD cop John McClane's plan to reconcile with his estranged wife, Holly, is thrown for a serious loop when minutes after he arrives at her office, the entire building is overtaken by a group of pitiless terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down.","release_date":"1988-07-14","inventory":4}},{"dates":{"returned_date":"07 Dec 2009 06:19:02","checkout_date":"03 Dec 2009 02:58:43"},"movie_data":{"id":72,"title":"Platoon","overview":"Chris Taylor, a young, naive recruit in Vietnam, faces a moral crisis when confronted with the horrors of war and the duality of man.","release_date":"1986-12-18","inventory":1}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":68,"title":"Halloween","overview":"A psychotic murderer institutionalized since childhood for the murder of his sister, escapes and stalks a bookish teenage girl and her friends while his doctor chases him through the streets.","release_date":"1978-10-25","inventory":4}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":100,"title":"The Adventures of Robin Hood","overview":"Robin Hood (Errol Flynn) fights nobly for justice against the evil Sir Guy of Gisbourne (Basil Rathbone) while striving to win the hand of the beautiful Maid Marian (Olivia de Havilland).","release_date":"1938-05-14","inventory":3}}]}} \ No newline at end of file From eaf7c9e0a58fb0294e81bbc1c53392cc5585fce1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:34:01 -0700 Subject: [PATCH 149/189] fixed typo in file name --- samples/get_customers_id.json | 1 + 1 file changed, 1 insertion(+) create mode 100644 samples/get_customers_id.json diff --git a/samples/get_customers_id.json b/samples/get_customers_id.json new file mode 100644 index 0000000..dd01545 --- /dev/null +++ b/samples/get_customers_id.json @@ -0,0 +1 @@ +{"customer_data":{"id":1,"name":"Shelley Rocha","registered_at":"Wed, 29 Apr 2015 07:54:14 -0700","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":1315},"movies":{"current_rentals":[{"id":2,"title":"Jaws","overview":"An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.","release_date":"1975-06-19","inventory":6},{"id":3,"title":"The Exorcist","overview":"12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.","release_date":"1973-12-26","inventory":7},{"id":5,"title":"The Silence of the Lambs","overview":"FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.","release_date":"1991-02-14","inventory":3},{"id":49,"title":"Ben-Hur","overview":"Ben-Hur is a 1959 epic film directed by William Wyler, the third film version of Lew Wallace's 1880 novel Ben-Hur: A Tale of the Christ. It premiered at Loew's State Theatre in New York City on November 18, 1959. The film went on to win a record of eleven Academy Awards, including Best Picture, a feat equaled only by Titanic in 1998 and The Lord of the Rings: The Return of the King in 2004. It was also the last film to win the Oscar for both Best Actor and Best Supporting Actor, until nearly 44 years later when Mystic River achieved the same feat.The movie revolves around a Jewish prince who is betrayed and sent into slavery by a Roman friend and how he regains his freedom and comes back for revenge.","release_date":"1959-11-18","inventory":5},{"id":84,"title":"Poltergeist","overview":"Craig T. Nelson stars as Steve Freeling, the main protagonist, who lives with his wife, Diane, (JoBeth Williams) and their three children, Dana (Dominique Dunne), Robbie (Oliver Robins), and Carol Anne (Heather O'Rourke), in Southern California where he sells houses for the company that built the neighborhood. It starts with just a few odd occurrences, such as broken dishes and furniture moving around by itself. However, a tree comes alive and takes Robbie through his bedroom window, and Carol Anne is abducted by ghosts. Realizing that something evil haunts his home, Steve calls in a team of parapsychologists led by Dr. Lesh (Beatrice Straight) to investigate, hoping to get Carol Anne back, so he can remove his family from the house before it's too late.","release_date":"1982-06-04","inventory":4},{"id":99,"title":"Speed","overview":"Los Angeles SWAT cop Jack Traven is up against bomb expert Howard Payne, who's after major ransom money. First it's a rigged elevator in a very tall building. Then it's a rigged bus--if it slows, it will blow, bad enough any day, but a nightmare in LA traffic. And that's still not the end.","release_date":"1994-06-09","inventory":10}],"past_rentals":[{"dates":{"returned_date":"07 Dec 2008 06:19:02","checkout_date":"03 Dec 2008 02:58:43"},"movie_data":{"id":39,"title":"Die Hard","overview":"NYPD cop John McClane's plan to reconcile with his estranged wife, Holly, is thrown for a serious loop when minutes after he arrives at her office, the entire building is overtaken by a group of pitiless terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down.","release_date":"1988-07-14","inventory":4}},{"dates":{"returned_date":"07 Dec 2009 06:19:02","checkout_date":"03 Dec 2009 02:58:43"},"movie_data":{"id":72,"title":"Platoon","overview":"Chris Taylor, a young, naive recruit in Vietnam, faces a moral crisis when confronted with the horrors of war and the duality of man.","release_date":"1986-12-18","inventory":1}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":68,"title":"Halloween","overview":"A psychotic murderer institutionalized since childhood for the murder of his sister, escapes and stalks a bookish teenage girl and her friends while his doctor chases him through the streets.","release_date":"1978-10-25","inventory":4}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":100,"title":"The Adventures of Robin Hood","overview":"Robin Hood (Errol Flynn) fights nobly for justice against the evil Sir Guy of Gisbourne (Basil Rathbone) while striving to win the hand of the beautiful Maid Marian (Olivia de Havilland).","release_date":"1938-05-14","inventory":3}}]}} \ No newline at end of file From 2b32996d2fcff195a066a734349f8c455fc04152 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:38:56 -0700 Subject: [PATCH 150/189] added formatting --- endpoint-readme.md | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index dc02005..24254dc 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -10,17 +10,21 @@ See below for the available endpoints for this API. GET '/customers' - Returns list of all customers. -- Includes the following properties: name, registered_at (date of registration), address, city, state, postal_code, phone, account_credit (in cents). +- Contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). - [Sample: GET '/customers'](./samples/get_customers.json) GET '/customers/:id' - Returns data about the customer identified by the id passed in the URI. -- Includes customer_data and rentals. - - customer_data includes the following properties: name, registered_at (date of registration), address, city, state, postal_code, phone, account_credit (in cents). - - rentals includes: current_rentals and past_rentals. - - current_rentals and past_rentals are lists of movies rented by the customer. - - Each movie object includes the following propeties: title, overview, release_date, inventory. +- Contains `customer_data` and `movies`. + - `customer_data` contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). + - `movies` contains: `current_rentals` and `past_rentals`. + - `current_rentals` is a list of movies rented by the customer. + - Each movie object contains the following propeties: `title`, `overview`, `release_date`, and `inventory`. + - `past_rentals` is a list of movie objects. + - Each movie object contains `movie_data` and `dates`. + - `dates` contains `checkout_date` and `returned_date`. + - `movie_data` contains: `title`, `overview`, `release_date`, and `inventory`. - [Sample: GET '/customers/1'](./samples/get_customers_id.json) GET '/customers/:sort_by/:limit/:offset' From af60c11ecfdf0def8d0ccd00bd7a42dd2a0272e0 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 25 Sep 2015 09:46:25 -0700 Subject: [PATCH 151/189] added testing for customer_account credit decrementing --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 39 +++++++++++++++++++++++++++++++++++++-- 2 files changed, 37 insertions(+), 2 deletions(-) diff --git a/db/test.db b/db/test.db index 79f67d6ed6e3f1a82e9fa441afb96e77649636b0..a05eea3ae512f696d761e2c0c905442125ff8e26 100644 GIT binary patch delta 46 wcmZorXi%6S#l-6|QN{^KZcKQ=CuV7CYHny^pl4ucVq$D&YzW~_j^keh02Ol!umAu6 delta 46 wcmZorXi%6S#l+(_QN{^KZcKQ=CuVMJXliI=u4iCqVq$D&WC`I;j^keh02C+-sQ>@~ diff --git a/test/routes/rentals.js b/test/routes/rentals.js index cd398e2..30816e8 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -4,14 +4,16 @@ var request = require('supertest'), sqlite3 = require('sqlite3').verbose(), agent = request.agent(app); -var Rental = require('../../models/rental'); +var Rental = require('../../models/rental'), + Movie = require('../../models/movie'); describe("rentals routes", function() { - var db_cleaner, rental; + var db_cleaner, rental, movie; beforeEach(function(done) { db_cleaner = new sqlite3.Database('db/test.db'); rental = new Rental(); + movie = new Movie(); db_cleaner.serialize(function() { db_cleaner.exec( @@ -211,5 +213,38 @@ describe("rentals routes", function() { }); }); }); + + it("decrements the account_credit for each customer by $1.00", function(done) { + var statement = + "SELECT * FROM customers \ + WHERE id = ?;"; + + var values = [1]; + var creditBeforeCheckout, + creditAfterCheckout; + + var db = new sqlite3.Database('db/test.db'); + + // get account_credit before checking out a movie + db.all(statement, values, function(err, row) { + creditBeforeCheckout = row[0].account_credit; + db.close(); + + agent.post('/rentals/checkout/1/Fight the Future').set('Accept', 'application/json') + .expect(200, function(error, response) { + var db = new sqlite3.Database('db/test.db'); + + // get account_credit after checking out a movie + db.all(statement, values, function(err, row) { + creditAfterCheckout = row[0].account_credit; + db.close(); + + // check to make sure the account_credit has decreased by 100 ($1.00) + assert(creditBeforeCheckout - 100 == creditAfterCheckout); + done(); + }); + }); + }); + }); }); }); From 95e32ed051676c18d486dc6e99441e6227502529 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 25 Sep 2015 09:47:57 -0700 Subject: [PATCH 152/189] removed movie requirement --- db/test.db | Bin 4096 -> 4096 bytes test/routes/rentals.js | 6 ++---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/db/test.db b/db/test.db index a05eea3ae512f696d761e2c0c905442125ff8e26..8d9eb789edef76a0e5074c39ff197954a225c71e 100644 GIT binary patch delta 43 ucmZorXi%6S%{X7Gv{EGk<+zbx@ delta 43 ucmZorXi%6S&FC>v#+lJ$W5P>5QBzZMLlXl%149!NV>4qz2zPQE{~`bZXA4~b diff --git a/test/routes/rentals.js b/test/routes/rentals.js index 30816e8..e3957eb 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -4,16 +4,14 @@ var request = require('supertest'), sqlite3 = require('sqlite3').verbose(), agent = request.agent(app); -var Rental = require('../../models/rental'), - Movie = require('../../models/movie'); +var Rental = require('../../models/rental'); describe("rentals routes", function() { - var db_cleaner, rental, movie; + var db_cleaner, rental; beforeEach(function(done) { db_cleaner = new sqlite3.Database('db/test.db'); rental = new Rental(); - movie = new Movie(); db_cleaner.serialize(function() { db_cleaner.exec( From b0ac2f79d5e763879d6a0bdbc49fa84521d9b9e1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:50:22 -0700 Subject: [PATCH 153/189] added sample for get_customers_sort_by_limit_offset --- endpoint-readme.md | 16 ++++++++++++---- samples/get_customers_sort_by_limit_offset.json | 1 + 2 files changed, 13 insertions(+), 4 deletions(-) create mode 100644 samples/get_customers_sort_by_limit_offset.json diff --git a/endpoint-readme.md b/endpoint-readme.md index 24254dc..479f9d2 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -9,14 +9,15 @@ See below for the available endpoints for this API. GET '/customers' -- Returns list of all customers. -- Contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- Retrieves a list of all customers. +- Returns an object with a `customers` property containing an array of customer objects. +- Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). - [Sample: GET '/customers'](./samples/get_customers.json) GET '/customers/:id' -- Returns data about the customer identified by the id passed in the URI. -- Contains `customer_data` and `movies`. +- Retrieves data about the customer identified by the id passed in the URL. +- Returns an object with `customer_data` and `movies` properties. - `customer_data` contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). - `movies` contains: `current_rentals` and `past_rentals`. - `current_rentals` is a list of movies rented by the customer. @@ -29,6 +30,13 @@ GET '/customers/:id' GET '/customers/:sort_by/:limit/:offset' +- Sorts the entire set of customers by a certain property (`sort_by`), then retrieves a number (`limit`) of customers, starting at a certain index (`offset`). + - `sort_by` accepts 'name' (customer name), 'id' (customer id), or 'checkout_date'. + - `limit` must be an integer >= 0. + - `offset` must be an integer >= 0. +- Returns an object with a `customers` property containing an array of customer objects. +- Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- [Sample: GET '/customers/name/2/2'](./samples/get_customers_sort_by_limit_offset.json) *Movies* diff --git a/samples/get_customers_sort_by_limit_offset.json b/samples/get_customers_sort_by_limit_offset.json new file mode 100644 index 0000000..36c63e8 --- /dev/null +++ b/samples/get_customers_sort_by_limit_offset.json @@ -0,0 +1 @@ +{"customers":[{"id":155,"name":"Abigail Lara","registered_at":"Wed, 12 Aug 2015 03:21:43 -0700","address":"P.O. Box 388, 1190 Donec St.","city":"Shreveport","state":"Louisiana","postal_code":"41243","phone":"(235) 178-3417","account_credit":8856},{"id":46,"name":"Acton Gilliam","registered_at":"Thu, 26 Feb 2015 20:00:53 -0800","address":"Ap #508-8214 Senectus Av.","city":"Portland","state":"Oregon","postal_code":"62594","phone":"(903) 973-1984","account_credit":4864}]} \ No newline at end of file From c2f8b2490da392fe992539303e2717a350fba61f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:54:18 -0700 Subject: [PATCH 154/189] adding example as block of code --- endpoint-readme.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/endpoint-readme.md b/endpoint-readme.md index 479f9d2..5f38a12 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -37,6 +37,10 @@ GET '/customers/:sort_by/:limit/:offset' - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). - [Sample: GET '/customers/name/2/2'](./samples/get_customers_sort_by_limit_offset.json) +```json +{"customers":[{"id":155,"name":"Abigail Lara","registered_at":"Wed, 12 Aug 2015 03:21:43 -0700","address":"P.O. Box 388, 1190 Donec St.","city":"Shreveport","state":"Louisiana","postal_code":"41243","phone":"(235) 178-3417","account_credit":8856},{"id":46,"name":"Acton Gilliam","registered_at":"Thu, 26 Feb 2015 20:00:53 -0800","address":"Ap #508-8214 Senectus Av.","city":"Portland","state":"Oregon","postal_code":"62594","phone":"(903) 973-1984","account_credit":4864}]} +``` + *Movies* From 3a75f8e04cda938d7684ec992b9895ba0ba44ce6 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:55:28 -0700 Subject: [PATCH 155/189] beautified json sample --- endpoint-readme.md | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 5f38a12..250d88c 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -38,7 +38,29 @@ GET '/customers/:sort_by/:limit/:offset' - Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). - [Sample: GET '/customers/name/2/2'](./samples/get_customers_sort_by_limit_offset.json) ```json -{"customers":[{"id":155,"name":"Abigail Lara","registered_at":"Wed, 12 Aug 2015 03:21:43 -0700","address":"P.O. Box 388, 1190 Donec St.","city":"Shreveport","state":"Louisiana","postal_code":"41243","phone":"(235) 178-3417","account_credit":8856},{"id":46,"name":"Acton Gilliam","registered_at":"Thu, 26 Feb 2015 20:00:53 -0800","address":"Ap #508-8214 Senectus Av.","city":"Portland","state":"Oregon","postal_code":"62594","phone":"(903) 973-1984","account_credit":4864}]} +{ + "customers": [{ + "id": 155, + "name": "Abigail Lara", + "registered_at": "Wed, 12 Aug 2015 03:21:43 -0700", + "address": "P.O. Box 388, 1190 Donec St.", + "city": "Shreveport", + "state": "Louisiana", + "postal_code": "41243", + "phone": "(235) 178-3417", + "account_credit": 8856 + }, { + "id": 46, + "name": "Acton Gilliam", + "registered_at": "Thu, 26 Feb 2015 20:00:53 -0800", + "address": "Ap #508-8214 Senectus Av.", + "city": "Portland", + "state": "Oregon", + "postal_code": "62594", + "phone": "(903) 973-1984", + "account_credit": 4864 + }] +} ``` From 6204d1b5bafc6d0bdfe4477514286bb81a779f05 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 09:57:55 -0700 Subject: [PATCH 156/189] beautifed and included in-line all json examples --- endpoint-readme.md | 164 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 161 insertions(+), 3 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 250d88c..1e91245 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -12,7 +12,62 @@ GET '/customers' - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- [Sample: GET '/customers'](./samples/get_customers.json) +- Sample: GET '/customers' +```json +{ + "customers": [{ + "id": 1, + "name": "Shelley Rocha", + "registered_at": "Wed, 29 Apr 2015 07:54:14 -0700", + "address": "Ap #292-5216 Ipsum Rd.", + "city": "Hillsboro", + "state": "OR", + "postal_code": "24309", + "phone": "(322) 510-8695", + "account_credit": 1315 + }, { + "id": 2, + "name": "XCurran Stout", + "registered_at": "Wed, 16 Apr 2014 21:40:20 -0700", + "address": "Ap #658-1540 Erat Rd.", + "city": "San Francisco", + "state": "California", + "postal_code": "94267", + "phone": "(908) 949-6758", + "account_credit": 3565.9999999999995 + }, { + "id": 3, + "name": "Roanna Robinson", + "registered_at": "Fri, 28 Nov 2014 13:14:08 -0800", + "address": "Ap #561-4214 Eget St.", + "city": "Harrisburg", + "state": "PA", + "postal_code": "15867", + "phone": "(323) 336-1841", + "account_credit": 5039 + }, { + "id": 4, + "name": "Carolyn Chandler", + "registered_at": "Fri, 04 Jul 2014 11:05:11 -0700", + "address": "133-8707 Arcu. Avenue", + "city": "Fort Wayne", + "state": "IN", + "postal_code": "73684", + "phone": "(234) 837-2886", + "account_credit": 2079 + }, { + "id": 5, + "name": "Aquila Riddle", + "registered_at": "Thu, 27 Aug 2015 08:17:24 -0700", + "address": "Ap #187-9582 Primis St.", + "city": "Tacoma", + "state": "WA", + "postal_code": "73251", + "phone": "(925) 161-2223", + "account_credit": 1782 + }] +} +``` GET '/customers/:id' @@ -26,7 +81,110 @@ GET '/customers/:id' - Each movie object contains `movie_data` and `dates`. - `dates` contains `checkout_date` and `returned_date`. - `movie_data` contains: `title`, `overview`, `release_date`, and `inventory`. -- [Sample: GET '/customers/1'](./samples/get_customers_id.json) +- Sample: GET '/customers/1' +```json +{ + "customer_data": { + "id": 1, + "name": "Shelley Rocha", + "registered_at": "Wed, 29 Apr 2015 07:54:14 -0700", + "address": "Ap #292-5216 Ipsum Rd.", + "city": "Hillsboro", + "state": "OR", + "postal_code": "24309", + "phone": "(322) 510-8695", + "account_credit": 1315 + }, + "movies": { + "current_rentals": [{ + "id": 2, + "title": "Jaws", + "overview": "An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.", + "release_date": "1975-06-19", + "inventory": 6 + }, { + "id": 3, + "title": "The Exorcist", + "overview": "12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.", + "release_date": "1973-12-26", + "inventory": 7 + }, { + "id": 5, + "title": "The Silence of the Lambs", + "overview": "FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.", + "release_date": "1991-02-14", + "inventory": 3 + }, { + "id": 49, + "title": "Ben-Hur", + "overview": "Ben-Hur is a 1959 epic film directed by William Wyler, the third film version of Lew Wallace's 1880 novel Ben-Hur: A Tale of the Christ. It premiered at Loew's State Theatre in New York City on November 18, 1959. The film went on to win a record of eleven Academy Awards, including Best Picture, a feat equaled only by Titanic in 1998 and The Lord of the Rings: The Return of the King in 2004. It was also the last film to win the Oscar for both Best Actor and Best Supporting Actor, until nearly 44 years later when Mystic River achieved the same feat.The movie revolves around a Jewish prince who is betrayed and sent into slavery by a Roman friend and how he regains his freedom and comes back for revenge.", + "release_date": "1959-11-18", + "inventory": 5 + }, { + "id": 84, + "title": "Poltergeist", + "overview": "Craig T. Nelson stars as Steve Freeling, the main protagonist, who lives with his wife, Diane, (JoBeth Williams) and their three children, Dana (Dominique Dunne), Robbie (Oliver Robins), and Carol Anne (Heather O'Rourke), in Southern California where he sells houses for the company that built the neighborhood. It starts with just a few odd occurrences, such as broken dishes and furniture moving around by itself. However, a tree comes alive and takes Robbie through his bedroom window, and Carol Anne is abducted by ghosts. Realizing that something evil haunts his home, Steve calls in a team of parapsychologists led by Dr. Lesh (Beatrice Straight) to investigate, hoping to get Carol Anne back, so he can remove his family from the house before it's too late.", + "release_date": "1982-06-04", + "inventory": 4 + }, { + "id": 99, + "title": "Speed", + "overview": "Los Angeles SWAT cop Jack Traven is up against bomb expert Howard Payne, who's after major ransom money. First it's a rigged elevator in a very tall building. Then it's a rigged bus--if it slows, it will blow, bad enough any day, but a nightmare in LA traffic. And that's still not the end.", + "release_date": "1994-06-09", + "inventory": 10 + }], + "past_rentals": [{ + "dates": { + "returned_date": "07 Dec 2008 06:19:02", + "checkout_date": "03 Dec 2008 02:58:43" + }, + "movie_data": { + "id": 39, + "title": "Die Hard", + "overview": "NYPD cop John McClane's plan to reconcile with his estranged wife, Holly, is thrown for a serious loop when minutes after he arrives at her office, the entire building is overtaken by a group of pitiless terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down.", + "release_date": "1988-07-14", + "inventory": 4 + } + }, { + "dates": { + "returned_date": "07 Dec 2009 06:19:02", + "checkout_date": "03 Dec 2009 02:58:43" + }, + "movie_data": { + "id": 72, + "title": "Platoon", + "overview": "Chris Taylor, a young, naive recruit in Vietnam, faces a moral crisis when confronted with the horrors of war and the duality of man.", + "release_date": "1986-12-18", + "inventory": 1 + } + }, { + "dates": { + "returned_date": "14 May 2011 02:58:43", + "checkout_date": "10 May 2011 02:58:43" + }, + "movie_data": { + "id": 68, + "title": "Halloween", + "overview": "A psychotic murderer institutionalized since childhood for the murder of his sister, escapes and stalks a bookish teenage girl and her friends while his doctor chases him through the streets.", + "release_date": "1978-10-25", + "inventory": 4 + } + }, { + "dates": { + "returned_date": "14 May 2011 02:58:43", + "checkout_date": "10 May 2011 02:58:43" + }, + "movie_data": { + "id": 100, + "title": "The Adventures of Robin Hood", + "overview": "Robin Hood (Errol Flynn) fights nobly for justice against the evil Sir Guy of Gisbourne (Basil Rathbone) while striving to win the hand of the beautiful Maid Marian (Olivia de Havilland).", + "release_date": "1938-05-14", + "inventory": 3 + } + }] + } +} +``` GET '/customers/:sort_by/:limit/:offset' @@ -36,7 +194,7 @@ GET '/customers/:sort_by/:limit/:offset' - `offset` must be an integer >= 0. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- [Sample: GET '/customers/name/2/2'](./samples/get_customers_sort_by_limit_offset.json) +- Sample: GET '/customers/name/2/2' ```json { "customers": [{ From d106cd67e0be9e8944eab1060f11e205b30606f8 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:02:56 -0700 Subject: [PATCH 157/189] added prose and sample for GET /movies --- endpoint-readme.md | 54 +++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 53 insertions(+), 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 1e91245..c918a97 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -5,6 +5,17 @@ Anita & Alice's Video Store See below for the available endpoints for this API. +1. GET '/customers' +2. GET '/customers/:id' +3. GET '/customers/:sort_by/:limit/:offset' +4. GET '/movies' +5. GET '/movies/:title/:order' +6. GET '/movies/:sort_by/:limit/:offset' +7. GET '/rentals/overdue' +8. GET '/rentals/:title' +9. POST '/rentals/checkout/:customer_id/:movie_title' +10. PUT '/rentals/checkin/:customer_id/:movie_title' + **Customers** GET '/customers' @@ -221,13 +232,54 @@ GET '/customers/:sort_by/:limit/:offset' } ``` - *Movies* GET '/movies' +- Retrieves a list of all movies. +- Returns an object with a `movies` property containing an array of movie objects. +- Each movie object contains the following properties: `title`, `overview`, `release_date`, and `inventory`. +- Sample: GET '/movies' +```json +{ + "movies": [{ + "id": 1, + "title": "Psycho", + "overview": "When larcenous real estate clerk Marion Crane goes on the lam with a wad of cash and hopes of starting a new life, she ends up at the notorious Bates Motel, where manager Norman Bates cares for his housebound mother. The place seems quirky, but fine… until Marion decides to take a shower.", + "release_date": "1960-06-16", + "inventory": 8 + }, { + "id": 2, + "title": "Jaws", + "overview": "An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.", + "release_date": "1975-06-19", + "inventory": 6 + }, { + "id": 3, + "title": "The Exorcist", + "overview": "12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.", + "release_date": "1973-12-26", + "inventory": 7 + }, { + "id": 4, + "title": "North by Northwest", + "overview": "Madison Avenue advertising man Roger Thornhill finds himself thrust into the world of spies when he is mistaken for a man by the name of George Kaplan. Foreign spy Philip Vandamm and his henchman Leonard try to eliminate him but when Thornhill tries to make sense of the case, he is framed for murder. Now on the run from the police, he manages to board the 20th Century Limited bound for Chicago where he meets a beautiful blond, Eve Kendall, who helps him to evade the authorities. His world is turned upside down yet again when he learns that Eve isn't the innocent bystander he thought she was. Not all is as it seems however, leading to a dramatic rescue and escape at the top of Mt. Rushmore.", + "release_date": "1959-07-17", + "inventory": 10 + }, { + "id": 5, + "title": "The Silence of the Lambs", + "overview": "FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.", + "release_date": "1991-02-14", + "inventory": 3 + }] +} +``` + GET '/movies/:title/:order' + + GET '/movies/:sort_by/:limit/:offset' *Rentals* From 5ea530fa1c735489f0345ff0c5033aa7b783f6d3 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:03:28 -0700 Subject: [PATCH 158/189] removed sample json files --- samples/get_customers.json | 1 - samples/get_customers_id.json | 1 - samples/get_customers_sort_by_limit_offset.json | 1 - 3 files changed, 3 deletions(-) delete mode 100644 samples/get_customers.json delete mode 100644 samples/get_customers_id.json delete mode 100644 samples/get_customers_sort_by_limit_offset.json diff --git a/samples/get_customers.json b/samples/get_customers.json deleted file mode 100644 index 31f8587..0000000 --- a/samples/get_customers.json +++ /dev/null @@ -1 +0,0 @@ -{"customers":[{"id":1,"name":"Shelley Rocha","registered_at":"Wed, 29 Apr 2015 07:54:14 -0700","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":1315},{"id":2,"name":"XCurran Stout","registered_at":"Wed, 16 Apr 2014 21:40:20 -0700","address":"Ap #658-1540 Erat Rd.","city":"San Francisco","state":"California","postal_code":"94267","phone":"(908) 949-6758","account_credit":3565.9999999999995},{"id":3,"name":"Roanna Robinson","registered_at":"Fri, 28 Nov 2014 13:14:08 -0800","address":"Ap #561-4214 Eget St.","city":"Harrisburg","state":"PA","postal_code":"15867","phone":"(323) 336-1841","account_credit":5039},{"id":4,"name":"Carolyn Chandler","registered_at":"Fri, 04 Jul 2014 11:05:11 -0700","address":"133-8707 Arcu. Avenue","city":"Fort Wayne","state":"IN","postal_code":"73684","phone":"(234) 837-2886","account_credit":2079},{"id":5,"name":"Aquila Riddle","registered_at":"Thu, 27 Aug 2015 08:17:24 -0700","address":"Ap #187-9582 Primis St.","city":"Tacoma","state":"WA","postal_code":"73251","phone":"(925) 161-2223","account_credit":1782}]} \ No newline at end of file diff --git a/samples/get_customers_id.json b/samples/get_customers_id.json deleted file mode 100644 index dd01545..0000000 --- a/samples/get_customers_id.json +++ /dev/null @@ -1 +0,0 @@ -{"customer_data":{"id":1,"name":"Shelley Rocha","registered_at":"Wed, 29 Apr 2015 07:54:14 -0700","address":"Ap #292-5216 Ipsum Rd.","city":"Hillsboro","state":"OR","postal_code":"24309","phone":"(322) 510-8695","account_credit":1315},"movies":{"current_rentals":[{"id":2,"title":"Jaws","overview":"An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.","release_date":"1975-06-19","inventory":6},{"id":3,"title":"The Exorcist","overview":"12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.","release_date":"1973-12-26","inventory":7},{"id":5,"title":"The Silence of the Lambs","overview":"FBI trainee Clarice Starling ventures into a maximum-security asylum to pick the diseased brain of Hannibal Lecter, a psychiatrist turned homicidal cannibal. Starling needs clues to help her capture a serial killer. Unfortunately, her Faustian relationship with Lecter soon leads to his escape, and now two deranged killers are on the loose.","release_date":"1991-02-14","inventory":3},{"id":49,"title":"Ben-Hur","overview":"Ben-Hur is a 1959 epic film directed by William Wyler, the third film version of Lew Wallace's 1880 novel Ben-Hur: A Tale of the Christ. It premiered at Loew's State Theatre in New York City on November 18, 1959. The film went on to win a record of eleven Academy Awards, including Best Picture, a feat equaled only by Titanic in 1998 and The Lord of the Rings: The Return of the King in 2004. It was also the last film to win the Oscar for both Best Actor and Best Supporting Actor, until nearly 44 years later when Mystic River achieved the same feat.The movie revolves around a Jewish prince who is betrayed and sent into slavery by a Roman friend and how he regains his freedom and comes back for revenge.","release_date":"1959-11-18","inventory":5},{"id":84,"title":"Poltergeist","overview":"Craig T. Nelson stars as Steve Freeling, the main protagonist, who lives with his wife, Diane, (JoBeth Williams) and their three children, Dana (Dominique Dunne), Robbie (Oliver Robins), and Carol Anne (Heather O'Rourke), in Southern California where he sells houses for the company that built the neighborhood. It starts with just a few odd occurrences, such as broken dishes and furniture moving around by itself. However, a tree comes alive and takes Robbie through his bedroom window, and Carol Anne is abducted by ghosts. Realizing that something evil haunts his home, Steve calls in a team of parapsychologists led by Dr. Lesh (Beatrice Straight) to investigate, hoping to get Carol Anne back, so he can remove his family from the house before it's too late.","release_date":"1982-06-04","inventory":4},{"id":99,"title":"Speed","overview":"Los Angeles SWAT cop Jack Traven is up against bomb expert Howard Payne, who's after major ransom money. First it's a rigged elevator in a very tall building. Then it's a rigged bus--if it slows, it will blow, bad enough any day, but a nightmare in LA traffic. And that's still not the end.","release_date":"1994-06-09","inventory":10}],"past_rentals":[{"dates":{"returned_date":"07 Dec 2008 06:19:02","checkout_date":"03 Dec 2008 02:58:43"},"movie_data":{"id":39,"title":"Die Hard","overview":"NYPD cop John McClane's plan to reconcile with his estranged wife, Holly, is thrown for a serious loop when minutes after he arrives at her office, the entire building is overtaken by a group of pitiless terrorists. With little help from the LAPD, wisecracking McClane sets out to single-handedly rescue the hostages and bring the bad guys down.","release_date":"1988-07-14","inventory":4}},{"dates":{"returned_date":"07 Dec 2009 06:19:02","checkout_date":"03 Dec 2009 02:58:43"},"movie_data":{"id":72,"title":"Platoon","overview":"Chris Taylor, a young, naive recruit in Vietnam, faces a moral crisis when confronted with the horrors of war and the duality of man.","release_date":"1986-12-18","inventory":1}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":68,"title":"Halloween","overview":"A psychotic murderer institutionalized since childhood for the murder of his sister, escapes and stalks a bookish teenage girl and her friends while his doctor chases him through the streets.","release_date":"1978-10-25","inventory":4}},{"dates":{"returned_date":"14 May 2011 02:58:43","checkout_date":"10 May 2011 02:58:43"},"movie_data":{"id":100,"title":"The Adventures of Robin Hood","overview":"Robin Hood (Errol Flynn) fights nobly for justice against the evil Sir Guy of Gisbourne (Basil Rathbone) while striving to win the hand of the beautiful Maid Marian (Olivia de Havilland).","release_date":"1938-05-14","inventory":3}}]}} \ No newline at end of file diff --git a/samples/get_customers_sort_by_limit_offset.json b/samples/get_customers_sort_by_limit_offset.json deleted file mode 100644 index 36c63e8..0000000 --- a/samples/get_customers_sort_by_limit_offset.json +++ /dev/null @@ -1 +0,0 @@ -{"customers":[{"id":155,"name":"Abigail Lara","registered_at":"Wed, 12 Aug 2015 03:21:43 -0700","address":"P.O. Box 388, 1190 Donec St.","city":"Shreveport","state":"Louisiana","postal_code":"41243","phone":"(235) 178-3417","account_credit":8856},{"id":46,"name":"Acton Gilliam","registered_at":"Thu, 26 Feb 2015 20:00:53 -0800","address":"Ap #508-8214 Senectus Av.","city":"Portland","state":"Oregon","postal_code":"62594","phone":"(903) 973-1984","account_credit":4864}]} \ No newline at end of file From a3e104968f3bdac7bd069ad2dc57dc3c761ae429 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:04:52 -0700 Subject: [PATCH 159/189] formatting internal anchor --- endpoint-readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index c918a97..bdb429c 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -5,7 +5,7 @@ Anita & Alice's Video Store See below for the available endpoints for this API. -1. GET '/customers' +1. [GET '/customers'](#GET-'/customers') 2. GET '/customers/:id' 3. GET '/customers/:sort_by/:limit/:offset' 4. GET '/movies' @@ -18,7 +18,7 @@ See below for the available endpoints for this API. **Customers** -GET '/customers' +###GET '/customers' - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. From e3840e124dcd46504af981f232135878fc72cb3f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:06:05 -0700 Subject: [PATCH 160/189] formatting again WIP --- endpoint-readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index bdb429c..8af4922 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -6,7 +6,7 @@ Anita & Alice's Video Store See below for the available endpoints for this API. 1. [GET '/customers'](#GET-'/customers') -2. GET '/customers/:id' +2. [GET '/customers/:id'](#GET-'/customers/:id') 3. GET '/customers/:sort_by/:limit/:offset' 4. GET '/movies' 5. GET '/movies/:title/:order' @@ -80,7 +80,7 @@ See below for the available endpoints for this API. } ``` -GET '/customers/:id' +###GET '/customers/:id' - Retrieves data about the customer identified by the id passed in the URL. - Returns an object with `customer_data` and `movies` properties. From 5bd6aaf90a9ecefe6b677432b5a4dccac857f131 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:06:58 -0700 Subject: [PATCH 161/189] formatting again WIP --- endpoint-readme.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 8af4922..489f699 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -5,8 +5,8 @@ Anita & Alice's Video Store See below for the available endpoints for this API. -1. [GET '/customers'](#GET-'/customers') -2. [GET '/customers/:id'](#GET-'/customers/:id') +1. [GET '/customers'](#get-'/customers') +2. [GET '/customers/:id'](#get-'/customers/:id') 3. GET '/customers/:sort_by/:limit/:offset' 4. GET '/movies' 5. GET '/movies/:title/:order' From 18d083dc208e940c33cc3b123fea37416f8e6fde Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:09:00 -0700 Subject: [PATCH 162/189] formatting again WIP --- endpoint-readme.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 489f699..187895f 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -5,8 +5,8 @@ Anita & Alice's Video Store See below for the available endpoints for this API. -1. [GET '/customers'](#get-'/customers') -2. [GET '/customers/:id'](#get-'/customers/:id') +1. [All Customers](#all-customers) +2. [Single Customer](#single-customer) 3. GET '/customers/:sort_by/:limit/:offset' 4. GET '/movies' 5. GET '/movies/:title/:order' @@ -18,8 +18,8 @@ See below for the available endpoints for this API. **Customers** -###GET '/customers' - +###All Customers +- GET '/customers' - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). @@ -80,8 +80,9 @@ See below for the available endpoints for this API. } ``` -###GET '/customers/:id' +###Single Customer +- GET '/customers/:id' - Retrieves data about the customer identified by the id passed in the URL. - Returns an object with `customer_data` and `movies` properties. - `customer_data` contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). From cc728d66170e834484843ce25c899b2a8dabd18a Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:14:13 -0700 Subject: [PATCH 163/189] formatted more of the endpoints with links --- endpoint-readme.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 187895f..cc1ee93 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -7,8 +7,8 @@ See below for the available endpoints for this API. 1. [All Customers](#all-customers) 2. [Single Customer](#single-customer) -3. GET '/customers/:sort_by/:limit/:offset' -4. GET '/movies' +3. [Subset of Customers](#subset-of-customers) +4. [All Movies](#all-movies) 5. GET '/movies/:title/:order' 6. GET '/movies/:sort_by/:limit/:offset' 7. GET '/rentals/overdue' @@ -19,7 +19,7 @@ See below for the available endpoints for this API. **Customers** ###All Customers -- GET '/customers' +- GET `/customers` - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). @@ -82,7 +82,7 @@ See below for the available endpoints for this API. ###Single Customer -- GET '/customers/:id' +- GET `/customers/:id` - Retrieves data about the customer identified by the id passed in the URL. - Returns an object with `customer_data` and `movies` properties. - `customer_data` contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). @@ -198,8 +198,9 @@ See below for the available endpoints for this API. } ``` -GET '/customers/:sort_by/:limit/:offset' +###Subset of Customers +- GET `/customers/:sort_by/:limit/:offset` - Sorts the entire set of customers by a certain property (`sort_by`), then retrieves a number (`limit`) of customers, starting at a certain index (`offset`). - `sort_by` accepts 'name' (customer name), 'id' (customer id), or 'checkout_date'. - `limit` must be an integer >= 0. @@ -235,8 +236,9 @@ GET '/customers/:sort_by/:limit/:offset' *Movies* -GET '/movies' +###All Movies +- GET `/movies` - Retrieves a list of all movies. - Returns an object with a `movies` property containing an array of movie objects. - Each movie object contains the following properties: `title`, `overview`, `release_date`, and `inventory`. From d8397ea60e8734c34c0b2a7ead8abab731e624b8 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:20:47 -0700 Subject: [PATCH 164/189] changed case from camel to snake on object properties --- routes/movies.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/movies.js b/routes/movies.js index d9c6858..24bbaa1 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -53,7 +53,7 @@ router.get('/:title/:order', function(req, res, next) { } customer.where_in('id', currentRentersIds, function(err, rows) { - movieObject.customers.currentRenters = rows; + movieObject.customers.current_renters = rows; var pastRentersArray = []; customer.where_in('id', pastRentersIds, function(err, rows) { @@ -80,7 +80,7 @@ router.get('/:title/:order', function(req, res, next) { var error_message = "You cannot sort by: " + order; } - movieObject.customers.pastRenters = pastRentersArray; + movieObject.customers.past_renters = pastRentersArray; if (error_message) { res.status(400).json(error_message); From d80b29beef3771b2b33e8bfc2c7e1183d8be720f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:25:29 -0700 Subject: [PATCH 165/189] complete info on get movies/title/sort --- endpoint-readme.md | 95 +++++++++++++++++++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 13 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index cc1ee93..848f7f3 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -22,8 +22,8 @@ See below for the available endpoints for this API. - GET `/customers` - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. -- Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET '/customers' +- Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- Sample: GET `/customers` ```json { "customers": [{ @@ -83,17 +83,17 @@ See below for the available endpoints for this API. ###Single Customer - GET `/customers/:id` -- Retrieves data about the customer identified by the id passed in the URL. +- Retrieves data about the customer identified by the `id` passed in the URL. - Returns an object with `customer_data` and `movies` properties. - - `customer_data` contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). + - `customer_data` contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). - `movies` contains: `current_rentals` and `past_rentals`. - `current_rentals` is a list of movies rented by the customer. - - Each movie object contains the following propeties: `title`, `overview`, `release_date`, and `inventory`. + - Each movie object contains the following propeties: `id`, `title`, `overview`, `release_date`, and `inventory`. - `past_rentals` is a list of movie objects. - Each movie object contains `movie_data` and `dates`. - `dates` contains `checkout_date` and `returned_date`. - - `movie_data` contains: `title`, `overview`, `release_date`, and `inventory`. -- Sample: GET '/customers/1' + - `movie_data` contains: `id`, `title`, `overview`, `release_date`, and `inventory`. +- Sample: GET `/customers/1` ```json { "customer_data": { @@ -202,12 +202,12 @@ See below for the available endpoints for this API. - GET `/customers/:sort_by/:limit/:offset` - Sorts the entire set of customers by a certain property (`sort_by`), then retrieves a number (`limit`) of customers, starting at a certain index (`offset`). - - `sort_by` accepts 'name' (customer name), 'id' (customer id), or 'checkout_date'. + - `sort_by` accepts `name` (customer name), `registered_at` (registration date), or `postal_code`. - `limit` must be an integer >= 0. - `offset` must be an integer >= 0. - Returns an object with a `customers` property containing an array of customer objects. -- Each customer object contains the following properties: `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET '/customers/name/2/2' +- Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- Sample: GET `/customers/name/2/2` ```json { "customers": [{ @@ -241,8 +241,8 @@ See below for the available endpoints for this API. - GET `/movies` - Retrieves a list of all movies. - Returns an object with a `movies` property containing an array of movie objects. -- Each movie object contains the following properties: `title`, `overview`, `release_date`, and `inventory`. -- Sample: GET '/movies' +- Each movie object contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. +- Sample: GET `/movies` ```json { "movies": [{ @@ -279,8 +279,77 @@ See below for the available endpoints for this API. } ``` -GET '/movies/:title/:order' +###Single Movie + +- GET `/movies/:title/:order` +- `order` accepts `name` (customer name), `id` (customer id), and `checkout_date`. +- Retrieves data about the movie identified by the `title` passed in the URL, with past customers sorted in the `order` passed in the URL. +- Returns an object with `movie_data` and `customers` properties. + - `movie_data` contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. + - `customers` contains: `current_renters` and `past_renters`. + - `current_renters` is a list of customers who have an unreturned rental of the movie. + - Each customer object contains the following propeties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). + - `past_renters` is a list of customer objects. + - Each customer object contains `customer_data` and `dates`. + - `dates` contains `checkout_date`. + - `customer_data` contains: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- Sample: GET `/movies/The Guns of Navarone/name` +```json +{ + "movie_data": { + "id": 89, + "title": "The Guns of Navarone", + "overview": "A team of allied saboteurs are assigned an impossible mission: infiltrate an impregnable Nazi-held island and destroy the two enormous long-range field guns that prevent the rescue of 2,000 trapped British soldiers.", + "release_date": "1961-06-22", + "inventory": 3 + }, + "customers": { + "current_renters": [{ + "id": 4, + "name": "Carolyn Chandler", + "registered_at": "Fri, 04 Jul 2014 11:05:11 -0700", + "address": "133-8707 Arcu. Avenue", + "city": "Fort Wayne", + "state": "IN", + "postal_code": "73684", + "phone": "(234) 837-2886", + "account_credit": 2079 + }], + "past_renters": [{ + "dates": { + "checkout_date": "2009-12-03T10:58:43.000Z" + }, + "customer_data": { + "id": 3, + "name": "Roanna Robinson", + "registered_at": "Fri, 28 Nov 2014 13:14:08 -0800", + "address": "Ap #561-4214 Eget St.", + "city": "Harrisburg", + "state": "PA", + "postal_code": "15867", + "phone": "(323) 336-1841", + "account_credit": 5039 + } + }, { + "dates": { + "checkout_date": "1999-10-03T07:25:08.000Z" + }, + "customer_data": { + "id": 2, + "name": "XCurran Stout", + "registered_at": "Wed, 16 Apr 2014 21:40:20 -0700", + "address": "Ap #658-1540 Erat Rd.", + "city": "San Francisco", + "state": "California", + "postal_code": "94267", + "phone": "(908) 949-6758", + "account_credit": 3565.9999999999995 + } + }] + } +} +``` GET '/movies/:sort_by/:limit/:offset' From 766adff58756e97f3359dea6f3fb5173bf05c438 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:27:04 -0700 Subject: [PATCH 166/189] formatting --- endpoint-readme.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 848f7f3..f2c7888 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -9,7 +9,7 @@ See below for the available endpoints for this API. 2. [Single Customer](#single-customer) 3. [Subset of Customers](#subset-of-customers) 4. [All Movies](#all-movies) -5. GET '/movies/:title/:order' +5. [Single Movie](#single-movie) 6. GET '/movies/:sort_by/:limit/:offset' 7. GET '/rentals/overdue' 8. GET '/rentals/:title' @@ -279,7 +279,6 @@ See below for the available endpoints for this API. } ``` - ###Single Movie - GET `/movies/:title/:order` From a17f9883f2460c1baae77d51bace86ef7abce364 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:29:50 -0700 Subject: [PATCH 167/189] experimenting with formatting --- endpoint-readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index f2c7888..ae33910 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -1,7 +1,7 @@ Anita & Alice's Video Store --------------------------- -**Endpoints** +#Endpoints See below for the available endpoints for this API. @@ -16,9 +16,9 @@ See below for the available endpoints for this API. 9. POST '/rentals/checkout/:customer_id/:movie_title' 10. PUT '/rentals/checkin/:customer_id/:movie_title' -**Customers** +###Customers -###All Customers +#####All Customers - GET `/customers` - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. From 8589af8ad350f465edc435973a660e64ecf59903 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:30:55 -0700 Subject: [PATCH 168/189] experimenting with formatting --- endpoint-readme.md | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index ae33910..94a72ed 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -1,8 +1,6 @@ -Anita & Alice's Video Store +#Anita & Alice's Video Store --------------------------- -#Endpoints - See below for the available endpoints for this API. 1. [All Customers](#all-customers) @@ -16,9 +14,9 @@ See below for the available endpoints for this API. 9. POST '/rentals/checkout/:customer_id/:movie_title' 10. PUT '/rentals/checkin/:customer_id/:movie_title' -###Customers +##Customers -#####All Customers +###All Customers - GET `/customers` - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. From 14f38e06e5f9e42da807218a0044ea7cb797bc0d Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:31:30 -0700 Subject: [PATCH 169/189] experimenting with formatting --- endpoint-readme.md | 1 - 1 file changed, 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 94a72ed..8c0892d 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -1,5 +1,4 @@ #Anita & Alice's Video Store ---------------------------- See below for the available endpoints for this API. From 686bd26626b742d76d0fdbdde272a8f439167817 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:37:45 -0700 Subject: [PATCH 170/189] added example and prose for get movies/sort_by/limit/offset --- endpoint-readme.md | 54 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 41 insertions(+), 13 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 8c0892d..cad9d25 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -7,11 +7,11 @@ See below for the available endpoints for this API. 3. [Subset of Customers](#subset-of-customers) 4. [All Movies](#all-movies) 5. [Single Movie](#single-movie) -6. GET '/movies/:sort_by/:limit/:offset' -7. GET '/rentals/overdue' -8. GET '/rentals/:title' -9. POST '/rentals/checkout/:customer_id/:movie_title' -10. PUT '/rentals/checkin/:customer_id/:movie_title' +6. [Subset of Movies](#subset-of-movies) +7. [Overdue Rentals](#overdue-rentals) +8. [Rental History of Single Movie](#rental-history-of-single-movie) +9. [Rent Movie](#rent-movie) +10. [Return Movie](#return-movie) ##Customers @@ -231,7 +231,7 @@ See below for the available endpoints for this API. } ``` -*Movies* +##Movies ###All Movies @@ -347,15 +347,43 @@ See below for the available endpoints for this API. } ``` +### Subset of Movies +- GET `/movies/:sort_by/:limit/:offset` +- Sorts the entire set of movies by a certain property (`sort_by`), then retrieves a number (`limit`) of movies, starting at a certain index (`offset`). + - `sort_by` accepts `title`, `release_date`. + - `limit` must be an integer >= 0. + - `offset` must be an integer >= 0. +- Returns an object with a `movies` property containing an array of movie objects. +- Each movie object contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. +- Sample: GET `/movies/title/2/2` +```json +{ + "movies": [{ + "id": 21, + "title": "A Clockwork Orange", + "overview": "The head of a gang of toughs, in an insensitive futuristic society, is conditioned to become physically ill at sex and violence during a prison sentence. When he is released, he's brutally beaten by all of his old adversaries.", + "release_date": "1971-12-18", + "inventory": 4 + }, { + "id": 6, + "title": "Alien", + "overview": "During its return to the earth, commercial spaceship Nostromo intercepts a distress signal from a distant planet. When a three-member team of the crew discovers a chamber containing thousands of eggs on the planet, a creature inside one of the eggs attacks an explorer. The entire crew is unaware of the impending nightmare set to descend upon them when the alien parasite planted inside its unfortunate host is birthed.", + "release_date": "1979-05-25", + "inventory": 4 + }] +} +``` -GET '/movies/:sort_by/:limit/:offset' - -*Rentals* +##Rentals -GET '/rentals/overdue' +###Overdue Rentals +- GET `/rentals/overdue` -GET '/rentals/:title' +###Rental History of Single Movie +- GET `/rentals/:title` -POST '/rentals/checkout/:customer_id/:movie_title' +###Rent Movie +- POST `/rentals/checkout/:customer_id/:movie_title` -PUT '/rentals/checkin/:customer_id/:movie_title' +###Return Movie +- PUT `/rentals/checkin/:customer_id/:movie_title` From 351726d57c7e6d6bb9b7a3ff68673a8bfbf69ec1 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 10:40:01 -0700 Subject: [PATCH 171/189] fixed typo; customer and movie routes documented --- endpoint-readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index cad9d25..e8fae35 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -350,7 +350,7 @@ See below for the available endpoints for this API. ### Subset of Movies - GET `/movies/:sort_by/:limit/:offset` - Sorts the entire set of movies by a certain property (`sort_by`), then retrieves a number (`limit`) of movies, starting at a certain index (`offset`). - - `sort_by` accepts `title`, `release_date`. + - `sort_by` accepts `title` and `release_date`. - `limit` must be an integer >= 0. - `offset` must be an integer >= 0. - Returns an object with a `movies` property containing an array of movie objects. From 9c267e11c88f40ff1959ed61faabd695fc37fd01 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:20:30 -0700 Subject: [PATCH 172/189] added example and prose for get rentals/overdue --- endpoint-readme.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/endpoint-readme.md b/endpoint-readme.md index e8fae35..89b5baf 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -378,6 +378,56 @@ See below for the available endpoints for this API. ###Overdue Rentals - GET `/rentals/overdue` +- Retrieves a list of all customers with overdue rentals. +- Returns an object with an `overdue_customers` property that contains a list of customer objects. + - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- Sample: GET `/rentals/overdue` +```json + +{ + "overdue_customers": [{ + "id": 1, + "name": "Shelley Rocha", + "registered_at": "Wed, 29 Apr 2015 07:54:14 -0700", + "address": "Ap #292-5216 Ipsum Rd.", + "city": "Hillsboro", + "state": "OR", + "postal_code": "24309", + "phone": "(322) 510-8695", + "account_credit": 1315 + }, { + "id": 2, + "name": "XCurran Stout", + "registered_at": "Wed, 16 Apr 2014 21:40:20 -0700", + "address": "Ap #658-1540 Erat Rd.", + "city": "San Francisco", + "state": "California", + "postal_code": "94267", + "phone": "(908) 949-6758", + "account_credit": 3565.9999999999995 + }, { + "id": 3, + "name": "Roanna Robinson", + "registered_at": "Fri, 28 Nov 2014 13:14:08 -0800", + "address": "Ap #561-4214 Eget St.", + "city": "Harrisburg", + "state": "PA", + "postal_code": "15867", + "phone": "(323) 336-1841", + "account_credit": 5039 + }, { + "id": 4, + "name": "Carolyn Chandler", + "registered_at": "Fri, 04 Jul 2014 11:05:11 -0700", + "address": "133-8707 Arcu. Avenue", + "city": "Fort Wayne", + "state": "IN", + "postal_code": "73684", + "phone": "(234) 837-2886", + "account_credit": 2079 + }] +} +``` ###Rental History of Single Movie - GET `/rentals/:title` From 04318b34e36535959c7fe0896c3218713727fef9 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:22:01 -0700 Subject: [PATCH 173/189] experimenting with formatting --- endpoint-readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 89b5baf..4236f14 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -377,7 +377,7 @@ See below for the available endpoints for this API. ##Rentals ###Overdue Rentals -- GET `/rentals/overdue` +- *Endpoint:* GET `/rentals/overdue` - Retrieves a list of all customers with overdue rentals. - Returns an object with an `overdue_customers` property that contains a list of customer objects. - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). From fe487e3ff48961cc4978540c4dea8723b098a200 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:22:28 -0700 Subject: [PATCH 174/189] experimenting with formatting --- endpoint-readme.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 4236f14..5a54c28 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -377,7 +377,7 @@ See below for the available endpoints for this API. ##Rentals ###Overdue Rentals -- *Endpoint:* GET `/rentals/overdue` +- **Endpoint:** GET `/rentals/overdue` - Retrieves a list of all customers with overdue rentals. - Returns an object with an `overdue_customers` property that contains a list of customer objects. - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). From 3570c468b8335e9ce54ae0ebe6d1a365acc33fbf Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 25 Sep 2015 11:30:03 -0700 Subject: [PATCH 175/189] added customers endpoints error handling and started rentals --- db/test.db | Bin 4096 -> 4096 bytes routes/customers.js | 19 ++++++++++++++++--- routes/rentals.js | 6 +++++- 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/db/test.db b/db/test.db index 8d9eb789edef76a0e5074c39ff197954a225c71e..1598f9e3e36fa3b48a144d68c8959dbec2528d97 100644 GIT binary patch delta 48 ycmZorXi%6S#l%-LQN{^KZcKQ_Ct+k@Y-(;|YHX-yU}$1uY-Vf<;ZBa@UjzU;d<=j9 delta 48 ycmZorXi%6S#l$;xqKp%e+?eo;Pr}gB(#*`%!o*b1z|h3R*v!}v!krw)zX$+Bs0_>i diff --git a/routes/customers.js b/routes/customers.js index 598816d..4ce5b7b 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -13,7 +13,11 @@ var Movie = require('../models/movie'), router.get('/', function(req, res, next) { customer.find_all(function(err, rows) { - res.status(200).json({ customers: rows }); + if (rows) { + return res.status(200).json({ customers: rows }); + } else { + return res.status(400).json({ "No customers were found." }); + } }); }); @@ -30,6 +34,10 @@ router.get('/:id', function(req, res, next) { customer.find_by('id', id, function(err, row) { customerObject.customer_data = row; + if (row == undefined) { + return res.status(403).json({ error: "Customer " + id + " does not exist." }); + } + // use where to pull all records that meet the condition rental.where(["customer_id"], [id], function(err, rows) { var currentMoviesIDs = []; @@ -68,7 +76,8 @@ router.get('/:id', function(req, res, next) { }); customerObject.movies.pastRentals = pastMoviesArray; - res.status(200).json(customerObject); + + return res.status(200).json(customerObject); }); }); }); @@ -82,7 +91,11 @@ router.get('/:sort_by/:limit/:offset', function(req, res, next) { var column = req.params.sort_by; customer.subset(column, values, function(err, rows) { - res.status(200).json({ customers: rows} ); + if (rows) { + return res.status(200).json({ customers: rows} ); + } else { + return res.status(400).json({ error: "Not found" }); + } }); }); diff --git a/routes/rentals.js b/routes/rentals.js index 6a545f6..029a48a 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -26,7 +26,11 @@ router.get('/overdue', function(req, res, next) { } customer.where_in("id", overdueCustomerIds, function(err, rows) { - res.status(200).json({ overdue_customers: rows }); + if (rows) { + return res.status(200).json({ overdue_customers: rows }); + } else { + return res.status(400).json({ error: "No overdue customers were found." }) + } }); }); }); From 92da789b3e6c7d111de76d30568030909ed8f36f Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:31:23 -0700 Subject: [PATCH 176/189] changed camel casing to snake case for json --- routes/rentals.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/routes/rentals.js b/routes/rentals.js index 6a545f6..5df93d5 100644 --- a/routes/rentals.js +++ b/routes/rentals.js @@ -52,10 +52,10 @@ router.get('/:title', function(request, response, next) { var inventory = movieObject.movie_data.inventory; var availableBool = (rentedCount < inventory) ? true : false; var availableCount = (rentedCount < inventory) ? (inventory - rentedCount) : 0; - movieObject.availability = { available: availableBool, copiesAvailable: availableCount } + movieObject.availability = { available: availableBool, copies_available: availableCount } customer.where_in('id', customerIdList, function(error, rows) { - movieObject.currentRenters = rows; + movieObject.current_renters = rows; response.status(200).json(movieObject); }); }); From 91258f22a6c0e6873d342e2a3ff85205e9d82c80 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:34:42 -0700 Subject: [PATCH 177/189] added example and prose for get rentals/overdue --- endpoint-readme.md | 52 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 43 insertions(+), 9 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index 5a54c28..b7b472f 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -16,7 +16,7 @@ See below for the available endpoints for this API. ##Customers ###All Customers -- GET `/customers` +- **Endpoint:** GET `/customers` - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). @@ -79,7 +79,7 @@ See below for the available endpoints for this API. ###Single Customer -- GET `/customers/:id` +- **Endpoint:** GET `/customers/:id` - Retrieves data about the customer identified by the `id` passed in the URL. - Returns an object with `customer_data` and `movies` properties. - `customer_data` contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). @@ -197,7 +197,7 @@ See below for the available endpoints for this API. ###Subset of Customers -- GET `/customers/:sort_by/:limit/:offset` +- **Endpoint:** GET `/customers/:sort_by/:limit/:offset` - Sorts the entire set of customers by a certain property (`sort_by`), then retrieves a number (`limit`) of customers, starting at a certain index (`offset`). - `sort_by` accepts `name` (customer name), `registered_at` (registration date), or `postal_code`. - `limit` must be an integer >= 0. @@ -235,7 +235,7 @@ See below for the available endpoints for this API. ###All Movies -- GET `/movies` +- **Endpoint:** GET `/movies` - Retrieves a list of all movies. - Returns an object with a `movies` property containing an array of movie objects. - Each movie object contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. @@ -278,7 +278,7 @@ See below for the available endpoints for this API. ###Single Movie -- GET `/movies/:title/:order` +- **Endpoint:** GET `/movies/:title/:order` - `order` accepts `name` (customer name), `id` (customer id), and `checkout_date`. - Retrieves data about the movie identified by the `title` passed in the URL, with past customers sorted in the `order` passed in the URL. - Returns an object with `movie_data` and `customers` properties. @@ -348,7 +348,7 @@ See below for the available endpoints for this API. ``` ### Subset of Movies -- GET `/movies/:sort_by/:limit/:offset` +- **Endpoint:** GET `/movies/:sort_by/:limit/:offset` - Sorts the entire set of movies by a certain property (`sort_by`), then retrieves a number (`limit`) of movies, starting at a certain index (`offset`). - `sort_by` accepts `title` and `release_date`. - `limit` must be an integer >= 0. @@ -430,10 +430,44 @@ See below for the available endpoints for this API. ``` ###Rental History of Single Movie -- GET `/rentals/:title` +- **Endpoint:** GET `/rentals/:title` +- Retrieves data and rental history about the movie identified by the `title` passed in the URL. +- Returns an object with `movie_data`, `availability`, `current_renters` properties. + - `movie_data` contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. + - `availability` contains: `available` (boolean) and `copies_available` (integer). + - `current_renters` is a list of customers who are currently renting the movie. + - Each customer object contains the following propeties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). +- Sample: GET `/rentals/jaws` +```json + +{ + "movie_data": { + "id": 2, + "title": "Jaws", + "overview": "An insatiable great white shark terrorizes the townspeople of Amity Island, The police chief, an oceanographer and a grizzled shark hunter seek to destroy the bloodthirsty beast.", + "release_date": "1975-06-19", + "inventory": 6 + }, + "availability": { + "available": true, + "copies_available": 5 + }, + "current_renters": [{ + "id": 1, + "name": "Shelley Rocha", + "registered_at": "Wed, 29 Apr 2015 07:54:14 -0700", + "address": "Ap #292-5216 Ipsum Rd.", + "city": "Hillsboro", + "state": "OR", + "postal_code": "24309", + "phone": "(322) 510-8695", + "account_credit": 1315 + }] +} +``` ###Rent Movie -- POST `/rentals/checkout/:customer_id/:movie_title` +- **Endpoint:** POST `/rentals/checkout/:customer_id/:movie_title` ###Return Movie -- PUT `/rentals/checkin/:customer_id/:movie_title` +- **Endpoint:** PUT `/rentals/checkin/:customer_id/:movie_title` From e0218e97e01cd56c6bf8ec5bb83eae305f659774 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:41:20 -0700 Subject: [PATCH 178/189] added example and prose for post rentals/checkout --- db/development.db | Bin 76800 -> 76800 bytes endpoint-readme.md | 12 ++++++++++++ 2 files changed, 12 insertions(+) diff --git a/db/development.db b/db/development.db index bd60a77341726ff5ae02a3d11e3d3a542e747429..21b86993ce85f02074e57be884caa2c4f01626c9 100644 GIT binary patch delta 94 zcmZp;!P0PpWr8&0wTUv$jMp|M%#&wg*}qAFB|(6V=_v#AS>`t8IA$|uUZ$s;1r07T qX{f2PGjK9$Yx6Q0nwS_H8JL-v8dzAG>KTBzX2upU?q=TR&no~Ch#5-& delta 51 zcmV-30L=e@*aU#s1dtm6)R7!R0o1Wzo*x1QBeEa_U=9TX4FChp1BL@$12zK Date: Fri, 25 Sep 2015 11:47:02 -0700 Subject: [PATCH 179/189] more error handling --- db/test.db | Bin 4096 -> 4096 bytes routes/customers.js | 2 +- routes/movies.js | 22 ++++++++++++++++++---- routes/rentals.js | 7 ++++++- 4 files changed, 25 insertions(+), 6 deletions(-) diff --git a/db/test.db b/db/test.db index 1598f9e3e36fa3b48a144d68c8959dbec2528d97..a1f5f597d1a17672652b273c08e921018ae595ef 100644 GIT binary patch delta 44 vcmZorXi%6S&3JO6j5FiOjR`OK#LP_1%`8mK^b8D5OpMKpEg;; Date: Fri, 25 Sep 2015 11:47:43 -0700 Subject: [PATCH 180/189] corrected typo --- db/test.db | Bin 4096 -> 4096 bytes routes/movies.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/db/test.db b/db/test.db index a1f5f597d1a17672652b273c08e921018ae595ef..21a7d8af858b0aeae1ab08146083b84db383effb 100644 GIT binary patch delta 45 vcmZorXi%6S#l$Z*QN{^KZcKQ|Cu(72X>MepXJBYzVr*t?0pU)L<6i^-{|pN{ delta 45 vcmZorXi%6S#l&}VqKp%e+?eo^Pt?@h%)-=6&%n^c#MsQ(0>Ygf$G->wE_@82 diff --git a/routes/movies.js b/routes/movies.js index 9d1c66f..0aa2114 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -113,7 +113,7 @@ router.get('/:sort_by/:limit/:offset', function(req, res, next) { if (rows) { return res.status(200).json({ movies: rows} ); } else { - return res.status(400).json({ error: "No results found or your paramters are inaccurate. Try again." }) + return res.status(400).json({ error: "No results found or your parameters are inaccurate. Try again." }) } }); }); From c90512a7099a57379ea8389b9a40e80ab8789a73 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:48:45 -0700 Subject: [PATCH 181/189] added example and prose for put rentals/checkin --- db/development.db | Bin 76800 -> 76800 bytes endpoint-readme.md | 16 ++++++++++++++-- routes/rentals.js | 2 +- 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/db/development.db b/db/development.db index 21b86993ce85f02074e57be884caa2c4f01626c9..e48209e7510f7b79c4a9c865ad5e43c799387dd8 100644 GIT binary patch delta 147 zcmZp;!P0PpWr8&0jfpbOj5jtWER)yKU|>GXJdxR(nU(1*g9g)Vrcfq+#%qi-7*iSL z7+y1MVkq%qV`t!GbhOuIn%tOZ%x`F7Vr*n!YGGz!WNf5ou-Tj^l4X{rj+tgWp*`CXGdFGR1Ig@K8Qh2>`M=C3ONmVPHp delta 82 zcmV-Y0ImOk*aU#s1dtm6){z`T0oJi#rXLD700YAVkpoKu1+x$g<^z+D4GOX(23!v1 o00Yefh67#$HUkX;<+Bkm(E Date: Fri, 25 Sep 2015 11:50:52 -0700 Subject: [PATCH 182/189] added formatting to sample text --- endpoint-readme.md | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/endpoint-readme.md b/endpoint-readme.md index e30e82e..66a615a 100644 --- a/endpoint-readme.md +++ b/endpoint-readme.md @@ -20,7 +20,7 @@ See below for the available endpoints for this API. - Retrieves a list of all customers. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET `/customers` +- **Sample:** GET `/customers` ```json { "customers": [{ @@ -90,7 +90,7 @@ See below for the available endpoints for this API. - Each movie object contains `movie_data` and `dates`. - `dates` contains `checkout_date` and `returned_date`. - `movie_data` contains: `id`, `title`, `overview`, `release_date`, and `inventory`. -- Sample: GET `/customers/1` +- **Sample:** GET `/customers/1` ```json { "customer_data": { @@ -204,7 +204,7 @@ See below for the available endpoints for this API. - `offset` must be an integer >= 0. - Returns an object with a `customers` property containing an array of customer objects. - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET `/customers/name/2/2` +- **Sample:** GET `/customers/name/2/2` ```json { "customers": [{ @@ -239,7 +239,7 @@ See below for the available endpoints for this API. - Retrieves a list of all movies. - Returns an object with a `movies` property containing an array of movie objects. - Each movie object contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. -- Sample: GET `/movies` +- **Sample:** GET `/movies` ```json { "movies": [{ @@ -290,7 +290,7 @@ See below for the available endpoints for this API. - Each customer object contains `customer_data` and `dates`. - `dates` contains `checkout_date`. - `customer_data` contains: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET `/movies/The Guns of Navarone/name` +- **Sample:** GET `/movies/The Guns of Navarone/name` ```json { "movie_data": { @@ -355,7 +355,7 @@ See below for the available endpoints for this API. - `offset` must be an integer >= 0. - Returns an object with a `movies` property containing an array of movie objects. - Each movie object contains the following properties: `id`, `title`, `overview`, `release_date`, and `inventory`. -- Sample: GET `/movies/title/2/2` +- **Sample:** GET `/movies/title/2/2` ```json { "movies": [{ @@ -381,7 +381,7 @@ See below for the available endpoints for this API. - Retrieves a list of all customers with overdue rentals. - Returns an object with an `overdue_customers` property that contains a list of customer objects. - Each customer object contains the following properties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET `/rentals/overdue` +- **Sample:** GET `/rentals/overdue` ```json { @@ -437,7 +437,7 @@ See below for the available endpoints for this API. - `availability` contains: `available` (boolean) and `copies_available` (integer). - `current_renters` is a list of customers who are currently renting the movie. - Each customer object contains the following propeties: `id`, `name`, `registered_at` (date of registration), `address`, `city`, `state`, `postal_code`, `phone`, and `account_credit` (in cents). -- Sample: GET `/rentals/jaws` +- **Sample:** GET `/rentals/jaws` ```json { @@ -475,7 +475,7 @@ See below for the available endpoints for this API. - Charges the customer's account credit $1.00 (decrements by `100`). - Returns an object with a `success` property. - `success` contains the message: `"Yay! You checked out " + movie_title"` -- Sample: POST `/rentals/checkout/1/Jaws` +- **Sample:** POST `/rentals/checkout/1/Jaws` ```json { "success": "Yay! You checked out Jaws" @@ -488,7 +488,7 @@ See below for the available endpoints for this API. - `returned_date` is set to the current day. - Returns an object with a `success` property. - `success` contains the message: `"Congratulations, you have checked in: " + movie_title` -- SAMPLE: PUT `/rentals/checkin/1/jaws` +- **Sample:** PUT `/rentals/checkin/1/jaws` ```json { "success": "Congratulations, you have checked in: jaws" From 18bdb80d5ebdcbc1c5621526c7fddbe716218549 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 25 Sep 2015 11:53:39 -0700 Subject: [PATCH 183/189] edited error message for sorting --- db/test.db | Bin 4096 -> 4096 bytes routes/movies.js | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/db/test.db b/db/test.db index 21a7d8af858b0aeae1ab08146083b84db383effb..2ff026541f1925b35268a269f1b2bcf5ad92578b 100644 GIT binary patch delta 44 vcmZorXi%6S&6qq<#+fmBW5NqQF>@nBLjx02Jp)4%6Js-DO9*#z9RDH!65b2I delta 44 vcmZorXi%6S%_ufe#+gxUW5NqQF*6GzOLHR&Jp)4%6Js-D3kY{|9RDH!0K*GX diff --git a/routes/movies.js b/routes/movies.js index 0aa2114..35a6c96 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -87,7 +87,7 @@ router.get('/:title/:order', function(req, res, next) { return a.dates.checkout_date - b.dates.checkout_date; }); } else { - var error_message = "You cannot sort by: " + order; + var error_message = { error: "You cannot sort by: " + order } } movieObject.customers.pastRenters = pastRentersArray; From eb7a8e7cf7de0bac3f393a27ac3f7db53d5342f5 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 25 Sep 2015 11:54:21 -0700 Subject: [PATCH 184/189] edited error message for no results --- routes/customers.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/customers.js b/routes/customers.js index b20a07f..b9fd074 100644 --- a/routes/customers.js +++ b/routes/customers.js @@ -94,7 +94,7 @@ router.get('/:sort_by/:limit/:offset', function(req, res, next) { if (rows) { return res.status(200).json({ customers: rows} ); } else { - return res.status(400).json({ error: "Not found" }); + return res.status(400).json({ error: "No results found or your parameters are inaccurate. Try again." }); } }); }); From 583bbbfdf051c726170d6b24c80d4f9cdae7c270 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:55:26 -0700 Subject: [PATCH 185/189] fixing casing on json responses in tests --- db/test.db | Bin 4096 -> 4096 bytes test/routes/customers.js | 10 +++++----- test/routes/movies.js | 4 ++-- test/routes/rentals.js | 8 ++++---- 4 files changed, 11 insertions(+), 11 deletions(-) diff --git a/db/test.db b/db/test.db index 79f67d6ed6e3f1a82e9fa441afb96e77649636b0..647fe98cf640002d3127f13ceca58e853769cbbe 100644 GIT binary patch delta 48 ycmZorXi%6S#l*W~qKp%e+?eo;Pr}H++}P02(7;g7z|h3R*v!}x!krw)zX$+H?hM)h delta 48 ycmZorXi%6S#l+(_QN{^KZcKQ_Ct+x5Zft03Xk@NuU}$1uY-VH$;ZBa@UjzUu!3+}s diff --git a/test/routes/customers.js b/test/routes/customers.js index 1e4e4c4..521167a 100644 --- a/test/routes/customers.js +++ b/test/routes/customers.js @@ -133,7 +133,7 @@ describe("customers routes", function() { agent.get('/customers/1').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - var currentRentals = response.body.movies.currentRentals; + var currentRentals = response.body.movies.current_rentals; var movie = currentRentals[0]; assert.equal(currentRentals.length, 1); @@ -149,7 +149,7 @@ describe("customers routes", function() { agent.get('/customers/1').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - var pastRentals = response.body.movies.pastRentals; + var pastRentals = response.body.movies.past_rentals; var movie = pastRentals[0].movie_data; assert.equal(pastRentals.length, 2); @@ -165,8 +165,8 @@ describe("customers routes", function() { agent.get('/customers/1').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - var pastRental1 = response.body.movies.pastRentals[0].movie_data; - var pastRental2 = response.body.movies.pastRentals[1].movie_data; + var pastRental1 = response.body.movies.past_rentals[0].movie_data; + var pastRental2 = response.body.movies.past_rentals[1].movie_data; assert.equal(pastRental1.title, "I Want to Believe"); assert.equal(pastRental2.title, "Fight the Future"); @@ -178,7 +178,7 @@ describe("customers routes", function() { agent.get('/customers/1').set('Accept', 'application/json') .expect('Content-Type', /application\/json/) .expect(200, function(error, response) { - var pastRentals = response.body.movies.pastRentals; + var pastRentals = response.body.movies.past_rentals; var movie1ReturnDate = pastRentals[0].dates.returned_date; var movie2ReturnDate = pastRentals[1].dates.returned_date; diff --git a/test/routes/movies.js b/test/routes/movies.js index b145236..6ae3c0b 100644 --- a/test/routes/movies.js +++ b/test/routes/movies.js @@ -122,7 +122,7 @@ describe("movies routes", function() { it("returns a currentRenters object with a list of current renters", function(done) { agent.get('/movies/Fight the Future/id').set('Accept', 'application/json') .expect(200, function(error, response) { - var currentRenters = response.body.customers.currentRenters; + var currentRenters = response.body.customers.current_renters; assert(currentRenters[0].name, 'Fox Mulder'); done(); @@ -132,7 +132,7 @@ describe("movies routes", function() { it("returns a pastRenters object with a list of past renters sorted by the order variable", function(done) { agent.get('/movies/Fight the Future/id').set('Accept', 'application/json') .expect(200, function(error, response) { - var pastRenters = response.body.customers.pastRenters; + var pastRenters = response.body.customers.past_renters; assert(pastRenters[0].customer_data.name, 'Alex Krychek'); done(); diff --git a/test/routes/rentals.js b/test/routes/rentals.js index cd398e2..767f787 100644 --- a/test/routes/rentals.js +++ b/test/routes/rentals.js @@ -114,7 +114,7 @@ describe("rentals routes", function() { agent.get('/rentals/Fight the Future').set('Accept', 'application/json') .expect(200, function(error, response) { assert.equal(response.body.availability.available, true); - assert.equal(response.body.availability.copiesAvailable, 1); + assert.equal(response.body.availability.copies_available, 1); done(); }); }); @@ -122,8 +122,8 @@ describe("rentals routes", function() { it("returns a list of customers who have currently rented the movie", function(done) { agent.get('/rentals/Fight the Future').set('Accept', 'application/json') .expect(200, function(error, response) { - assert(response.body.currentRenters instanceof Object); - assert.equal(response.body.currentRenters[0].name, "Fox Mulder"); + assert(response.body.current_renters instanceof Object); + assert.equal(response.body.current_renters[0].name, "Fox Mulder"); done(); }); }); @@ -142,7 +142,7 @@ describe("rentals routes", function() { it("returns a message that you checked in that movie", function(done) { agent.put('/rentals/checkin/2/Fight the Future').set('Accept', 'application/json') .expect(200, function(error, response) { - assert.equal(response.body, "Congratulations, you have checked in: Fight the Future"); + assert.equal(response.body.success, "Congratulations, you have checked in: Fight the Future"); done(); }); }); From 1db3d199176cdfbcf7e3056cc52877c91a4ce219 Mon Sep 17 00:00:00 2001 From: Anita Date: Fri, 25 Sep 2015 11:57:10 -0700 Subject: [PATCH 186/189] more editing of messages --- routes/movies.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/routes/movies.js b/routes/movies.js index 35a6c96..e01d56a 100644 --- a/routes/movies.js +++ b/routes/movies.js @@ -87,7 +87,7 @@ router.get('/:title/:order', function(req, res, next) { return a.dates.checkout_date - b.dates.checkout_date; }); } else { - var error_message = { error: "You cannot sort by: " + order } + var error_message = { error: "You cannot sort by " + order } } movieObject.customers.pastRenters = pastRentersArray; From d6dde62ee57cb4cc2e44ab29b0fafbcd5674ca85 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:59:14 -0700 Subject: [PATCH 187/189] added instructions to our README.md --- README.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/README.md b/README.md index e3012ac..8cb6175 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,14 @@ Alice & Anita # Project: VideoStoreAPI +###How to run +1. Clone the repo. +2. Install all packages by running `npm install`. +3. Set up the development.db by running `npm run db:setup`. +4. Set up the test.db by running `DB=test npm run db:schema`. +5. See tests by running `npm test`. +6. See instructions for using our endpoints [here](./endpoint-readme.md). + 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. From 952498b41b56dbe61db5a2f2ce9107b4771f46f4 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 11:59:55 -0700 Subject: [PATCH 188/189] added line to separate instructions from specs --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 8cb6175..c632643 100644 --- a/README.md +++ b/README.md @@ -10,6 +10,8 @@ Alice & Anita 5. See tests by running `npm test`. 6. See instructions for using our endpoints [here](./endpoint-readme.md). +------------- + 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. From de66489629ee875648a0b84d70515f2c9dcb7cf4 Mon Sep 17 00:00:00 2001 From: Alice Rhomieux Date: Fri, 25 Sep 2015 13:29:06 -0700 Subject: [PATCH 189/189] fixed instructions --- README.md | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index c632643..3200f8a 100644 --- a/README.md +++ b/README.md @@ -5,10 +5,8 @@ Alice & Anita ###How to run 1. Clone the repo. 2. Install all packages by running `npm install`. -3. Set up the development.db by running `npm run db:setup`. -4. Set up the test.db by running `DB=test npm run db:schema`. -5. See tests by running `npm test`. -6. See instructions for using our endpoints [here](./endpoint-readme.md). +3. See tests by running `npm test`. +4. See instructions for using our endpoints [here](./endpoint-readme.md). -------------