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 362e2791..bcd6dcdd 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -11,6 +11,34 @@ def index render status: :ok, json: data end + def create + @movie = Movie.find_by(title: params[:title]) + data = MovieWrapper.search(params[:title]) + + # data exists for the sole purpose of when someone tries to add a movie NOT through our web app (ex: postman) + # if movie is not in our library, and also exists as a real movie in the external api, THEN add it + if !@movie && !data.empty? + new_movie = Movie.new(movie_params) + + if new_movie.save + render json: new_movie.as_json(only: [:id]), + status: :ok + else + render json: { + ok: false, + message: new_movie.errors.messages + }, status: :bad_request + end + else + render json: { + ok: false, + message: "Movie already exists in the library OR movie does not exist in this world." + }, status: :bad_request + end + + end + + def show render( status: :ok, @@ -23,10 +51,15 @@ def show private + def movie_params + params.permit(:title, :external_id, :overview, :image_url, :release_date) + end + def require_movie @movie = Movie.find_by(title: params[:title]) unless @movie render status: :not_found, json: { errors: { title: ["No movie with title #{params["title"]}"] } } end end + end diff --git a/app/models/movie.rb b/app/models/movie.rb index 0016080b..89927704 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,6 +2,13 @@ class Movie < ApplicationRecord has_many :rentals has_many :customers, through: :rentals + + validates :title, presence: true + validates :overview, presence: true + validates :image_url, presence: true + validates :release_date, presence: true + validates :external_id, presence: true + def available_inventory self.inventory - Rental.where(movie: self, returned: false).length end diff --git a/config/database.yml b/config/database.yml index 50748d61..5e7bd939 100644 --- a/config/database.yml +++ b/config/database.yml @@ -21,7 +21,9 @@ 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'] %> diff --git a/config/routes.rb b/config/routes.rb index f4c99688..29205898 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -3,12 +3,13 @@ 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" get "/rentals/overdue", to: "rentals#overdue", as: "overdue" + root 'movies#index' end diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 9172cf6e..f603c1ff 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -74,5 +74,103 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest data["errors"].must_include "title" end + end + + describe "create" do + let(:movie_data) { + { + "title": "Jack the Movie", + "overview": "A cool movie", + "release_date": "Oct 23 2018", + "external_id": 10, + "image_url": "image", + } + } + + 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 invalid movie data" do + # arrange + movie_data["title"] = nil + + expect { + post movies_path, params: { movie: movie_data } + }.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 + + it "returns an error for invalid movie data" do + # arrange + movie_data["overview"] = nil + + expect { + post movies_path, params: { movie: movie_data } + }.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 "overview" + must_respond_with :bad_request + end + + it "returns an error for invalid movie data" do + # arrange + movie_data["release_date"] = nil + + expect { + post movies_path, params: { movie: movie_data } + }.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 "release_date" + must_respond_with :bad_request + end + + it "returns an error for invalid movie data" do + # arrange + movie_data["external_id"] = nil + + expect { + post movies_path, params: { movie: movie_data } + }.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 "external_id" + must_respond_with :bad_request + end + + + + end end diff --git a/test/fixtures/movies.yml b/test/fixtures/movies.yml index caf6e68b..7162f057 100644 --- a/test/fixtures/movies.yml +++ b/test/fixtures/movies.yml @@ -5,9 +5,13 @@ one: overview: MyText release_date: 2017-01-11 inventory: 4 + external_id: 121323 + image_url: http://lorempixel.com/185/278/ two: title: MuchFilm overview: MyText release_date: 2017-01-11 inventory: 7 + external_id: 3545 + image_url: http://lorempixel.com/185/278/ diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 70b6a7c6..3e0934a1 100644 --- a/test/models/movie_test.rb +++ b/test/models/movie_test.rb @@ -6,7 +6,9 @@ class MovieTest < ActiveSupport::TestCase "title": "Hidden Figures", "overview": "Some text", "release_date": "1960-06-16", - "inventory": 8 + "inventory": 8, + "external_id": 343, + "image_url": "http://lorempixel.com/185/278/" } }