diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 362e2791..449bfb1a 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -21,6 +21,17 @@ def show ) end + def create + movie = Movie.new(movie_params) + if movie.save + render json: movie.as_json, status: :created + return + else + render json: {errors: movie.errors.messages}, status: :bad_request + return + end + end + private def require_movie @@ -29,4 +40,9 @@ 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 diff --git a/app/controllers/rentals_controller.rb b/app/controllers/rentals_controller.rb index 67e77073..b67dac93 100644 --- a/app/controllers/rentals_controller.rb +++ b/app/controllers/rentals_controller.rb @@ -5,7 +5,6 @@ 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]) - if rental.save render status: :ok, json: {} else diff --git a/app/models/movie.rb b/app/models/movie.rb index fda94941..f9e28242 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -2,6 +2,9 @@ class Movie < ApplicationRecord has_many :rentals has_many :customers, through: :rentals + validates :title, :overview, :release_date, :image_url, :external_id, presence: true + validates :external_id, uniqueness: true + def available_inventory self.inventory - Rental.where(movie: self, returned: false).length 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" diff --git a/test/controllers/movies_controller_test.rb b/test/controllers/movies_controller_test.rb index 9172cf6e..aff43fac 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -75,4 +75,39 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest end end + + describe "create" do + before do + @valid_movie = { + title: "something", + overview: "something", + release_date: "01-01-2020", + inventory: 5, + image_url: "https://designerdoginfo.files.wordpress.com/2012/10/apricot-cavoodle-puppy-on-blue-blanket.jpg", + external_id: 6 + } + @invalid_movie = { + inventory: 5, + } + end + + + + + it "can create a new movie with valid data" do + expect { post movies_path, params: @valid_movie }.must_differ "Movie.count", 1 + end + + it "responds with bad request and errors for invalid data" do + expect { post movies_path, params: @invalid_movie }.wont_change "Movie.count" + + body = check_response(expected_type: Hash, expected_status: :bad_request) + expect(body.keys).must_include "errors" + expect(body["errors"].keys).must_include "title" + expect(body["errors"].keys).must_include "overview" + expect(body["errors"].keys).must_include "release_date" + expect(body["errors"].keys).must_include "external_id" + end + + end end diff --git a/test/models/movie_test.rb b/test/models/movie_test.rb index 70b6a7c6..9d5910ff 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, + "image_url": "https://designerdoginfo.files.wordpress.com/2012/10/apricot-cavoodle-puppy-on-blue-blanket.jpg", + "external_id": 5, } } diff --git a/test/test_helper.rb b/test/test_helper.rb index df134a4d..b6faa6fd 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -17,4 +17,13 @@ class ActiveSupport::TestCase fixtures :all # Add more helper methods to be used by all tests here... + # helper method + 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 end