From b15b00d827b81cdf601006044e825a68b7fbf9d7 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 13:51:21 -0800 Subject: [PATCH 01/53] initial setup --- .gitignore | 16 + Gemfile | 53 +++ Gemfile.lock | 170 ++++++++++ README.md | 303 +----------------- Rakefile | 6 + app/channels/application_cable/channel.rb | 4 + app/channels/application_cable/connection.rb | 4 + app/controllers/application_controller.rb | 2 + app/controllers/concerns/.keep | 0 app/jobs/application_job.rb | 2 + app/mailers/application_mailer.rb | 4 + app/models/application_record.rb | 3 + app/models/concerns/.keep | 0 app/views/layouts/mailer.html.erb | 13 + app/views/layouts/mailer.text.erb | 1 + bin/bundle | 3 + bin/rails | 9 + bin/rake | 9 + bin/setup | 35 ++ bin/spring | 17 + bin/update | 29 ++ config.ru | 5 + config/application.rb | 40 +++ config/boot.rb | 3 + config/cable.yml | 10 + config/database.yml | 85 +++++ config/environment.rb | 5 + config/environments/development.rb | 47 +++ config/environments/production.rb | 83 +++++ config/environments/test.rb | 42 +++ .../application_controller_renderer.rb | 8 + config/initializers/backtrace_silencers.rb | 7 + config/initializers/cors.rb | 16 + .../initializers/filter_parameter_logging.rb | 4 + config/initializers/inflections.rb | 16 + config/initializers/mime_types.rb | 4 + config/initializers/wrap_parameters.rb | 14 + config/locales/en.yml | 33 ++ config/puma.rb | 56 ++++ config/routes.rb | 3 + config/secrets.yml | 32 ++ config/spring.rb | 6 + db/schema.rb | 18 ++ db/seeds.rb | 14 +- lib/tasks/.keep | 0 log/.keep | 0 public/robots.txt | 1 + test/controllers/.keep | 0 test/fixtures/.keep | 0 test/fixtures/files/.keep | 0 test/integration/.keep | 0 test/mailers/.keep | 0 test/models/.keep | 0 test/test_helper.rb | 26 ++ tmp/.keep | 0 vendor/.keep | 0 56 files changed, 964 insertions(+), 297 deletions(-) create mode 100644 .gitignore create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Rakefile create mode 100644 app/channels/application_cable/channel.rb create mode 100644 app/channels/application_cable/connection.rb create mode 100644 app/controllers/application_controller.rb create mode 100644 app/controllers/concerns/.keep create mode 100644 app/jobs/application_job.rb create mode 100644 app/mailers/application_mailer.rb create mode 100644 app/models/application_record.rb create mode 100644 app/models/concerns/.keep create mode 100644 app/views/layouts/mailer.html.erb create mode 100644 app/views/layouts/mailer.text.erb create mode 100755 bin/bundle create mode 100755 bin/rails create mode 100755 bin/rake create mode 100755 bin/setup create mode 100755 bin/spring create mode 100755 bin/update create mode 100644 config.ru create mode 100644 config/application.rb create mode 100644 config/boot.rb create mode 100644 config/cable.yml create mode 100644 config/database.yml create mode 100644 config/environment.rb create mode 100644 config/environments/development.rb create mode 100644 config/environments/production.rb create mode 100644 config/environments/test.rb create mode 100644 config/initializers/application_controller_renderer.rb create mode 100644 config/initializers/backtrace_silencers.rb create mode 100644 config/initializers/cors.rb create mode 100644 config/initializers/filter_parameter_logging.rb create mode 100644 config/initializers/inflections.rb create mode 100644 config/initializers/mime_types.rb create mode 100644 config/initializers/wrap_parameters.rb create mode 100644 config/locales/en.yml create mode 100644 config/puma.rb create mode 100644 config/routes.rb create mode 100644 config/secrets.yml create mode 100644 config/spring.rb create mode 100644 db/schema.rb create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 public/robots.txt create mode 100644 test/controllers/.keep create mode 100644 test/fixtures/.keep create mode 100644 test/fixtures/files/.keep create mode 100644 test/integration/.keep create mode 100644 test/mailers/.keep create mode 100644 test/models/.keep create mode 100644 test/test_helper.rb create mode 100644 tmp/.keep create mode 100644 vendor/.keep diff --git a/.gitignore b/.gitignore new file mode 100644 index 000000000..68ac019ec --- /dev/null +++ b/.gitignore @@ -0,0 +1,16 @@ +# See https://help.github.com/articles/ignoring-files for more about ignoring files. +# +# If you find yourself ignoring temporary files generated by your text editor +# or operating system, you probably want to add a global ignore instead: +# git config --global core.excludesfile '~/.gitignore_global' + +# Ignore bundler config. +/.bundle + +# Ignore all logfiles and tempfiles. +/log/* +/tmp/* +!/log/.keep +!/tmp/.keep + +.byebug_history diff --git a/Gemfile b/Gemfile new file mode 100644 index 000000000..4ae55c93d --- /dev/null +++ b/Gemfile @@ -0,0 +1,53 @@ +source 'https://rubygems.org' + +git_source(:github) do |repo_name| + repo_name = "#{repo_name}/#{repo_name}" unless repo_name.include?("/") + "https://github.com/#{repo_name}.git" +end + + +# Bundle edge Rails instead: gem 'rails', github: 'rails/rails' +gem 'rails', '~> 5.1.4' +# Use postgresql as the database for Active Record +gem 'pg', '~> 0.18' +# Use Puma as the app server +gem 'puma', '~> 3.7' +# Build JSON APIs with ease. Read more: https://github.com/rails/jbuilder +# gem 'jbuilder', '~> 2.5' +# Use Redis adapter to run Action Cable in production +# gem 'redis', '~> 3.0' +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +# Use Rack CORS for handling Cross-Origin Resource Sharing (CORS), making cross-origin AJAX possible +# gem 'rack-cors' + +group :development, :test do + # Call 'byebug' anywhere in the code to stop execution and get a debugger console + gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] +end + +group :development do + gem 'listen', '>= 3.0.5', '< 3.2' + # Spring speeds up development by keeping your application running in the background. Read more: https://github.com/rails/spring + gem 'spring' + gem 'spring-watcher-listen', '~> 2.0.0' +end + +# Windows does not include zoneinfo files, so bundle the tzinfo-data gem +gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] + +gem 'jquery-turbolinks' +group :development do + gem 'better_errors' + gem 'pry-rails' + gem 'binding_of_caller' +end + +group :test do + gem 'minitest-rails' + gem 'minitest-reporters' +end diff --git a/Gemfile.lock b/Gemfile.lock new file mode 100644 index 000000000..ae9937c72 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,170 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.1.4) + actionpack (= 5.1.4) + nio4r (~> 2.0) + websocket-driver (~> 0.6.1) + actionmailer (5.1.4) + actionpack (= 5.1.4) + actionview (= 5.1.4) + activejob (= 5.1.4) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.1.4) + actionview (= 5.1.4) + activesupport (= 5.1.4) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.1.4) + activesupport (= 5.1.4) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.1.4) + activesupport (= 5.1.4) + globalid (>= 0.3.6) + activemodel (5.1.4) + activesupport (= 5.1.4) + activerecord (5.1.4) + activemodel (= 5.1.4) + activesupport (= 5.1.4) + arel (~> 8.0) + activesupport (5.1.4) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (~> 0.7) + minitest (~> 5.1) + tzinfo (~> 1.1) + ansi (1.5.0) + arel (8.0.0) + better_errors (2.4.0) + coderay (>= 1.0.0) + erubi (>= 1.0.0) + rack (>= 0.9.0) + binding_of_caller (0.7.3) + debug_inspector (>= 0.0.1) + builder (3.2.3) + byebug (9.1.0) + coderay (1.1.2) + concurrent-ruby (1.0.5) + crass (1.0.2) + debug_inspector (0.0.3) + erubi (1.7.0) + ffi (1.9.18) + globalid (0.4.1) + activesupport (>= 4.2.0) + i18n (0.9.1) + concurrent-ruby (~> 1.0) + jquery-turbolinks (2.1.0) + railties (>= 3.1.0) + turbolinks + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + loofah (2.1.1) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.0) + mini_mime (>= 0.1.1) + method_source (0.9.0) + mini_mime (0.1.4) + mini_portile2 (2.3.0) + minitest (5.10.3) + minitest-rails (3.0.0) + minitest (~> 5.8) + railties (~> 5.0) + minitest-reporters (1.1.18) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + nio4r (2.1.0) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) + pg (0.21.0) + pry (0.11.2) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-rails (0.3.6) + pry (>= 0.10.4) + puma (3.10.0) + rack (2.0.3) + rack-test (0.7.0) + rack (>= 1.0, < 3) + rails (5.1.4) + actioncable (= 5.1.4) + actionmailer (= 5.1.4) + actionpack (= 5.1.4) + actionview (= 5.1.4) + activejob (= 5.1.4) + activemodel (= 5.1.4) + activerecord (= 5.1.4) + activesupport (= 5.1.4) + bundler (>= 1.3.0) + railties (= 5.1.4) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.3) + loofah (~> 2.0) + railties (5.1.4) + actionpack (= 5.1.4) + activesupport (= 5.1.4) + method_source + rake (>= 0.8.7) + thor (>= 0.18.1, < 2.0) + rake (12.2.1) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + ruby-progressbar (1.9.0) + ruby_dep (1.5.0) + spring (2.0.2) + activesupport (>= 4.2) + spring-watcher-listen (2.0.1) + listen (>= 2.7, < 4.0) + spring (>= 1.2, < 3.0) + sprockets (3.7.1) + concurrent-ruby (~> 1.0) + rack (> 1, < 3) + sprockets-rails (3.2.1) + actionpack (>= 4.0) + activesupport (>= 4.0) + sprockets (>= 3.0.0) + thor (0.20.0) + thread_safe (0.3.6) + turbolinks (5.0.1) + turbolinks-source (~> 5) + turbolinks-source (5.0.3) + tzinfo (1.2.4) + thread_safe (~> 0.1) + websocket-driver (0.6.5) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.2) + +PLATFORMS + ruby + +DEPENDENCIES + better_errors + binding_of_caller + byebug + jquery-turbolinks + listen (>= 3.0.5, < 3.2) + minitest-rails + minitest-reporters + pg (~> 0.18) + pry-rails + puma (~> 3.7) + rails (~> 5.1.4) + spring + spring-watcher-listen (~> 2.0.0) + tzinfo-data + +BUNDLED WITH + 1.16.0 diff --git a/README.md b/README.md index e47ff3004..7db80e4ca 100644 --- a/README.md +++ b/README.md @@ -1,301 +1,24 @@ -# Project: VideoStoreAPI -The 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 list of customers. +# README -We will use Rails to construct a RESTful API. The purpose 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. +This README would normally document whatever steps are necessary to get the +application up and running. -This is a pair project. You and your partner should use all the techniques we've learned so far to keep yourselves organized and on track, and ensure that no requirements slip through the cracks. +Things you may want to cover: -## Learning Goals -Upon completing this project, students should be able to: +* Ruby version -- Build an ERD and set up ActiveRecord models for a given dataset / use-case -- Expose database contents through a web API -- Respond reasonably to bad user data in the context of an API -- Verify the correctness of an API using controller tests +* System dependencies -This is a [stage 2](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/rule-of-three.md) project. +* Configuration -## Success Criteria -Your project will be evaluated against the following requirements: +* Database creation -- API conformance - - The provided smoke tests should pass (see the subfolder) - - Bad data sent to the API should result in an appropriate status code and helpful error -- Test coverage - - Models: All relations, validations, and custom model methods should include at least one positive and one negative test case - - Controllers: Every API endpoint should include at least one positive and one negative test case -- Style and Organization - - Business logic should be live in models +* Database initialization -## Project Baseline -- Read the API Requirements below and create a pseudo-code "routes" file that specifies - - The _endpoints_ your API will need - - The _HTTP verbs_ each endpoint will use - - Any data that must be provided to the endpoint in order for it to do its work -- Read the Seed Data description below and, bearing in mind the API Requirements, create an ERD for your database that specifies - - The _models_ your database will require - - The _attributes_ for each model - - Any _relationships_ between models -- Create a new Rails app to serve as the API - - **Create the rails app with:** `$ rails new . --api` -- Create a route that responds to `/zomg` that serves a json-encoded "it works!" +* How to run the test suite -## Wave 1: Database Models, Tables, & Seeds -- Generate Rails models and associations to match your ERD -- Use the provided seed script `db/seeds.rb` to import the provided JSON data into your database +* Services (job queues, cache servers, search engines, etc.) -In the past, many students have spent lots of time writing and testing validations for these models. Because project time is limited and validations are not an important learning objective this week, we do not recommend this. Instead, validate only those fields that, if they are absent, will break your API. +* Deployment instructions -### Seed Data -`movies.json` contains information about the videos available to rent at the store. The data is presented as an array of objects, with each object having the following key-value pairs: - -| Field | Datatype | Description -|----------------|----------|------------ -| `title` | string | The title of the film -| `overview` | string | A short plot synopsis -| `release_date` | string | `YYYY-MM-DD`, Day the film was originally released -| `inventory` | integer | How many copies of the film the video store owns - -`customers.json` contains information about the customers that have rented with the store in the past. The data is presented as, you guessed it, an array of objects, with each object have the following key-value pairs: - -| Field | Datatype | Description -|------------------|----------|------------ -| `name` | string | The customer's name -| `registered_at` | string | `Wed, 29 Apr 2015 07:54:14 -0700`, When the customer first visited the store -| `address` | string | Street address -| `city` | string |   -| `state` | string |   -| `postal_code` | string |   -| `phone` | string | Primary contact phone number - -### Testing -As with all Rails projects, model testing is a requirement. You should have _at least_ one positive and one negative test case for each relation, validation, and custom function you add to your models. - -Use good TDD practices, and test _before_ you code. Remember: red-green-refactor. - -## Waves 2 Coding The API -In this wave, you will implement the API described below. The endpoints are described more-or-less in order of complexity, and we recommend you build them in that order. Every endpoint must serve JSON data, and must use HTTP response codes to indicate the status of the request. - -The schema of your database and the structure of your rails app are completely up to you, so long as the API conforms to the description and provided script. - -### Error Handling -If something goes wrong, your API should return an appropriate [HTTP status code](http://billpatrianakos.me/blog/2013/10/13/list-of-rails-status-code-symbols/), as well as a list of errors. The list should be formatted like this: - -```json -{ - "errors": { - "title": ["Movie 'Revenge of the Gnomes' not found"] - } -} -``` - -All errors your API can return should be covered by at least one test case. - -### Testing -Because APIs are often open to the public, thorough testing is essential. For a Rails API, that means controller testing. - -For each API endpoint, you should have _at least_: -- A basic test with no parameters, if applicable -- Positive and negative tests for any URI parameters (user ID, movie title) -- Testing around any data in the request body - -Use good TDD practices, and test _before_ you code. Remember: red-green-refactor. - -#### Smoke Tests -Because this API will be used as the backend for a future project, there are strict requirements about how it should be structured. To this end, we have provided a set of [smoke tests](http://softwaretestingfundamentals.com/smoke-testing/) written in Postman to exercise all the endpoints. - -The smoke tests will verify that your API looks correct to the outside world, by sending actual HTTP requests to your running server and checking the results. They test things like: - -- Did I get a success response for a valid request? -- Did the API return JSON? -- Does the JSON contain the expected property names? - -**The smoke tests are not a substitute for writing your own tests!!!!!** They do **not** check that the content is _correct_, nor do they cover any negative or edge cases. Verifying correctness in these cases is **your** responsibility. - -The smoke tests live in the file [`test/VideoStoreAPI_smoke_tests.postman_collection.json`](test/VideoStoreAPI_smoke_tests.postman_collection.json). To run them: - -1. Open Postman -1. Click `Import` in the top left -1. Drag-and-drop the file into the box -1. In the left sidebar, click on the `Collections` tab -1. There should now be an entry for the smoke tests. Hover over it and click the `>` icon for a detail view. You will notice they are in the format `{{url}}/movies`. `{{url}}` is a key which you can give a value on your computer. -1. To do so go to the Gearbox in the top-right and select `Manage Environments` -![Manage Environments](images/manage-environment.png) -1. Then Select `Add` -![add button](images/add-btn.png) -1. Lastly add a key `url` and value `http://localhost:3000` -![Key & Value](images/key-value.png) -1. Click the blue `Run` button. This will launch the collection runner. -1. In the collection runner, scroll down in the center pane and click the blue `Start Test` button - -## API Description - -#### `GET /customers` -List all customers - -Fields to return: -- `id` -- `name` -- `registered_at` -- `postal_code` -- `phone` -- `movies_checked_out_count` - - This will be 0 unless you've completed optional requirements - -#### `GET /movies` -List all movies - -Fields to return: -- `id` -- `title` -- `release_date` - -#### `GET /movies/:id` -Look a movie up by `id` - -URI parameters: -- `id`: Movie identifier - -Fields to return: -- `title` -- `overview` -- `release_date` -- `inventory` (total) -- `available_inventory` (not currently checked-out to a customer) - - This will be the same as `inventory` unless you've completed the optional endpoints. - -#### `POST /movies` -Create a new movie in the video store inventory. - -Upon success, this request should return the `id` of the movie created. - -Request body: - -| Field | Datatype | Description -|---------------|---------------------|------------ -| `title` | string | Title of the movie -| `overview` | string | Descriptive summary of the movie -| `release_date` | string `YYYY-MM-DD` | Date the movie was released -| `inventory` | integer | Quantity available in the video store - -### Optional Rentals - -Wave 2 focused on working with customers and movies. With these endpoints you can extend the functionality of your API to allow managing the rental process. - -#### `POST /rentals/check-out` -Check out one of the movie's inventory to the customer. The rental's check-out date should be set to today. - -**Note:** Some of the fields from wave 2 should now have interesting values. Good thing you wrote tests for them, right... right? - -Request body: - -| Field | Datatype | Description -|---------------|---------------------|------------ -| `customer_id` | integer | ID of the customer checking out this film -| `movie_id` | integer | ID of the movie to be checked out -| `due_date` | string `YYYY-MM-DD` | When should this movie be checked back in? - -#### `POST /rentals/check-in` -Check in one of a customer's rentals - -Request body: - -| Field | Datatype | Description -|---------------|----------|------------ -| `customer_id` | integer | ID of the customer checking in this film -| `movie_id` | integer | ID of the movie to be checked in - -#### `GET /rentals/overdue` -List all customers with overdue movies - -Fields to return: -- `title` -- `customer_id` -- `name` -- `postal_code` -- `checkout_date` -- `due_date` - -## Going Further -These really are **optional** - if you've gotten here and you have time left, that means you're moving speedy fast! - -### Query Parameters -Any endpoint that returns a list should accept 3 _optional_ [query parameters](http://guides.rubyonrails.org/action_controller_overview.html#parameters): - -| Name | Value | Description -|--------|---------|------------ -| `sort` | string | Sort objects by this field, in ascending order -| `n` | integer | Number of responses to return per page -| `p` | integer | Page of responses to return - -So, for an API endpoint like `GET /customers`, the following requests should be valid: -- `GET /customers`: All customers, sorted by ID -- `GET /customers?sort=name`: All customers, sorted by name -- `GET /customers?n=10&p=2`: Customers 10-19, sorted by ID -- `GET /customers?sort=name&n=10&p=2`: Customers 10-19, sorted by name - -Of course, adding new features means you should be adding new controller tests to verify them. - -Things to note: -- Sorting by ID is the rails default -- Possible sort fields: - - Customers can be sorted by `name`, `registered_at` and `postal_code` - - Movies can be sorted by `title` and `release_date` - - Overdue rentals can be sorted by `title`, `name`, `checkout_date` and `due_date` -- If the client requests both sorting and pagination, pagination should be relative to the sorted order -- Check out the [will_paginate gem](https://github.com/mislav/will_paginate) - -### More Endpoints: Inventory Management -All these endpoints should support all 3 query parameters. All fields are sortable. - -#### `GET /movies/:id/current` -List customers that have _currently_ checked out a copy of the film - -URI parameters: -- `id`: Movie identifier - -Fields to return: -- `customer_id` -- `name` -- `postal_code` -- `checkout_date` -- `due_date` - -#### `GET /movies/:id/history` -List customers that have checked out a copy of the film _in the past_ - -URI parameters: -- `id`: Movie identifier - -Fields to return: -- `customer_id` -- `name` -- `postal_code` -- `checkout_date` -- `due_date` - -#### `GET /customers/:id/current` -List the movies a customer _currently_ has checked out - -URI parameters: -- `id`: Customer ID - -Fields to return: -- `title` -- `checkout_date` -- `due_date` - -#### `GET /customers/:id/history` -List the movies a customer has checked out _in the past_ - -URI parameters: -- `id`: Customer ID - -Fields to return: -- `title` -- `checkout_date` -- `due_date` - - -# Reference -- [Postman on Environments](https://www.getpostman.com/docs/environments) +* ... diff --git a/Rakefile b/Rakefile new file mode 100644 index 000000000..e85f91391 --- /dev/null +++ b/Rakefile @@ -0,0 +1,6 @@ +# Add your own tasks in files placed in lib/tasks ending in .rake, +# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. + +require_relative 'config/application' + +Rails.application.load_tasks diff --git a/app/channels/application_cable/channel.rb b/app/channels/application_cable/channel.rb new file mode 100644 index 000000000..d67269728 --- /dev/null +++ b/app/channels/application_cable/channel.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Channel < ActionCable::Channel::Base + end +end diff --git a/app/channels/application_cable/connection.rb b/app/channels/application_cable/connection.rb new file mode 100644 index 000000000..0ff5442f4 --- /dev/null +++ b/app/channels/application_cable/connection.rb @@ -0,0 +1,4 @@ +module ApplicationCable + class Connection < ActionCable::Connection::Base + end +end diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb new file mode 100644 index 000000000..4ac8823b0 --- /dev/null +++ b/app/controllers/application_controller.rb @@ -0,0 +1,2 @@ +class ApplicationController < ActionController::API +end diff --git a/app/controllers/concerns/.keep b/app/controllers/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/jobs/application_job.rb b/app/jobs/application_job.rb new file mode 100644 index 000000000..a009ace51 --- /dev/null +++ b/app/jobs/application_job.rb @@ -0,0 +1,2 @@ +class ApplicationJob < ActiveJob::Base +end diff --git a/app/mailers/application_mailer.rb b/app/mailers/application_mailer.rb new file mode 100644 index 000000000..286b2239d --- /dev/null +++ b/app/mailers/application_mailer.rb @@ -0,0 +1,4 @@ +class ApplicationMailer < ActionMailer::Base + default from: 'from@example.com' + layout 'mailer' +end diff --git a/app/models/application_record.rb b/app/models/application_record.rb new file mode 100644 index 000000000..10a4cba84 --- /dev/null +++ b/app/models/application_record.rb @@ -0,0 +1,3 @@ +class ApplicationRecord < ActiveRecord::Base + self.abstract_class = true +end diff --git a/app/models/concerns/.keep b/app/models/concerns/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/app/views/layouts/mailer.html.erb b/app/views/layouts/mailer.html.erb new file mode 100644 index 000000000..cbd34d2e9 --- /dev/null +++ b/app/views/layouts/mailer.html.erb @@ -0,0 +1,13 @@ + + + + + + + + + <%= yield %> + + diff --git a/app/views/layouts/mailer.text.erb b/app/views/layouts/mailer.text.erb new file mode 100644 index 000000000..37f0bddbd --- /dev/null +++ b/app/views/layouts/mailer.text.erb @@ -0,0 +1 @@ +<%= yield %> diff --git a/bin/bundle b/bin/bundle new file mode 100755 index 000000000..66e9889e8 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) +load Gem.bin_path('bundler', 'bundle') diff --git a/bin/rails b/bin/rails new file mode 100755 index 000000000..5badb2fde --- /dev/null +++ b/bin/rails @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +APP_PATH = File.expand_path('../config/application', __dir__) +require_relative '../config/boot' +require 'rails/commands' diff --git a/bin/rake b/bin/rake new file mode 100755 index 000000000..d87d5f578 --- /dev/null +++ b/bin/rake @@ -0,0 +1,9 @@ +#!/usr/bin/env ruby +begin + load File.expand_path('../spring', __FILE__) +rescue LoadError => e + raise unless e.message.include?('spring') +end +require_relative '../config/boot' +require 'rake' +Rake.application.run diff --git a/bin/setup b/bin/setup new file mode 100755 index 000000000..104e40c1c --- /dev/null +++ b/bin/setup @@ -0,0 +1,35 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a starting point to setup your application. + # Add necessary setup steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + + # puts "\n== Copying sample files ==" + # unless File.exist?('config/database.yml') + # cp 'config/database.yml.sample', 'config/database.yml' + # end + + puts "\n== Preparing database ==" + system! 'bin/rails db:setup' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/bin/spring b/bin/spring new file mode 100755 index 000000000..fb2ec2ebb --- /dev/null +++ b/bin/spring @@ -0,0 +1,17 @@ +#!/usr/bin/env ruby + +# This file loads spring without using Bundler, in order to be fast. +# It gets overwritten when you run the `spring binstub` command. + +unless defined?(Spring) + require 'rubygems' + require 'bundler' + + lockfile = Bundler::LockfileParser.new(Bundler.default_lockfile.read) + spring = lockfile.specs.detect { |spec| spec.name == "spring" } + if spring + Gem.use_paths Gem.dir, Bundler.bundle_path.to_s, *Gem.path + gem 'spring', spring.version + require 'spring/binstub' + end +end diff --git a/bin/update b/bin/update new file mode 100755 index 000000000..a8e4462f2 --- /dev/null +++ b/bin/update @@ -0,0 +1,29 @@ +#!/usr/bin/env ruby +require 'pathname' +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) + +def system!(*args) + system(*args) || abort("\n== Command #{args} failed ==") +end + +chdir APP_ROOT do + # This script is a way to update your development environment automatically. + # Add necessary update steps to this file. + + puts '== Installing dependencies ==' + system! 'gem install bundler --conservative' + system('bundle check') || system!('bundle install') + + puts "\n== Updating database ==" + system! 'bin/rails db:migrate' + + puts "\n== Removing old logs and tempfiles ==" + system! 'bin/rails log:clear tmp:clear' + + puts "\n== Restarting application server ==" + system! 'bin/rails restart' +end diff --git a/config.ru b/config.ru new file mode 100644 index 000000000..f7ba0b527 --- /dev/null +++ b/config.ru @@ -0,0 +1,5 @@ +# This file is used by Rack-based servers to start the application. + +require_relative 'config/environment' + +run Rails.application diff --git a/config/application.rb b/config/application.rb new file mode 100644 index 000000000..7d3c866ff --- /dev/null +++ b/config/application.rb @@ -0,0 +1,40 @@ +require_relative 'boot' + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "action_controller/railtie" +require "action_mailer/railtie" +require "action_view/railtie" +require "action_cable/engine" +# require "sprockets/railtie" +require "rails/test_unit/railtie" + +# Require the gems listed in Gemfile, including any gems +# you've limited to :test, :development, or :production. +Bundler.require(*Rails.groups) + +module VideoStoreAPI + class Application < Rails::Application + config.generators do |g| + # Force new test files to be generated in the minitest-spec style + g.test_framework :minitest, spec: true + + # Always use .js files, never .coffee + g.javascript_engine :js + end + # Initialize configuration defaults for originally generated Rails version. + config.load_defaults 5.1 + + # Settings in config/environments/* take precedence over those specified here. + # Application configuration should go into files in config/initializers + # -- all .rb files in that directory are automatically loaded. + + # Only loads a smaller set of middleware suitable for API only apps. + # Middleware like session, flash, cookies can be added back manually. + # Skip views, helpers and assets when generating a new resource. + config.api_only = true + end +end diff --git a/config/boot.rb b/config/boot.rb new file mode 100644 index 000000000..30f5120df --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,3 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..ad59bcd88 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: redis://localhost:6379/1 + channel_prefix: VideoStoreAPI_production diff --git a/config/database.yml b/config/database.yml new file mode 100644 index 000000000..720570700 --- /dev/null +++ b/config/database.yml @@ -0,0 +1,85 @@ +# PostgreSQL. Versions 9.1 and up are supported. +# +# Install the pg driver: +# gem install pg +# On OS X with Homebrew: +# gem install pg -- --with-pg-config=/usr/local/bin/pg_config +# On OS X with MacPorts: +# gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config +# On Windows: +# gem install pg +# Choose the win32 build. +# Install PostgreSQL and put its /bin directory on your path. +# +# Configure Using Gemfile +# gem 'pg' +# +default: &default + adapter: postgresql + encoding: unicode + # For details on connection pooling, see Rails configuration guide + # http://guides.rubyonrails.org/configuring.html#database-pooling + pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> + +development: + <<: *default + database: VideoStoreAPI_development + + # The specified database role being used to connect to postgres. + # To create additional roles in postgres see `$ createuser --help`. + # When left blank, postgres will use the default role. This is + # the same name as the operating system user that initialized the database. + #username: VideoStoreAPI + + # The password associated with the postgres role (username). + #password: + + # Connect on a TCP socket. Omitted by default since the client uses a + # domain socket that doesn't need configuration. Windows does not have + # domain sockets, so uncomment these lines. + #host: localhost + + # The TCP port the server listens on. Defaults to 5432. + # If your server runs on a different port number, change accordingly. + #port: 5432 + + # Schema search path. The server defaults to $user,public + #schema_search_path: myapp,sharedapp,public + + # Minimum log levels, in increasing order: + # debug5, debug4, debug3, debug2, debug1, + # log, notice, warning, error, fatal, and panic + # Defaults to warning. + #min_messages: notice + +# Warning: The database defined as "test" will be erased and +# re-generated from your development database when you run "rake". +# Do not set this db to the same as development or production. +test: + <<: *default + database: VideoStoreAPI_test + +# As with config/secrets.yml, you never want to store sensitive information, +# like your database password, in your source code. If your source code is +# ever seen by anyone, they now have access to your database. +# +# Instead, provide the password as a unix environment variable when you boot +# the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database +# for a full rundown on how to provide these environment variables in a +# production deployment. +# +# On Heroku and other platform providers, you may have a full connection URL +# available as an environment variable. For example: +# +# DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" +# +# You can use this database configuration with: +# +# production: +# url: <%= ENV['DATABASE_URL'] %> +# +production: + <<: *default + database: VideoStoreAPI_production + username: VideoStoreAPI + password: <%= ENV['VIDEOSTOREAPI_DATABASE_PASSWORD'] %> diff --git a/config/environment.rb b/config/environment.rb new file mode 100644 index 000000000..426333bb4 --- /dev/null +++ b/config/environment.rb @@ -0,0 +1,5 @@ +# Load the Rails application. +require_relative 'application' + +# Initialize the Rails application. +Rails.application.initialize! diff --git a/config/environments/development.rb b/config/environments/development.rb new file mode 100644 index 000000000..abc82221c --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,47 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # In the development environment your application's code is reloaded on + # every request. This slows down response time but is perfect for development + # since you don't have to restart the web server when you make code changes. + config.cache_classes = false + + # Do not eager load code on boot. + config.eager_load = false + + # Show full error reports. + config.consider_all_requests_local = true + + # Enable/disable caching. By default caching is disabled. + if Rails.root.join('tmp/caching-dev.txt').exist? + config.action_controller.perform_caching = true + + config.cache_store = :memory_store + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{2.days.seconds.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Don't care if the mailer can't send. + config.action_mailer.raise_delivery_errors = false + + config.action_mailer.perform_caching = false + + # Print deprecation notices to the Rails logger. + config.active_support.deprecation = :log + + # Raise an error on page load if there are pending migrations. + config.active_record.migration_error = :page_load + + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true + + # Use an evented file watcher to asynchronously detect changes in source code, + # routes, locales, etc. This feature depends on the listen gem. + config.file_watcher = ActiveSupport::EventedFileUpdateChecker +end diff --git a/config/environments/production.rb b/config/environments/production.rb new file mode 100644 index 000000000..3bd8115ea --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,83 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # Code is not reloaded between requests. + config.cache_classes = true + + # Eager load code on boot. This eager loads most of Rails and + # your application in memory, allowing both threaded web servers + # and those relying on copy on write to perform better. + # Rake tasks automatically ignore this option for performance. + config.eager_load = true + + # Full error reports are disabled and caching is turned on. + config.consider_all_requests_local = false + config.action_controller.perform_caching = true + + # Attempt to read encrypted secrets from `config/secrets.yml.enc`. + # Requires an encryption key in `ENV["RAILS_MASTER_KEY"]` or + # `config/secrets.yml.key`. + config.read_encrypted_secrets = true + + # Disable serving static files from the `/public` folder by default since + # Apache or NGINX already handles this. + config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present? + + + # Enable serving of images, stylesheets, and JavaScripts from an asset server. + # config.action_controller.asset_host = 'http://assets.example.com' + + # Specifies the header that your server uses for sending files. + # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache + # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX + + # Mount Action Cable outside main process or domain + # config.action_cable.mount_path = nil + # config.action_cable.url = 'wss://example.com/cable' + # config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ] + + # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. + # config.force_ssl = true + + # Use the lowest log level to ensure availability of diagnostic information + # when problems arise. + config.log_level = :debug + + # Prepend all log lines with the following tags. + config.log_tags = [ :request_id ] + + # Use a different cache store in production. + # config.cache_store = :mem_cache_store + + # Use a real queuing backend for Active Job (and separate queues per environment) + # config.active_job.queue_adapter = :resque + # config.active_job.queue_name_prefix = "VideoStoreAPI_#{Rails.env}" + config.action_mailer.perform_caching = false + + # Ignore bad email addresses and do not raise email delivery errors. + # Set this to true and configure the email server for immediate delivery to raise delivery errors. + # config.action_mailer.raise_delivery_errors = false + + # Enable locale fallbacks for I18n (makes lookups for any locale fall back to + # the I18n.default_locale when a translation cannot be found). + config.i18n.fallbacks = true + + # Send deprecation notices to registered listeners. + config.active_support.deprecation = :notify + + # Use default logging formatter so that PID and timestamp are not suppressed. + config.log_formatter = ::Logger::Formatter.new + + # Use a different logger for distributed setups. + # require 'syslog/logger' + # config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name') + + if ENV["RAILS_LOG_TO_STDOUT"].present? + logger = ActiveSupport::Logger.new(STDOUT) + logger.formatter = config.log_formatter + config.logger = ActiveSupport::TaggedLogging.new(logger) + end + + # Do not dump schema after migrations. + config.active_record.dump_schema_after_migration = false +end diff --git a/config/environments/test.rb b/config/environments/test.rb new file mode 100644 index 000000000..8e5cbde53 --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,42 @@ +Rails.application.configure do + # Settings specified here will take precedence over those in config/application.rb. + + # The test environment is used exclusively to run your application's + # test suite. You never need to work with it otherwise. Remember that + # your test database is "scratch space" for the test suite and is wiped + # and recreated between test runs. Don't rely on the data there! + config.cache_classes = true + + # Do not eager load code on boot. This avoids loading your whole application + # just for the purpose of running a single test. If you are using a tool that + # preloads Rails for running tests, you may have to set it to true. + config.eager_load = false + + # Configure public file server for tests with Cache-Control for performance. + config.public_file_server.enabled = true + config.public_file_server.headers = { + 'Cache-Control' => "public, max-age=#{1.hour.seconds.to_i}" + } + + # Show full error reports and disable caching. + config.consider_all_requests_local = true + config.action_controller.perform_caching = false + + # Raise exceptions instead of rendering exception templates. + config.action_dispatch.show_exceptions = false + + # Disable request forgery protection in test environment. + config.action_controller.allow_forgery_protection = false + config.action_mailer.perform_caching = false + + # Tell Action Mailer not to deliver emails to the real world. + # The :test delivery method accumulates sent emails in the + # ActionMailer::Base.deliveries array. + config.action_mailer.delivery_method = :test + + # Print deprecation notices to the stderr. + config.active_support.deprecation = :stderr + + # Raises error for missing translations + # config.action_view.raise_on_missing_translations = true +end diff --git a/config/initializers/application_controller_renderer.rb b/config/initializers/application_controller_renderer.rb new file mode 100644 index 000000000..89d2efab2 --- /dev/null +++ b/config/initializers/application_controller_renderer.rb @@ -0,0 +1,8 @@ +# Be sure to restart your server when you modify this file. + +# ActiveSupport::Reloader.to_prepare do +# ApplicationController.renderer.defaults.merge!( +# http_host: 'example.org', +# https: false +# ) +# end diff --git a/config/initializers/backtrace_silencers.rb b/config/initializers/backtrace_silencers.rb new file mode 100644 index 000000000..59385cdf3 --- /dev/null +++ b/config/initializers/backtrace_silencers.rb @@ -0,0 +1,7 @@ +# Be sure to restart your server when you modify this file. + +# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. +# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } + +# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. +# Rails.backtrace_cleaner.remove_silencers! diff --git a/config/initializers/cors.rb b/config/initializers/cors.rb new file mode 100644 index 000000000..3b1c1b5ed --- /dev/null +++ b/config/initializers/cors.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Avoid CORS issues when API is called from the frontend app. +# Handle Cross-Origin Resource Sharing (CORS) in order to accept cross-origin AJAX requests. + +# Read more: https://github.com/cyu/rack-cors + +# Rails.application.config.middleware.insert_before 0, Rack::Cors do +# allow do +# origins 'example.com' +# +# resource '*', +# headers: :any, +# methods: [:get, :post, :put, :patch, :delete, :options, :head] +# end +# end diff --git a/config/initializers/filter_parameter_logging.rb b/config/initializers/filter_parameter_logging.rb new file mode 100644 index 000000000..4a994e1e7 --- /dev/null +++ b/config/initializers/filter_parameter_logging.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Configure sensitive parameters which will be filtered from the log file. +Rails.application.config.filter_parameters += [:password] diff --git a/config/initializers/inflections.rb b/config/initializers/inflections.rb new file mode 100644 index 000000000..ac033bf9d --- /dev/null +++ b/config/initializers/inflections.rb @@ -0,0 +1,16 @@ +# Be sure to restart your server when you modify this file. + +# Add new inflection rules using the following format. Inflections +# are locale specific, and you may define rules for as many different +# locales as you wish. All of these examples are active by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.plural /^(ox)$/i, '\1en' +# inflect.singular /^(ox)en/i, '\1' +# inflect.irregular 'person', 'people' +# inflect.uncountable %w( fish sheep ) +# end + +# These inflection rules are supported but not enabled by default: +# ActiveSupport::Inflector.inflections(:en) do |inflect| +# inflect.acronym 'RESTful' +# end diff --git a/config/initializers/mime_types.rb b/config/initializers/mime_types.rb new file mode 100644 index 000000000..dc1899682 --- /dev/null +++ b/config/initializers/mime_types.rb @@ -0,0 +1,4 @@ +# Be sure to restart your server when you modify this file. + +# Add new mime types for use in respond_to blocks: +# Mime::Type.register "text/richtext", :rtf diff --git a/config/initializers/wrap_parameters.rb b/config/initializers/wrap_parameters.rb new file mode 100644 index 000000000..bbfc3961b --- /dev/null +++ b/config/initializers/wrap_parameters.rb @@ -0,0 +1,14 @@ +# Be sure to restart your server when you modify this file. + +# This file contains settings for ActionController::ParamsWrapper which +# is enabled by default. + +# Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. +ActiveSupport.on_load(:action_controller) do + wrap_parameters format: [:json] +end + +# To enable root element in JSON for ActiveRecord objects. +# ActiveSupport.on_load(:active_record) do +# self.include_root_in_json = true +# end diff --git a/config/locales/en.yml b/config/locales/en.yml new file mode 100644 index 000000000..decc5a857 --- /dev/null +++ b/config/locales/en.yml @@ -0,0 +1,33 @@ +# Files in the config/locales directory are used for internationalization +# and are automatically loaded by Rails. If you want to use locales other +# than English, add the necessary files in this directory. +# +# To use the locales, use `I18n.t`: +# +# I18n.t 'hello' +# +# In views, this is aliased to just `t`: +# +# <%= t('hello') %> +# +# To use a different locale, set it with `I18n.locale`: +# +# I18n.locale = :es +# +# This would use the information in config/locales/es.yml. +# +# The following keys must be escaped otherwise they will not be retrieved by +# the default I18n backend: +# +# true, false, on, off, yes, no +# +# Instead, surround them with single quotes. +# +# en: +# 'true': 'foo' +# +# To learn more, please read the Rails Internationalization guide +# available at http://guides.rubyonrails.org/i18n.html. + +en: + hello: "Hello world" diff --git a/config/puma.rb b/config/puma.rb new file mode 100644 index 000000000..1e19380dc --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,56 @@ +# Puma can serve each request in a thread from an internal thread pool. +# The `threads` method setting takes two numbers: a minimum and maximum. +# Any libraries that use thread pools should be configured to match +# the maximum value specified for Puma. Default is set to 5 threads for minimum +# and maximum; this matches the default thread size of Active Record. +# +threads_count = ENV.fetch("RAILS_MAX_THREADS") { 5 } +threads threads_count, threads_count + +# Specifies the `port` that Puma will listen on to receive requests; default is 3000. +# +port ENV.fetch("PORT") { 3000 } + +# Specifies the `environment` that Puma will run in. +# +environment ENV.fetch("RAILS_ENV") { "development" } + +# Specifies the number of `workers` to boot in clustered mode. +# Workers are forked webserver processes. If using threads and workers together +# the concurrency of the application would be max `threads` * `workers`. +# Workers do not work on JRuby or Windows (both of which do not support +# processes). +# +# workers ENV.fetch("WEB_CONCURRENCY") { 2 } + +# Use the `preload_app!` method when specifying a `workers` number. +# This directive tells Puma to first boot the application and load code +# before forking the application. This takes advantage of Copy On Write +# process behavior so workers use less memory. If you use this option +# you need to make sure to reconnect any threads in the `on_worker_boot` +# block. +# +# preload_app! + +# If you are preloading your application and using Active Record, it's +# recommended that you close any connections to the database before workers +# are forked to prevent connection leakage. +# +# before_fork do +# ActiveRecord::Base.connection_pool.disconnect! if defined?(ActiveRecord) +# end + +# The code in the `on_worker_boot` will be called if you are using +# clustered mode by specifying a number of `workers`. After each worker +# process is booted, this block will be run. If you are using the `preload_app!` +# option, you will want to use this block to reconnect to any threads +# or connections that may have been created at application boot, as Ruby +# cannot share connections between processes. +# +# on_worker_boot do +# ActiveRecord::Base.establish_connection if defined?(ActiveRecord) +# end +# + +# Allow puma to be restarted by `rails restart` command. +plugin :tmp_restart diff --git a/config/routes.rb b/config/routes.rb new file mode 100644 index 000000000..787824f88 --- /dev/null +++ b/config/routes.rb @@ -0,0 +1,3 @@ +Rails.application.routes.draw do + # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html +end diff --git a/config/secrets.yml b/config/secrets.yml new file mode 100644 index 000000000..55f95aef7 --- /dev/null +++ b/config/secrets.yml @@ -0,0 +1,32 @@ +# Be sure to restart your server when you modify this file. + +# Your secret key is used for verifying the integrity of signed cookies. +# If you change this key, all old signed cookies will become invalid! + +# Make sure the secret is at least 30 characters and all random, +# no regular words or you'll be exposed to dictionary attacks. +# You can use `rails secret` to generate a secure secret key. + +# Make sure the secrets in this file are kept private +# if you're sharing your code publicly. + +# Shared secrets are available across all environments. + +# shared: +# api_key: a1B2c3D4e5F6 + +# Environmental secrets are only available for that specific environment. + +development: + secret_key_base: a9f4eef79415c6b308c1ef248cbfdd62363d984f8c77c344be022995415860697dc32ed2ff0cb9519104c0a108b77649326aebf9c780eecfdeb6fd0c7c77a364 + +test: + secret_key_base: c0a8888e800510dd630d6991fadac4173c592f6c16d86006e106093d52e0a49cc40d2fb1076d8d07beda812106635bde330f7960038c1cc529a63110106b1645 + +# Do not keep production secrets in the unencrypted secrets file. +# Instead, either read values from the environment. +# Or, use `bin/rails secrets:setup` to configure encrypted secrets +# and move the `production:` environment over there. + +production: + secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> diff --git a/config/spring.rb b/config/spring.rb new file mode 100644 index 000000000..c9119b40c --- /dev/null +++ b/config/spring.rb @@ -0,0 +1,6 @@ +%w( + .ruby-version + .rbenv-vars + tmp/restart.txt + tmp/caching-dev.txt +).each { |path| Spring.watch(path) } diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..2611543b3 --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,18 @@ +# This file is auto-generated from the current state of the database. Instead +# of editing this file, please use the migrations feature of Active Record to +# incrementally modify your database, and then regenerate this schema definition. +# +# Note that this schema.rb definition is the authoritative source for your +# database schema. If you need to create the application database on another +# system, you should be using db:schema:load, not running all the migrations +# from scratch. The latter is a flawed and unsustainable approach (the more migrations +# you'll amass, the slower it'll run and the greater likelihood for issues). +# +# It's strongly recommended that you check this file into your version control system. + +ActiveRecord::Schema.define(version: 0) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" + +end diff --git a/db/seeds.rb b/db/seeds.rb index 5322340ba..1beea2acc 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -1,7 +1,7 @@ -JSON.parse(File.read('db/seeds/customers.json')).each do |customer| - Customer.create!(customer) -end - -JSON.parse(File.read('db/seeds/movies.json')).each do |movie| - Movie.create!(movie) -end +# This file should contain all the record creation needed to seed the database with its default values. +# The data can then be loaded with the rails db:seed command (or created alongside the database with db:setup). +# +# Examples: +# +# movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) +# Character.create(name: 'Luke', movie: movies.first) diff --git a/lib/tasks/.keep b/lib/tasks/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/log/.keep b/log/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/public/robots.txt b/public/robots.txt new file mode 100644 index 000000000..37b576a4a --- /dev/null +++ b/public/robots.txt @@ -0,0 +1 @@ +# See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file diff --git a/test/controllers/.keep b/test/controllers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/.keep b/test/fixtures/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/fixtures/files/.keep b/test/fixtures/files/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/integration/.keep b/test/integration/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/mailers/.keep b/test/mailers/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/models/.keep b/test/models/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/test/test_helper.rb b/test/test_helper.rb new file mode 100644 index 000000000..10594a324 --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,26 @@ +ENV["RAILS_ENV"] = "test" +require File.expand_path("../../config/environment", __FILE__) +require "rails/test_help" +require "minitest/rails" +require "minitest/reporters" # for Colorized output + +# For colorful output! +Minitest::Reporters.use!( + Minitest::Reporters::SpecReporter.new, + ENV, + Minitest.backtrace_filter +) + + +# To add Capybara feature tests add `gem "minitest-rails-capybara"` +# to the test group in the Gemfile and uncomment the following: +# require "minitest/rails/capybara" + +# Uncomment for awesome colorful output +# require "minitest/pride" + +class ActiveSupport::TestCase + # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. + fixtures :all + # Add more helper methods to be used by all tests here... +end diff --git a/tmp/.keep b/tmp/.keep new file mode 100644 index 000000000..e69de29bb diff --git a/vendor/.keep b/vendor/.keep new file mode 100644 index 000000000..e69de29bb From e8833648760f36e825cd4ada5f7194af0c3cd482 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 14:31:08 -0800 Subject: [PATCH 02/53] got seed data loaded --- app/models/customer.rb | 2 ++ app/models/movie.rb | 2 ++ db/migrate/20171106215333_create_movies.rb | 11 +++++++++ db/migrate/20171106215454_create_customers.rb | 15 ++++++++++++ db/schema.rb | 24 ++++++++++++++++++- db/seeds.rb | 20 ++++++++++++++++ test/fixtures/customers.yml | 11 +++++++++ test/fixtures/movies.yml | 11 +++++++++ test/models/customer_test.rb | 9 +++++++ test/models/movie_test.rb | 9 +++++++ 10 files changed, 113 insertions(+), 1 deletion(-) create mode 100644 app/models/customer.rb create mode 100644 app/models/movie.rb create mode 100644 db/migrate/20171106215333_create_movies.rb create mode 100644 db/migrate/20171106215454_create_customers.rb create mode 100644 test/fixtures/customers.yml create mode 100644 test/fixtures/movies.yml create mode 100644 test/models/customer_test.rb create mode 100644 test/models/movie_test.rb diff --git a/app/models/customer.rb b/app/models/customer.rb new file mode 100644 index 000000000..0b5277335 --- /dev/null +++ b/app/models/customer.rb @@ -0,0 +1,2 @@ +class Customer < ApplicationRecord +end diff --git a/app/models/movie.rb b/app/models/movie.rb new file mode 100644 index 000000000..dc614df15 --- /dev/null +++ b/app/models/movie.rb @@ -0,0 +1,2 @@ +class Movie < ApplicationRecord +end diff --git a/db/migrate/20171106215333_create_movies.rb b/db/migrate/20171106215333_create_movies.rb new file mode 100644 index 000000000..c0e32f968 --- /dev/null +++ b/db/migrate/20171106215333_create_movies.rb @@ -0,0 +1,11 @@ +class CreateMovies < ActiveRecord::Migration[5.1] + def change + create_table :movies do |t| + t.string :title + t.string :overview + t.string :release_date + t.integer :inventory + t.timestamps + end + end +end diff --git a/db/migrate/20171106215454_create_customers.rb b/db/migrate/20171106215454_create_customers.rb new file mode 100644 index 000000000..f2eaedc0e --- /dev/null +++ b/db/migrate/20171106215454_create_customers.rb @@ -0,0 +1,15 @@ +class CreateCustomers < ActiveRecord::Migration[5.1] + def change + create_table :customers do |t| + t.string :name + t.string :registered_at + t.string :address + t.string :city + t.string :state + t.string :postal_code + t.string :phone + t.float :account_credit, default: 0.00 + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index 2611543b3..e0b7addf3 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,9 +10,31 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 0) do +ActiveRecord::Schema.define(version: 20171106215454) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" + create_table "customers", force: :cascade do |t| + t.string "name" + t.string "registered_at" + t.string "address" + t.string "city" + t.string "state" + t.string "postal_code" + t.string "phone" + t.float "account_credit", default: 0.0 + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "movies", force: :cascade do |t| + t.string "title" + t.string "overview" + t.string "release_date" + t.integer "inventory" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + end diff --git a/db/seeds.rb b/db/seeds.rb index 1beea2acc..e9ac9c831 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -5,3 +5,23 @@ # # movies = Movie.create([{ name: 'Star Wars' }, { name: 'Lord of the Rings' }]) # Character.create(name: 'Luke', movie: movies.first) + +MOVIE_FILE = Rails.root.join('db', 'seeds', 'movies.json') + +movies = JSON.parse(File.read(MOVIE_FILE)) +# +# PRODUCT_FILE = Rails.root.join('db', 'seed_data', 'products.csv') +# puts "Loading raw product data from #{PRODUCT_FILE}" + +movies.each do |movie| + Movie.create!(movie) +end + + +CUSTOMER_FILE = Rails.root.join('db', 'seeds', 'customers.json') + +customers = JSON.parse(File.read(CUSTOMER_FILE)) + +customers.each do |customer| + Customer.create!(customer) +end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/customers.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/movies.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb new file mode 100644 index 000000000..5ebc5c850 --- /dev/null +++ b/test/models/customer_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Customer do + let(:customer) { Customer.new } + + it "must be valid" do + value(customer).must_be :valid? + end +end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb new file mode 100644 index 000000000..34d1d30a5 --- /dev/null +++ b/test/models/movie_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Movie do + let(:movie) { Movie.new } + + it "must be valid" do + value(movie).must_be :valid? + end +end From e501466a1e4686dfd9a7c007240dc077f1184463 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 15:07:08 -0800 Subject: [PATCH 03/53] did zomg route and method --- app/controllers/application_controller.rb | 2 ++ app/controllers/movies_controller.rb | 10 ++++++++++ config/routes.rb | 2 ++ test/controllers/movies_controller_test.rb | 7 +++++++ 4 files changed, 21 insertions(+) create mode 100644 app/controllers/movies_controller.rb create mode 100644 test/controllers/movies_controller_test.rb diff --git a/app/controllers/application_controller.rb b/app/controllers/application_controller.rb index 4ac8823b0..69ea87a39 100644 --- a/app/controllers/application_controller.rb +++ b/app/controllers/application_controller.rb @@ -1,2 +1,4 @@ class ApplicationController < ActionController::API + + end diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb new file mode 100644 index 000000000..cbc5f57db --- /dev/null +++ b/app/controllers/movies_controller.rb @@ -0,0 +1,10 @@ +class MoviesController < ApplicationController + + def zomg + render json: { + status: 200, + message: "IT WORKS!" + }.to_json + end + +end diff --git a/config/routes.rb b/config/routes.rb index 787824f88..0a33c7a71 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,5 @@ Rails.application.routes.draw do # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + + get '/zomg', to: 'movies#zomg' end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb new file mode 100644 index 000000000..67fabbcfb --- /dev/null +++ b/test/controllers/movies_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +describe MoviesController do + # it "must be a real test" do + # flunk "Need real tests" + # end +end From 9186f3ae08b62c762234646011d2be06e3ad0bfc Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 15:09:15 -0800 Subject: [PATCH 04/53] added controller for customers --- app/controllers/customers_controller.rb | 2 ++ test/controllers/customers_controller_test.rb | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 app/controllers/customers_controller.rb create mode 100644 test/controllers/customers_controller_test.rb diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb new file mode 100644 index 000000000..ca3b6e024 --- /dev/null +++ b/app/controllers/customers_controller.rb @@ -0,0 +1,2 @@ +class CustomersController < ApplicationController +end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb new file mode 100644 index 000000000..5e123f6cd --- /dev/null +++ b/test/controllers/customers_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +describe CustomersController do + # it "must be a real test" do + # flunk "Need real tests" + # end +end From 15a3716bf73af17d40e6937d6b2ae57bf13b0aa5 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 15:16:46 -0800 Subject: [PATCH 05/53] added index def to movies and an appropriate route --- app/controllers/movies_controller.rb | 9 ++++++++- config/routes.rb | 2 ++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index cbc5f57db..03cd3cbcc 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -6,5 +6,12 @@ def zomg message: "IT WORKS!" }.to_json end - + + def index + movies = Movie.all + render( + :json => movies.as_json(only: [:id, :title, :overview, :release_date, :inventory]), status: :ok + ) + end + end diff --git a/config/routes.rb b/config/routes.rb index 0a33c7a71..4034a6b33 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,4 +2,6 @@ # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get '/zomg', to: 'movies#zomg' + + resources :movies, only: [:index] end From 9f6ddc0343474763a2784dcea30d04b25031dcd2 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 15:20:32 -0800 Subject: [PATCH 06/53] added index method for customers controller and an appropriate route --- app/controllers/customers_controller.rb | 7 +++++++ config/routes.rb | 1 + 2 files changed, 8 insertions(+) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index ca3b6e024..bd09e0c7d 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -1,2 +1,9 @@ class CustomersController < ApplicationController + + def index + customers = Customer.all + render( + :json => customers.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone]), status: :ok + ) + end end diff --git a/config/routes.rb b/config/routes.rb index 4034a6b33..31efb350f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,4 +4,5 @@ get '/zomg', to: 'movies#zomg' resources :movies, only: [:index] + resources :customers, only: [:index] end From 631f1fe2124628bb66e52de07ec05975c4780f35 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 15:45:32 -0800 Subject: [PATCH 07/53] added tests for customers index controller method --- test/controllers/customers_controller_test.rb | 51 +++++++++++++++++-- 1 file changed, 48 insertions(+), 3 deletions(-) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 5e123f6cd..0aa4aa70e 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -1,7 +1,52 @@ require "test_helper" describe CustomersController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe "index" do + it "is a real working route" do + get customers_path + must_respond_with :success + end + + it "returns json" do + get customers_path + response.header['Content-Type'].must_include 'json' + end + + it "returns an Array" do + get customers_path + + body = JSON.parse(response.body) + body.must_be_kind_of Array + end + + it "returns all of the customers" do + get customers_path + + body = JSON.parse(response.body) + body.length.must_equal Customer.count + end + + it "returns customers with exactly the required fields" do + keys = %w(address city id name phone postal_code registered_at state) + + get customers_path + body = JSON.parse(response.body) + body.each do |customer| + customer.keys.sort.must_equal keys + end + end + + it "returns an empty array if there are no customers" do + Customer.destroy_all + + get customers_path + + must_respond_with :success + body = JSON.parse(response.body) + body.must_be_kind_of Array + body.must_be :empty? + end + + + end end From 3011912b33776033c0bf6c1b245fb603e67feaad Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 16:03:11 -0800 Subject: [PATCH 08/53] Add index controller tests for movies controller --- app/controllers/customers_controller.rb | 1 + test/controllers/movies_controller_test.rb | 51 ++++++++++++++++++++-- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index bd09e0c7d..1cae446f9 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -6,4 +6,5 @@ def index :json => customers.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone]), status: :ok ) end + end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 67fabbcfb..cc63f28bf 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -1,7 +1,52 @@ require "test_helper" describe MoviesController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe "index" do + + it "is a working route" do + get movies_path + must_respond_with :success + end + + it "returns json" do + get movies_path + response.header['Content-Type'].must_include 'json' + end + + it "returns an array" do + get movies_path + + body = JSON.parse(response.body) + body.must_be_kind_of Array + end + + it "returns all of the movies" do + get movies_path + + body = JSON.parse(response.body) + body.length.must_equal Movie.count + end + + it "returns movies with the required fields" do + keys = %w(id inventory overview release_date title) + + get movies_path + body = JSON.parse(response.body) + body.each do |movie| + movie.keys.sort.must_equal keys + end + end + + it "returns an empty array if there are no movies" do + Movie.destroy_all + + get movies_path + + must_respond_with :success + body = JSON.parse(response.body) + body.must_be_kind_of Array + body.must_be :empty? + end + + end end From 05fd82aecf771cfe6f033a86f187bc74f10bb996 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 16:10:01 -0800 Subject: [PATCH 09/53] Add gem pry and began controller testing for customers show --- Gemfile | 1 + test/controllers/customers_controller_test.rb | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/Gemfile b/Gemfile index 4ae55c93d..a6e0bdd54 100644 --- a/Gemfile +++ b/Gemfile @@ -28,6 +28,7 @@ gem 'puma', '~> 3.7' group :development, :test do # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] + gem 'pry-rails' end group :development do diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 0aa4aa70e..fae10f9ae 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -46,7 +46,17 @@ body.must_be_kind_of Array body.must_be :empty? end + end + describe "show" do + it "is a real working route" do + first_id = Customer.first.id + binding.pry + get customers_path(first_id) + must_respond_with :success + end end + + end From 5e5a4680ca218846b531ea2f44a8f1c427a88498 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 16:26:56 -0800 Subject: [PATCH 10/53] Add controller tests for customers show and add customers show controller --- app/controllers/customers_controller.rb | 21 +++++++++++++++++-- config/routes.rb | 2 +- test/controllers/customers_controller_test.rb | 11 ++++++++-- 3 files changed, 29 insertions(+), 5 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 1cae446f9..980ec9b19 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -3,8 +3,25 @@ class CustomersController < ApplicationController def index customers = Customer.all render( - :json => customers.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone]), status: :ok + :json => customers.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone]), status: :ok ) end - + + def show + customer = Customer.find_by(id: params[:id]) + + if customer + render( + json: customer.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone]), + status: :ok + ) + else + render( + json: {id: "Invalid Customer ID"}, + status: :not_found + ) + end + + end + end diff --git a/config/routes.rb b/config/routes.rb index 31efb350f..eca7e082b 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,5 +4,5 @@ get '/zomg', to: 'movies#zomg' resources :movies, only: [:index] - resources :customers, only: [:index] + resources :customers, only: [:index, :show] end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index fae10f9ae..97bf62270 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -51,11 +51,18 @@ describe "show" do it "is a real working route" do first_id = Customer.first.id - binding.pry - get customers_path(first_id) + get customer_path(first_id) must_respond_with :success end + it "responds correctly when the customer is not found" do + invalid_id = Customer.last.id + 1 + get customer_path(invalid_id) + must_respond_with :not_found + + body = JSON.parse(response.body) + body.must_equal "id" => "Invalid Customer ID" + end end From 4122c25628e9bc1f017b1d98efccd9d914a6947a Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 16:31:29 -0800 Subject: [PATCH 11/53] Changes to requirements on API information shared for customers and movies index --- app/controllers/customers_controller.rb | 2 +- app/controllers/movies_controller.rb | 2 +- test/controllers/customers_controller_test.rb | 2 +- test/controllers/movies_controller_test.rb | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 980ec9b19..114554b3d 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -3,7 +3,7 @@ class CustomersController < ApplicationController def index customers = Customer.all render( - :json => customers.as_json(only: [:id, :name, :registered_at, :address, :city, :state, :postal_code, :phone]), status: :ok + :json => customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]), status: :ok ) end diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 03cd3cbcc..ac15c2d2d 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -10,7 +10,7 @@ def zomg def index movies = Movie.all render( - :json => movies.as_json(only: [:id, :title, :overview, :release_date, :inventory]), status: :ok + :json => movies.as_json(only: [:id, :title, :release_date]), status: :ok ) end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 97bf62270..b4454fefe 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -27,7 +27,7 @@ end it "returns customers with exactly the required fields" do - keys = %w(address city id name phone postal_code registered_at state) + keys = %w(id name phone postal_code registered_at) get customers_path body = JSON.parse(response.body) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index cc63f28bf..0a7010283 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -28,7 +28,7 @@ end it "returns movies with the required fields" do - keys = %w(id inventory overview release_date title) + keys = %w(id release_date title) get movies_path body = JSON.parse(response.body) From 682bbdf8d4fc5ba6e733ac3fdf55474d1ffc4806 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 16:41:07 -0800 Subject: [PATCH 12/53] movie show method and controller test complete --- app/controllers/movies_controller.rb | 19 ++++++++++++++++++- config/routes.rb | 2 +- test/controllers/movies_controller_test.rb | 16 ++++++++++++++++ 3 files changed, 35 insertions(+), 2 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index ac15c2d2d..94c148500 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -10,8 +10,25 @@ def zomg def index movies = Movie.all render( - :json => movies.as_json(only: [:id, :title, :release_date]), status: :ok + :json => movies.as_json(only: [:id, :title, :release_date]), + status: :ok ) end + def show + movie = Movie.find_by(id: params[:id]) + + if movie + render( + :json => movie.as_json(only: [:title, :overview, :release_date, :inventory]), + status: :ok + ) + else + render( + json: {id: "Invalid Movie ID"}, + status: :not_found + ) + end + end + end diff --git a/config/routes.rb b/config/routes.rb index eca7e082b..b15e6635c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,6 +3,6 @@ get '/zomg', to: 'movies#zomg' - resources :movies, only: [:index] + resources :movies, only: [:index, :show] resources :customers, only: [:index, :show] end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 0a7010283..6bbcdd838 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -47,6 +47,22 @@ body.must_be_kind_of Array body.must_be :empty? end + end + + describe "show" do + it "is a working route" do + first_id = Movie.first.id + get movie_path(first_id) + must_respond_with :success + end + + it "responds as expected when movie not found" do + first_id = Movie.first.id + 1 + get movie_path(first_id) + must_respond_with :not_found + body = JSON.parse(response.body) + body.must_equal "id" => "Invalid Movie ID" + end end end From 71033c80d87d39cdc5e910d805016ffd1f0819ba Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Mon, 6 Nov 2017 17:26:52 -0800 Subject: [PATCH 13/53] create method nd controller tests for movies --- app/controllers/movies_controller.rb | 32 +++++++++++++---- config/routes.rb | 2 +- test/controllers/customers_controller_test.rb | 1 + test/controllers/movies_controller_test.rb | 34 +++++++++++++++++++ 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 94c148500..9b4e14a7b 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -10,8 +10,8 @@ def zomg def index movies = Movie.all render( - :json => movies.as_json(only: [:id, :title, :release_date]), - status: :ok + :json => movies.as_json(only: [:id, :title, :release_date]), + status: :ok ) end @@ -20,15 +20,35 @@ def show if movie render( - :json => movie.as_json(only: [:title, :overview, :release_date, :inventory]), - status: :ok + :json => movie.as_json(only: [:title, :overview, :release_date, :inventory]), + status: :ok + ) + else + render( + json: {id: "Invalid Movie ID"}, + status: :not_found + ) + end + end + + def create + movie = Movie.new(movie_params) + + if movie.save + render( + json: {id: movie.id}, status: :ok ) else render( - json: {id: "Invalid Movie ID"}, - status: :not_found + json: {errors: movie.errors.messages}, status: :bad_request ) end end + private + + def movie_params + params.require(:movie).permit(:title, :overview, :release_date, :inventory) + end + end diff --git a/config/routes.rb b/config/routes.rb index b15e6635c..abefdd977 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,6 +3,6 @@ get '/zomg', to: 'movies#zomg' - resources :movies, only: [:index, :show] + resources :movies, only: [:index, :show, :create] resources :customers, only: [:index, :show] end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index b4454fefe..850c65f15 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -66,4 +66,5 @@ end + end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 6bbcdd838..d84c6bf19 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -65,4 +65,38 @@ body.must_equal "id" => "Invalid Movie ID" end end + + describe "create" do + + let(:movie_data) { + { + title: "Jack", + overview: "Blahblah", + release_date: "1984", + inventory: 5 + } + } + + it "Create a Movie" do + proc { + post movies_path, params: {movie: movie_data} + }.must_change 'Movie.count', 1 + + must_respond_with :success + end + + it "Won't change the database if data is missing" do + invalid_movie_data = { + title: "Nada" + } + + proc { + post movies_path, params: { movie: invalid_movie_data} + }.wont_change 'Movie.count' + + # body = JSON.parse(response.body) + # body.must_equal "errors" => {} + end + + end end From c99690ee2a28fbd772d3ecaa99296d3bd9152450 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 19:06:32 -0800 Subject: [PATCH 14/53] Adding edit controller test for customers but not complete. Add some model validations --- app/controllers/customers_controller.rb | 20 ++++++++++ app/models/customer.rb | 3 ++ config/routes.rb | 2 +- test/controllers/customers_controller_test.rb | 39 +++++++++++++++++++ 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 114554b3d..06eb5958d 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -21,7 +21,27 @@ def show status: :not_found ) end + end + + def create + customer = Customer.new(customer_params) + + if customer.save + render( + json: {id: customer.id}, + status: :ok + ) + else + render( + json: {errors: customers.errors.messages}, status: :bad_request + ) + end + end + + private + def customer_params + params.require(:customer).permit(:name, :registered_at, :address, :city, :state, :postal_code, :phone) end end diff --git a/app/models/customer.rb b/app/models/customer.rb index 0b5277335..fd6c49c42 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,2 +1,5 @@ class Customer < ApplicationRecord + +validates :name, presence: true +validates :phone, presence: true end diff --git a/config/routes.rb b/config/routes.rb index b15e6635c..c7125266f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,5 +4,5 @@ get '/zomg', to: 'movies#zomg' resources :movies, only: [:index, :show] - resources :customers, only: [:index, :show] + resources :customers, only: [:index, :show, :create] end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index b4454fefe..3262e25b9 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -65,5 +65,44 @@ end end + describe "create" do + it "Can create a new customer" do + customer_data = { + name: "name", + registered_at: "registered at", + address: "address", + city: "city", + state: "state", + postal_code: "postal code" + } + + proc{ + post customers_path, params: {customer: customer_data} + }.must_change 'Customer.count', 1 + must_respond_with :success + end + + it "won't change db if data is missing" do + invalid_customer_data = { + # name: "name", + # registered_at: "registered at", + # address: "address", + # city: "city", + # state: "state", + # postal_code: "postal code" + fake: "fake" + } + binding.pry + + proc { + post customers_path, params: {customer: invalid_customer_data} + }.wont_change 'Customer.count' + + must_respond_with :bad_request + body = JSON.parse(response.body) + body.must_equal errors:{"invalid data" => ["Missing needed information"]} + end + end + end From 8b5f0564dc166d1007df74c790e0a71b31f83aa8 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Mon, 6 Nov 2017 19:18:35 -0800 Subject: [PATCH 15/53] passing controller create tests and commented out model tests for now --- app/controllers/customers_controller.rb | 2 +- app/models/movie.rb | 4 ++++ test/controllers/customers_controller_test.rb | 8 +++----- test/models/customer_test.rb | 10 +++++----- test/models/movie_test.rb | 10 +++++----- 5 files changed, 18 insertions(+), 16 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 06eb5958d..813f87cbf 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -33,7 +33,7 @@ def create ) else render( - json: {errors: customers.errors.messages}, status: :bad_request + json: {errors: customer.errors.messages}, status: :bad_request ) end end diff --git a/app/models/movie.rb b/app/models/movie.rb index dc614df15..eb5885304 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,2 +1,6 @@ class Movie < ApplicationRecord + validates :title, presence: true + validates :overview, presence: true + validates :release_date, presence: true + validates :inventory, presence: true end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 7d69955a1..dacd79de3 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -69,6 +69,7 @@ it "Can create a new customer" do customer_data = { name: "name", + phone: "phone", registered_at: "registered at", address: "address", city: "city", @@ -84,23 +85,20 @@ it "won't change db if data is missing" do invalid_customer_data = { - # name: "name", + name: "name", # registered_at: "registered at", # address: "address", # city: "city", # state: "state", # postal_code: "postal code" - fake: "fake" } - binding.pry - proc { post customers_path, params: {customer: invalid_customer_data} }.wont_change 'Customer.count' must_respond_with :bad_request body = JSON.parse(response.body) - body.must_equal errors:{"invalid data" => ["Missing needed information"]} + body.must_equal "errors" => {"phone" => ["can't be blank"]} end end diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 5ebc5c850..8b1c9e20c 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -1,9 +1,9 @@ require "test_helper" describe Customer do - let(:customer) { Customer.new } - - it "must be valid" do - value(customer).must_be :valid? - end + # let(:customer) { Customer.new } + # + # it "must be valid" do + # value(customer).must_be :valid? + # end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 34d1d30a5..b66f2d71c 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -1,9 +1,9 @@ require "test_helper" describe Movie do - let(:movie) { Movie.new } - - it "must be valid" do - value(movie).must_be :valid? - end + # let(:movie) { Movie.new } + # + # it "must be valid" do + # value(movie).must_be :valid? + # end end From 62e295875f2a63481e7f758b82d3a0912c3bbb01 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 09:27:07 -0800 Subject: [PATCH 16/53] added movie yml data --- test/fixtures/movies.yml | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index dc3ee79b5..63d60addd 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -4,8 +4,20 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} -# column: value -# -two: {} -# column: value +movie_one: + title: "Gone with the Wind" + overview: "Lovely drama" + release_date: "1950" + inventory: 2 + +movie_two: + title: "Hitchiker's Guide to the Galaxy" + overview: "Philosophical fiction" + release_date: "2000" + inventory: 3 + +movie_three: + title: "Sharknato" + overview: "Just Because" + release_date: "1995" + inventory: 5 From 45529caaaccddafe2fe8a1f424cf76878562f2ff Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 09:27:59 -0800 Subject: [PATCH 17/53] Add customer fixture data --- test/fixtures/customers.yml | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index dc3ee79b5..93a6d9ebf 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -4,8 +4,22 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} -# column: value -# -two: {} -# column: value +customer_one: + name: Betsy + registered_at: Tues, 07 Nov 2017 + address: 123 Glisan St. + city: Seattle + state: WA + postal_code: "12345" + phone: "12345678" + account_credit: 12.34 + +customer_two: + name: Betsy + registered_at: Wed, 29 Apr 2015 + address: 45 Columbia Street + city: Hood River + state: OR + postal_code: "12345" + phone: "56789043" + account_credit: 12.34 From 59a7e96f4441a02c6377f0062bcea2cb1cda401d Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 09:42:18 -0800 Subject: [PATCH 18/53] Add customer model validation testing - passing --- app/models/customer.rb | 6 +++++ test/models/customer_test.rb | 46 ++++++++++++++++++++++++++++++++---- 2 files changed, 47 insertions(+), 5 deletions(-) diff --git a/app/models/customer.rb b/app/models/customer.rb index fd6c49c42..78b8e9b9d 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,5 +1,11 @@ class Customer < ApplicationRecord validates :name, presence: true +validates :registered_at, presence: true +validates :address, presence: true +validates :city, presence: true +validates :state, presence: true +validates :postal_code, presence: true validates :phone, presence: true + end diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 8b1c9e20c..7404dfcc5 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -1,9 +1,45 @@ require "test_helper" describe Customer do - # let(:customer) { Customer.new } - # - # it "must be valid" do - # value(customer).must_be :valid? - # end + let(:customer_one) { customers(:customer_one) } + let(:customer_two) { customers(:customer_two) } + + describe "valid" do + + it "will return false without name" do + customer_one.name = nil + customer_one.wont_be :valid? + end + + it "will return false without registered_at" do + customer_one.registered_at = nil + customer_one.wont_be :valid? + end + + it "will return false without address" do + customer_one.address = nil + customer_one.wont_be :valid? + end + + it "will return false without city" do + customer_one.city = nil + customer_one.wont_be :valid? + end + + it "will return false without state" do + customer_one.state = nil + customer_one.wont_be :valid? + end + + it "will return false without postal code" do + customer_one.postal_code = nil + customer_one.wont_be :valid? + end + + it "will return false without phone" do + customer_one.phone = nil + customer_one.wont_be :valid? + end + + end end From 7f47644aee7508e0a9bf349d05b1cefe7fd7cf6c Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 09:44:47 -0800 Subject: [PATCH 19/53] Change to customer controller test to get it to pass with new customer model validation --- test/controllers/customers_controller_test.rb | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index dacd79de3..18b710550 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -83,14 +83,15 @@ must_respond_with :success end + #only testing one missing attribute; validation model testing covers some of this(I think...) it "won't change db if data is missing" do invalid_customer_data = { name: "name", - # registered_at: "registered at", - # address: "address", - # city: "city", - # state: "state", - # postal_code: "postal code" + registered_at: "registered at", + address: "address", + city: "city", + state: "state", + postal_code: "postal code" } proc { post customers_path, params: {customer: invalid_customer_data} From 6a9a4b0bb3a16c8dc43dce71bfc40262e7910ff7 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 10:01:53 -0800 Subject: [PATCH 20/53] added validation tests for movies --- test/controllers/movies_controller_test.rb | 8 +++-- test/models/movie_test.rb | 42 +++++++++++++++++++--- 2 files changed, 42 insertions(+), 8 deletions(-) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index d84c6bf19..f210d12de 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -87,15 +87,17 @@ it "Won't change the database if data is missing" do invalid_movie_data = { - title: "Nada" + overview: "Nada", + release_date: "1984", + inventory: 5 } proc { post movies_path, params: { movie: invalid_movie_data} }.wont_change 'Movie.count' - # body = JSON.parse(response.body) - # body.must_equal "errors" => {} + body = JSON.parse(response.body) + body.must_equal "errors"=>{"title"=>["can't be blank"]} end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index b66f2d71c..ae4db2865 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -1,9 +1,41 @@ require "test_helper" describe Movie do - # let(:movie) { Movie.new } - # - # it "must be valid" do - # value(movie).must_be :valid? - # end + before do + @invalid_movie_data = {} + end + describe "validations" do + it "can be created with all fields" do + valid = movies(:movie_one).valid? + valid.must_equal true + end + + it "requires a title" do + invalid_movie = Movie.new(@invalid_movie_data) + valid = invalid_movie.valid? + valid.must_equal false + invalid_movie.errors.messages.must_include :title + end + + it "requires an overview" do + invalid_movie = Movie.new(@invalid_movie_data) + valid = invalid_movie.valid? + valid.must_equal false + invalid_movie.errors.messages.must_include :overview + end + + it "requires a release date" do + invalid_movie = Movie.new(@invalid_movie_data) + valid = invalid_movie.valid? + valid.must_equal false + invalid_movie.errors.messages.must_include :release_date + end + + it "requires inventory to be specified" do + invalid_movie = Movie.new(@invalid_movie_data) + valid = invalid_movie.valid? + valid.must_equal false + invalid_movie.errors.messages.must_include :inventory + end + end end From c7d3bb4a9ae53b9b25207160f507d14a5a6ef0bc Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 10:18:31 -0800 Subject: [PATCH 21/53] update --- .DS_Store | Bin 0 -> 6148 bytes 1 file changed, 0 insertions(+), 0 deletions(-) create mode 100644 .DS_Store diff --git a/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..9654d442049ee1e4e342ff94f8ff29b9375e5d2e GIT binary patch literal 6148 zcmeHK%}N6?5Kd~<1`n`FJahf-Kyzz0yT z{yc}igb(5aIFp2;R4*Px$_&hWli8W1^97QIF~+N%V1+SC%QMA7mNNBu|NP5Vl&VtcjpxSl;}eqwA*O^7)8e$& zOu9AYsZLt;+Q&HB_f*sO+6`y176l=AM^T`f^)TLPg;!y`*WUG1Xj1D*(t-qCR`>kF zDC{G{QM0LPwDW(*AM>%b$27$63Sfzf8bo`Z#{ z(QcEvBL;|pUoe2@g9Jr%EoKJw(E&z30RZz5)&f4hC9p~*c`+w)>_y5--8W97; zz(_H`^V_xUDzs$p)}iL`u9cwYpeUG^861>=qpxDf#jAK8R13r Date: Tue, 7 Nov 2017 10:31:50 -0800 Subject: [PATCH 22/53] added rentals model and relationships to all models --- app/models/customer.rb | 2 ++ app/models/movie.rb | 3 +++ app/models/rental.rb | 4 ++++ db/migrate/20171107182008_create_rentals.rb | 11 +++++++++++ db/schema.rb | 11 ++++++++++- test/fixtures/rentals.yml | 11 +++++++++++ test/models/rental_test.rb | 9 +++++++++ 7 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 app/models/rental.rb create mode 100644 db/migrate/20171107182008_create_rentals.rb create mode 100644 test/fixtures/rentals.yml create mode 100644 test/models/rental_test.rb diff --git a/app/models/customer.rb b/app/models/customer.rb index 78b8e9b9d..da17f78ce 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,4 +1,6 @@ class Customer < ApplicationRecord +has_many :movies, through: :rentals +has_many :rentals validates :name, presence: true validates :registered_at, presence: true diff --git a/app/models/movie.rb b/app/models/movie.rb index eb5885304..4ba84143d 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,4 +1,7 @@ class Movie < ApplicationRecord + has_many :customers, through: :rentals + has_many :rentals + validates :title, presence: true validates :overview, presence: true validates :release_date, presence: true diff --git a/app/models/rental.rb b/app/models/rental.rb new file mode 100644 index 000000000..e001ff37c --- /dev/null +++ b/app/models/rental.rb @@ -0,0 +1,4 @@ +class Rental < ApplicationRecord + belongs_to :customer + belongs_to :movie +end diff --git a/db/migrate/20171107182008_create_rentals.rb b/db/migrate/20171107182008_create_rentals.rb new file mode 100644 index 000000000..75a4dcbe5 --- /dev/null +++ b/db/migrate/20171107182008_create_rentals.rb @@ -0,0 +1,11 @@ +class CreateRentals < ActiveRecord::Migration[5.1] + def change + create_table :rentals do |t| + t.integer :customer_id + t.integer :movie_id + t.string :checkout_date + t.string :due_date + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index e0b7addf3..60c5bc2eb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171106215454) do +ActiveRecord::Schema.define(version: 20171107182008) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -37,4 +37,13 @@ t.datetime "updated_at", null: false end + create_table "rentals", force: :cascade do |t| + t.integer "customer_id" + t.integer "movie_id" + t.string "checkout_date" + t.string "due_date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + end diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml new file mode 100644 index 000000000..dc3ee79b5 --- /dev/null +++ b/test/fixtures/rentals.yml @@ -0,0 +1,11 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +# This model initially had no columns defined. If you add columns to the +# model remove the "{}" from the fixture names and add the columns immediately +# below each fixture, per the syntax in the comments below +# +one: {} +# column: value +# +two: {} +# column: value diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb new file mode 100644 index 000000000..6ea53d94f --- /dev/null +++ b/test/models/rental_test.rb @@ -0,0 +1,9 @@ +require "test_helper" + +describe Rental do + let(:rental) { Rental.new } + + it "must be valid" do + value(rental).must_be :valid? + end +end From 4dc7c7861443ae1af3db7ea45b50d046071a8270 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 10:38:03 -0800 Subject: [PATCH 23/53] set up model validations for rentals --- app/models/rental.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/app/models/rental.rb b/app/models/rental.rb index e001ff37c..c0ec9bf64 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,4 +1,10 @@ class Rental < ApplicationRecord belongs_to :customer belongs_to :movie + + validates :customer_id, presence: true, numericality: { only_integer: true } + validates :movie_id, presence: true, numericality: { only_integer: true } + validates :checkout_date, presence: true + validates :due_date, presence: true + end From 23a9e31bdc80886842fa075a5ee7f57693176466 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 10:49:15 -0800 Subject: [PATCH 24/53] Add rental YAML data and begin work on rental relationship testing --- app/models/rental.rb | 8 ++++---- test/fixtures/rentals.yml | 16 +++++++++++----- test/models/rental_test.rb | 8 +++++++- 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/app/models/rental.rb b/app/models/rental.rb index c0ec9bf64..acd3c7b23 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -2,9 +2,9 @@ class Rental < ApplicationRecord belongs_to :customer belongs_to :movie - validates :customer_id, presence: true, numericality: { only_integer: true } - validates :movie_id, presence: true, numericality: { only_integer: true } - validates :checkout_date, presence: true - validates :due_date, presence: true + # validates :customer_id, presence: true, numericality: { only_integer: true } + # validates :movie_id, presence: true, numericality: { only_integer: true } + # validates :checkout_date, presence: true + # validates :due_date, presence: true end diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index dc3ee79b5..6c9227186 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -4,8 +4,14 @@ # model remove the "{}" from the fixture names and add the columns immediately # below each fixture, per the syntax in the comments below # -one: {} -# column: value -# -two: {} -# column: value +rental_one: + customer_id: customer_one + movie_id: movie_one + checkout_date: "2017-11-06" + due_date: "2017-11-13" + +rental_two: + customer_id: customer_two + movie_id: movie_two + checkout_date: "2017-11-07" + due_date: "2017-11-14" diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6ea53d94f..6734d5052 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -1,7 +1,13 @@ require "test_helper" describe Rental do - let(:rental) { Rental.new } + + #rentals YAML + let(:rental_one) { rentals :rental_one } + let(:rental_two) { rentals :rental_two } + + # + it "must be valid" do value(rental).must_be :valid? From 3092add71f6f55d23655277da903540ddc130b29 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 11:06:07 -0800 Subject: [PATCH 25/53] initial rental model relationship test passing with change in YAML rental test file --- test/fixtures/rentals.yml | 8 ++++---- test/models/rental_test.rb | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 34 insertions(+), 7 deletions(-) diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 6c9227186..084fca871 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -5,13 +5,13 @@ # below each fixture, per the syntax in the comments below # rental_one: - customer_id: customer_one - movie_id: movie_one + customer: customer_one + movie: movie_one checkout_date: "2017-11-06" due_date: "2017-11-13" rental_two: - customer_id: customer_two - movie_id: movie_two + customer: customer_two + movie: movie_one checkout_date: "2017-11-07" due_date: "2017-11-14" diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6734d5052..3245ad15e 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -6,10 +6,37 @@ let(:rental_one) { rentals :rental_one } let(:rental_two) { rentals :rental_two } - # + #customer YAML + let(:customer_one) { customers :customer_one} + let(:customer_two) { customers :customer_two} + #movie YAML + let(:movie_one) { movies :movie_one} + let(:movie_two) { movies :movie_two} + + describe "relations" do + it "has a customer" do + rental_one.must_respond_to :customer + rental_one.customer.must_be_kind_of Customer + end + + it "has a movie" do + rental_one.must_respond_to :movie + rental_one.movie.must_be_kind_of Movie + end + + it "allows one movie to have many customers" do + movie_one.customers.count.must_be :>, 1 + movie_one.customers.must_include customer_one + movie_one.customers.must_include customer_two + end + + it "allows one customer to have many movies" do + + end - it "must be valid" do - value(rental).must_be :valid? end + # it "must be valid" do + # value(rental).must_be :valid? + # end end From d0c27195369d31a50a89a5e0f623db7e174427dd Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:07:35 -0800 Subject: [PATCH 26/53] adding tests for movies model relationships --- test/models/movie_test.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index ae4db2865..ed3ea2292 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -38,4 +38,21 @@ invalid_movie.errors.messages.must_include :inventory end end + + describe "relationship between movie and rentals" do + before do + @movie = (:movie_one) + end + + it "movie responds to rentals" do + @movie.must_respond_to :rentals + end + + it "lists rentals for a given movie" do + movie = movies(:movie_one) + # movie.rentals.count.must_equal 1 + + movie.rentals[0].must_be_kind_of Rental + end + end end From 7faae8a95f8d403b629f452071f5c7ed0aa70990 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 11:10:33 -0800 Subject: [PATCH 27/53] Change in model through relationships in customers and movies --- app/models/customer.rb | 3 ++- app/models/movie.rb | 2 +- test/models/rental_test.rb | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/models/customer.rb b/app/models/customer.rb index da17f78ce..d57136f52 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,6 +1,7 @@ class Customer < ApplicationRecord -has_many :movies, through: :rentals has_many :rentals +has_many :movies, through: :rentals + validates :name, presence: true validates :registered_at, presence: true diff --git a/app/models/movie.rb b/app/models/movie.rb index 4ba84143d..0533a1b45 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,6 +1,6 @@ class Movie < ApplicationRecord - has_many :customers, through: :rentals has_many :rentals + has_many :customers, through: :rentals validates :title, presence: true validates :overview, presence: true diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 3245ad15e..960847a61 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -27,8 +27,8 @@ it "allows one movie to have many customers" do movie_one.customers.count.must_be :>, 1 - movie_one.customers.must_include customer_one - movie_one.customers.must_include customer_two + # movie_one.customers.must_include customer_one + # movie_one.customers.must_include customer_two end it "allows one customer to have many movies" do From cbb57425f84b673e01c9cc44a2e3a5602e0ae454 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:10:59 -0800 Subject: [PATCH 28/53] update --- test/models/movie_test.rb | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index ed3ea2292..9b1a432f4 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -49,10 +49,9 @@ end it "lists rentals for a given movie" do - movie = movies(:movie_one) - # movie.rentals.count.must_equal 1 + @movie.rentals.count.must_equal 1 - movie.rentals[0].must_be_kind_of Rental + @movie.rentals[0].must_be_kind_of Rental end end end From e81f5c121a622960f3fb0c42068d7d2218f3bd6a Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 11:15:49 -0800 Subject: [PATCH 29/53] Basic rentals relationship model tests passing with addition of two rental objects in yaml file --- test/fixtures/rentals.yml | 12 ++++++++++++ test/models/rental_test.rb | 10 +++++++--- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 084fca871..6f9bf8167 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -15,3 +15,15 @@ rental_two: movie: movie_one checkout_date: "2017-11-07" due_date: "2017-11-14" + +rental_three: + customer: customer_one + movie: movie_two + checkout_date: "2017-11-07" + due_date: "2017-11-14" + +rental_four: + customer: customer_two + movie: movie_two + checkout_date: "2017-11-07" + due_date: "2017-11-14" diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 960847a61..371d390a2 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -5,6 +5,8 @@ #rentals YAML let(:rental_one) { rentals :rental_one } let(:rental_two) { rentals :rental_two } + let(:rental_three) { rentals :rental_three } + let(:rental_four) { rentals :rental_four } #customer YAML let(:customer_one) { customers :customer_one} @@ -27,12 +29,14 @@ it "allows one movie to have many customers" do movie_one.customers.count.must_be :>, 1 - # movie_one.customers.must_include customer_one - # movie_one.customers.must_include customer_two + movie_one.customers.must_include customer_one + movie_one.customers.must_include customer_two end it "allows one customer to have many movies" do - + customer_one.movies.count.must_be :>, 1 + customer_one.movies.must_include movie_one + customer_one.movies.must_include movie_two end end From 730eb9a38ebc0301c2ecb7dbfbf8358107307274 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:15:58 -0800 Subject: [PATCH 30/53] some basic relationship tests for movie model --- test/models/movie_test.rb | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 9b1a432f4..b70ae00eb 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -41,7 +41,7 @@ describe "relationship between movie and rentals" do before do - @movie = (:movie_one) + @movie = movies(:movie_one) end it "movie responds to rentals" do @@ -49,9 +49,25 @@ end it "lists rentals for a given movie" do - @movie.rentals.count.must_equal 1 + @movie.rentals.each do |rental| + rental.must_be_kind_of Rental + end + end + end - @movie.rentals[0].must_be_kind_of Rental + describe "relationship between movies and customers" do + before do + @movie = movies(:movie_one) + end + + it "movie responds to customers" do + @movie.must_respond_to :customers + end + + it "lists customers for a given movie" do + @movie.customers.each do |customer| + customer.must_be_kind_of Customer end end + end end From 686d6a186b52637fc4ba8d1c222be959072f70ac Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:25:03 -0800 Subject: [PATCH 31/53] added tests for relationshiops in customer model --- test/models/customer_test.rb | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 7404dfcc5..8d39f4370 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -42,4 +42,35 @@ end end + + describe "relationships" do + before do + @customer = customers(:customer_one) + end + + describe "relationship between customers and movies" do + + it "customer responds to movies" do + @customer.must_respond_to :movies + end + + it "lists movies for a given customer" do + @customer.movies.each do |movie| + movie.must_be_kind_of Movie + end + end + end + + describe "relationship between customers and rentals" do + it "responds to rentals" do + @customer.must_respond_to :rentals + end + + it "lists rentals for a given customer" do + @customer.rentals.each do |rental| + rental.must_be_kind_of Rental + end + end + end + end end From 1f9ab8780124a360365fe82203ff63478fcf8f23 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:28:46 -0800 Subject: [PATCH 32/53] generated rentals controller --- app/controllers/rentals_controller.rb | 2 ++ test/controllers/rentals_controller_test.rb | 7 +++++++ 2 files changed, 9 insertions(+) create mode 100644 app/controllers/rentals_controller.rb create mode 100644 test/controllers/rentals_controller_test.rb diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb new file mode 100644 index 000000000..58c72b791 --- /dev/null +++ b/app/controllers/rentals_controller.rb @@ -0,0 +1,2 @@ +class RentalsController < ApplicationController +end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb new file mode 100644 index 000000000..f0227216c --- /dev/null +++ b/test/controllers/rentals_controller_test.rb @@ -0,0 +1,7 @@ +require "test_helper" + +describe RentalsController do + # it "must be a real test" do + # flunk "Need real tests" + # end +end From e164aa04ade44fdfed89d7c6ab63202e32a36176 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 11:34:13 -0800 Subject: [PATCH 33/53] Added validation testing for rental model --- app/models/rental.rb | 8 ++++---- test/models/rental_test.rb | 37 ++++++++++++++++++++++++++++++++++--- 2 files changed, 38 insertions(+), 7 deletions(-) diff --git a/app/models/rental.rb b/app/models/rental.rb index acd3c7b23..c0ec9bf64 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -2,9 +2,9 @@ class Rental < ApplicationRecord belongs_to :customer belongs_to :movie - # validates :customer_id, presence: true, numericality: { only_integer: true } - # validates :movie_id, presence: true, numericality: { only_integer: true } - # validates :checkout_date, presence: true - # validates :due_date, presence: true + validates :customer_id, presence: true, numericality: { only_integer: true } + validates :movie_id, presence: true, numericality: { only_integer: true } + validates :checkout_date, presence: true + validates :due_date, presence: true end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 371d390a2..35253ab9f 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -40,7 +40,38 @@ end end - # it "must be valid" do - # value(rental).must_be :valid? - # end + + describe "valid" do + it "will return false without a customer id" do + rental_one.customer_id = nil + rental_one.wont_be :valid? + end + + it "will return false if customer id is not a number" do + rental_one.customer_id = " " + rental_one.wont_be :valid? + end + + it "will return false without a movie id" do + rental_one.movie_id = nil + rental_one.wont_be :valid? + end + + it "will return false if movie id is not a number" do + rental_one.movie_id = " " + rental_one.wont_be :valid? + end + + it "will return false without a checkout date" do + rental_two.checkout_date = nil + rental_two.wont_be :valid? + end + + it "will return false without a due date" do + rental_three.due_date = nil + rental_three.wont_be :valid? + end + + + end end From 49fce95a039c52b3df577fa23875fe4b34b42393 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:37:19 -0800 Subject: [PATCH 34/53] added index method for rentals controller --- app/controllers/rentals_controller.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 58c72b791..2aea8beff 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,2 +1,11 @@ class RentalsController < ApplicationController + + def index + rentals = Rental.all + + render( + :json => rentals.as_json(only: [:customer_id, :movie_id, :checkout_id, :due_date]), + status: :ok + ) + end end From 65e0f4c84ea5cfb972ddcb3f20bb6e6d6fa47d7b Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 11:57:38 -0800 Subject: [PATCH 35/53] added column to rentals model for checkin_date --- db/migrate/20171107195527_add_checkin_date_to_rentals.rb | 5 +++++ db/schema.rb | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20171107195527_add_checkin_date_to_rentals.rb diff --git a/db/migrate/20171107195527_add_checkin_date_to_rentals.rb b/db/migrate/20171107195527_add_checkin_date_to_rentals.rb new file mode 100644 index 000000000..4ac1137d7 --- /dev/null +++ b/db/migrate/20171107195527_add_checkin_date_to_rentals.rb @@ -0,0 +1,5 @@ +class AddCheckinDateToRentals < ActiveRecord::Migration[5.1] + def change + add_column :rentals, :checkin_date, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index 60c5bc2eb..9eef14cbb 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171107182008) do +ActiveRecord::Schema.define(version: 20171107195527) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -44,6 +44,7 @@ t.string "due_date" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.string "checkin_date" end end From 1f269de7c10f5415ff039a2c98845ed52c076a70 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 12:08:09 -0800 Subject: [PATCH 36/53] made route for rentals checkout --- config/routes.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 0a8561b79..3963aa250 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,7 +2,9 @@ # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get '/zomg', to: 'movies#zomg' - + get '/rentals/checkout', to: 'rentals#checkout', as: 'checkout' + resources :movies, only: [:index, :show, :create] resources :customers, only: [:index, :show, :create] + end From 5f5be208dce7779c8eeaf983c339696aa718eaee Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 12:09:05 -0800 Subject: [PATCH 37/53] deleted last update --- config/routes.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 3963aa250..c17530798 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -2,8 +2,7 @@ # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html get '/zomg', to: 'movies#zomg' - get '/rentals/checkout', to: 'rentals#checkout', as: 'checkout' - + resources :movies, only: [:index, :show, :create] resources :customers, only: [:index, :show, :create] From 6efbc5ed59e8af4e3149fbb4d0a154e2388d72ca Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 12:26:52 -0800 Subject: [PATCH 38/53] Add checkout route, stub out checkout controller tests --- app/controllers/rentals_controller.rb | 3 + config/routes.rb | 2 + test/controllers/rentals_controller_test.rb | 70 ++++++++++++++++++++- 3 files changed, 72 insertions(+), 3 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 2aea8beff..6059946e9 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -8,4 +8,7 @@ def index status: :ok ) end + + def checkout + end end diff --git a/config/routes.rb b/config/routes.rb index 0a8561b79..77f5b8bae 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -5,4 +5,6 @@ resources :movies, only: [:index, :show, :create] resources :customers, only: [:index, :show, :create] + + post 'rentals/checkout', to: 'rentals#checkout', as: 'checkout' end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index f0227216c..4755a500b 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -1,7 +1,71 @@ require "test_helper" describe RentalsController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe "checkout" do + it "is a working route" do + post checkout_path + must_respond_with :success + end + + it "return json" do + post checkout_path + response.header['Content-Type'].must_include 'json' + end + + it "returns an Array" do + post checkout_path + + body = JSON.parse(response.body) + body.must_be_kind_of Array + end + + it "increases the number of rentals in db" do + rental_count = Rental.count + post checkout_path + + Rental.count.must_equal (rental_count + 1) + end + + it "returns cust id, movie id and due date" do + keys = %w(customer_id due_date movie_id) + + post checkout_path + body = JSON.parse(response.body) + body.each do |checkout| + checkout.keys.sort.must_equal keys + end + end + + + it "returns an error message if not enough inventory" do + skip + end + + + it "returns an error message if the input is incorrect" do + skip + end + + it "won't change db if data is missing" do + let(:customer_one) { customers :customer_one} + let(:movie_one) { movies :movie_one} + + invalid_rental_info = { + customer_id: customer_one, + movie_id: movie_one, + due_date: "2017-11-14", + # checkout_date: "2017-11-07", + } + + proc { + post checkout_path, params: {rental: invalid_rental_info} + }.wont_change 'Rental.count' + + must_respond_with :bad_request + body = JSON.parse(response.body) + #this error message could change but just a sample of what we might want to output + body.must_equal "errors" => {"checkout_date" => ["can't be blank"]} + end + + end end From 46434c63d4fc86f0560146b36c0a4ee7bd563448 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 13:26:29 -0800 Subject: [PATCH 39/53] trying to flesh out checkout method in controller but not working yet --- app/controllers/rentals_controller.rb | 28 ++++++++++++++++++++++++++- app/models/movie.rb | 9 +++++++++ app/models/rental.rb | 8 ++++++++ 3 files changed, 44 insertions(+), 1 deletion(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 6059946e9..81e4607b1 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -10,5 +10,31 @@ def index end def checkout - end + rental = Rental.new(rental_params) + # movie = Movie.find_by(id: params[:movie_id]) + # unless movie.inventory? + # render( + # json: {inventory: "Not enough inventory"}, + # status: :bad_request + # ) + # return + # end + + if rental.save + render( + json: {id: rental.id}, status: :ok + ) + else + render( + json: {errors: rental.errors.messages}, status: :bad_request + ) + end + end + + private + + def rental_params + params.require(:rental).permit(:customer_id, :movie_id, :checkout_date, :due_date) + end + end diff --git a/app/models/movie.rb b/app/models/movie.rb index 0533a1b45..74805298e 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -6,4 +6,13 @@ class Movie < ApplicationRecord validates :overview, presence: true validates :release_date, presence: true validates :inventory, presence: true + + + def inventory? + # movie = Movie.find_by(id: params[:movie_id]) + if movie.inventory < 1 + # if inventory < 1 + return false + end + end end diff --git a/app/models/rental.rb b/app/models/rental.rb index c0ec9bf64..a04dca36b 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -7,4 +7,12 @@ class Rental < ApplicationRecord validates :checkout_date, presence: true validates :due_date, presence: true + + # def inventory? + # movie = movie.find_by(id: params[:movie_id]) + # if movie.inventory < 1 + # return false + # end + # end + end From 8b0c9ce7036dfdec2c275ddda420a041a9a2c24a Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 13:40:46 -0800 Subject: [PATCH 40/53] added a method in movie model for checking a movie's inventory and added a test for it. It seems like it works now --- app/models/movie.rb | 2 +- test/models/movie_test.rb | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 74805298e..851f2aa16 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -8,7 +8,7 @@ class Movie < ApplicationRecord validates :inventory, presence: true - def inventory? + def self.inventory? # movie = Movie.find_by(id: params[:movie_id]) if movie.inventory < 1 # if inventory < 1 diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index b70ae00eb..fec32cd29 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -70,4 +70,21 @@ end end end + + describe "inventory" do + it "returns false if a movie does not have any inventory" do + movie_data = + { + title: "Jack", + overview: "Blahblah", + release_date: "1984", + inventory: 0 + } + + + movie = Movie.new(movie_data) + + movie.inventory?.must_equal false + end + end end From ea6f4de3b1cddb9eec997b4e579c7d691fb7daef Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 13:45:04 -0800 Subject: [PATCH 41/53] started some methods in movie model for adding and decreasing inventory --- app/models/movie.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/models/movie.rb b/app/models/movie.rb index 851f2aa16..a2c8fb2d4 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -15,4 +15,18 @@ def self.inventory? return false end end + +#TEST THIS - NOT YET IMPLEMENTED + def self.reduce_inventory(rental) + rental.movie.inventory = movie.inventory - 1 + + rental.movie.save + end + +#TEST THIS - NOT YET IMPLEMENTED + def self.increase_inventory(rental) + rental.movie.inventory = movie.inventory + 1 + + rental.movie.save + end end From ebbd7be8d021a5b052a1bec706b4b68bab1b66f3 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 14:21:25 -0800 Subject: [PATCH 42/53] added some tests in movie model for increase and decrease inventory but they are not passing for some reason --- app/models/movie.rb | 12 ++++++------ test/models/movie_test.rb | 24 ++++++++++++++++++++++++ 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index a2c8fb2d4..fe67d4581 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -17,16 +17,16 @@ def self.inventory? end #TEST THIS - NOT YET IMPLEMENTED - def self.reduce_inventory(rental) - rental.movie.inventory = movie.inventory - 1 + def self.reduce_inventory + movie.inventory = movie.inventory - 1 - rental.movie.save + movie.save end #TEST THIS - NOT YET IMPLEMENTED - def self.increase_inventory(rental) - rental.movie.inventory = movie.inventory + 1 + def self.increase_inventory + movie.inventory = movie.inventory + 1 - rental.movie.save + movie.save end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index fec32cd29..e711f8753 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -86,5 +86,29 @@ movie.inventory?.must_equal false end + + it "returns true if a movie has at least one in inventory" do + movie = movies(:movie_one) + + movie.inventory?.must_equal true + end + end + + describe "reduce inventory" do + it "will reduce the inventory of a movie by one" do + movie = movies(:movie_one) + start_inventory = movie.inventory + movie.reduce_inventory + movie.inventory.must_equal start_inventory - 1 + end + end + + describe "increase inventory" do + it "will reduce the inventory of a movie by one" do + movie = movies(:movie_one) + start_inventory = movie.inventory + movie.increase_inventory + movie.inventory.must_equal start_inventory + 1 + end end end From 9679fddb5d472de51886235151ad8f2957db9a31 Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 14:53:21 -0800 Subject: [PATCH 43/53] fixed movie model issues with inventory check, increase and decrease --- app/controllers/rentals_controller.rb | 3 ++- app/models/movie.rb | 23 +++++++++++------------ test/models/movie_test.rb | 4 ++-- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 81e4607b1..b90aaa745 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -12,7 +12,7 @@ def index def checkout rental = Rental.new(rental_params) # movie = Movie.find_by(id: params[:movie_id]) - # unless movie.inventory? + # unless movie.check_inventory? # render( # json: {inventory: "Not enough inventory"}, # status: :bad_request @@ -34,6 +34,7 @@ def checkout private def rental_params + binding.pry params.require(:rental).permit(:customer_id, :movie_id, :checkout_date, :due_date) end diff --git a/app/models/movie.rb b/app/models/movie.rb index fe67d4581..ed6d7c8a7 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -8,25 +8,24 @@ class Movie < ApplicationRecord validates :inventory, presence: true - def self.inventory? - # movie = Movie.find_by(id: params[:movie_id]) - if movie.inventory < 1 - # if inventory < 1 + def check_inventory? + + if self.inventory < 1 return false + else + return true end end -#TEST THIS - NOT YET IMPLEMENTED - def self.reduce_inventory - movie.inventory = movie.inventory - 1 + def reduce_inventory + self.inventory = self.inventory - 1 - movie.save + self.save end -#TEST THIS - NOT YET IMPLEMENTED - def self.increase_inventory - movie.inventory = movie.inventory + 1 + def increase_inventory + self.inventory = self.inventory + 1 - movie.save + self.save end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index e711f8753..b5d70dd7d 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -84,13 +84,13 @@ movie = Movie.new(movie_data) - movie.inventory?.must_equal false + movie.check_inventory?.must_equal false end it "returns true if a movie has at least one in inventory" do movie = movies(:movie_one) - movie.inventory?.must_equal true + movie.check_inventory?.must_equal true end end From 81f4b42c9180bdc6a808e2a9a1e585b6a0efe09c Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 15:25:06 -0800 Subject: [PATCH 44/53] Playing around with checkout tests, specifically strong params --- test/controllers/rentals_controller_test.rb | 27 ++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 4755a500b..03a912d7c 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -2,17 +2,39 @@ describe RentalsController do describe "checkout" do + let(:customer_one) { customers :customer_one} + let(:movie_one) { movies :movie_one} + it "is a working route" do - post checkout_path + # valid_rental_info = { + # customer_id: customer_one, + # movie_id: movie_one, + # due_date: "2019-11-14", + # checkout_date: "2019-11-07", + # } + kim = customers(:customer_one) + jaws = movies(:movie_one) + rental_data = { + rental: { + customer_id: kim.id, + movie_id: jaws.id, + due_date: "2019-11-14", + checkout_date: "2019-11-14" + } + } + + post checkout_path, rental_params: rental_data[:rental] must_respond_with :success end it "return json" do + skip post checkout_path response.header['Content-Type'].must_include 'json' end it "returns an Array" do + skip post checkout_path body = JSON.parse(response.body) @@ -20,6 +42,7 @@ end it "increases the number of rentals in db" do + skip rental_count = Rental.count post checkout_path @@ -27,6 +50,7 @@ end it "returns cust id, movie id and due date" do + skip keys = %w(customer_id due_date movie_id) post checkout_path @@ -47,6 +71,7 @@ end it "won't change db if data is missing" do + skip let(:customer_one) { customers :customer_one} let(:movie_one) { movies :movie_one} From ce265436d89d02fa3de8d6bd7fd3b982df3247ba Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 15:48:25 -0800 Subject: [PATCH 45/53] Passing checkout controller test 1 with correct params call syntax --- app/controllers/rentals_controller.rb | 1 - test/controllers/rentals_controller_test.rb | 18 +++++------------- 2 files changed, 5 insertions(+), 14 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index b90aaa745..c763c6fd7 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -34,7 +34,6 @@ def checkout private def rental_params - binding.pry params.require(:rental).permit(:customer_id, :movie_id, :checkout_date, :due_date) end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 03a912d7c..fad7e9145 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -6,24 +6,16 @@ let(:movie_one) { movies :movie_one} it "is a working route" do - # valid_rental_info = { - # customer_id: customer_one, - # movie_id: movie_one, - # due_date: "2019-11-14", - # checkout_date: "2019-11-07", - # } - kim = customers(:customer_one) - jaws = movies(:movie_one) - rental_data = { + valid_rental_info = { rental: { - customer_id: kim.id, - movie_id: jaws.id, + customer_id: customer_one.id, + movie_id: movie_one.id, due_date: "2019-11-14", - checkout_date: "2019-11-14" + checkout_date: "2019-11-07", } } - post checkout_path, rental_params: rental_data[:rental] + post checkout_path(params: valid_rental_info) must_respond_with :success end From ca3a9c28916a04520059be10caf8be1e34689e4e Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Tue, 7 Nov 2017 18:14:51 -0800 Subject: [PATCH 46/53] updated check in method in Rentals Controller --- app/controllers/rentals_controller.rb | 53 ++++++-- app/models/movie.rb | 4 +- test/controllers/rentals_controller_test.rb | 131 ++++++++++++++------ test/models/movie_test.rb | 4 +- 4 files changed, 143 insertions(+), 49 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index c763c6fd7..9149adec4 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -11,16 +11,26 @@ def index def checkout rental = Rental.new(rental_params) - # movie = Movie.find_by(id: params[:movie_id]) - # unless movie.check_inventory? - # render( - # json: {inventory: "Not enough inventory"}, - # status: :bad_request - # ) - # return - # end + movie = rental.movie + + if movie.nil? + render( + json: {errors: ["Movie does not exist"]}, + status: :bad_request + ) + return + end + + unless movie.check_inventory? + render( + json: {errors: ["Not enough inventory"]}, + status: :bad_request + ) + return + end if rental.save + movie.reduce_inventory! render( json: {id: rental.id}, status: :ok ) @@ -31,6 +41,33 @@ def checkout end end + def check_in + # find the rental instance + rental = Rental.where(customer_id: params[:customer_id], movie_id: params[:movie_id]).order(due_date: :asc).first + + if rental.nil? + render( + json: {errors: ["Rental not found"]}, + status: :not_found + ) + return + else + rental.checkin_date = Date.today + rental.save + + rental.movie.increase_inventory! + + render( + json: { } + ) + end + end + + def overdue + + end + + private def rental_params diff --git a/app/models/movie.rb b/app/models/movie.rb index ed6d7c8a7..d49cb7a95 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -17,13 +17,13 @@ def check_inventory? end end - def reduce_inventory + def reduce_inventory! self.inventory = self.inventory - 1 self.save end - def increase_inventory + def increase_inventory! self.inventory = self.inventory + 1 self.save diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index fad7e9145..cebc2762c 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -20,69 +20,126 @@ end it "return json" do - skip - post checkout_path + valid_rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: movie_one.id, + due_date: "2019-11-14", + checkout_date: "2019-11-07", + } + } + post checkout_path(params: valid_rental_info) response.header['Content-Type'].must_include 'json' end it "returns an Array" do - skip - post checkout_path + valid_rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: movie_one.id, + due_date: "2019-11-14", + checkout_date: "2019-11-07", + } + } + post checkout_path(params: valid_rental_info) body = JSON.parse(response.body) - body.must_be_kind_of Array + body.must_be_kind_of Hash end it "increases the number of rentals in db" do - skip rental_count = Rental.count - post checkout_path + + valid_rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: movie_one.id, + due_date: "2019-11-14", + checkout_date: "2019-11-07", + } + } + post checkout_path(params: valid_rental_info) Rental.count.must_equal (rental_count + 1) end - it "returns cust id, movie id and due date" do - skip - keys = %w(customer_id due_date movie_id) + it "returns rental id" do + valid_rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: movie_one.id, + due_date: "2019-11-14", + checkout_date: "2019-11-07", + } + } + post checkout_path(params: valid_rental_info) - post checkout_path body = JSON.parse(response.body) - body.each do |checkout| - checkout.keys.sort.must_equal keys - end + body.must_include "id" + end + end + it "returns an error message if not enough inventory" do + movie = Movie.create(title: "title", overview: "Great story", inventory: 0, release_date: "2017-4-17") - it "returns an error message if not enough inventory" do - skip - end + rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: movie.id, + due_date: "2019-11-14", + checkout_date: "2019-11-07" + } + } + post checkout_path(params: rental_info) - it "returns an error message if the input is incorrect" do - skip - end + must_respond_with :bad_request - it "won't change db if data is missing" do - skip - let(:customer_one) { customers :customer_one} - let(:movie_one) { movies :movie_one} + body = JSON.parse(response.body) + body.must_equal "errors" => ["Not enough inventory"] + + end - invalid_rental_info = { - customer_id: customer_one, - movie_id: movie_one, - due_date: "2017-11-14", - # checkout_date: "2017-11-07", + it "returns an error message if the input is incorrect" do + invalid_rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: 44444444444, + due_date: "2019-11-14", + checkout_date: "2019-11-07", } + } - proc { - post checkout_path, params: {rental: invalid_rental_info} - }.wont_change 'Rental.count' + post checkout_path(params: invalid_rental_info) - must_respond_with :bad_request - body = JSON.parse(response.body) - #this error message could change but just a sample of what we might want to output - body.must_equal "errors" => {"checkout_date" => ["can't be blank"]} - end + must_respond_with :bad_request + body = JSON.parse(response.body) + body.must_equal "errors" => ["Movie does not exist"] end + + let(:customer_one) { customers :customer_one} + let(:movie_one) { movies :movie_one} + + it "won't change db if data is missing" do + invalid_rental_info = { + rental: { + customer_id: customer_one.id, + movie_id: movie_one.id, + due_date: "2019-11-14", + # checkout_date: "2019-11-07", + } + } + + proc { + post checkout_path(params: invalid_rental_info) + }.wont_change 'Rental.count' + + must_respond_with :bad_request + body = JSON.parse(response.body) + #this error message could change but just a sample of what we might want to output + body.must_equal "errors" => {"checkout_date" => ["can't be blank"]} + end + end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index b5d70dd7d..1babc4714 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -98,7 +98,7 @@ it "will reduce the inventory of a movie by one" do movie = movies(:movie_one) start_inventory = movie.inventory - movie.reduce_inventory + movie.reduce_inventory! movie.inventory.must_equal start_inventory - 1 end end @@ -107,7 +107,7 @@ it "will reduce the inventory of a movie by one" do movie = movies(:movie_one) start_inventory = movie.inventory - movie.increase_inventory + movie.increase_inventory! movie.inventory.must_equal start_inventory + 1 end end From e4fa2a97ae0655738c4fe65c952088e7ae3783dd Mon Sep 17 00:00:00 2001 From: Kimberley Zell Date: Tue, 7 Nov 2017 18:54:50 -0800 Subject: [PATCH 47/53] Added model method for overdue and controller method for overdue and a route --- app/controllers/rentals_controller.rb | 20 ++++++++++++++----- app/models/rental.rb | 28 +++++++++++++++++++++------ config/routes.rb | 2 ++ 3 files changed, 39 insertions(+), 11 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 9149adec4..c49c9d0ed 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -53,18 +53,28 @@ def check_in return else rental.checkin_date = Date.today - rental.save - rental.movie.increase_inventory! + if rental.save - render( - json: { } - ) + rental.movie.increase_inventory! + + render( + json: {id: rental.id}, status: :ok + ) + else + render( + json: {errors: rental.error.messages}, status: :bad_request + ) + end end end def overdue + # overdue_rentals = Rental.find_overdue + render( + json: Rental.find_overdue.as_json, status: :ok + ) end diff --git a/app/models/rental.rb b/app/models/rental.rb index a04dca36b..19d071470 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -8,11 +8,27 @@ class Rental < ApplicationRecord validates :due_date, presence: true - # def inventory? - # movie = movie.find_by(id: params[:movie_id]) - # if movie.inventory < 1 - # return false - # end - # end + def self.find_overdue + #first check that check-in date is nil + #then check if today's date is past the due date + overdue_rentals = Rental.where(checkin_date: nil).where("due_date < ?", Date.today) + + overdue_rentals_array = [] + + overdue_rentals.each do |rental| + c = rental.customer + overdue = { + title: rental.movie.title, + customer_id: rental.customer_id, + name: c.name, + postal_code: c.postal_code, + checkout_date: rental.checkout_date, + due_date: rental.due_date + } + overdue_rentals_array << overdue + end + + return overdue_rentals_array + end end diff --git a/config/routes.rb b/config/routes.rb index 3f1f6ba4a..01ada24de 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,4 +8,6 @@ post 'rentals/checkout', to: 'rentals#checkout', as: 'checkout' + get 'rentals/overdue', to: 'rentals#overdue', as: 'overdue' + end From e16326c3f7790b874fdfd83403d7f77db02a2ebd Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Wed, 8 Nov 2017 11:07:17 -0800 Subject: [PATCH 48/53] Migrations for date types made for customers registered at and rentals checkout date, due date, and checkin date --- ...ange_customers_registered_at_from_string_to_date.rb | 5 +++++ ...als_data_for_checkout_date_due_date_checkin_date.rb | 7 +++++++ db/schema.rb | 10 +++++----- 3 files changed, 17 insertions(+), 5 deletions(-) create mode 100644 db/migrate/20171108185147_change_customers_registered_at_from_string_to_date.rb create mode 100644 db/migrate/20171108190434_change_rentals_data_for_checkout_date_due_date_checkin_date.rb diff --git a/db/migrate/20171108185147_change_customers_registered_at_from_string_to_date.rb b/db/migrate/20171108185147_change_customers_registered_at_from_string_to_date.rb new file mode 100644 index 000000000..813bd6513 --- /dev/null +++ b/db/migrate/20171108185147_change_customers_registered_at_from_string_to_date.rb @@ -0,0 +1,5 @@ +class ChangeCustomersRegisteredAtFromStringToDate < ActiveRecord::Migration[5.1] + def change + change_column :customers, :registered_at, 'date USING CAST(registered_at AS date)' + end +end diff --git a/db/migrate/20171108190434_change_rentals_data_for_checkout_date_due_date_checkin_date.rb b/db/migrate/20171108190434_change_rentals_data_for_checkout_date_due_date_checkin_date.rb new file mode 100644 index 000000000..ce9c6856d --- /dev/null +++ b/db/migrate/20171108190434_change_rentals_data_for_checkout_date_due_date_checkin_date.rb @@ -0,0 +1,7 @@ +class ChangeRentalsDataForCheckoutDateDueDateCheckinDate < ActiveRecord::Migration[5.1] + def change + change_column :rentals, :checkout_date, 'date USING CAST(checkout_date AS date)' + change_column :rentals, :due_date, 'date USING CAST(due_date AS date)' + change_column :rentals, :checkin_date, 'date USING CAST(checkin_date AS date)' + end +end diff --git a/db/schema.rb b/db/schema.rb index 9eef14cbb..d384a5aed 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,14 +10,14 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171107195527) do +ActiveRecord::Schema.define(version: 20171108190434) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" create_table "customers", force: :cascade do |t| t.string "name" - t.string "registered_at" + t.date "registered_at" t.string "address" t.string "city" t.string "state" @@ -40,11 +40,11 @@ create_table "rentals", force: :cascade do |t| t.integer "customer_id" t.integer "movie_id" - t.string "checkout_date" - t.string "due_date" + t.date "checkout_date" + t.date "due_date" t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.string "checkin_date" + t.date "checkin_date" end end From 4fe821bd3a3f224f03629265bf1a95998849804c Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Wed, 8 Nov 2017 11:16:14 -0800 Subject: [PATCH 49/53] Change to customers controller tests to account for change in date type --- test/controllers/customers_controller_test.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 18b710550..ac2e1cb87 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -70,7 +70,7 @@ customer_data = { name: "name", phone: "phone", - registered_at: "registered at", + registered_at: Date.today, address: "address", city: "city", state: "state", @@ -87,7 +87,7 @@ it "won't change db if data is missing" do invalid_customer_data = { name: "name", - registered_at: "registered at", + registered_at: Date.today, address: "address", city: "city", state: "state", From cce67b6491ad05f7175c5d92961ba315b7cc2fcb Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Wed, 8 Nov 2017 12:12:38 -0800 Subject: [PATCH 50/53] Add migrations to include an additional column to movies and customers and changes in the controller to allow smoke tests to pass --- app/controllers/customers_controller.rb | 2 +- app/controllers/movies_controller.rb | 2 +- app/controllers/rentals_controller.rb | 52 +++++++++---------- config/routes.rb | 2 + ...95943_add_available_inventory_to_movies.rb | 5 ++ ..._add_movies_checked_out_count_customers.rb | 5 ++ db/schema.rb | 4 +- test/controllers/rentals_controller_test.rb | 32 +++++++++++- 8 files changed, 74 insertions(+), 30 deletions(-) create mode 100644 db/migrate/20171108195943_add_available_inventory_to_movies.rb create mode 100644 db/migrate/20171108200209_add_movies_checked_out_count_customers.rb diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 813f87cbf..1de34aebc 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -3,7 +3,7 @@ class CustomersController < ApplicationController def index customers = Customer.all render( - :json => customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]), status: :ok + :json => customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone, :movies_checked_out_count]), status: :ok ) end diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 9b4e14a7b..2e5a530e6 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -20,7 +20,7 @@ def show if movie render( - :json => movie.as_json(only: [:title, :overview, :release_date, :inventory]), + :json => movie.as_json(only: [:title, :overview, :release_date, :inventory, :available_inventory]), status: :ok ) else diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index c49c9d0ed..97c24082e 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,13 +1,13 @@ class RentalsController < ApplicationController - def index - rentals = Rental.all - - render( - :json => rentals.as_json(only: [:customer_id, :movie_id, :checkout_id, :due_date]), - status: :ok - ) - end + # def index + # rentals = Rental.all + # + # render( + # :json => rentals.as_json(only: [:customer_id, :movie_id, :checkout_id, :due_date]), + # status: :ok + # ) + # end def checkout rental = Rental.new(rental_params) @@ -23,8 +23,8 @@ def checkout unless movie.check_inventory? render( - json: {errors: ["Not enough inventory"]}, - status: :bad_request + json: {errors: ["Not enough inventory"]}, + status: :bad_request ) return end @@ -32,17 +32,16 @@ def checkout if rental.save movie.reduce_inventory! render( - json: {id: rental.id}, status: :ok + json: {id: rental.id}, status: :ok ) else render( - json: {errors: rental.errors.messages}, status: :bad_request + json: {errors: rental.errors.messages}, status: :bad_request ) end end - def check_in - # find the rental instance + def checkin rental = Rental.where(customer_id: params[:customer_id], movie_id: params[:movie_id]).order(due_date: :asc).first if rental.nil? @@ -54,18 +53,19 @@ def check_in else rental.checkin_date = Date.today - if rental.save + if rental.save - rental.movie.increase_inventory! - - render( - json: {id: rental.id}, status: :ok - ) - else - render( - json: {errors: rental.error.messages}, status: :bad_request - ) - end + rental.movie.increase_inventory! + render( + json: {id: rental.id}, + status: :ok + ) + else + render( + json: {errors: rental.error.messages}, + status: :bad_request + ) + end end end @@ -73,7 +73,7 @@ def overdue # overdue_rentals = Rental.find_overdue render( - json: Rental.find_overdue.as_json, status: :ok + json: Rental.find_overdue.as_json, status: :ok ) end diff --git a/config/routes.rb b/config/routes.rb index 01ada24de..78fc44274 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,8 @@ post 'rentals/checkout', to: 'rentals#checkout', as: 'checkout' + post 'rentals/checkin', to: 'rentals#checkin', as: 'checkin' + get 'rentals/overdue', to: 'rentals#overdue', as: 'overdue' end diff --git a/db/migrate/20171108195943_add_available_inventory_to_movies.rb b/db/migrate/20171108195943_add_available_inventory_to_movies.rb new file mode 100644 index 000000000..8d07ed201 --- /dev/null +++ b/db/migrate/20171108195943_add_available_inventory_to_movies.rb @@ -0,0 +1,5 @@ +class AddAvailableInventoryToMovies < ActiveRecord::Migration[5.1] + def change + add_column :movies, :available_inventory, :integer + end +end diff --git a/db/migrate/20171108200209_add_movies_checked_out_count_customers.rb b/db/migrate/20171108200209_add_movies_checked_out_count_customers.rb new file mode 100644 index 000000000..b1be8c824 --- /dev/null +++ b/db/migrate/20171108200209_add_movies_checked_out_count_customers.rb @@ -0,0 +1,5 @@ +class AddMoviesCheckedOutCountCustomers < ActiveRecord::Migration[5.1] + def change + add_column :customers, :movies_checked_out_count, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index d384a5aed..f83ed9ae6 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20171108190434) do +ActiveRecord::Schema.define(version: 20171108200209) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -26,6 +26,7 @@ t.float "account_credit", default: 0.0 t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "movies_checked_out_count" end create_table "movies", force: :cascade do |t| @@ -35,6 +36,7 @@ t.integer "inventory" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "available_inventory" end create_table "rentals", force: :cascade do |t| diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index cebc2762c..c14fe0b3b 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -32,7 +32,7 @@ response.header['Content-Type'].must_include 'json' end - it "returns an Array" do + it "returns a hash" do valid_rental_info = { rental: { customer_id: customer_one.id, @@ -142,4 +142,34 @@ body.must_equal "errors" => {"checkout_date" => ["can't be blank"]} end + describe "check_in" do + let(:rental_one) { rentals :rental_one} + let(:customer_one) { customers :customer_one} + let(:movie_one) { movies :movie_one} + + it "is a working route" do + post checkin_path(params: {customer_id: customer_one.id, movie_id: movie_one.id}) + must_respond_with :ok + end + + it "returns a json" do + post checkin_path(params: {customer_id: customer_one.id, movie_id: movie_one.id}) + response.header['Content-Type'].must_include 'json' + end + + it "returns a hash" do + post checkin_path(params: {customer_id: customer_one.id, movie_id: movie_one.id}) + body = JSON.parse(response.body) + body.must_be_kind_of Hash + end + + it "changes check_in from nil to today's date" do + + end + end + + describe "overdue" do + end + + end From b50c087402fe488b2ee4130664c1431717ff4572 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Wed, 8 Nov 2017 12:15:55 -0800 Subject: [PATCH 51/53] Add additional data to yaml files --- test/fixtures/customers.yml | 2 ++ test/fixtures/movies.yml | 3 +++ 2 files changed, 5 insertions(+) diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index 93a6d9ebf..841f83298 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -13,6 +13,7 @@ customer_one: postal_code: "12345" phone: "12345678" account_credit: 12.34 + movies_checked_out_count: 0 customer_two: name: Betsy @@ -23,3 +24,4 @@ customer_two: postal_code: "12345" phone: "56789043" account_credit: 12.34 + movies_checked_out_count: 0 diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index 63d60addd..3ec0992f2 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -9,15 +9,18 @@ movie_one: overview: "Lovely drama" release_date: "1950" inventory: 2 + available_inventory: 2 movie_two: title: "Hitchiker's Guide to the Galaxy" overview: "Philosophical fiction" release_date: "2000" inventory: 3 + available_inventory: 3 movie_three: title: "Sharknato" overview: "Just Because" release_date: "1995" inventory: 5 + available_inventory: 5 From e9010a06b3bd6b38779b7450f9193dbf1c9e11c8 Mon Sep 17 00:00:00 2001 From: Bianca M Fernandez Date: Wed, 8 Nov 2017 12:36:01 -0800 Subject: [PATCH 52/53] Changes to tests to factor with additional columns added to movies and customers --- app/models/movie.rb | 7 +- db/seeds/movies.json | 300 ++++++++++++------ test/controllers/customers_controller_test.rb | 2 +- test/controllers/rentals_controller_test.rb | 2 +- test/models/movie_test.rb | 11 +- 5 files changed, 211 insertions(+), 111 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index d49cb7a95..cc1a7b611 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -9,8 +9,7 @@ class Movie < ApplicationRecord def check_inventory? - - if self.inventory < 1 + if self.available_inventory < 1 return false else return true @@ -18,13 +17,13 @@ def check_inventory? end def reduce_inventory! - self.inventory = self.inventory - 1 + self.available_inventory = self.available_inventory - 1 self.save end def increase_inventory! - self.inventory = self.inventory + 1 + self.available_inventory = self.available_inventory + 1 self.save end diff --git a/db/seeds/movies.json b/db/seeds/movies.json index 98c6cf8e3..2701c9a19 100644 --- a/db/seeds/movies.json +++ b/db/seeds/movies.json @@ -3,600 +3,700 @@ "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 +"inventory": 8, +"available_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 +"inventory": 6, +"available_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 +"inventory": 7, +"available_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 +"inventory": 10, +"available_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 +"inventory": 3, +"available_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 +"inventory": 4, +"available_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 +"inventory": 1, +"available_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 +"inventory": 8, +"available_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 +"inventory": 2, +"available_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 +"inventory": 9, +"available_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 +"inventory": 5, +"available_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 +"inventory": 10, +"available_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 +"inventory": 4, +"available_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 +"inventory": 10, +"available_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 +"inventory": 2, +"available_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 +"inventory": 6, +"available_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 +"inventory": 1, +"available_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 +"inventory": 10, +"available_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 +"inventory": 4, +"available_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 +"inventory": 4, +"available_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 +"inventory": 4, +"available_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 +"inventory": 4, +"available_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 +"inventory": 6, +"available_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 +"inventory": 5, +"available_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 +"inventory": 5, +"available_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 +"inventory": 2, +"available_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 +"inventory": 2, +"available_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 +"inventory": 8, +"available_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 +"inventory": 3, +"available_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 +"inventory": 4, +"available_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 +"inventory": 3, +"available_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 +"inventory": 9, +"available_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 +"inventory": 9, +"available_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 +"inventory": 9, +"available_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 +"inventory": 4, +"available_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 +"inventory": 8, +"available_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 +"inventory": 8, +"available_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 +"inventory": 1, +"available_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 +"inventory": 4, +"available_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 +"inventory": 7, +"available_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 +"inventory": 4, +"available_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 +"inventory": 7, +"available_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 +"inventory": 1, +"available_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 +"inventory": 2, +"available_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 +"inventory": 2, +"available_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 +"inventory": 3, +"available_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 +"inventory": 1, +"available_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 +"inventory": 6, +"available_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 +"inventory": 5, +"available_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 +"inventory": 1, +"available_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 +"inventory": 2, +"available_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 +"inventory": 10, +"available_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 +"inventory": 10, +"available_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 +"inventory": 5, +"available_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 +"inventory": 6, +"available_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 +"inventory": 8, +"available_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 +"inventory": 4, +"available_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 +"inventory": 9, +"available_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 +"inventory": 10, +"available_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 +"inventory": 6, +"available_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 +"inventory": 3, +"available_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 +"inventory": 4, +"available_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 +"inventory": 7, +"available_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 +"inventory": 5, +"available_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 +"inventory": 10, +"available_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 +"inventory": 1, +"available_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 +"inventory": 4, +"available_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 +"inventory": 4, +"available_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 +"inventory": 2 , +"available_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 +"inventory": 9, +"available_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 +"inventory": 1, +"available_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 +"inventory": 1, +"available_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 +"inventory": 5, +"available_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 +"inventory": 9, +"available_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 +"inventory": 9, +"available_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 +"inventory": 4, +"available_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 +"inventory": 1, +"available_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 +"inventory": 8, +"available_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 +"inventory": 10, +"available_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 +"inventory": 3, +"available_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 +"inventory": 1, +"available_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 +"inventory": 4, +"available_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 +"inventory": 4, +"available_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 +"inventory": 4, +"available_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 +"inventory": 9, +"available_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 +"inventory": 8, +"available_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 +"inventory": 10, +"available_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 +"inventory": 9, +"available_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 +"inventory": 3, +"available_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 +"inventory": 3, +"available_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 +"inventory": 9, +"available_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 +"inventory": 5, +"available_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 +"inventory": 9, +"available_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 +"inventory": 4, +"available_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 +"inventory": 3, +"available_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 +"inventory": 7, +"available_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 +"inventory": 6, +"available_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 +"inventory": 4, +"available_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 +"inventory": 10, +"available_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 +"inventory": 3, +"available_inventory": 3 } ] diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index ac2e1cb87..11fa3bb27 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -27,7 +27,7 @@ end it "returns customers with exactly the required fields" do - keys = %w(id name phone postal_code registered_at) + keys = %w(id movies_checked_out_count name phone postal_code registered_at) get customers_path body = JSON.parse(response.body) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index c14fe0b3b..9e460f646 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -81,7 +81,7 @@ end it "returns an error message if not enough inventory" do - movie = Movie.create(title: "title", overview: "Great story", inventory: 0, release_date: "2017-4-17") + movie = Movie.create(title: "title", overview: "Great story", inventory: 0, available_inventory: 0, release_date: "2017-4-17") rental_info = { rental: { diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 1babc4714..7af0a764d 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -78,7 +78,8 @@ title: "Jack", overview: "Blahblah", release_date: "1984", - inventory: 0 + inventory: 0, + available_inventory: 0 } @@ -97,18 +98,18 @@ describe "reduce inventory" do it "will reduce the inventory of a movie by one" do movie = movies(:movie_one) - start_inventory = movie.inventory + start_inventory = movie.available_inventory movie.reduce_inventory! - movie.inventory.must_equal start_inventory - 1 + movie.available_inventory.must_equal start_inventory - 1 end end describe "increase inventory" do it "will reduce the inventory of a movie by one" do movie = movies(:movie_one) - start_inventory = movie.inventory + start_inventory = movie.available_inventory movie.increase_inventory! - movie.inventory.must_equal start_inventory + 1 + movie.available_inventory.must_equal start_inventory + 1 end end end From 7965d1433ca8a81f7a4c0cb6d087579621eb5fc1 Mon Sep 17 00:00:00 2001 From: Kimberley Date: Mon, 14 May 2018 22:02:52 -0700 Subject: [PATCH 53/53] Update README.md --- README.md | 25 +++---------------------- 1 file changed, 3 insertions(+), 22 deletions(-) diff --git a/README.md b/README.md index 7db80e4ca..8de70751a 100644 --- a/README.md +++ b/README.md @@ -1,24 +1,5 @@ -# README +# README - VideoStoreAPI -This README would normally document whatever steps are necessary to get the -application up and running. +API used with database to keep track of customers, movie inventory, due dates, etc, for a video store. -Things you may want to cover: - -* Ruby version - -* System dependencies - -* Configuration - -* Database creation - -* Database initialization - -* How to run the test suite - -* Services (job queues, cache servers, search engines, etc.) - -* Deployment instructions - -* ... +* Ruby on Rails API using Rails 5.1.4