From 2feed6121290e9a3226c6c4931dfd3479564093d Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 13:17:53 -0700 Subject: [PATCH 01/57] initial rails api setup --- .DS_Store | Bin 0 -> 6148 bytes .gitignore | 23 ++ .ruby-version | 1 + Gemfile | 54 +++ Gemfile.lock | 169 ++++++++++ Guardfile | 9 + README.md | 313 +----------------- 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 | 33 ++ bin/spring | 17 + bin/update | 28 ++ config.ru | 5 + config/application.rb | 41 +++ config/boot.rb | 4 + config/cable.yml | 10 + config/credentials.yml.enc | 1 + config/database.yml | 85 +++++ config/environment.rb | 5 + config/environments/development.rb | 54 +++ config/environments/production.rb | 85 +++++ config/environments/test.rb | 46 +++ config/initializers/action_view.rb | 1 + .../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 | 34 ++ config/routes.rb | 3 + config/spring.rb | 6 + config/storage.yml | 34 ++ lib/tasks/.keep | 0 log/.keep | 0 public/robots.txt | 1 + storage/.keep | 0 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 | 24 ++ tmp/.keep | 0 vendor/.keep | 0 60 files changed, 948 insertions(+), 300 deletions(-) create mode 100644 .DS_Store create mode 100644 .gitignore create mode 100644 .ruby-version create mode 100644 Gemfile create mode 100644 Gemfile.lock create mode 100644 Guardfile 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/credentials.yml.enc 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/action_view.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/spring.rb create mode 100644 config/storage.yml create mode 100644 lib/tasks/.keep create mode 100644 log/.keep create mode 100644 public/robots.txt create mode 100644 storage/.keep 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/.DS_Store b/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..01e759cd4f20e2ad82e6b9416af746549b20ad57 GIT binary patch literal 6148 zcmeHKO>Wab6n>MK#z|EXB&2rf4HAojQZ(BC=5!ts1IJjOV$m zSV@oE01A$A5G8#tN<8#ApfRI>QQ+@ZfZtthl%pEx3bxMB*%$xz%N^y8FC`%yHSHM1D~_!P%^EylFbpU(;{iC<@c8 z(fBS(W$W5n#kOm9ZKL+4cbrUnnVU`0jyrzEy{B$=?CJLNB#AECuJnyq`=PP4f?-*#rLRs-$b`}29# z-n_N*;NWO@_HOom{^2tcfeCB}(ynVfhc9SI0Zx14I7;FH`pjL2*a3c!1`FAz6G%BE zzaS+q=dw%{dJLbTT&Sq{aPhJVJGZPMxGo;XfYN+qUe+Afre|QDfXNTRN^D-#9KQJ?^xoThea9RNAaZ-$T7!5%2#E2k?i%Wx`2sm6fg?>vkLI{!9ihcYg{Ol zpAJ;=2mrJ&EDde>*B|Kc0I;obp%5c5p+%ezQ{Dng0PC{N8arBji zKA{MG@DPrqlV~e6wNbz*kXN9rx^>?F_kVx>&pVl(QNSqhUnwB0Zm-)xN_uZyNsjkg u2jvKbjd=@&(gl^?j%9 5.2.3' +# Use postgresql as the database for Active Record +gem 'pg', '>= 0.18', '< 2.0' +# Use Puma as the app server +gem 'puma', '~> 3.11' +# 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', '~> 4.0' +# Use ActiveModel has_secure_password +# gem 'bcrypt', '~> 3.1.7' + +# Use ActiveStorage variant +# gem 'mini_magick', '~> 4.8' + +# Use Capistrano for deployment +# gem 'capistrano-rails', group: :development + +# Reduces boot times through caching; required in config/boot.rb +gem 'bootsnap', '>= 1.1.0', require: false + +# 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] + +group :development, :test do + gem 'pry-rails' +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..c2391c2f9 --- /dev/null +++ b/Gemfile.lock @@ -0,0 +1,169 @@ +GEM + remote: https://rubygems.org/ + specs: + actioncable (5.2.3) + actionpack (= 5.2.3) + nio4r (~> 2.0) + websocket-driver (>= 0.6.1) + actionmailer (5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + mail (~> 2.5, >= 2.5.4) + rails-dom-testing (~> 2.0) + actionpack (5.2.3) + actionview (= 5.2.3) + activesupport (= 5.2.3) + rack (~> 2.0) + rack-test (>= 0.6.3) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.2) + actionview (5.2.3) + activesupport (= 5.2.3) + builder (~> 3.1) + erubi (~> 1.4) + rails-dom-testing (~> 2.0) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + activejob (5.2.3) + activesupport (= 5.2.3) + globalid (>= 0.3.6) + activemodel (5.2.3) + activesupport (= 5.2.3) + activerecord (5.2.3) + activemodel (= 5.2.3) + activesupport (= 5.2.3) + arel (>= 9.0) + activestorage (5.2.3) + actionpack (= 5.2.3) + activerecord (= 5.2.3) + marcel (~> 0.3.1) + activesupport (5.2.3) + concurrent-ruby (~> 1.0, >= 1.0.2) + i18n (>= 0.7, < 2) + minitest (~> 5.1) + tzinfo (~> 1.1) + ansi (1.5.0) + arel (9.0.0) + bootsnap (1.4.4) + msgpack (~> 1.0) + builder (3.2.3) + byebug (11.0.1) + coderay (1.1.2) + concurrent-ruby (1.1.5) + crass (1.0.4) + erubi (1.8.0) + ffi (1.10.0) + globalid (0.4.2) + activesupport (>= 4.2.0) + i18n (1.6.0) + concurrent-ruby (~> 1.0) + listen (3.1.5) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + ruby_dep (~> 1.2) + loofah (2.2.3) + crass (~> 1.0.2) + nokogiri (>= 1.5.9) + mail (2.7.1) + mini_mime (>= 0.1.1) + marcel (0.3.3) + mimemagic (~> 0.3.2) + method_source (0.9.2) + mimemagic (0.3.3) + mini_mime (1.0.1) + mini_portile2 (2.4.0) + minitest (5.11.3) + minitest-rails (3.0.0) + minitest (~> 5.8) + railties (~> 5.0) + minitest-reporters (1.3.6) + ansi + builder + minitest (>= 5.0) + ruby-progressbar + msgpack (1.2.10) + nio4r (2.3.1) + nokogiri (1.10.3) + mini_portile2 (~> 2.4.0) + pg (1.1.4) + pry (0.12.2) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + pry-rails (0.3.9) + pry (>= 0.10.4) + puma (3.12.1) + rack (2.0.7) + rack-test (1.1.0) + rack (>= 1.0, < 3) + rails (5.2.3) + actioncable (= 5.2.3) + actionmailer (= 5.2.3) + actionpack (= 5.2.3) + actionview (= 5.2.3) + activejob (= 5.2.3) + activemodel (= 5.2.3) + activerecord (= 5.2.3) + activestorage (= 5.2.3) + activesupport (= 5.2.3) + bundler (>= 1.3.0) + railties (= 5.2.3) + sprockets-rails (>= 2.0.0) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) + rails-html-sanitizer (1.0.4) + loofah (~> 2.2, >= 2.2.2) + railties (5.2.3) + actionpack (= 5.2.3) + activesupport (= 5.2.3) + method_source + rake (>= 0.8.7) + thor (>= 0.19.0, < 2.0) + rake (12.3.2) + rb-fsevent (0.10.3) + rb-inotify (0.10.0) + ffi (~> 1.0) + ruby-progressbar (1.10.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.2) + 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.3) + thread_safe (0.3.6) + tzinfo (1.2.5) + thread_safe (~> 0.1) + websocket-driver (0.7.0) + websocket-extensions (>= 0.1.0) + websocket-extensions (0.1.3) + +PLATFORMS + ruby + +DEPENDENCIES + bootsnap (>= 1.1.0) + byebug + listen (>= 3.0.5, < 3.2) + minitest-rails + minitest-reporters + pg (>= 0.18, < 2.0) + pry-rails + puma (~> 3.11) + rails (~> 5.2.3) + spring + spring-watcher-listen (~> 2.0.0) + tzinfo-data + +RUBY VERSION + ruby 2.4.1p111 + +BUNDLED WITH + 1.16.6 diff --git a/Guardfile b/Guardfile new file mode 100644 index 000000000..e34f706f4 --- /dev/null +++ b/Guardfile @@ -0,0 +1,9 @@ +guard :minitest, autorun: false, spring: true do + watch(%r{^app/(.+).rb$}) { |m| "test/#{m[1]}_test.rb" } + watch(%r{^app/controllers/application_controller.rb$}) { 'test/controllers' } + watch(%r{^app/controllers/(.+)_controller.rb$}) { |m| "test/integration/#{m[1]}_test.rb" } + watch(%r{^app/views/(.+)_mailer/.+}) { |m| "test/mailers/#{m[1]}_mailer_test.rb" } + watch(%r{^lib/(.+).rb$}) { |m| "test/lib/#{m[1]}_test.rb" } + watch(%r{^test/.+_test.rb$}) + watch(%r{^test/test_helper.rb$}) { 'test' } +end diff --git a/README.md b/README.md index 5a23d9ab8..7db80e4ca 100644 --- a/README.md +++ b/README.md @@ -1,311 +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: -This project is due: **Friday May 17th** +* Ruby version -## Learning Goals -Upon completing this project, students should be able to: +* System dependencies -- 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 +* Configuration -This is a [stage 2](https://github.com/Ada-Developers-Academy/pedagogy/blob/master/rule-of-three.md) project. +* Database creation -## Success Criteria -Your project will be evaluated against the following requirements: +* Database initialization -- API conformity - - 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 - - Everything we've learned so far about how to design and build a Rails app still applies! +* How to run the test suite -## 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!" +* Services (job queues, cache servers, search engines, etc.) -## 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 +* Deployment instructions -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. - -### 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` | date | `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` | datetime | `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 and 3: 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? - -We have also included [this video](https://adaacademy.hosted.panopto.com/Panopto/Pages/Viewer.aspx?id=1324e06e-9767-49e4-85a0-a98c0122d69a) to show you how to run and use smoke tests. - -**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 - -### Wave 2: Customers and Movies - -#### `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 - -### Wave 3: 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, and the due date should be set to a week from 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 - -#### `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 - -## Optional Enhancements -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 11-20, sorted by ID -- `GET /customers?sort=name&n=10&p=2`: Customers 11-20, 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 /rentals/overdue` -List all customers with overdue movies - -Fields to return: -- `movie_id` -- `title` -- `customer_id` -- `name` -- `postal_code` -- `checkout_date` -- `due_date` - -#### `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) - -## What We're Looking For - -Check the [feedback template](./feedback.md) to see how we will evaluate your project. +* ... 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..f19acf5b5 --- /dev/null +++ b/bin/bundle @@ -0,0 +1,3 @@ +#!/usr/bin/env ruby +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) +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..a334d86a6 --- /dev/null +++ b/bin/setup @@ -0,0 +1,33 @@ +#!/usr/bin/env ruby +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +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..67d0d4964 --- /dev/null +++ b/bin/update @@ -0,0 +1,28 @@ +#!/usr/bin/env ruby +require 'fileutils' +include FileUtils + +# path to your application root. +APP_ROOT = File.expand_path('..', __dir__) + +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..641b5d08c --- /dev/null +++ b/config/application.rb @@ -0,0 +1,41 @@ +require_relative 'boot' + +require "rails" +# Pick the frameworks you want: +require "active_model/railtie" +require "active_job/railtie" +require "active_record/railtie" +require "active_storage/engine" +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.2 + + # Settings in config/environments/* take precedence over those specified here. + # Application configuration can go into files in config/initializers + # -- all .rb files in that directory are automatically loaded after loading + # the framework and any gems in your application. + + # 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..b9e460cef --- /dev/null +++ b/config/boot.rb @@ -0,0 +1,4 @@ +ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__) + +require 'bundler/setup' # Set up gems listed in the Gemfile. +require 'bootsnap/setup' # Speed up boot time by caching expensive operations. diff --git a/config/cable.yml b/config/cable.yml new file mode 100644 index 000000000..0d86702e8 --- /dev/null +++ b/config/cable.yml @@ -0,0 +1,10 @@ +development: + adapter: async + +test: + adapter: async + +production: + adapter: redis + url: <%= ENV.fetch("REDIS_URL") { "redis://localhost:6379/1" } %> + channel_prefix: VideoStoreAPI_production diff --git a/config/credentials.yml.enc b/config/credentials.yml.enc new file mode 100644 index 000000000..095a514f3 --- /dev/null +++ b/config/credentials.yml.enc @@ -0,0 +1 @@ +EhdFHpABlfaJyo5vp7e/9RpjqGFkYVyDNBuq+dC6QdiilHyNQTto0iFZREFN6jF+hQ2I9Zo/YagLTj48beTUbYsPEeiU1DaxtZxndNu6nhnTjrxL4JIDv7K985XP1eKzKStV8LpcjFtZH5GZn9YwMKq7iaM0tZRjrIiwc+tDgUaLFSVER0WlQo2/zf2m92dEKkZhY/DU5Xi0EtXGeNPChjYNJGeOnvuf+ajOuC0Tm88o75qNDk3l4E4oRup1U2zSI759bGDyZtk603K9SkJHdcOrXdo4E/aAyepA/g3M/S2sFMMx1iWqaE3skbNMp1Fia9DqT5tK1ZqhfvSgMisxafO/qN1GTwVrt0XGVy/uRuPvLiiNCv1B79s9UdQZQK/VobAVAOR5Xxteh5bBa0dh7XqJrrXVqI5jJMW0--VKAXyUl9ifyIB9K+--QIj3MH4C1+K1riYP/VukBg== \ No newline at end of file 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..d52ec9efb --- /dev/null +++ b/config/environments/development.rb @@ -0,0 +1,54 @@ +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. + # Run rails dev:cache to toggle caching. + 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.to_i}" + } + else + config.action_controller.perform_caching = false + + config.cache_store = :null_store + end + + # Store uploaded files on the local file system (see config/storage.yml for options) + config.active_storage.service = :local + + # 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 + + # Highlight code that triggered database queries in logs. + config.active_record.verbose_query_logs = true + + + # 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..5f44b9bda --- /dev/null +++ b/config/environments/production.rb @@ -0,0 +1,85 @@ +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 + + # Ensures that a master key has been made available in either ENV["RAILS_MASTER_KEY"] + # or in config/master.key. This key is used to decrypt credentials (and other encrypted files). + # config.require_master_key = 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 + + # Store uploaded files on the local file system (see config/storage.yml for options) + config.active_storage.service = :local + + # 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..0a38fd3ce --- /dev/null +++ b/config/environments/test.rb @@ -0,0 +1,46 @@ +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.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 + + # Store uploaded files on the local file system in a temporary directory + config.active_storage.service = :test + + 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/action_view.rb b/config/initializers/action_view.rb new file mode 100644 index 000000000..142d382f8 --- /dev/null +++ b/config/initializers/action_view.rb @@ -0,0 +1 @@ +Rails.application.config.action_view.form_with_generates_remote_forms = false 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..a5eccf816 --- /dev/null +++ b/config/puma.rb @@ -0,0 +1,34 @@ +# 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. +# +# preload_app! + +# 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/spring.rb b/config/spring.rb new file mode 100644 index 000000000..9fa7863f9 --- /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/config/storage.yml b/config/storage.yml new file mode 100644 index 000000000..d32f76e8f --- /dev/null +++ b/config/storage.yml @@ -0,0 +1,34 @@ +test: + service: Disk + root: <%= Rails.root.join("tmp/storage") %> + +local: + service: Disk + root: <%= Rails.root.join("storage") %> + +# Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) +# amazon: +# service: S3 +# access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> +# secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> +# region: us-east-1 +# bucket: your_own_bucket + +# Remember not to checkin your GCS keyfile to a repository +# google: +# service: GCS +# project: your_project +# credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> +# bucket: your_own_bucket + +# Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) +# microsoft: +# service: AzureStorage +# storage_account_name: your_account_name +# storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> +# container: your_container_name + +# mirror: +# service: Mirror +# primary: local +# mirrors: [ amazon, google, microsoft ] 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/storage/.keep b/storage/.keep new file mode 100644 index 000000000..e69de29bb 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..2b5172a7d --- /dev/null +++ b/test/test_helper.rb @@ -0,0 +1,24 @@ +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 ffef6d6b76ef0026a3fffca9f7e7a6b08632f03e Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Tue, 14 May 2019 13:33:36 -0700 Subject: [PATCH 02/57] Initial db setup --- app/models/customer.rb | 2 + app/models/movie.rb | 2 + app/models/rental.rb | 4 ++ db/migrate/20190514202648_create_movies.rb | 12 +++++ db/migrate/20190514202809_create_customers.rb | 15 ++++++ db/migrate/20190514203117_create_rentals.rb | 10 ++++ db/schema.rb | 50 +++++++++++++++++++ test/fixtures/customers.yml | 19 +++++++ test/fixtures/movies.yml | 13 +++++ test/fixtures/rentals.yml | 9 ++++ test/models/customer_test.rb | 9 ++++ test/models/movie_test.rb | 9 ++++ test/models/rental_test.rb | 9 ++++ 13 files changed, 163 insertions(+) create mode 100644 app/models/customer.rb create mode 100644 app/models/movie.rb create mode 100644 app/models/rental.rb create mode 100644 db/migrate/20190514202648_create_movies.rb create mode 100644 db/migrate/20190514202809_create_customers.rb create mode 100644 db/migrate/20190514203117_create_rentals.rb create mode 100644 db/schema.rb create mode 100644 test/fixtures/customers.yml create mode 100644 test/fixtures/movies.yml create mode 100644 test/fixtures/rentals.yml create mode 100644 test/models/customer_test.rb create mode 100644 test/models/movie_test.rb create mode 100644 test/models/rental_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/app/models/rental.rb b/app/models/rental.rb new file mode 100644 index 000000000..34d3f4df8 --- /dev/null +++ b/app/models/rental.rb @@ -0,0 +1,4 @@ +class Rental < ApplicationRecord + belongs_to :movie + belongs_to :customer +end diff --git a/db/migrate/20190514202648_create_movies.rb b/db/migrate/20190514202648_create_movies.rb new file mode 100644 index 000000000..acf6962ef --- /dev/null +++ b/db/migrate/20190514202648_create_movies.rb @@ -0,0 +1,12 @@ +class CreateMovies < ActiveRecord::Migration[5.2] + def change + create_table :movies do |t| + t.string :title + t.string :overview + t.date :release_date + t.integer :inventory + + t.timestamps + end + end +end diff --git a/db/migrate/20190514202809_create_customers.rb b/db/migrate/20190514202809_create_customers.rb new file mode 100644 index 000000000..bacf35c8f --- /dev/null +++ b/db/migrate/20190514202809_create_customers.rb @@ -0,0 +1,15 @@ +class CreateCustomers < ActiveRecord::Migration[5.2] + def change + create_table :customers do |t| + t.string :name + t.datetime :registered_at + t.string :address + t.string :city + t.string :state + t.string :postal_code + t.string :phone + + t.timestamps + end + end +end diff --git a/db/migrate/20190514203117_create_rentals.rb b/db/migrate/20190514203117_create_rentals.rb new file mode 100644 index 000000000..74e167e86 --- /dev/null +++ b/db/migrate/20190514203117_create_rentals.rb @@ -0,0 +1,10 @@ +class CreateRentals < ActiveRecord::Migration[5.2] + def change + create_table :rentals do |t| + t.references :movie, foreign_key: true + t.references :customer, foreign_key: true + + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb new file mode 100644 index 000000000..d41ffe73d --- /dev/null +++ b/db/schema.rb @@ -0,0 +1,50 @@ +# 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: 2019_05_14_203117) 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.datetime "registered_at" + t.string "address" + t.string "city" + t.string "state" + t.string "postal_code" + t.string "phone" + 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.date "release_date" + t.integer "inventory" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + create_table "rentals", force: :cascade do |t| + t.bigint "movie_id" + t.bigint "customer_id" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.index ["customer_id"], name: "index_rentals_on_customer_id" + t.index ["movie_id"], name: "index_rentals_on_movie_id" + end + + add_foreign_key "rentals", "customers" + add_foreign_key "rentals", "movies" +end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml new file mode 100644 index 000000000..2f7fe0fcf --- /dev/null +++ b/test/fixtures/customers.yml @@ -0,0 +1,19 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + name: MyString + registered_at: 2019-05-14 13:28:09 + address: MyString + city: MyString + state: MyString + postal_code: MyString + phone: MyString + +two: + name: MyString + registered_at: 2019-05-14 13:28:09 + address: MyString + city: MyString + state: MyString + postal_code: MyString + phone: MyString diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml new file mode 100644 index 000000000..e8afe187d --- /dev/null +++ b/test/fixtures/movies.yml @@ -0,0 +1,13 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + title: MyString + overview: MyString + release_date: 2019-05-14 + inventory: 1 + +two: + title: MyString + overview: MyString + release_date: 2019-05-14 + inventory: 1 diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml new file mode 100644 index 000000000..6a1ad3712 --- /dev/null +++ b/test/fixtures/rentals.yml @@ -0,0 +1,9 @@ +# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html + +one: + movie: one + customer: one + +two: + movie: two + customer: two 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 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 b824647b53ce39e7e929618d8d5380faba65739b Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 13:38:33 -0700 Subject: [PATCH 03/57] generated controllers --- .DS_Store | Bin 6148 -> 6148 bytes app/controllers/customers_controller.rb | 2 ++ app/controllers/movies_controller.rb | 2 ++ app/controllers/rentals_controller.rb | 2 ++ test/controllers/customers_controller_test.rb | 7 +++++++ test/controllers/movies_controller_test.rb | 7 +++++++ test/controllers/rentals_controller_test.rb | 7 +++++++ 7 files changed, 27 insertions(+) create mode 100644 app/controllers/customers_controller.rb create mode 100644 app/controllers/movies_controller.rb create mode 100644 app/controllers/rentals_controller.rb create mode 100644 test/controllers/customers_controller_test.rb create mode 100644 test/controllers/movies_controller_test.rb create mode 100644 test/controllers/rentals_controller_test.rb diff --git a/.DS_Store b/.DS_Store index 01e759cd4f20e2ad82e6b9416af746549b20ad57..012e1c9ab95d24af0d23371e8ddbda11ca6d95dd 100644 GIT binary patch delta 20 bcmZoMXffDe#>Q@8s-s|HV!qjy?YJNSJAMU% delta 20 bcmZoMXffDe#>Q@Ls-s|HV!YXw?YJNSJ6Z*O 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/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb new file mode 100644 index 000000000..6c4c51614 --- /dev/null +++ b/app/controllers/movies_controller.rb @@ -0,0 +1,2 @@ +class MoviesController < ApplicationController +end 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/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 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 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 c5cf4168cacbfd12d7e6970783cc97863056b90d Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 13:53:36 -0700 Subject: [PATCH 04/57] added routes --- config/routes.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 787824f88..3f106f46a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ Rails.application.routes.draw do - # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html + resources :customers, only: [:index] + resources :movies, only: [:index, :show, :create] end From e2665db24b11737f9a8b46a0471a11cc163f6e75 Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Tue, 14 May 2019 13:55:09 -0700 Subject: [PATCH 05/57] Added validations for customer and movie --- app/controllers/movies_controller.rb | 3 +++ app/models/customer.rb | 3 +++ app/models/movie.rb | 3 +++ config/routes.rb | 1 + 4 files changed, 10 insertions(+) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 6c4c51614..885d235f9 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -1,2 +1,5 @@ class MoviesController < ApplicationController + def zomg + render json: { ready_for_lunch: "It works" } + end end diff --git a/app/models/customer.rb b/app/models/customer.rb index 0b5277335..761d24808 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,2 +1,5 @@ class Customer < ApplicationRecord + has_many :rentals + + validates :name end diff --git a/app/models/movie.rb b/app/models/movie.rb index dc614df15..b8d770e21 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,2 +1,5 @@ class Movie < ApplicationRecord + has_many :rentals + + validates :title end diff --git a/config/routes.rb b/config/routes.rb index 787824f88..7ae6ef2e9 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,3 +1,4 @@ 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', as: 'zomg' end From 62aaff36b4afd17d4796c04b655fa0a15bec27b8 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 14:19:39 -0700 Subject: [PATCH 06/57] added create valid rental test --- test/controllers/rentals_controller_test.rb | 17 ++++++++++++++--- 1 file changed, 14 insertions(+), 3 deletions(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index f0227216c..863030cb4 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -1,7 +1,18 @@ require "test_helper" describe RentalsController do - # it "must be a real test" do - # flunk "Need real tests" - # end + describe "creating rental" do + let(:rental_data) { + { + movie_id: movies(:one).movie_id, + customer_id: customers(:one).id, + } + } + + it "can create a new rental provided valid data" do + expect { + post rental_path, params: rental_data + }.must_change "Rental.count", +1 + end + end end From 12724c8bd9de3a1cb175211ed9d92f99902eec2a Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 14:21:36 -0700 Subject: [PATCH 07/57] fleshed out valid new rental test --- test/controllers/rentals_controller_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 863030cb4..84557d4ba 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -13,6 +13,13 @@ expect { post rental_path, params: rental_data }.must_change "Rental.count", +1 + + new_rental = Rental.last + + must_respond_with :success + + body = JSON.parse(response.body) + expet(body).must_be_kind_of Hash end end end From 002679ca6dec7bf9e2c2f494f97aa1e0e50595a6 Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Tue, 14 May 2019 14:21:38 -0700 Subject: [PATCH 08/57] Added index to customer --- app/controllers/customers_controller.rb | 12 ++++++++++++ app/models/customer.rb | 2 +- app/models/movie.rb | 2 +- config/routes.rb | 3 ++- test/controllers/customers_controller_test.rb | 9 ++++++--- test/test_helper.rb | 3 ++- 6 files changed, 24 insertions(+), 7 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index ca3b6e024..854cbfc9c 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -1,2 +1,14 @@ class CustomersController < ApplicationController + + def index + customers = Customer.all + render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]) + 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 761d24808..431ece235 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,5 +1,5 @@ class Customer < ApplicationRecord has_many :rentals - validates :name + # validates :name end diff --git a/app/models/movie.rb b/app/models/movie.rb index b8d770e21..f2ba9e656 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,5 +1,5 @@ class Movie < ApplicationRecord has_many :rentals - validates :title + # validates :title end diff --git a/config/routes.rb b/config/routes.rb index 1091923b7..2b62ba77c 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,6 +1,7 @@ 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', as: 'zomg' + # get 'zomg', to: 'movies#zomg', as: 'zomg' resources :customers, only: [:index] resources :movies, only: [:index, :show, :create] + get 'zomg', to: 'movies#zomg', as: 'zomg' end diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 5e123f6cd..3f02cf17b 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -1,7 +1,10 @@ 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 + end end diff --git a/test/test_helper.rb b/test/test_helper.rb index 2b5172a7d..fb7dd505e 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,7 +1,8 @@ ENV["RAILS_ENV"] = "test" require File.expand_path("../../config/environment", __FILE__) require "rails/test_help" -require "minitest/rails"require "minitest/reporters" # for Colorized output +require "minitest/rails" +require "minitest/reporters" # for Colorized output # For colorful output! Minitest::Reporters.use!( Minitest::Reporters::SpecReporter.new, From 0b28dc62682ec210090fe0040f1862ca64823b10 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 14:23:34 -0700 Subject: [PATCH 09/57] added test for new rental w/ invalid customer id --- test/controllers/rentals_controller_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 84557d4ba..aa7d071f1 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -21,5 +21,15 @@ body = JSON.parse(response.body) expet(body).must_be_kind_of Hash end + + it "won't create new rental with invalid customer" do + rental_data["customer_id"] = -7 + + expect { + post rental_path, params: rental_data + }.wont_change "Rental.count" + + must_respond_with :bad_request + end end end From be39749254231bb0e6366785261b4b6b3014fac4 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 14:25:44 -0700 Subject: [PATCH 10/57] added test for new rental w/ invalid movie --- test/controllers/rentals_controller_test.rb | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index aa7d071f1..a953c5b90 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -31,5 +31,15 @@ must_respond_with :bad_request end + + it "won't create new rental with invalid movie" do + rental_data["movie_id"] = -7 + + expect { + post rental_path, params: rental_data + }.wont_change "Rental.count" + + must_respond_with :bad_request + end end end From fccbdafc6565cc56d4815ecfd1f5da22f48a2716 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 14:47:38 -0700 Subject: [PATCH 11/57] added movies fixtures --- test/fixtures/movies.yml | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index e8afe187d..ecff1cef1 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -1,13 +1,13 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - title: MyString - overview: MyString - release_date: 2019-05-14 - inventory: 1 + title: Avatar + overview: Blue aliens on beautiful planet defeat sky people. + release_date: 2009-12-18 + inventory: 5 two: - title: MyString - overview: MyString - release_date: 2019-05-14 - inventory: 1 + title: Star Wars + overview: A long time ago, in a galaxy far, far away. + release_date: 1977-05-25 + inventory: 20 From fbc79131e5b86fbc2af689b1beb9311e668a160e Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Tue, 14 May 2019 14:59:58 -0700 Subject: [PATCH 12/57] Added test to customer model --- app/controllers/customers_controller.rb | 2 +- app/models/customer.rb | 2 +- app/models/movie.rb | 2 +- test/fixtures/customers.yml | 24 ++++++++++++------------ test/models/customer_test.rb | 14 +++++++++++--- 5 files changed, 26 insertions(+), 18 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 854cbfc9c..19a187ffe 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -2,7 +2,7 @@ class CustomersController < ApplicationController def index customers = Customer.all - render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]) + render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]), status: :ok end diff --git a/app/models/customer.rb b/app/models/customer.rb index 431ece235..68e735ecb 100644 --- a/app/models/customer.rb +++ b/app/models/customer.rb @@ -1,5 +1,5 @@ class Customer < ApplicationRecord has_many :rentals - # validates :name + validates :name, presence: true end diff --git a/app/models/movie.rb b/app/models/movie.rb index f2ba9e656..00280a8e1 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,5 +1,5 @@ class Movie < ApplicationRecord has_many :rentals - # validates :title + validates :title, presence: true end diff --git a/test/fixtures/customers.yml b/test/fixtures/customers.yml index 2f7fe0fcf..000c74c64 100644 --- a/test/fixtures/customers.yml +++ b/test/fixtures/customers.yml @@ -1,19 +1,19 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - name: MyString + name: "Ana Maria" registered_at: 2019-05-14 13:28:09 - address: MyString - city: MyString - state: MyString - postal_code: MyString - phone: MyString + address: "200 S st" + city: "Seattle" + state: "WA" + postal_code: "98033" + phone: "425-555-5555" two: - name: MyString + name: "John Smith" registered_at: 2019-05-14 13:28:09 - address: MyString - city: MyString - state: MyString - postal_code: MyString - phone: MyString + address: "14 Av. S" + city: "Seattle" + state: "WA" + postal_code: "98033" + phone: "425-444-4444" diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 5ebc5c850..004b9b75c 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -1,9 +1,17 @@ require "test_helper" describe Customer do - let(:customer) { Customer.new } + let(:customer) { customers(:one) } - it "must be valid" do - value(customer).must_be :valid? + it "requires a name" do + required_fields = [:name] + + required_fields.each do |field| + customer[:name] = nil + + expect(customer.valid?).must_equal false + + customer.reload + end end end From 932e23fa7c09a5b777b04517655d9aef02d2ecc0 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:04:52 -0700 Subject: [PATCH 13/57] added movies index test 1 --- test/controllers/movies_controller_test.rb | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 67fabbcfb..4d2e69e73 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -1,7 +1,10 @@ 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 + end end From 56e0ba22e0f0067833ce4b84638e5e2246adedf9 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:09:11 -0700 Subject: [PATCH 14/57] added check for json and array in index test --- test/controllers/movies_controller_test.rb | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 4d2e69e73..63422625f 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -2,9 +2,18 @@ describe MoviesController do describe "index" do - it "is a working route" do + it "is a working route that returns a JSON array" do get movies_path + must_respond_with :success + expect(response.header["Content-Type"]).must_include "json" + + body = JSON.parse(response.body) + body.must_be_kind_of Array end + + # it "" do + + # end end end From 70fa899bc12d123c2738af2ddfa1f88e6eed6f91 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:11:14 -0700 Subject: [PATCH 15/57] added response length = movie count check --- test/controllers/movies_controller_test.rb | 1 + 1 file changed, 1 insertion(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 63422625f..80df016ce 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -10,6 +10,7 @@ body = JSON.parse(response.body) body.must_be_kind_of Array + body.length.must_equal Movie.count end # it "" do From 424c4158ade747381213c94a762b4e2a1b9f138c Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Tue, 14 May 2019 15:15:36 -0700 Subject: [PATCH 16/57] Added checked-out count column to customers table --- app/controllers/customers_controller.rb | 4 ++-- ...190514220941_add_movies_checked_out_count_to_customers.rb | 5 +++++ db/schema.rb | 3 ++- 3 files changed, 9 insertions(+), 3 deletions(-) create mode 100644 db/migrate/20190514220941_add_movies_checked_out_count_to_customers.rb diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 19a187ffe..962251b92 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -2,13 +2,13 @@ class CustomersController < ApplicationController def index customers = Customer.all - render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone]), status: :ok + render json: customers.as_json(only: [:id, :name, :registered_at, :postal_code, :phone, :movies_checked_out_count]), status: :ok end private def customer_params - params.require(:customer).permit(:name, :registered_at, :address, :city, :state, :postal_code, :phone) + params.require(:customer).permit(:name, :registered_at, :address, :city, :state, :postal_code, :phone, :movies_checked_out_count) end end diff --git a/db/migrate/20190514220941_add_movies_checked_out_count_to_customers.rb b/db/migrate/20190514220941_add_movies_checked_out_count_to_customers.rb new file mode 100644 index 000000000..dac80cbe6 --- /dev/null +++ b/db/migrate/20190514220941_add_movies_checked_out_count_to_customers.rb @@ -0,0 +1,5 @@ +class AddMoviesCheckedOutCountToCustomers < ActiveRecord::Migration[5.2] + def change + add_column :customers, :movies_checked_out_count, :integer, default: 0 + end +end diff --git a/db/schema.rb b/db/schema.rb index d41ffe73d..1a06ecb8b 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: 2019_05_14_203117) do +ActiveRecord::Schema.define(version: 2019_05_14_220941) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -25,6 +25,7 @@ t.string "phone" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.integer "movies_checked_out_count", default: 0 end create_table "movies", force: :cascade do |t| From eb87d6ae08fb53455106cf19bd75af390c6582f5 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:32:40 -0700 Subject: [PATCH 17/57] added movie field test --- test/controllers/movies_controller_test.rb | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 80df016ce..ac5a82b58 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -13,8 +13,15 @@ body.length.must_equal Movie.count end - # it "" do + it "returns correct movie fields" do + movie_fields = ["id", "release_date", "title", "overview", "inventory"] - # end + get movies_path + body = JSON.parse(response.body) + + body.each do |movie| + movie.keys.sort.must_equal movie_fields + end + end end end From 6a12ac9720e5e9ff5dbc6b7b2f7f214e38b53354 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:36:00 -0700 Subject: [PATCH 18/57] added movie sort tests --- test/controllers/movies_controller_test.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index ac5a82b58..25ce30540 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -23,5 +23,17 @@ movie.keys.sort.must_equal movie_fields end end + + it "can sort movies by their fields" do + get movies_path(sort: :title) + body = JSON.parse(response.body) + + must_respond_with :success + expect(body.first["title"]).must_equal movies(:one)["title"] + + get movies_path(sort: :release_date) + body = JSON.parse(response.body) + expect(body.first["title"]).must_equal movies(:two)["title"] + end end end From 25e083bd7dd2ba5423e995f573ccb9eb770c64f0 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:45:03 -0700 Subject: [PATCH 19/57] added test for create movie w/ valid data --- test/controllers/movies_controller_test.rb | 27 ++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 25ce30540..2b359da46 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -36,4 +36,31 @@ expect(body.first["title"]).must_equal movies(:two)["title"] end end + + describe "create" do + let(:movie_data) { + { + title: "Pulp Fiction", + overview: "Friends have fun in LA.", + release_date: "1994-10-14", + inventory: 3, + } + } + + it "creates new movie provided valid data" do + expect { + post movies_path, params: movie_data + }.must_change "Movie.count", +1 + + body = JSON.parse(response.body) + expect(body).must_be_kind_of Hash + expect(body).must_include "id" + + new_movie = Movie.find(body["id"].to_i) + + expect(new_movie.title).must_equal movie_data[:title] + + must_respond_with :success + end + end end From 74b2b3c76be732af6a1ec3fbab20bf99d8d5bfda Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 15:48:18 -0700 Subject: [PATCH 20/57] added create movie test for invalid data --- test/controllers/movies_controller_test.rb | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 2b359da46..12b4faa47 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -62,5 +62,20 @@ must_respond_with :success end + + it "does not create a new movie provided invalid data" do + movie_data[:title] = nil + + expect { + post movies_path, params: movie_data + }.wont_change "Movie.count" + + body = JSON.parse(response.body) + expect(body).must_be_kind_of Hash + expect(body).must_include "errors" + expect(body["errors"]).must_include "title" + + must_respond_with :bad_request + end end end From 0365f3f5bc45d70c80a599ba3755b4e21f09ab80 Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Tue, 14 May 2019 16:02:58 -0700 Subject: [PATCH 21/57] Added tests for json response in customer controller --- .DS_Store | Bin 6148 -> 6148 bytes test/controllers/customers_controller_test.rb | 49 ++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/.DS_Store b/.DS_Store index 012e1c9ab95d24af0d23371e8ddbda11ca6d95dd..fbcb3c8eeea8e7203bc3dc081189b7c2c8a9e8bb 100644 GIT binary patch delta 46 zcmZoMXfc@J&nUDpU^g?P&}JT%1 Date: Tue, 14 May 2019 16:03:24 -0700 Subject: [PATCH 22/57] added movies index method --- app/controllers/movies_controller.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 885d235f9..174b5ac2e 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -1,5 +1,11 @@ class MoviesController < ApplicationController def zomg - render json: { ready_for_lunch: "It works" } + render json: {ready_for_lunch: "It works"} + end + + def index + params[:sort] ? movies = Movie.order(params[:sort]) : movies = Movie.all + + render json: movies.as_json, status: :ok end end From 2c5c257368e6a523d1cbead7706d01ef3640b3f7 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 16:17:26 -0700 Subject: [PATCH 23/57] added movie show method and params --- app/controllers/movies_controller.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 174b5ac2e..43b0e5434 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -8,4 +8,27 @@ def index render json: movies.as_json, status: :ok end + + def show + movie = Movie.find_by(id: params[:id]) + + if movie.nil? + render json: { + errors: "Movie not found.", + }, status: :not_found + else + render json: { + title: movie.title, + overview: movie.overview, + release_date: movie.release_date, + inventory: movie.inventory, + }, status: :ok + end + end + + private + + def movie_params + params.permit(:title, :overview, :release_date, :inventory) + end end From 8bd03b351f55a35ea7d0029c1859ca6499bde031 Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 16:18:26 -0700 Subject: [PATCH 24/57] added create movie method --- app/controllers/movies_controller.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 43b0e5434..984660c8f 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -26,6 +26,18 @@ def show end end + def create + new_movie = Movie.new(movie_params) + + if new_movie.save + render json: new_movie.as_json(only: [:id]), status: :ok + else + render json: { + errors: new_movie.errors.messages, + }, status: :bad_request + end + end + private def movie_params From 7efcaad06d7ccca0380fbf9b96e723f7494f620c Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 16:19:07 -0700 Subject: [PATCH 25/57] edited variable name for consistency new_movie -> movie --- app/controllers/movies_controller.rb | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 984660c8f..07ff8140d 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -27,13 +27,13 @@ def show end def create - new_movie = Movie.new(movie_params) + movie = Movie.new(movie_params) - if new_movie.save + if movie.save render json: new_movie.as_json(only: [:id]), status: :ok else render json: { - errors: new_movie.errors.messages, + errors: movie.errors.messages, }, status: :bad_request end end From df2c3c2f020f7f5ddac1e8a19bf740c9330854ab Mon Sep 17 00:00:00 2001 From: laneia Date: Tue, 14 May 2019 16:43:12 -0700 Subject: [PATCH 26/57] all movies controller tests passing --- app/controllers/movies_controller.rb | 4 ++-- config/routes.rb | 3 ++- test/controllers/movies_controller_test.rb | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 07ff8140d..b574a6894 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -6,7 +6,7 @@ def zomg def index params[:sort] ? movies = Movie.order(params[:sort]) : movies = Movie.all - render json: movies.as_json, status: :ok + render json: movies.as_json(only: [:id, :inventory, :overview, :release_date, :title]), status: :ok end def show @@ -30,7 +30,7 @@ def create movie = Movie.new(movie_params) if movie.save - render json: new_movie.as_json(only: [:id]), status: :ok + render json: movie.as_json(only: [:id]), status: :ok else render json: { errors: movie.errors.messages, diff --git a/config/routes.rb b/config/routes.rb index 2b62ba77c..7099acd8f 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,5 +3,6 @@ # get 'zomg', to: 'movies#zomg', as: 'zomg' resources :customers, only: [:index] resources :movies, only: [:index, :show, :create] - get 'zomg', to: 'movies#zomg', as: 'zomg' + + get "zomg", to: "movies#zomg", as: "zomg" end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 12b4faa47..3b7385667 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -14,7 +14,7 @@ end it "returns correct movie fields" do - movie_fields = ["id", "release_date", "title", "overview", "inventory"] + movie_fields = ["id", "inventory", "overview", "release_date", "title"] get movies_path body = JSON.parse(response.body) From b480c67edabac86c13b7b9aac70a8df04fee7db8 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 11:49:39 -0700 Subject: [PATCH 27/57] added show movie valid id test --- test/controllers/movies_controller_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 3b7385667..11a0b2a7e 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -37,6 +37,13 @@ end end + describe "show" do + it "can show a movie" do + get movie_path(movies(:one).id) + must_respond_with :success + end + end + describe "create" do let(:movie_data) { { From 88fa6e162ad1e231d0b5beb2c86dd03ca5b01afb Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 11:51:45 -0700 Subject: [PATCH 28/57] added movie show test for invalid id --- test/controllers/movies_controller_test.rb | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 11a0b2a7e..caa097f14 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -38,10 +38,16 @@ end describe "show" do - it "can show a movie" do + it "can show a movie provided valid id" do get movie_path(movies(:one).id) must_respond_with :success end + + it "responds with not found for invalid/nonexistant movie" do + invalid_id = -7 + get movie_path(invalid_id) + must_respond_with :not_found + end end describe "create" do From 457e5e91e65b047d478f011b3b553aae999a33c5 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 11:58:01 -0700 Subject: [PATCH 29/57] added movie show correct fields test --- test/controllers/movies_controller_test.rb | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index caa097f14..cdafb0e6d 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -48,6 +48,15 @@ get movie_path(invalid_id) must_respond_with :not_found end + + it "returns correct movie fields" do + movie_fields = ["inventory", "overview", "release_date", "title"] + + get movie_path(movies(:one).id) + body = JSON.parse(response.body) + + expect(body.keys.sort).must_equal movie_fields + end end describe "create" do From c7b3548c3699e68aade44b5f9dc517fb5e922697 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 12:17:06 -0700 Subject: [PATCH 30/57] added rental_params --- app/controllers/rentals_controller.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 58c72b791..cb0344fcf 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,2 +1,13 @@ class RentalsController < ApplicationController + def checkout + end + + def checkin + end + + private + + def rental_params + params.permit(:movie_id, :customer_id) + end end From 7e46e2336f93febc95c12590d1795dd66220d21c Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 12:27:07 -0700 Subject: [PATCH 31/57] added checkout, due date, status to rentals --- db/migrate/20190515192136_add_columns_to_rentals.rb | 7 +++++++ db/schema.rb | 5 ++++- 2 files changed, 11 insertions(+), 1 deletion(-) create mode 100644 db/migrate/20190515192136_add_columns_to_rentals.rb diff --git a/db/migrate/20190515192136_add_columns_to_rentals.rb b/db/migrate/20190515192136_add_columns_to_rentals.rb new file mode 100644 index 000000000..18e371999 --- /dev/null +++ b/db/migrate/20190515192136_add_columns_to_rentals.rb @@ -0,0 +1,7 @@ +class AddColumnsToRentals < ActiveRecord::Migration[5.2] + def change + add_column(:rentals, :checkout, :date) + add_column(:rentals, :due_date, :date) + add_column(:rentals, :status, :string) + end +end diff --git a/db/schema.rb b/db/schema.rb index 1a06ecb8b..93aff74da 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: 2019_05_14_220941) do +ActiveRecord::Schema.define(version: 2019_05_15_192136) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -42,6 +42,9 @@ t.bigint "customer_id" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.date "checkout" + t.date "due_date" + t.string "status" t.index ["customer_id"], name: "index_rentals_on_customer_id" t.index ["movie_id"], name: "index_rentals_on_movie_id" end From 040b374838e66a585b98ce80156457503ca4f2cb Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 12:30:41 -0700 Subject: [PATCH 32/57] added availability rental model --- app/models/rental.rb | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/app/models/rental.rb b/app/models/rental.rb index 34d3f4df8..ed01d2e43 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -1,4 +1,16 @@ class Rental < ApplicationRecord belongs_to :movie belongs_to :customer + + def available?(movie_id) + movie = Movie.find_by(id: movie_id) + + if !movie + return false + elsif movie.available_inventory > 0 + return true + else + return false + end + end end From efe362178de1d294ac0ae217f8c5c60390beda18 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 12:47:53 -0700 Subject: [PATCH 33/57] added checkout rentals controller method --- app/controllers/rentals_controller.rb | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index cb0344fcf..54f7874c9 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -1,8 +1,20 @@ class RentalsController < ApplicationController def checkout - end + rental = Rental.new(rental_params) + + rental.checkout = Date.today + rental.due_date = rental.checkout + 7 + rental.status = "Checked Out" - def checkin + if rental.available?(rental_params[:movie_id]) + if rental.save + render json: rental.as_json(except: [:created_at, :updated_at]), status: :ok + else + render json: {errors: rental.errors.messages}, status: :bad_request + end + else + render json: {errors: "Movie unavailable."}, status: :bad_request + end end private From cb295c49b433ef9ebfe756187a7c4111d8d042fd Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 12:49:40 -0700 Subject: [PATCH 34/57] added checkin rentals method --- app/controllers/rentals_controller.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 54f7874c9..b791af3bb 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -17,6 +17,20 @@ def checkout end end + def checkin + rental = Rental.find_by(movie_id: rental_params[:movie_id], customer_id: rental_params[:customer_id], status: "Checked Out") + if rental + rental.status = "Checked In" + if rental.save + render json: rental.as_json(except: [:created_at, :updated_at]), status: :ok + else + render json: {errors: rental.errors.messages}, status: :bad_request + end + else + render json: {errors: "Rental not located, please check information."}, status: :not_found + end + end + private def rental_params From ae236eef4d46f6f90bda1887ea041ff8e8743e2e Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 12:51:09 -0700 Subject: [PATCH 35/57] renamed test to match rental checkout --- test/controllers/rentals_controller_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index a953c5b90..7a62789ab 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -1,7 +1,7 @@ require "test_helper" describe RentalsController do - describe "creating rental" do + describe "checkout" do let(:rental_data) { { movie_id: movies(:one).movie_id, From d75a1ae50ef01252d8fcbbd46b7e6761fed5aee0 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 13:03:22 -0700 Subject: [PATCH 36/57] added rental routes and new tests, not passing yet --- config/routes.rb | 3 ++ test/controllers/rentals_controller_test.rb | 40 +++++++++++++++++++-- 2 files changed, 40 insertions(+), 3 deletions(-) diff --git a/config/routes.rb b/config/routes.rb index 7099acd8f..a3ac613b2 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -4,5 +4,8 @@ resources :customers, only: [:index] resources :movies, only: [:index, :show, :create] + post "/rentals/checkout", to: "rentals#checkout", as: "checkout" + post "/rentals/checkin", to: "rentals#checkin", as: "checkin" + get "zomg", to: "movies#zomg", as: "zomg" end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 7a62789ab..8a6dfa3c9 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -11,7 +11,7 @@ it "can create a new rental provided valid data" do expect { - post rental_path, params: rental_data + post checkin_path, params: rental_data }.must_change "Rental.count", +1 new_rental = Rental.last @@ -26,7 +26,7 @@ rental_data["customer_id"] = -7 expect { - post rental_path, params: rental_data + post checkin_path, params: rental_data }.wont_change "Rental.count" must_respond_with :bad_request @@ -36,10 +36,44 @@ rental_data["movie_id"] = -7 expect { - post rental_path, params: rental_data + post checkin_path, params: rental_data }.wont_change "Rental.count" must_respond_with :bad_request end end + + describe "checkin" do + it "performs checkin for valid rental" do + movie = movies(:one) + customer = customers(:one) + expect { + post checkin_path, params: {customer_id: customer.id, movie_id: movie.id} + }.wont_change "Rental.count" + + must_respond_with :success + + body = JSON.parse(response.body) + expect(body).must_be_kind_of Hash + expect(body).must_include "status" + end + + it "does not checkin provided invalid params" do + movie = movies(:one) + expect { + post checkin_path, params: {customer_id: -7, movie_id: movie.id} + }.wont_change "Rental.count" + + must_respond_with :not_found + end + + it "does not check in if parameters are missing" do + movie = movies(:scream) + expect { + post checkin_path, params: {movie_id: movie.id} + }.wont_change "Rental.count" + + must_respond_with :not_found + end + end end From 9300e214c3fac451248af1571016c426af9d288c Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Wed, 15 May 2019 13:24:33 -0700 Subject: [PATCH 37/57] Added validations for rental, tests for movie model --- app/models/movie.rb | 2 ++ app/models/rental.rb | 4 ++++ test/models/movie_test.rb | 11 ++++++++++- 3 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 00280a8e1..1a635bfad 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,4 +2,6 @@ class Movie < ApplicationRecord has_many :rentals validates :title, presence: true + + end diff --git a/app/models/rental.rb b/app/models/rental.rb index ed01d2e43..5b1d7867a 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -2,6 +2,10 @@ class Rental < ApplicationRecord belongs_to :movie belongs_to :customer + validates :customer_id, presence: true + validates :movie_id, presence: true + + def available?(movie_id) movie = Movie.find_by(id: movie_id) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 34d1d30a5..b2c2f8242 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -1,9 +1,18 @@ require "test_helper" describe Movie do - let(:movie) { Movie.new } + let(:movie) { movies(:one) } it "must be valid" do value(movie).must_be :valid? end + + it "requires a title" do + required_fields = [:title] + movie[:title] = nil + + expect(movie.valid?).must_equal false + + movie.reload + end end From 73edce59d66349bbecedd287bf1c8a8e0044cd05 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 13:29:51 -0700 Subject: [PATCH 38/57] added rental fixture --- test/controllers/rentals_controller_test.rb | 4 ++-- test/fixtures/rentals.yml | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 8a6dfa3c9..edd2d8a87 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -4,7 +4,7 @@ describe "checkout" do let(:rental_data) { { - movie_id: movies(:one).movie_id, + movie_id: movies(:one).id, customer_id: customers(:one).id, } } @@ -68,7 +68,7 @@ end it "does not check in if parameters are missing" do - movie = movies(:scream) + movie = movies(:one) expect { post checkin_path, params: {movie_id: movie.id} }.wont_change "Rental.count" diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 6a1ad3712..7d73fc0aa 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -3,7 +3,6 @@ one: movie: one customer: one - -two: - movie: two - customer: two + check_out: 2019-05-15 + due_date: 2019-05-22 + status: "Checked Out" \ No newline at end of file From 3feae0689d79ffc7d6b6076a192db3eae58a41bc Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 13:49:16 -0700 Subject: [PATCH 39/57] added available_inventory to movies --- app/controllers/rentals_controller.rb | 2 +- .../20190515204803_add_available_inventory_to_movies.rb | 5 +++++ db/schema.rb | 3 ++- test/controllers/rentals_controller_test.rb | 8 ++++---- test/fixtures/rentals.yml | 9 ++++++++- 5 files changed, 20 insertions(+), 7 deletions(-) create mode 100644 db/migrate/20190515204803_add_available_inventory_to_movies.rb diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index b791af3bb..39d2f4380 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -34,6 +34,6 @@ def checkin private def rental_params - params.permit(:movie_id, :customer_id) + params.permit(:movie_id, :customer_id, :checkout, :due_date, :status) end end diff --git a/db/migrate/20190515204803_add_available_inventory_to_movies.rb b/db/migrate/20190515204803_add_available_inventory_to_movies.rb new file mode 100644 index 000000000..4890d9cb3 --- /dev/null +++ b/db/migrate/20190515204803_add_available_inventory_to_movies.rb @@ -0,0 +1,5 @@ +class AddAvailableInventoryToMovies < ActiveRecord::Migration[5.2] + def change + add_column(:movies, :available_inventory, :integer) + end +end diff --git a/db/schema.rb b/db/schema.rb index 93aff74da..7eff28d6c 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: 2019_05_15_192136) do +ActiveRecord::Schema.define(version: 2019_05_15_204803) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -35,6 +35,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 edd2d8a87..3e912744e 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -5,13 +5,13 @@ let(:rental_data) { { movie_id: movies(:one).id, - customer_id: customers(:one).id, + customer_id: customers(:two).id, } } it "can create a new rental provided valid data" do expect { - post checkin_path, params: rental_data + post checkout_path, params: rental_data }.must_change "Rental.count", +1 new_rental = Rental.last @@ -26,7 +26,7 @@ rental_data["customer_id"] = -7 expect { - post checkin_path, params: rental_data + post checkout_path, params: rental_data }.wont_change "Rental.count" must_respond_with :bad_request @@ -36,7 +36,7 @@ rental_data["movie_id"] = -7 expect { - post checkin_path, params: rental_data + post checkout_path, params: rental_data }.wont_change "Rental.count" must_respond_with :bad_request diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 7d73fc0aa..573ba7c33 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -3,6 +3,13 @@ one: movie: one customer: one - check_out: 2019-05-15 + checkout: 2019-05-15 + due_date: 2019-05-22 + status: "Checked Out" + +two: + movie_id: 2 + customer_id: 2 + checkout: 2019-05-15 due_date: 2019-05-22 status: "Checked Out" \ No newline at end of file From 084788ea9216579cd906748fa098ec1a918a9902 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 13:56:37 -0700 Subject: [PATCH 40/57] got rental tests passing, updated fixtures for available_inventory --- test/controllers/rentals_controller_test.rb | 2 +- test/fixtures/movies.yml | 2 ++ test/models/movie_test.rb | 12 ++++++------ test/models/rental_test.rb | 12 ++++++------ 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 3e912744e..61cd12164 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -19,7 +19,7 @@ must_respond_with :success body = JSON.parse(response.body) - expet(body).must_be_kind_of Hash + expect(body).must_be_kind_of Hash end it "won't create new rental with invalid customer" do diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index ecff1cef1..7fee73ac8 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -5,9 +5,11 @@ one: overview: Blue aliens on beautiful planet defeat sky people. release_date: 2009-12-18 inventory: 5 + available_inventory: 4 two: title: Star Wars overview: A long time ago, in a galaxy far, far away. release_date: 1977-05-25 inventory: 20 + available_inventory: 17 diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 34d1d30a5..c50093c5a 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 } +# describe Movie do +# let(:movie) { Movie.new } - it "must be valid" do - value(movie).must_be :valid? - end -end +# it "must be valid" do +# value(movie).must_be :valid? +# end +# end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6ea53d94f..c7a3565ea 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -1,9 +1,9 @@ require "test_helper" -describe Rental do - let(:rental) { Rental.new } +# describe Rental do +# let(:rental) { Rental.new } - it "must be valid" do - value(rental).must_be :valid? - end -end +# it "must be valid" do +# value(rental).must_be :valid? +# end +# end From 99281be03fcc2d813520cc39474fc101f13e8a34 Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Wed, 15 May 2019 14:04:40 -0700 Subject: [PATCH 41/57] Changed rental fixtures, added rental validation test --- test/fixtures/rentals.yml | 13 ++++++++++--- test/models/rental_test.rb | 13 ++++++++++--- 2 files changed, 20 insertions(+), 6 deletions(-) diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 7d73fc0aa..21784c7d2 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -1,8 +1,15 @@ # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html one: - movie: one - customer: one - check_out: 2019-05-15 + movie_id: 1 + customer_id: 1 + checkout: 2019-05-15 + due_date: 2019-05-22 + status: "Checked Out" + +two: + movie_id: 2 + customer_id: 2 + checkout: 2019-05-15 due_date: 2019-05-22 status: "Checked Out" \ No newline at end of file diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 6ea53d94f..025f1d192 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -1,9 +1,16 @@ require "test_helper" describe Rental do - let(:rental) { Rental.new } + let(:rental) { rentals(:one) } - it "must be valid" do - value(rental).must_be :valid? + it "requires movie and customer ids" do + required_fields = [:customer_id, :movie_id] + + required_fields.each do |field| + rental[field] = nil + expect(rental.valid?).must_equal false + + rental.reload + end end end From 7d241646c373898b35086c4b4d9952bf9ee6dbe7 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 14:21:02 -0700 Subject: [PATCH 42/57] added available_inventory method to movie --- app/models/movie.rb | 11 ++++++- test/models/movie_test.rb | 61 +++++---------------------------------- 2 files changed, 18 insertions(+), 54 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 1a635bfad..9eb17f215 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -3,5 +3,14 @@ class Movie < ApplicationRecord validates :title, presence: true - + def available_inventory + checkedout = 0 + + self.rentals.each do |rental| + if rental.status == "Checked Out" + checkedout += 1 + end + end + return self.inventory - checkedout + end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 68aa83be8..b2c2f8242 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -1,63 +1,18 @@ require "test_helper" describe Movie do - describe "validations" do - it "must be valid with all params present" do - movie = movies(:movie_with_all_params) - result = movie.valid? + let(:movie) { movies(:one) } - expect(result).must_equal true - end - - it "must be valid with only title and inventory present" do - movie = movies(:movie_with_title_and_inv) - result = movie.valid? - - expect(result).must_equal true - end - - it "must have a unique title" do - movie = Movie.new(title: "Parkor", inventory: 7) - movie.title = movies(:existing_movie).title - - result = movie.valid? - expect(result).must_equal false - end - - it "must be invalid without a title" do - movie = movies(:existing_movie) - movie.title = nil - - result = movie.valid? - expect(result).must_equal false - end - - it "must be invalid without inventory" do - movie = movies(:existing_movie) - movie.inventory = nil - - result = movie.valid? - expect(result).must_equal false - end - - it "must be invalid if inventory is not an integer" do - movie = movies(:movie_with_all_params) - movie.inventory = "three" - - result = movie.valid? - expect(result).must_equal false - end + it "must be valid" do + value(movie).must_be :valid? end - describe "relations" do - it "can access an array of rentals" do - movie = movies(:movie_with_all_params) - rental = rentals(:rental_two) + it "requires a title" do + required_fields = [:title] + movie[:title] = nil - movie_rentals = movie.rentals + expect(movie.valid?).must_equal false - expect(movie_rentals.length).must_equal 1 - expect(movie_rentals.first).must_be_instance_of Rental - end + movie.reload end end From 7195177e4a886ee33d8c7fd66924af4e606a7d98 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 14:24:56 -0700 Subject: [PATCH 43/57] fixing test description for consistency --- test/controllers/rentals_controller_test.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 61cd12164..d2823e3af 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -22,7 +22,7 @@ expect(body).must_be_kind_of Hash end - it "won't create new rental with invalid customer" do + it "won't create new rental provided invalid customer" do rental_data["customer_id"] = -7 expect { @@ -32,7 +32,7 @@ must_respond_with :bad_request end - it "won't create new rental with invalid movie" do + it "won't create new rental provided invalid movie" do rental_data["movie_id"] = -7 expect { @@ -44,7 +44,7 @@ end describe "checkin" do - it "performs checkin for valid rental" do + it "performs checkin provided valid data" do movie = movies(:one) customer = customers(:one) expect { @@ -58,7 +58,7 @@ expect(body).must_include "status" end - it "does not checkin provided invalid params" do + it "does not checkin provided invalid data" do movie = movies(:one) expect { post checkin_path, params: {customer_id: -7, movie_id: movie.id} @@ -67,7 +67,7 @@ must_respond_with :not_found end - it "does not check in if parameters are missing" do + it "does not checkin if missing data" do movie = movies(:one) expect { post checkin_path, params: {movie_id: movie.id} From 1709dbe4b314f967c7648918ab1d040281dfc3a6 Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Wed, 15 May 2019 14:34:33 -0700 Subject: [PATCH 44/57] Added relations tests to rental --- test/models/rental_test.rb | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index d48704525..a143555b0 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -13,5 +13,19 @@ rental.reload end end + + describe "relations" do + it "relates to a customer" do + r = rentals(:one) + r.must_respond_to :customer + r.customer.must_be_kind_of Customer + end + + it "relates to a movie" do + r = rentals(:one) + r.must_respond_to :movie + r.movie.must_be_kind_of Movie + end + end end From 771265d7fda22c0816307833975e3043f16ef4ee Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Wed, 15 May 2019 14:39:06 -0700 Subject: [PATCH 45/57] Removed unnecessary line from movies model test --- test/models/movie_test.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index b2c2f8242..95c278bf4 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -8,7 +8,7 @@ end it "requires a title" do - required_fields = [:title] + movie[:title] = nil expect(movie.valid?).must_equal false From 3aff11da9306aa87666b745644081438206010d5 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 14:54:41 -0700 Subject: [PATCH 46/57] added available_inventory test one --- test/fixtures/movies.yml | 2 -- test/models/movie_test.rb | 29 ++++++++++++++++++++--------- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index 7fee73ac8..ecff1cef1 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -5,11 +5,9 @@ one: overview: Blue aliens on beautiful planet defeat sky people. release_date: 2009-12-18 inventory: 5 - available_inventory: 4 two: title: Star Wars overview: A long time ago, in a galaxy far, far away. release_date: 1977-05-25 inventory: 20 - available_inventory: 17 diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index b2c2f8242..979858793 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -1,18 +1,29 @@ require "test_helper" describe Movie do - let(:movie) { movies(:one) } + describe "validation tests" do + let(:movie) { movies(:one) } - it "must be valid" do - value(movie).must_be :valid? - end + it "must be valid" do + value(movie).must_be :valid? + end + + it "requires a title" do + required_fields = [:title] + movie[:title] = nil - it "requires a title" do - required_fields = [:title] - movie[:title] = nil + expect(movie.valid?).must_equal false + + movie.reload + end + end - expect(movie.valid?).must_equal false + describe "available_inventory" do + it "can calculate available_inventory for movie with rentals" do + movie = movies(:one) + num_available = movie.available_inventory - movie.reload + expect(num_available).must_equal 4 + end end end From 047b2ff63a3f27798305544ecab73872d5b55f32 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 14:56:16 -0700 Subject: [PATCH 47/57] added new movie fixture with no rentals --- test/fixtures/movies.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index ecff1cef1..c3ed561f0 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -11,3 +11,9 @@ two: overview: A long time ago, in a galaxy far, far away. release_date: 1977-05-25 inventory: 20 + +three: + title: Terror in the Outback + overview: Teen smut written by Laneia, you're welcome. + release_date: 2019-05-15 + inventory: 1 From f3311451491d843d8087e17becb579a2ab14c1d4 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 14:57:20 -0700 Subject: [PATCH 48/57] added second available_inventory test for no rental --- test/models/movie_test.rb | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 979858793..b04e4febf 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -25,5 +25,12 @@ expect(num_available).must_equal 4 end + + it "can calculate available_inventory for movie with no rentals" do + movie = movies(:three) + num_available = movie.available_inventory + + expect(num_available).must_equal movie.inventory + end end end From 45d779544b6df6068b9374df0768460de7b4becd Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 15:19:43 -0700 Subject: [PATCH 49/57] added available_inventory to movie show & test --- app/controllers/movies_controller.rb | 3 ++- test/controllers/movies_controller_test.rb | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index b574a6894..07e83df14 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -22,6 +22,7 @@ def show overview: movie.overview, release_date: movie.release_date, inventory: movie.inventory, + available_inventory: movie.available_inventory, }, status: :ok end end @@ -41,6 +42,6 @@ def create private def movie_params - params.permit(:title, :overview, :release_date, :inventory) + params.permit(:title, :overview, :release_date, :inventory, :available_inventory) end end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index cdafb0e6d..2e1337acd 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -50,7 +50,7 @@ end it "returns correct movie fields" do - movie_fields = ["inventory", "overview", "release_date", "title"] + movie_fields = ["available_inventory", "inventory", "overview", "release_date", "title"] get movie_path(movies(:one).id) body = JSON.parse(response.body) From b5e9f8558bf3c0d851c7e952af615a9171a50e71 Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Wed, 15 May 2019 15:20:05 -0700 Subject: [PATCH 50/57] Changed available inventory default to inventory --- app/models/movie.rb | 7 +++++++ .../20190515204803_add_available_inventory_to_movies.rb | 4 ++++ 2 files changed, 11 insertions(+) diff --git a/app/models/movie.rb b/app/models/movie.rb index 9eb17f215..b988a7f8c 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,4 +1,5 @@ class Movie < ApplicationRecord + before_create :set_inventory_default has_many :rentals validates :title, presence: true @@ -13,4 +14,10 @@ def available_inventory end return self.inventory - checkedout end + + private + + def set_inventory_default + self.available_inventory = self.inventory + end end diff --git a/db/migrate/20190515204803_add_available_inventory_to_movies.rb b/db/migrate/20190515204803_add_available_inventory_to_movies.rb index 4890d9cb3..78537644b 100644 --- a/db/migrate/20190515204803_add_available_inventory_to_movies.rb +++ b/db/migrate/20190515204803_add_available_inventory_to_movies.rb @@ -2,4 +2,8 @@ class AddAvailableInventoryToMovies < ActiveRecord::Migration[5.2] def change add_column(:movies, :available_inventory, :integer) end + + reversible do |dir| + dir.up {Movie.update_all('available_inventory = inventory')} + end end From f0ad8e9fb9ec061d2a722b706c9b2ed2416d240e Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 15:22:02 -0700 Subject: [PATCH 51/57] added available_inventory to movies index & test --- app/controllers/movies_controller.rb | 2 +- test/controllers/movies_controller_test.rb | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 07e83df14..344674501 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -6,7 +6,7 @@ def zomg def index params[:sort] ? movies = Movie.order(params[:sort]) : movies = Movie.all - render json: movies.as_json(only: [:id, :inventory, :overview, :release_date, :title]), status: :ok + render json: movies.as_json(only: [:id, :available_inventory, :inventory, :overview, :release_date, :title]), status: :ok end def show diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 2e1337acd..3da8c4c10 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -14,7 +14,7 @@ end it "returns correct movie fields" do - movie_fields = ["id", "inventory", "overview", "release_date", "title"] + movie_fields = ["available_inventory", "id", "inventory", "overview", "release_date", "title"] get movies_path body = JSON.parse(response.body) From 08ab61aa423b4a57ac48b5a35fec58a08a95728d Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 15:28:03 -0700 Subject: [PATCH 52/57] added test and validations for movies model --- app/models/movie.rb | 2 +- test/models/movie_test.rb | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 9eb17f215..9d904fa58 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,7 +1,7 @@ class Movie < ApplicationRecord has_many :rentals - validates :title, presence: true + validates :title, :overview, :release_date, :inventory, presence: true def available_inventory checkedout = 0 diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index b04e4febf..4b555fe6c 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -16,6 +16,14 @@ movie.reload end + + it "has required fields" do + fields = [:title, :overview, :release_date, :inventory] + + fields.each do |field| + expect(movie).must_respond_to field + end + end end describe "available_inventory" do From 51518d835cf49a2a4a33ece30981ea594afe029e Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 15:48:21 -0700 Subject: [PATCH 53/57] added integer validation tests --- app/models/movie.rb | 3 +- test/models/movie_test.rb | 58 +++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 6 deletions(-) diff --git a/app/models/movie.rb b/app/models/movie.rb index 56c176c9c..0d42b78df 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,7 +2,8 @@ class Movie < ApplicationRecord before_create :set_inventory_default has_many :rentals - validates :title, :overview, :release_date, :inventory, presence: true + validates :title, :overview, :release_date, presence: true + validates :inventory, :available_inventory, presence: true, numericality: {only_integer: true, greater_than_or_equal_to: 0} def available_inventory checkedout = 0 diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 4b555fe6c..ea02356a3 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -8,6 +8,14 @@ value(movie).must_be :valid? end + it "has all required fields" do + fields = [:title, :overview, :release_date, :inventory, :available_inventory] + + fields.each do |field| + expect(movie).must_respond_to field + end + end + it "requires a title" do required_fields = [:title] movie[:title] = nil @@ -17,12 +25,52 @@ movie.reload end - it "has required fields" do - fields = [:title, :overview, :release_date, :inventory] + it "requires an overview" do + movie.overview = nil + valid = movie.save - fields.each do |field| - expect(movie).must_respond_to field - end + expect(valid).must_equal false + expect(movie.errors.messages).must_include :overview + end + + it "requires a release date" do + movie.release_date = nil + valid = movie.save + + expect(valid).must_equal false + expect(movie.errors.messages).must_include :release_date + end + + it "requires an integer for inventory" do + movie.inventory = "two" + valid = movie.save + + expect(valid).must_equal false + expect(movie.errors.messages).must_include :inventory + end + + it "requires an integer that is greater than 0 for inventory" do + movie.inventory = -1 + valid = movie.save + + expect(valid).must_equal false + expect(movie.errors.messages).must_include :inventory + end + + it "requires an integer for available_inventory" do + movie.available_inventory = "two" + valid = movie.save + + expect(valid).must_equal false + expect(movie.errors.messages).must_include :available_inventory + end + + it "requires an integer that is greater than 0 for available_inventory" do + movie.available_inventory = -1 + valid = movie.save + + expect(valid).must_equal false + expect(movie.errors.messages).must_include :available_inventory end end From d64632e2b9e432447713d3aae950d827bdd04fa9 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 16:06:05 -0700 Subject: [PATCH 54/57] added relationship tests to movie test --- 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 ea02356a3..cfabe2315 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -89,4 +89,21 @@ expect(num_available).must_equal movie.inventory end end + + describe "relations" do + let(:movie) { movies(:one) } + + it "can have many rentals" do + num_rentals = movie.rentals.count + + expect(num_rentals).must_equal 1 + end + + it "can have zero rentals" do + movie = movies(:three) + num_rentals = movie.rentals.count + + expect(num_rentals).must_equal 0 + end + end end From ac630b55e01455f3adfb1df5f364df74a09e6aa6 Mon Sep 17 00:00:00 2001 From: laneia Date: Wed, 15 May 2019 16:13:01 -0700 Subject: [PATCH 55/57] test fixture cosistency --- test/fixtures/rentals.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 573ba7c33..6f76f787b 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -8,8 +8,8 @@ one: status: "Checked Out" two: - movie_id: 2 - customer_id: 2 + movie: two + customer: two checkout: 2019-05-15 due_date: 2019-05-22 status: "Checked Out" \ No newline at end of file From 16257368e002c4238ecd9ad0654df2f5d1285b7b Mon Sep 17 00:00:00 2001 From: Carla Bosco Date: Thu, 16 May 2019 07:22:24 -0700 Subject: [PATCH 56/57] Added tests to customer model and controller --- test/controllers/customers_controller_test.rb | 7 +++++++ test/models/customer_test.rb | 11 +++++++++++ 2 files changed, 18 insertions(+) diff --git a/test/controllers/customers_controller_test.rb b/test/controllers/customers_controller_test.rb index 35ae4d32e..b69917ca0 100644 --- a/test/controllers/customers_controller_test.rb +++ b/test/controllers/customers_controller_test.rb @@ -55,5 +55,12 @@ expect(customer.keys.length).must_equal keys.length end end + + it "returns an empty array if there are no customers" do + Rental.destroy_all + Customer.destroy_all + get customers_path + expect(Customer.count).must_equal 0 + end end end diff --git a/test/models/customer_test.rb b/test/models/customer_test.rb index 004b9b75c..831bf6904 100644 --- a/test/models/customer_test.rb +++ b/test/models/customer_test.rb @@ -14,4 +14,15 @@ customer.reload end end + + it 'is invalid without a given customer name' do + + @customer = Customer.new() + result = @customer.valid? + + expect(result).must_equal false + expect(@customer.errors.messages).must_include :name + end end + + From a173b16709e630fd439ae173eea2dc9d8cbcd91c Mon Sep 17 00:00:00 2001 From: laneia Date: Thu, 16 May 2019 09:25:09 -0700 Subject: [PATCH 57/57] added rental validations and tests, relevant test fixtures --- app/models/rental.rb | 4 +- test/fixtures/movies.yml | 6 +++ test/fixtures/rentals.yml | 7 ++++ test/models/rental_test.rb | 77 +++++++++++++++++++++++++++++++------- 4 files changed, 78 insertions(+), 16 deletions(-) diff --git a/app/models/rental.rb b/app/models/rental.rb index 5b1d7867a..421de5cda 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -2,9 +2,7 @@ class Rental < ApplicationRecord belongs_to :movie belongs_to :customer - validates :customer_id, presence: true - validates :movie_id, presence: true - + validates :customer_id, :movie_id, :due_date, :checkout, :status, presence: true def available?(movie_id) movie = Movie.find_by(id: movie_id) diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index c3ed561f0..b8bf8e8a9 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -17,3 +17,9 @@ three: overview: Teen smut written by Laneia, you're welcome. release_date: 2019-05-15 inventory: 1 + +four: + title: Pride and Prejudice + overview: Such pride, much prejudice. + release_date: 2005-09-11 + inventory: 1 \ No newline at end of file diff --git a/test/fixtures/rentals.yml b/test/fixtures/rentals.yml index 6f76f787b..9e8961ee5 100644 --- a/test/fixtures/rentals.yml +++ b/test/fixtures/rentals.yml @@ -12,4 +12,11 @@ two: customer: two checkout: 2019-05-15 due_date: 2019-05-22 + status: "Checked Out" + +three: + movie: four + customer: two + checkout: 2019-05-15 + due_date: 2019-05-22 status: "Checked Out" \ No newline at end of file diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index a143555b0..fe065a04e 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -3,29 +3,80 @@ describe Rental do let(:rental) { rentals(:one) } - it "requires movie and customer ids" do - required_fields = [:customer_id, :movie_id] + describe "validations" do + it "must be valid" do + value(rental).must_be :valid? + end + + it "has required fields" do + fields = [:movie_id, :customer_id, :checkout, :due_date, :status] + + fields.each do |field| + expect(rental).must_respond_to field + end + end + + it "requires movie and customer ids" do + required_fields = [:customer_id, :movie_id] + + required_fields.each do |field| + rental[field] = nil + expect(rental.valid?).must_equal false + + rental.reload + end + end + + it "must have a check_out date" do + rental.checkout = nil + valid = rental.save + + expect(valid).must_equal false + expect(rental.errors.messages).must_include :checkout + end - required_fields.each do |field| - rental[field] = nil - expect(rental.valid?).must_equal false + it "must have a due date" do + rental.due_date = nil + valid = rental.save - rental.reload + expect(valid).must_equal false + expect(rental.errors.messages).must_include :due_date + end + + it "must have a status" do + rental.status = nil + valid = rental.save + + expect(valid).must_equal false + expect(rental.errors.messages).must_include :status end end describe "relations" do it "relates to a customer" do - r = rentals(:one) - r.must_respond_to :customer - r.customer.must_be_kind_of Customer + rental.must_respond_to :customer + rental.customer.must_be_kind_of Customer + expect(rental.customer.id).must_equal rental.customer_id end it "relates to a movie" do - r = rentals(:one) - r.must_respond_to :movie - r.movie.must_be_kind_of Movie + rental.must_respond_to :movie + rental.movie.must_be_kind_of Movie + expect(rental.movie.id).must_equal rental.movie_id end end -end + describe "available?" do + it "shows movie available if copy checked out but available inventory > 0" do + movie = movies(:two) + availability = rental.available?(movie.id) + expect(availability).must_equal true + end + + it "shows movie unavailable if all copies checked out" do + movie = movies(:four) + availability = rental.available?(movie.id) + expect(availability).must_equal false + end + end +end