From 8435f768e27d9d179afd36ab47b65feafb07d8ed Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Tue, 23 Jun 2020 14:15:00 -0700 Subject: [PATCH 1/9] added gem --- Gemfile | 1 + 1 file changed, 1 insertion(+) diff --git a/Gemfile b/Gemfile index 25fddaae..7159c815 100644 --- a/Gemfile +++ b/Gemfile @@ -49,6 +49,7 @@ gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby] group :development, :test do gem 'pry-rails' + gem 'dotenv-rails' end group :development do From 92e9296305f8cacd761bb70e5f1bf52fcf1a8614 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Wed, 24 Jun 2020 10:55:32 -0700 Subject: [PATCH 2/9] added show action to customer controller --- app/controllers/customers_controller.rb | 24 ++++++++++++++++++++++++ config/routes.rb | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index be25f1be..371b95f2 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -18,6 +18,30 @@ def index ) end + def show + @customer = Customer.find_by(id: params[:id]) + + if @customer + @customer_rentals = @customer.rentals.map{|rental| { + title: rental.moive.title, + checkout_date: rental.checkout_date, + due_date: rental.due_date, + status: rental.status, + }} + render json: + @customer_rentals.as_json(), + status: :ok + return + else + render json: { + errors: [ + 'Customer Not Found' + ] + }, status: :not_found + return + end + end + private def parse_query_args errors = {} diff --git a/config/routes.rb b/config/routes.rb index f4c99688..0ce4b7a5 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -1,7 +1,7 @@ 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 :customers, only: [:index, :show] resources :movies, only: [:index, :show], param: :title From 649d154629e307674d3c0fd890f7e4e63edbb623 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Wed, 24 Jun 2020 11:09:56 -0700 Subject: [PATCH 3/9] modify the due date --- app/controllers/customers_controller.rb | 4 ++-- app/controllers/rentals_controller.rb | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/app/controllers/customers_controller.rb b/app/controllers/customers_controller.rb index 371b95f2..3b1b7918 100644 --- a/app/controllers/customers_controller.rb +++ b/app/controllers/customers_controller.rb @@ -23,10 +23,10 @@ def show if @customer @customer_rentals = @customer.rentals.map{|rental| { - title: rental.moive.title, + title: rental.movie.title, checkout_date: rental.checkout_date, due_date: rental.due_date, - status: rental.status, + status: rental.returned, }} render json: @customer_rentals.as_json(), diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 67e77073..d56db346 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -4,7 +4,8 @@ class RentalsController < ApplicationController # TODO: make sure that wave 2 works all the way def check_out - rental = Rental.new(movie: @movie, customer: @customer, due_date: params[:due_date]) + rental = Rental.new(movie: @movie, customer: @customer) + rental.due_date = Date.today + 7.days if rental.save render status: :ok, json: {} From bc04c35016d2f482c8716b12316603686b4da7c1 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Thu, 25 Jun 2020 23:02:32 -0700 Subject: [PATCH 4/9] added create route for movies --- config/routes.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config/routes.rb b/config/routes.rb index 0ce4b7a5..593e5f15 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ resources :customers, only: [:index, :show] - resources :movies, only: [:index, :show], param: :title + resources :movies, only: [:index, :show, :create], param: :title post "/rentals/:title/check-out", to: "rentals#check_out", as: "check_out" post "/rentals/:title/return", to: "rentals#check_in", as: "check_in" From 66dc010cba7d67bf362278bcb491898ca331c926 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Thu, 25 Jun 2020 23:05:31 -0700 Subject: [PATCH 5/9] added create action --- app/controllers/movies_controller.rb | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 362e2791..b0810674 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -20,6 +20,22 @@ def show ) ) end + + def create + movie = Movie.new(movie_params) + + if movie.save + render json: movie.as_json(only: [:id]), status: :ok + return + else + render json: { + ok: false + errors: movie.errors.messages + }, + status: :bad_request + return + end + end private @@ -29,4 +45,8 @@ def require_movie render status: :not_found, json: { errors: { title: ["No movie with title #{params["title"]}"] } } end end + + def movie_params + params.permit(:title, :overview, :release_date, :image_url, :external_id) + end end From 51b2efba23e109c1096ab7f46728184903c9242d Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Thu, 25 Jun 2020 23:06:53 -0700 Subject: [PATCH 6/9] added uniqueness id validation for movie --- app/models/movie.rb | 2 ++ 1 file changed, 2 insertions(+) diff --git a/app/models/movie.rb b/app/models/movie.rb index fda94941..7a589c1c 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,6 +2,8 @@ class Movie < ApplicationRecord has_many :rentals has_many :customers, through: :rentals + validates :external_id, presence: true, uniqueness: true + def available_inventory self.inventory - Rental.where(movie: self, returned: false).length end From 2bf78a1487debce3c7f34166f92407c09ab58954 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Thu, 25 Jun 2020 23:26:27 -0700 Subject: [PATCH 7/9] fix missing comma --- app/controllers/movies_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index b0810674..20cb85ae 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -29,7 +29,7 @@ def create return else render json: { - ok: false + ok: false, errors: movie.errors.messages }, status: :bad_request From d9801a89169684a491a853c3174263ce04a51ac7 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Fri, 26 Jun 2020 16:35:05 -0700 Subject: [PATCH 8/9] added movie controller tests --- test/controllers/movies_controller_test.rb | 57 ++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 9172cf6e..6ef9b5b4 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -1,6 +1,15 @@ require 'test_helper' class MoviesControllerTest < ActionDispatch::IntegrationTest + def check_response(expected_type: ,expected_status: :success) + must_respond_with expected_status + expect(response.header['Content-Type']).must_include 'json' + + body = JSON.parse(response.body) + expect(body).must_be_kind_of expected_type + return body + end + describe "index" do it "returns a JSON array" do get movies_url @@ -75,4 +84,52 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest end end + + describe 'create' do + let(:movies_data) { + { + + title: 'Harry Potter 3', + overview: 'The best movie ever!', + release_date: 'Wed, 22 Jun 1960', + inventory: 10, + image_url: "some image", + external_id: 1547, + } + } + + it 'can create a new movies' do + expect { + post movies_path, params: movies_data + }.must_differ 'Movie.count', 1 + + check_response(expected_type: Hash, expected_status: :ok) + end + + it 'will respond with bad_request for invalid data' do + movies_data[:external_id] = nil + + expect { + post movies_path, params: movies_data + }.wont_change "Movie.count" + body = check_response(expected_type: Hash, expected_status: :bad_request) + expect(body["errors"].keys).must_include 'external_id' + end + + it 'cannot be added twice for the same movie' do + first_count = Movie.count + + expect { + post movies_path, params: movies_data + }.must_differ 'Movie.count', 1 + + second_count = Movie.count + + expect { + post movies_path, params: movies_data + }.wont_change 'Movie.count' + + end + end + end From eb0282571f52f694a75f0d60fdb1c77df56693f9 Mon Sep 17 00:00:00 2001 From: Sharon Cheung Date: Fri, 26 Jun 2020 16:40:04 -0700 Subject: [PATCH 9/9] added model validation tests --- test/models/movie_test.rb | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 70b6a7c6..f89eb62c 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -6,7 +6,8 @@ class MovieTest < ActiveSupport::TestCase "title": "Hidden Figures", "overview": "Some text", "release_date": "1960-06-16", - "inventory": 8 + "inventory": 8, + "external_id": 1233454, } } @@ -78,4 +79,27 @@ class MovieTest < ActiveSupport::TestCase after_ai.must_equal before_ai + 1 end end + + describe 'validations' do + it 'is valid when all the required fields are provided' do + new_movie = Movie.new( + title: 'Harry Potter 3', + overview: 'The best movie ever!', + release_date: 'Wed, 22 Jun 1960', + inventory: 10, + image_url: "some image", + external_id: 15482656, + ) + + expect(new_movie.valid?).must_equal true + end + + it 'fails validation when there is one or more required field is missing' do + @movie.external_id = nil + + expect(@movie.valid?).must_equal false + expect(@movie.errors.messages).must_include :external_id + + end + end end