diff --git a/Gemfile b/Gemfile index d5c7affd..de65f25a 100644 --- a/Gemfile +++ b/Gemfile @@ -5,6 +5,7 @@ git_source(:github) do |repo_name| "https://github.com/#{repo_name}.git" end +gem 'rack-cors', :require => 'rack/cors' # Bundle edge Rails instead: gem 'rails', github: 'rails/rails' gem 'rails', '~> 5.0.1' diff --git a/Gemfile.lock b/Gemfile.lock index b39604fa..8a214b36 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -1,104 +1,107 @@ GEM remote: https://rubygems.org/ specs: - actioncable (5.0.1) - actionpack (= 5.0.1) - nio4r (~> 1.2) + actioncable (5.0.6) + actionpack (= 5.0.6) + nio4r (>= 1.2, < 3.0) websocket-driver (~> 0.6.1) - actionmailer (5.0.1) - actionpack (= 5.0.1) - actionview (= 5.0.1) - activejob (= 5.0.1) + actionmailer (5.0.6) + actionpack (= 5.0.6) + actionview (= 5.0.6) + activejob (= 5.0.6) mail (~> 2.5, >= 2.5.4) rails-dom-testing (~> 2.0) - actionpack (5.0.1) - actionview (= 5.0.1) - activesupport (= 5.0.1) + actionpack (5.0.6) + actionview (= 5.0.6) + activesupport (= 5.0.6) rack (~> 2.0) rack-test (~> 0.6.3) rails-dom-testing (~> 2.0) rails-html-sanitizer (~> 1.0, >= 1.0.2) - actionview (5.0.1) - activesupport (= 5.0.1) + actionview (5.0.6) + activesupport (= 5.0.6) builder (~> 3.1) erubis (~> 2.7.0) rails-dom-testing (~> 2.0) - rails-html-sanitizer (~> 1.0, >= 1.0.2) - active_model_serializers (0.10.6) + rails-html-sanitizer (~> 1.0, >= 1.0.3) + active_model_serializers (0.10.7) actionpack (>= 4.1, < 6) activemodel (>= 4.1, < 6) case_transform (>= 0.2) - jsonapi-renderer (>= 0.1.1.beta1, < 0.2) - activejob (5.0.1) - activesupport (= 5.0.1) + jsonapi-renderer (>= 0.1.1.beta1, < 0.3) + activejob (5.0.6) + activesupport (= 5.0.6) globalid (>= 0.3.6) - activemodel (5.0.1) - activesupport (= 5.0.1) - activerecord (5.0.1) - activemodel (= 5.0.1) - activesupport (= 5.0.1) + activemodel (5.0.6) + activesupport (= 5.0.6) + activerecord (5.0.6) + activemodel (= 5.0.6) + activesupport (= 5.0.6) arel (~> 7.0) - activesupport (5.0.1) + activesupport (5.0.6) concurrent-ruby (~> 1.0, >= 1.0.2) i18n (~> 0.7) minitest (~> 5.1) tzinfo (~> 1.1) ansi (1.5.0) arel (7.1.4) - better_errors (2.1.1) + better_errors (2.4.0) coderay (>= 1.0.0) - erubis (>= 2.6.6) + erubi (>= 1.0.0) rack (>= 0.9.0) - binding_of_caller (0.7.2) + bindex (0.5.0) + binding_of_caller (0.7.3) debug_inspector (>= 0.0.1) - builder (3.2.2) - byebug (9.0.6) + builder (3.2.3) + byebug (9.1.0) case_transform (0.2) activesupport - coderay (1.1.1) - coffee-rails (4.2.1) + coderay (1.1.2) + coffee-rails (4.2.2) coffee-script (>= 2.2.0) - railties (>= 4.0.0, < 5.2.x) + railties (>= 4.0.0) coffee-script (2.4.1) coffee-script-source execjs coffee-script-source (1.12.2) - concurrent-ruby (1.0.4) - debug_inspector (0.0.2) - dotenv (2.2.0) - dotenv-rails (2.2.0) - dotenv (= 2.2.0) - railties (>= 3.2, < 5.1) + concurrent-ruby (1.0.5) + crass (1.0.3) + debug_inspector (0.0.3) + dotenv (2.2.1) + dotenv-rails (2.2.1) + dotenv (= 2.2.1) + railties (>= 3.2, < 5.2) + erubi (1.7.0) erubis (2.7.0) execjs (2.7.0) - ffi (1.9.14) - globalid (0.3.7) - activesupport (>= 4.1.0) - httparty (0.15.5) + ffi (1.9.18) + globalid (0.4.1) + activesupport (>= 4.2.0) + httparty (0.15.6) multi_xml (>= 0.5.2) - i18n (0.7.0) - jbuilder (2.6.1) - activesupport (>= 3.0.0, < 5.1) - multi_json (~> 1.2) - jquery-rails (4.2.2) + i18n (0.9.1) + concurrent-ruby (~> 1.0) + jbuilder (2.7.0) + activesupport (>= 4.2.0) + multi_json (>= 1.2) + jquery-rails (4.3.1) rails-dom-testing (>= 1, < 3) railties (>= 4.2.0) thor (>= 0.14, < 2.0) - jsonapi-renderer (0.1.2) + jsonapi-renderer (0.2.0) listen (3.0.8) rb-fsevent (~> 0.9, >= 0.9.4) rb-inotify (~> 0.9, >= 0.9.7) - loofah (2.0.3) + loofah (2.1.1) + crass (~> 1.0.2) nokogiri (>= 1.5.9) - mail (2.6.4) - mime-types (>= 1.16, < 4) - method_source (0.8.2) - mime-types (3.1) - mime-types-data (~> 3.2015) - mime-types-data (3.2016.0521) - mini_portile2 (2.1.0) - minitest (5.10.1) - minitest-reporters (1.1.12) + mail (2.7.0) + mini_mime (>= 0.1.1) + method_source (0.9.0) + mini_mime (1.0.0) + mini_portile2 (2.3.0) + minitest (5.10.3) + minitest-reporters (1.1.19) ansi builder minitest (>= 5.0) @@ -106,58 +109,61 @@ GEM minitest-spec-rails (5.4.0) minitest (~> 5.0) rails (>= 4.1) - multi_json (1.12.1) + multi_json (1.12.2) multi_xml (0.6.0) - nio4r (1.2.1) - nokogiri (1.7.0.1) - mini_portile2 (~> 2.1.0) - pry (0.10.4) + nio4r (2.1.0) + nokogiri (1.8.1) + mini_portile2 (~> 2.3.0) + pry (0.11.3) coderay (~> 1.1.0) - method_source (~> 0.8.1) - slop (~> 3.4) - pry-rails (0.3.4) - pry (>= 0.9.10) - puma (3.6.2) - rack (2.0.1) + method_source (~> 0.9.0) + pry-rails (0.3.6) + pry (>= 0.10.4) + puma (3.11.0) + rack (2.0.3) + rack-cors (1.0.2) rack-test (0.6.3) rack (>= 1.0) - rails (5.0.1) - actioncable (= 5.0.1) - actionmailer (= 5.0.1) - actionpack (= 5.0.1) - actionview (= 5.0.1) - activejob (= 5.0.1) - activemodel (= 5.0.1) - activerecord (= 5.0.1) - activesupport (= 5.0.1) - bundler (>= 1.3.0, < 2.0) - railties (= 5.0.1) + rails (5.0.6) + actioncable (= 5.0.6) + actionmailer (= 5.0.6) + actionpack (= 5.0.6) + actionview (= 5.0.6) + activejob (= 5.0.6) + activemodel (= 5.0.6) + activerecord (= 5.0.6) + activesupport (= 5.0.6) + bundler (>= 1.3.0) + railties (= 5.0.6) sprockets-rails (>= 2.0.0) - rails-dom-testing (2.0.2) - activesupport (>= 4.2.0, < 6.0) - nokogiri (~> 1.6) + rails-dom-testing (2.0.3) + activesupport (>= 4.2.0) + nokogiri (>= 1.6) rails-html-sanitizer (1.0.3) loofah (~> 2.0) - railties (5.0.1) - actionpack (= 5.0.1) - activesupport (= 5.0.1) + railties (5.0.6) + actionpack (= 5.0.6) + activesupport (= 5.0.6) method_source rake (>= 0.8.7) thor (>= 0.18.1, < 2.0) - rake (12.0.0) - rb-fsevent (0.9.8) - rb-inotify (0.9.7) - ffi (>= 0.5.0) - ruby-progressbar (1.8.1) - sass (3.4.23) - sass-rails (5.0.6) + rake (12.3.0) + rb-fsevent (0.10.2) + rb-inotify (0.9.10) + ffi (>= 0.5.0, < 2) + ruby-progressbar (1.9.0) + sass (3.5.4) + sass-listen (~> 4.0.0) + sass-listen (4.0.0) + rb-fsevent (~> 0.9, >= 0.9.4) + rb-inotify (~> 0.9, >= 0.9.7) + sass-rails (5.0.7) railties (>= 4.0.0, < 6) sass (~> 3.1) sprockets (>= 2.8, < 4.0) sprockets-rails (>= 2.0, < 4.0) tilt (>= 1.1, < 3) - slop (3.6.0) - spring (2.0.0) + spring (2.0.2) activesupport (>= 4.2) spring-watcher-listen (2.0.1) listen (>= 2.7, < 4.0) @@ -165,30 +171,30 @@ GEM sprockets (3.7.1) concurrent-ruby (~> 1.0) rack (> 1, < 3) - sprockets-rails (3.2.0) + sprockets-rails (3.2.1) actionpack (>= 4.0) activesupport (>= 4.0) sprockets (>= 3.0.0) sqlite3 (1.3.13) - thor (0.19.4) - thread_safe (0.3.5) - tilt (2.0.5) + thor (0.20.0) + thread_safe (0.3.6) + tilt (2.0.8) turbolinks (5.0.1) turbolinks-source (~> 5) - turbolinks-source (5.0.0) - tzinfo (1.2.2) + turbolinks-source (5.0.3) + tzinfo (1.2.4) thread_safe (~> 0.1) - uglifier (3.0.4) + uglifier (4.0.2) execjs (>= 0.3.0, < 3) - web-console (3.4.0) + web-console (3.5.1) actionview (>= 5.0) activemodel (>= 5.0) - debug_inspector + bindex (>= 0.4.0) railties (>= 5.0) - websocket-driver (0.6.4) + websocket-driver (0.6.5) websocket-extensions (>= 0.1.0) - websocket-extensions (0.1.2) - will_paginate (3.1.5) + websocket-extensions (0.1.3) + will_paginate (3.1.6) PLATFORMS ruby @@ -208,6 +214,7 @@ DEPENDENCIES minitest-spec-rails pry-rails puma (~> 3.0) + rack-cors rails (~> 5.0.1) sass-rails (~> 5.0) spring @@ -220,4 +227,4 @@ DEPENDENCIES will_paginate BUNDLED WITH - 1.14.6 + 1.15.4 diff --git a/app/controllers/movies_controller.rb b/app/controllers/movies_controller.rb index 362e2791..72130b61 100644 --- a/app/controllers/movies_controller.rb +++ b/app/controllers/movies_controller.rb @@ -11,18 +11,31 @@ def index render status: :ok, json: data end + def create + movie = Movie.new(movie_params) + if movie.save + render json: {id: movie.id} + else + render json: {errors: movie.errors.messages}, status: :bad_request + end + end + def show render( status: :ok, json: @movie.as_json( only: [:title, :overview, :release_date, :inventory], methods: [:available_inventory] - ) ) + ) end private + def movie_params + params.permit(:title, :overview, :inventory, :release_date) + end + def require_movie @movie = Movie.find_by(title: params[:title]) unless @movie diff --git a/app/models/movie.rb b/app/models/movie.rb index 2d5bd4d3..4850beec 100644 --- a/app/models/movie.rb +++ b/app/models/movie.rb @@ -4,6 +4,9 @@ class Movie < ApplicationRecord has_many :rentals has_many :customers, through: :rentals + validates :overview, uniqueness: { scope: :title, + message: "Movie already exists in our rental Library" } + def available_inventory self.inventory - Rental.where(movie: self, returned: false).length end diff --git a/config/application.rb b/config/application.rb index 2ac21a62..b80d5d87 100644 --- a/config/application.rb +++ b/config/application.rb @@ -16,8 +16,18 @@ class Application < Rails::Application config.eager_load_paths << Rails.root.join('lib') config.action_dispatch.default_headers = { - 'Access-Control-Allow-Origin' => 'http://localhost:8081', + 'Access-Control-Allow-Origin' => '*', 'Access-Control-Request-Method' => %w{GET POST OPTIONS}.join(",") } + + config.middleware.insert_before 0, Rack::Cors do + allow do + origins '*' + resource '*', :headers => :any, :methods => [:get, :post, :options] + end + end + end + + end diff --git a/config/routes.rb b/config/routes.rb index 54bf033e..8eff1ff6 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..43be33a8 100644 --- a/test/controllers/movies_controller_test.rb +++ b/test/controllers/movies_controller_test.rb @@ -42,6 +42,41 @@ class MoviesControllerTest < ActionDispatch::IntegrationTest end end + describe 'create' do + let(:movie_data ) { + { + "title": "The Exorcist", + "overview": "12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.", + "release_date": "1973-12-26", + "inventory": 7 + } + } + # .must_change and .wont_change is not supported with this rails version + it "creates a movie" do + proc { + post movies_path, params: movie_data + }.must_change 'Movie.count', 1 + + must_respond_with :success + end + it "won't save a movie in database with invalid data" do + invalid_movie_data = { + "overview": "12-year-old Regan MacNeil begins to adapt an explicit new personality as strange events befall the local area of Georgetown. Her mother becomes torn between science and superstition in a desperate bid to save her daughter, and ultimately turns to her last hope: Father Damien Karras, a troubled priest who is struggling with his own faith.", + "release_date": "1973-12-26", + "inventory": 7 + } + + proc { + post movies_path, params: invalid_movie_data + }.wont_change 'Movie.count' + + must_respond_with :bad_request + + body = JSON.parse(response.body) + body["errors"].must_include "title" + end + end + describe "show" do it "Returns a JSON object" do get movie_url(title: movies(:one).title)