From d812640f88796dd28f1fa2d4da607accc0aaa766 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Mon, 17 Dec 2018 13:18:09 -0800 Subject: [PATCH 01/20] Add schema file generated by migrations --- db/schema.rb | 53 +++++++++++++++++++++++++++------------------------- 1 file changed, 28 insertions(+), 25 deletions(-) diff --git a/db/schema.rb b/db/schema.rb index ffb28f7e..c7cb7c0a 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,40 +10,43 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20180618042754) do +ActiveRecord::Schema.define(version: 2018_06_18_042754) do + + # These are extensions that must be enabled in order to support this database + enable_extension "plpgsql" create_table "customers", force: :cascade do |t| - t.string "name" + t.string "name" t.datetime "registered_at" - t.string "address" - t.string "city" - t.string "state" - t.string "postal_code" - t.string "phone" - t.float "account_credit" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false + t.string "address" + t.string "city" + t.string "state" + t.string "postal_code" + t.string "phone" + t.float "account_credit" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false end create_table "movies", force: :cascade do |t| - t.string "title" - t.text "overview" - t.date "release_date" - t.integer "inventory" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.string "image_url" - t.integer "external_id" + t.string "title" + t.text "overview" + t.date "release_date" + t.integer "inventory" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.string "image_url" + t.integer "external_id" end create_table "rentals", force: :cascade do |t| - t.integer "customer_id" - t.integer "movie_id" - t.date "checkout_date" - t.date "due_date" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - t.boolean "returned" + t.integer "customer_id" + t.integer "movie_id" + t.date "checkout_date" + t.date "due_date" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + t.boolean "returned" t.index ["customer_id"], name: "index_rentals_on_customer_id" t.index ["movie_id"], name: "index_rentals_on_movie_id" end From aa0fe2f844ed7f922ba9c36ec3ec3ff660802c32 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Mon, 17 Dec 2018 18:16:30 -0800 Subject: [PATCH 02/20] Add create movie functionality to the Rails App with a movie create route and contoller method --- app/controllers/movies_controller.rb | 18 ++++++++++++++++++ config/routes.rb | 2 +- 2 files changed, 19 insertions(+), 1 deletion(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 362e2791..f5444536 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -11,6 +11,20 @@ def index render status: :ok, json: data end + def create + movie = Movie.new(movie_params) + if movie.save + render json: { + id: movie.id, + title: movie.title, + external_id: movie.external_id }, status: :ok + else + render json: { + message: movie.errors.messages + }, status: :bad_request + end + end + def show render( status: :ok, @@ -29,4 +43,8 @@ def require_movie render status: :not_found, json: { errors: { title: ["No movie with title #{params["title"]}"] } } end end + + def movie_params + params.permit(:external_id, :image_url, :overview, :release_date, :title) + end end diff --git a/config/routes.rb b/config/routes.rb index f4c99688..76715f9a 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,7 +3,7 @@ resources :customers, only: [:index] - 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 c901e5f6eeb203418b2c58ede6576525e0fe1a44 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Mon, 17 Dec 2018 18:40:14 -0800 Subject: [PATCH 03/20] Add validation requiring new movie to have at least a title and an external_id, setup movie controller tests for create action --- app/controllers/movies_controller.rb | 2 +- app/models/movie.rb | 1 + test/controllers/movies_controller_test.rb | 44 ++++++++++++++++++++++ test/models/movie_test.rb | 3 +- 4 files changed, 48 insertions(+), 2 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index f5444536..0cea82f7 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -45,6 +45,6 @@ def require_movie end def movie_params - params.permit(:external_id, :image_url, :overview, :release_date, :title) + params.permit(:external_id, :image_url, :overview, :release_date, :title, :inventory) end end diff --git a/app/models/movie.rb b/app/models/movie.rb index 0016080b..389595bb 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -1,6 +1,7 @@ class Movie < ApplicationRecord has_many :rentals has_many :customers, through: :rentals + validates :title, :external_id, presence: true def available_inventory self.inventory - Rental.where(movie: self, returned: false).length diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 9172cf6e..c1d3608b 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -1,4 +1,5 @@ require 'test_helper' +require 'pry' class MoviesControllerTest < ActionDispatch::IntegrationTest describe "index" do @@ -42,6 +43,49 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest end end + describe "create" do + let(:movie_data) { + { + title: "Savior Of The Curse", + overview: "The strange woman claims the boy has a DNA strain which very likely offers the key to cure several crippling diseases. Tests will have to be done, but the key to save millions of lives is within the grasp of science through this DNA strain. Unsure what to think of all this and of this strange woman, the boy hesitantly agrees to the proposal, there's something exciting about this whole situation, surely the right choice was made.", + release_date: "2010-11-05", + inventory: 5, + image_url: "/81d8oyEFgj7FlxJqSDXWr8JH8kV.jpg", + external_id: 999999999 + } + } + + it "creates a new movie given 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" + + movie = Movie.find(body["id"].to_i) + + expect(movie.title).must_equal movie_data[:title] + must_respond_with :success + end + + it "returns an error for missing needed movie info to create object" do + expect { + post movies_path + }.wont_change "Movie.count" + + body = JSON.parse(response.body) + + expect(body).must_be_kind_of Hash + expect(body).must_include "message" + expect(body["message"]).must_include "title" + must_respond_with :bad_request + end + + end + + describe "show" do it "Returns a JSON object" do get movie_url(title: movies(:one).title) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 70b6a7c6..ab048665 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": 9999 } } From 42fffff9343ef3c61f420ae411c5f6f1eab59006 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Tue, 18 Dec 2018 12:08:57 -0800 Subject: [PATCH 04/20] Adjust movie controller test to expect the word errors instead of the word message returned when an post request fails --- app/controllers/movies_controller.rb | 2 +- test/controllers/movies_controller_test.rb | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 0cea82f7..bd5ffef4 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -20,7 +20,7 @@ def create external_id: movie.external_id }, status: :ok else render json: { - message: movie.errors.messages + errors: movie.errors.messages }, status: :bad_request end end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index c1d3608b..1acf8a0b 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -78,8 +78,8 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest body = JSON.parse(response.body) expect(body).must_be_kind_of Hash - expect(body).must_include "message" - expect(body["message"]).must_include "title" + expect(body).must_include "errors" + expect(body["errors"]).must_include "title" must_respond_with :bad_request end From 58e7309f3bc1894352825e4a6102b3905f01cd73 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Tue, 18 Dec 2018 13:58:47 -0800 Subject: [PATCH 05/20] Add validation for uniqueness of external_id with a customer error message when a post request to create a movie fails --- app/controllers/movies_controller.rb | 12 +++++++++--- app/models/movie.rb | 1 + 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index bd5ffef4..368a97c7 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -19,9 +19,15 @@ def create title: movie.title, external_id: movie.external_id }, status: :ok else - render json: { - errors: movie.errors.messages - }, status: :bad_request + if movie.errors.messages[:external_id] == ["has already been taken"] + render json: { + errors: "This movie has already been added to your film library." + }, status: :bad_request + else + render json: { + errors: movie.errors.messages + }, status: :bad_request + end end end diff --git a/app/models/movie.rb b/app/models/movie.rb index 389595bb..36e42b91 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,6 +2,7 @@ class Movie < ApplicationRecord has_many :rentals has_many :customers, through: :rentals validates :title, :external_id, presence: true + validates :external_id, uniqueness: true def available_inventory self.inventory - Rental.where(movie: self, returned: false).length From 4adc36da2a3e262c1a0069d147c97cac2fd31ad8 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Tue, 18 Dec 2018 14:12:13 -0800 Subject: [PATCH 06/20] Add model test verifying error messages are present when there is an attempt to create a movie with a duplicate external_id --- test/models/movie_test.rb | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index ab048665..d0f67823 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -13,6 +13,7 @@ class MovieTest < ActiveSupport::TestCase before do @movie = Movie.new(movie_data) + @duplicate_movie = Movie.new(movie_data) end describe "Constructor" do @@ -27,6 +28,11 @@ class MovieTest < ActiveSupport::TestCase it "Has customers" do @movie.must_respond_to :customers end + + it "Will not create a movie if external_id is not unique" do + @duplicate_movie.save + expect(@duplicate_movie.errors.messages).present? + end end describe "available_inventory" do From bbfd7318c5dfe6feac34f8bc5ad072c92687f725 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Wed, 19 Dec 2018 09:49:58 -0800 Subject: [PATCH 07/20] Change create controller method to slice movie URL when creating movies, adjust controller test --- app/controllers/movies_controller.rb | 16 ++++++++++++++-- test/controllers/movies_controller_test.rb | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 368a97c7..4dfa2a59 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -12,7 +12,17 @@ def index end def create - movie = Movie.new(movie_params) + if movie_params[:image_url] != nil + url = movie_params[:image_url] + url = url.slice(31, url.length) + else + url = movie_params[:image_url] + end + movie = Movie.new({external_id: movie_params[:external_id], + image_url: url, + release_date: movie_params[:release_date], + title: movie_params[:title], + inventory: movie_params[:inventory]}) if movie.save render json: { id: movie.id, @@ -21,7 +31,8 @@ def create else if movie.errors.messages[:external_id] == ["has already been taken"] render json: { - errors: "This movie has already been added to your film library." + errors: "Hmm... + We think you already have that movie in your film library." }, status: :bad_request else render json: { @@ -29,6 +40,7 @@ def create }, status: :bad_request end end + end def show diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 1acf8a0b..72ac49bc 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -50,7 +50,7 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest overview: "The strange woman claims the boy has a DNA strain which very likely offers the key to cure several crippling diseases. Tests will have to be done, but the key to save millions of lives is within the grasp of science through this DNA strain. Unsure what to think of all this and of this strange woman, the boy hesitantly agrees to the proposal, there's something exciting about this whole situation, surely the right choice was made.", release_date: "2010-11-05", inventory: 5, - image_url: "/81d8oyEFgj7FlxJqSDXWr8JH8kV.jpg", + image_url: "https://image.tmdb.org/t/p/w185/kMQPixpwZ9KDTxvjlXJ5HHJtYOG.jpg", external_id: 999999999 } } From d35d03882c973baa12ab4b98a4bf136e3c52cd28 Mon Sep 17 00:00:00 2001 From: sjlee3157 Date: Wed, 19 Dec 2018 15:07:47 -0800 Subject: [PATCH 08/20] Add new model methods for rentals (tests pass) --- app/controllers/rentals_controller.rb | 15 +++++ app/models/rental.rb | 10 +++- test/models/rental_test.rb | 80 +++++++++++++++++++++++++++ 3 files changed, 104 insertions(+), 1 deletion(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 67e77073..62df2ad8 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -44,6 +44,21 @@ def overdue render status: :ok, json: rentals end + def complete + rentals = Rental.complete.map do |rental| + { + title: rental.movie.title, + customer_id: rental.customer_id, + name: rental.customer.name, + postal_code: rental.customer.postal_code, + checkout_date: rental.checkout_date, + checkin_date: rental.checkin_date, + due_date: rental.due_date + } + end + render status: :ok, json: rentals + end + private # TODO: make error payloads arrays def require_movie diff --git a/app/models/rental.rb b/app/models/rental.rb index 18654f04..8ea402a1 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -15,7 +15,15 @@ def self.first_outstanding(movie, customer) end def self.overdue - self.where(returned: false).where("due_date < ?", Date.today) + self.where(returned: false).where("due_date < ?", Date.today).order(:due_date) + end + + def self.all_returned + self.where(returned: true).order(:due_date) + end + + def self.all_outstanding_before_due + self.where(returned: false).where("due_date >= ?", Date.today).order(:due_date) end private diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 3a83449c..1952c36b 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -186,4 +186,84 @@ class RentalTest < ActiveSupport::TestCase Rental.overdue.length.must_equal 0 end end + + describe "all_returned" do + it "returns all returned rentals" do + # Start with a clean slate + Rental.destroy_all + + outstanding = Rental.create!( + movie: movies(:one), + customer: customers(:one), + due_date: Date.today + 30, + returned: false + ) + Rental.new( + movie: movies(:one), + customer: customers(:one), + due_date: Date.today - 10, + returned: true + ).save!(validate: false) + + second = Rental.create!( + movie: movies(:one), + customer: customers(:two), + due_date: Date.today + 10, + returned: true + ) + Rental.all_returned.length.must_equal 2 + Rental.all_returned.last.must_equal second + Rental.all.count.must_equal 3 + end + end + + describe "all_outstanding_before_due" do + it "returns all outstanding rentals" do + # Start with a clean slate + Rental.destroy_all + + first = Rental.create!( + movie: movies(:one), + customer: customers(:one), + due_date: Date.today + 10, + returned: false + ) + second = Rental.create!( + movie: movies(:one), + customer: customers(:two), + due_date: Date.today + 20, + returned: false + ) + returned = Rental.create!( + movie: movies(:two), + customer: customers(:two), + due_date: Date.today + 10, + returned: true + ) + Rental.new( + movie: movies(:two), + customer: customers(:one), + due_date: Date.today - 30, + returned: false + ).save!(validate: false) + Rental.all_outstanding_before_due.length.must_equal 2 + Rental.all_outstanding_before_due.first.must_equal first + Rental.all.count.must_equal 4 + end + + it "considers today's date as not yet overdue" do + # Start with a clean slate + Rental.destroy_all + + Rental.new( + movie: movies(:one), + customer: customers(:one), + due_date: Date.today, + returned: false + ).save!(validate: false) + Rental.all_outstanding_before_due.length.must_equal 1 + Rental.all.count.must_equal 1 + end + end + end From 898847544971889f537af8f312339a5ff75a9432 Mon Sep 17 00:00:00 2001 From: sjlee3157 Date: Wed, 19 Dec 2018 15:24:50 -0800 Subject: [PATCH 09/20] Add endpoints for rentals/returned and rentals/out-ok (tests pass) --- app/controllers/rentals_controller.rb | 19 +++- app/models/rental.rb | 4 +- config/routes.rb | 3 + test/controllers/rentals_controller_test.rb | 115 +++++++++++++++++++- test/models/rental_test.rb | 18 +-- 5 files changed, 142 insertions(+), 17 deletions(-) diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 62df2ad8..ef9c8a0e 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -44,15 +44,28 @@ def overdue render status: :ok, json: rentals end - def complete - rentals = Rental.complete.map do |rental| + def returned + rentals = Rental.returned.map do |rental| + { + title: rental.movie.title, + customer_id: rental.customer_id, + name: rental.customer.name, + postal_code: rental.customer.postal_code, + checkout_date: rental.checkout_date, + due_date: rental.due_date + } + end + render status: :ok, json: rentals + end + + def out_ok + rentals = Rental.out_ok.map do |rental| { title: rental.movie.title, customer_id: rental.customer_id, name: rental.customer.name, postal_code: rental.customer.postal_code, checkout_date: rental.checkout_date, - checkin_date: rental.checkin_date, due_date: rental.due_date } end diff --git a/app/models/rental.rb b/app/models/rental.rb index 8ea402a1..e9147cfb 100644 --- a/app/models/rental.rb +++ b/app/models/rental.rb @@ -18,11 +18,11 @@ def self.overdue self.where(returned: false).where("due_date < ?", Date.today).order(:due_date) end - def self.all_returned + def self.returned self.where(returned: true).order(:due_date) end - def self.all_outstanding_before_due + def self.out_ok self.where(returned: false).where("due_date >= ?", Date.today).order(:due_date) end diff --git a/config/routes.rb b/config/routes.rb index 76715f9a..49611027 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -9,6 +9,9 @@ post "/rentals/:title/return", to: "rentals#check_in", as: "check_in" get "/rentals/overdue", to: "rentals#overdue", as: "overdue" + get "/rentals/returned", to: "rentals#returned", as: "returned" + get "/rentals/out-ok", to: "rentals#out_ok", as: "out_ok" + root 'movies#index' end diff --git a/test/controllers/rentals_controller_test.rb b/test/controllers/rentals_controller_test.rb index 831b5230..4339eb0c 100644 --- a/test/controllers/rentals_controller_test.rb +++ b/test/controllers/rentals_controller_test.rb @@ -90,7 +90,7 @@ class RentalsControllerTest < ActionDispatch::IntegrationTest @rental.returned.must_equal true end - it "can check out a rental and return it" do + it "can check out a rental and return it" do # Arrange Rental.destroy_all customer = Customer.first @@ -117,11 +117,11 @@ class RentalsControllerTest < ActionDispatch::IntegrationTest expect(rental.returned).must_equal true - + end - + it "requires a valid movie title" do post check_in_path(title: "does not exist"), params: { customer_id: @rental.customer.id @@ -273,4 +273,113 @@ class RentalsControllerTest < ActionDispatch::IntegrationTest end end end + + describe "returned" do + + it "Returns a JSON array" do + get returned_path + must_respond_with :success + @response.headers['Content-Type'].must_include 'json' + + # Attempt to parse + data = JSON.parse @response.body + data.must_be_kind_of Array + end + + it "Returns an empty array if no rentals returned" do + # Make sure there's none returned + Rental.all.each do |r| + r.returned = false + r.save! + end + + get returned_path + must_respond_with :success + + data = JSON.parse @response.body + data.must_be_kind_of Array + data.length.must_equal 0 + end + + it "Returns expected fields" do + # Make sure we get something back + first = Rental.first + first.returned = true + first.save! + Rental.returned.length.must_be :>, 0 + + get returned_path + must_respond_with :success + + data = JSON.parse @response.body + data.must_be_kind_of Array + data.length.must_equal Rental.returned.length + + data.each do |rental| + rental.must_be_kind_of Hash + rental.must_include "title" + rental.must_include "customer_id" + rental.must_include "name" + rental.must_include "postal_code" + rental.must_include "checkout_date" + rental.must_include "due_date" + end + end + end + + describe "out_ok" do + + it "Returns a JSON array" do + get out_ok_path + must_respond_with :success + @response.headers['Content-Type'].must_include 'json' + + # Attempt to parse + data = JSON.parse @response.body + data.must_be_kind_of Array + end + + it "Returns an empty array if no checked-out rentals currently in good standing" do + # Make sure they're all either checked out and overdue, + # or checked out with a due date in the past + Rental.all.each do |r| + r.due_date = Date.today - 30 + r.save! + end + + get out_ok_path + must_respond_with :success + + data = JSON.parse @response.body + data.must_be_kind_of Array + data.length.must_equal 0 + end + + it "Returns expected fields" do + # Make sure we get something back + first = Rental.first + first.due_date = Date.today + 30 + first.returned = false + first.save! + Rental.out_ok.length.must_be :>, 0 + + get out_ok_path + must_respond_with :success + + data = JSON.parse @response.body + data.must_be_kind_of Array + data.length.must_equal Rental.out_ok.length + + data.each do |rental| + rental.must_be_kind_of Hash + rental.must_include "title" + rental.must_include "customer_id" + rental.must_include "name" + rental.must_include "postal_code" + rental.must_include "checkout_date" + rental.must_include "due_date" + end + end + end + end diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 1952c36b..72ccd349 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -187,7 +187,7 @@ class RentalTest < ActiveSupport::TestCase end end - describe "all_returned" do + describe "returned" do it "returns all returned rentals" do # Start with a clean slate Rental.destroy_all @@ -211,14 +211,14 @@ class RentalTest < ActiveSupport::TestCase due_date: Date.today + 10, returned: true ) - Rental.all_returned.length.must_equal 2 - Rental.all_returned.last.must_equal second + Rental.returned.length.must_equal 2 + Rental.returned.last.must_equal second Rental.all.count.must_equal 3 end end - describe "all_outstanding_before_due" do - it "returns all outstanding rentals" do + describe "out_ok" do + it "returns all outstanding rentals that aren't due yet" do # Start with a clean slate Rental.destroy_all @@ -246,8 +246,8 @@ class RentalTest < ActiveSupport::TestCase due_date: Date.today - 30, returned: false ).save!(validate: false) - Rental.all_outstanding_before_due.length.must_equal 2 - Rental.all_outstanding_before_due.first.must_equal first + Rental.out_ok.length.must_equal 2 + Rental.out_ok.first.must_equal first Rental.all.count.must_equal 4 end @@ -261,9 +261,9 @@ class RentalTest < ActiveSupport::TestCase due_date: Date.today, returned: false ).save!(validate: false) - Rental.all_outstanding_before_due.length.must_equal 1 + Rental.out_ok.length.must_equal 1 Rental.all.count.must_equal 1 end end - + end From 32c17a58b375e74387754385387b9c869c007f9a Mon Sep 17 00:00:00 2001 From: sjlee3157 Date: Wed, 19 Dec 2018 15:54:52 -0800 Subject: [PATCH 10/20] Add one more rental model test --- test/models/rental_test.rb | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/test/models/rental_test.rb b/test/models/rental_test.rb index 72ccd349..767eaf8a 100644 --- a/test/models/rental_test.rb +++ b/test/models/rental_test.rb @@ -1,4 +1,5 @@ require 'test_helper' +require 'pry' class RentalTest < ActiveSupport::TestCase let(:rental_data) { @@ -266,4 +267,40 @@ class RentalTest < ActiveSupport::TestCase end end + describe "all rentals" do + it "all rentals = overdue + returned + out_ok" do + # Start with a clean slate + Rental.destroy_all + + out_ok = Rental.create!( + movie: movies(:one), + customer: customers(:one), + due_date: Date.today + 10, + returned: true + ) + # Overdue rental: + Rental.new( + movie: movies(:one), + customer: customers(:two), + due_date: Date.today - 10, + returned: false + ).save!(validate: false) + returned_due_later = Rental.create!( + movie: movies(:two), + customer: customers(:two), + due_date: Date.today + 10, + returned: true + ) + # Returned rental due in the past: + Rental.new( + movie: movies(:two), + customer: customers(:one), + due_date: Date.today - 10, + returned: true + ).save!(validate: false) + expected_count = (Rental.overdue.length + Rental.returned.length + Rental.out_ok.length) + Rental.all.count.must_equal expected_count + end + end + end From ababf0c2b473204f1edfe6a7ce050b901d7c922f Mon Sep 17 00:00:00 2001 From: jfahmy Date: Wed, 19 Dec 2018 18:12:41 -0800 Subject: [PATCH 11/20] Add image url to json response from movie show controller --- .gitignore | 5 +++++ app/controllers/movies_controller.rb | 2 +- config/database.yml | 9 +++++---- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 4a494a75..58456ca4 100644 --- a/.gitignore +++ b/.gitignore @@ -23,3 +23,8 @@ # Ignore master key for decrypting credentials and more. /config/master.key + +# Elastic Beanstalk Files +.elasticbeanstalk/* +!.elasticbeanstalk/*.cfg.yml +!.elasticbeanstalk/*.global.yml diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 4dfa2a59..1b31843c 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -47,7 +47,7 @@ def show render( status: :ok, json: @movie.as_json( - only: [:title, :overview, :release_date, :inventory], + only: [:title, :overview, :release_date, :inventory, :image_url], methods: [:available_inventory] ) ) diff --git a/config/database.yml b/config/database.yml index 50748d61..3b9343e6 100644 --- a/config/database.yml +++ b/config/database.yml @@ -21,7 +21,8 @@ test: production: <<: *default - database: _production - username: - password: <%= ENV['_DATABASE_PASSWORD'] %> - + database: <%= ENV['RDS_DB_NAME'] %> + username: <%= ENV['RDS_USERNAME'] %> + password: <%= ENV['RDS_PASSWORD'] %> + host: <%= ENV['RDS_HOSTNAME'] %> + port: <%= ENV['RDS_PORT'] %> From 1e50fb7e0d66cd72544675a7feb698e02f1831ea Mon Sep 17 00:00:00 2001 From: jfahmy Date: Wed, 19 Dec 2018 18:54:43 -0800 Subject: [PATCH 12/20] change database.yml --- config/database.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/config/database.yml b/config/database.yml index 3b9343e6..cedbd30d 100644 --- a/config/database.yml +++ b/config/database.yml @@ -20,9 +20,6 @@ test: database: _test production: - <<: *default - database: <%= ENV['RDS_DB_NAME'] %> - username: <%= ENV['RDS_USERNAME'] %> - password: <%= ENV['RDS_PASSWORD'] %> - host: <%= ENV['RDS_HOSTNAME'] %> - port: <%= ENV['RDS_PORT'] %> + <<: *default + adapter: postgresql + database: db/production.sqlite3 From b00d6e26ee6bcf2eefcf912402c9a6469b26f26d Mon Sep 17 00:00:00 2001 From: jfahmy Date: Wed, 19 Dec 2018 19:19:03 -0800 Subject: [PATCH 13/20] Add travis.yml file --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 00000000..5b77ff56 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: ruby +rvm: + - 2.2 + - jruby From c0425dcedaa5922ed2d3babbab2f3d6333d547c0 Mon Sep 17 00:00:00 2001 From: sjlee3157 Date: Wed, 19 Dec 2018 22:17:54 -0800 Subject: [PATCH 14/20] Fix missing overview for movie create --- app/controllers/movies_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 1b31843c..9dbfa4cd 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -19,6 +19,7 @@ def create url = movie_params[:image_url] end movie = Movie.new({external_id: movie_params[:external_id], + overview: movie_params[:overview], image_url: url, release_date: movie_params[:release_date], title: movie_params[:title], @@ -27,6 +28,10 @@ def create render json: { id: movie.id, title: movie.title, + overview: movie.overview, + image_url: movie.image_url, + release_date: movie.release_date, + inventory: movie.inventory, external_id: movie.external_id }, status: :ok else if movie.errors.messages[:external_id] == ["has already been taken"] From f7f225b77c1debddd9727ab69065a945c978d74e Mon Sep 17 00:00:00 2001 From: jfahmy Date: Thu, 20 Dec 2018 10:02:35 -0800 Subject: [PATCH 15/20] Modify travis.yml file to connect to Heroku --- .travis.yml | 14 ++++++++++++-- Gemfile.lock | 34 +++++++++++++++++++++++++++++++++- 2 files changed, 45 insertions(+), 3 deletions(-) diff --git a/.travis.yml b/.travis.yml index 5b77ff56..b23f0cb5 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,14 @@ language: ruby rvm: - - 2.2 - - jruby +- 2.2 +- jruby + +deploy: + provider: heroku + api_key: + secure: GItCjV2InWRINoetFPfjsKkbGrxkpEzBVudcXAaZb9sQxhG6Sqg3T6TqRyRKheY6aHJMQyjFCtxsRUbGV3p/MZJpFDOTFsor/V08yjixIy4OGOvEhp69f7tlIvJ6lfGaftv9Jd/dhV1ZfbSLXvvVDBbsDJP3OhY9gt34SSu0IfajDvvPK+JfaYr96KlEITFZVFA+dtU5KKbuUE8+wRJF2wRx1ZDXIbaG4V3sLykajm8wqxTqdcb5uDXll4zz8/s5xNaKSufYMcTeUiUpH/dvxFTn82ydT+xEbRL6MoMCWCbtyjVcddeJ/8gfnkM5ka+pNnTDv9u2nM6XMhJibdSqWWgWMkNQeuFpD7rfh3sn70+RTLtHbLqTWG7vDHiMamfGpVret1CDM2/naAesiiwhER8KR1gm1bPNEeSGn+WHKJHFiWfgVehfIeYRaYxaoXiZ6hCYHH0rmvFzSRYMpAUZyEsTt71rAUxi6iScV6K5pKvglnsKIbOUoQoixKcw4auQiwZYSqVh0Q/D1w6wZRi1WIJK7kvAF36A/1NNzJSykCVHZz4xQyXZ4i10PfmLtgSnv+VsNTXq9zXEwoMnmZI6SrpTPHW68+PSy/Vq35gQHp0u4dLRCODUe9V3aMjJgk+niZhIS3SXSmQjHrmaJyp4iuglE96iNUV0B2mOig80tJs= + app: rails-videostore-api + run: + - "sleep 15" + - "rake db:migrate" + - "run rake db:seed" diff --git a/Gemfile.lock b/Gemfile.lock index a0a07df1..ac7226b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -52,6 +52,8 @@ GEM awesome_print (1.8.0) bootsnap (1.3.2) msgpack (~> 1.0) + bootsnap (1.3.2-java) + msgpack (~> 1.0) builder (3.2.3) byebug (10.0.2) case_transform (0.2) @@ -65,6 +67,9 @@ GEM railties (>= 3.2, < 6.0) erubi (1.7.1) ffi (1.9.25) + ffi (1.9.25-java) + ffi (1.9.25-x64-mingw32) + ffi (1.9.25-x86-mingw32) globalid (0.4.1) activesupport (>= 4.2.0) httparty (0.16.3) @@ -104,18 +109,34 @@ GEM minitest (>= 5.0) ruby-progressbar msgpack (1.2.4) + msgpack (1.2.4-java) + msgpack (1.2.4-x64-mingw32) + msgpack (1.2.4-x86-mingw32) multi_json (1.13.1) multi_xml (0.6.0) nio4r (2.3.1) + nio4r (2.3.1-java) nokogiri (1.8.5) mini_portile2 (~> 2.3.0) + nokogiri (1.8.5-java) + nokogiri (1.8.5-x64-mingw32) + mini_portile2 (~> 2.3.0) + nokogiri (1.8.5-x86-mingw32) + mini_portile2 (~> 2.3.0) pg (1.1.3) + pg (1.1.3-x64-mingw32) + pg (1.1.3-x86-mingw32) pry (0.12.2) coderay (~> 1.1.0) method_source (~> 0.9.0) + pry (0.12.2-java) + coderay (~> 1.1.0) + method_source (~> 0.9.0) + spoon (~> 0.0) pry-rails (0.3.8) pry (>= 0.10.4) puma (3.12.0) + puma (3.12.0-java) rack (2.0.6) rack-cors (1.0.2) rack-test (1.1.0) @@ -150,6 +171,8 @@ GEM ffi (~> 1.0) ruby-progressbar (1.10.0) ruby_dep (1.5.0) + spoon (0.0.6) + ffi spring (2.0.2) activesupport (>= 4.2) spring-watcher-listen (2.0.1) @@ -164,15 +187,24 @@ GEM sprockets (>= 3.0.0) thor (0.20.3) thread_safe (0.3.6) + thread_safe (0.3.6-java) tzinfo (1.2.5) thread_safe (~> 0.1) + tzinfo-data (1.2018.7) + tzinfo (>= 1.0.0) websocket-driver (0.7.0) websocket-extensions (>= 0.1.0) + websocket-driver (0.7.0-java) + websocket-extensions (>= 0.1.0) websocket-extensions (0.1.3) will_paginate (3.1.6) PLATFORMS + java ruby + x64-mingw32 + x86-mingw32 + x86-mswin32 DEPENDENCIES active_model_serializers @@ -199,4 +231,4 @@ RUBY VERSION ruby 2.5.1p57 BUNDLED WITH - 1.16.6 + 1.17.2 From 07a0884797f1642c1a0a24fc977ace55ec12a1ba Mon Sep 17 00:00:00 2001 From: jfahmy Date: Thu, 20 Dec 2018 10:42:40 -0800 Subject: [PATCH 16/20] Add sleep command to seed data so we don't hit TMDB request rate limiting --- Gemfile | 2 +- Gemfile.lock | 2 +- db/seeds.rb | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/Gemfile b/Gemfile index 2d53ba9c..da8b9153 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '2.5.1' +ruby '2.2.7' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' diff --git a/Gemfile.lock b/Gemfile.lock index ac7226b0..19913637 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -228,7 +228,7 @@ DEPENDENCIES will_paginate RUBY VERSION - ruby 2.5.1p57 + ruby 2.2.7p470 BUNDLED WITH 1.17.2 diff --git a/db/seeds.rb b/db/seeds.rb index 6abb1e9f..4c88d3b3 100644 --- a/db/seeds.rb +++ b/db/seeds.rb @@ -9,4 +9,5 @@ ap "#{movie_data['title']} Added to the library!" movies.first.inventory = movie_data['inventory'] movies.first.save unless movies.empty? + sleep(2) end From 296717b84db7e1973c59fe402abcc5a326c50024 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Thu, 20 Dec 2018 10:44:47 -0800 Subject: [PATCH 17/20] Adjust gemfile ruby version --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index da8b9153..2d53ba9c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '2.2.7' +ruby '2.5.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' From b839ae2746d828630abe5778576d329817e4e143 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Thu, 20 Dec 2018 10:48:50 -0800 Subject: [PATCH 18/20] One last change to gemfile --- Gemfile.lock | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile.lock b/Gemfile.lock index 19913637..ac7226b0 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -228,7 +228,7 @@ DEPENDENCIES will_paginate RUBY VERSION - ruby 2.2.7p470 + ruby 2.5.1p57 BUNDLED WITH 1.17.2 From 5aaaf686a38b5671b58965f20da932ad7896e2e1 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Fri, 21 Dec 2018 11:13:29 -0800 Subject: [PATCH 19/20] Adjust ruby version to see if it will help TravisCI not fail --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index 2d53ba9c..a2835339 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby '2.5.1' +ruby'~> 2.5' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' From 249d8f93bd6d5c583e63c05d7b637e5d249abc23 Mon Sep 17 00:00:00 2001 From: jfahmy Date: Fri, 21 Dec 2018 11:19:37 -0800 Subject: [PATCH 20/20] Change gemfile back to previous version --- Gemfile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Gemfile b/Gemfile index a2835339..2d53ba9c 100644 --- a/Gemfile +++ b/Gemfile @@ -1,7 +1,7 @@ source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } -ruby'~> 2.5' +ruby '2.5.1' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails'