diff --git a/.generators b/.generators
new file mode 100644
index 00000000..16189766
--- /dev/null
+++ b/.generators
@@ -0,0 +1,8 @@
+
+
diff --git a/.idea/.generators b/.idea/.generators
new file mode 100644
index 00000000..16189766
--- /dev/null
+++ b/.idea/.generators
@@ -0,0 +1,8 @@
+
+
diff --git a/.idea/.gitignore b/.idea/.gitignore
new file mode 100644
index 00000000..8bf4d45d
--- /dev/null
+++ b/.idea/.gitignore
@@ -0,0 +1,6 @@
+# Default ignored files
+/shelf/
+/workspace.xml
+# Datasource local storage ignored files
+/dataSources/
+/dataSources.local.xml
diff --git a/.idea/.rakeTasks b/.idea/.rakeTasks
new file mode 100644
index 00000000..c6865d9a
--- /dev/null
+++ b/.idea/.rakeTasks
@@ -0,0 +1,7 @@
+
+
diff --git a/.idea/misc.xml b/.idea/misc.xml
new file mode 100644
index 00000000..510e7fcc
--- /dev/null
+++ b/.idea/misc.xml
@@ -0,0 +1,4 @@
+
+
+
+
\ No newline at end of file
diff --git a/.idea/modules.xml b/.idea/modules.xml
new file mode 100644
index 00000000..f00f0a95
--- /dev/null
+++ b/.idea/modules.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/vcs.xml b/.idea/vcs.xml
new file mode 100644
index 00000000..94a25f7f
--- /dev/null
+++ b/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/video-store-consumer-api.iml b/.idea/video-store-consumer-api.iml
new file mode 100644
index 00000000..f72e8960
--- /dev/null
+++ b/.idea/video-store-consumer-api.iml
@@ -0,0 +1,121 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/app/controllers/videos_controller.rb b/app/controllers/videos_controller.rb
index c9a2bb08..6ba4cb5b 100644
--- a/app/controllers/videos_controller.rb
+++ b/app/controllers/videos_controller.rb
@@ -2,11 +2,11 @@ class VideosController < ApplicationController
before_action :require_video, only: [:show]
def index
- if params[:query]
- data = VideoWrapper.search(params[:query])
+ data = if params[:query]
+ VideoWrapper.search(params[:query])
else
- data = Video.all
- end
+ Video.all
+ end
render status: :ok, json: data
end
@@ -15,18 +15,40 @@ def show
render(
status: :ok,
json: @video.as_json(
- only: [:title, :overview, :release_date, :inventory],
+ only: %i[title overview release_date inventory],
methods: [:available_inventory]
)
)
end
+ def create
+ video = Video.new(video_params)
+ result = video.save
+ if result
+ render(
+ status: :ok,
+ json: result.as_json(
+ only: %i[title overview release_date inventory],
+ methods: [:available_inventory]
+ )
+ )
+ else
+ render status: :bad_request, json: {
+ errors: video.errors.messages
+ }
+ end
+ end
+
private
def require_video
@video = Video.find_by(title: params[:title])
unless @video
- render status: :not_found, json: { errors: { title: ["No video with title #{params["title"]}"] } }
+ render status: :not_found, json: { errors: { title: ["No video with title #{params['title']}"] } }
end
end
+
+ def video_params
+ return params.permit(:title, :release_date, :overview, :inventory, :image_url, :external_id)
+ end
end
diff --git a/app/models/video.rb b/app/models/video.rb
index f47b7f0b..3d6e3062 100644
--- a/app/models/video.rb
+++ b/app/models/video.rb
@@ -2,6 +2,9 @@ class Video < ApplicationRecord
has_many :rentals
has_many :customers, through: :rentals
+ validates :external_id, uniqueness: true
+ validates :title, presence: true
+
def available_inventory
self.inventory - self.rentals.where(returned: false).length
end
diff --git a/config/routes.rb b/config/routes.rb
index 16fc2214..1111b4bf 100644
--- a/config/routes.rb
+++ b/config/routes.rb
@@ -3,7 +3,7 @@
resources :customers, only: [:index]
- resources :videos, only: [:index, :show], param: :title
+ resources :videos, 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/videos_controller_test.rb b/test/controllers/videos_controller_test.rb
index 730915ed..ed3834dd 100644
--- a/test/controllers/videos_controller_test.rb
+++ b/test/controllers/videos_controller_test.rb
@@ -1,6 +1,7 @@
require 'test_helper'
class VideosControllerTest < ActionDispatch::IntegrationTest
+
describe "index" do
it "returns a JSON array" do
get videos_url
@@ -77,4 +78,45 @@ class VideosControllerTest < ActionDispatch::IntegrationTest
expect(data["errors"]).must_include "title"
end
end
+
+ describe "create" do
+ it "creates a video" do
+ video1 = {
+ "title": 'Hidden Figures',
+ "overview": 'Some text',
+ "release_date": '1960-06-16',
+ "inventory": 8,
+ "external_id": 99999
+ }
+
+ expect {
+ post videos_path, params: video1
+ }.must_differ "Video.count", 1
+ end
+
+ it "won't add duplicate videos" do
+ video1 = {
+ "title": 'Hidden Figures',
+ "overview": 'Some text',
+ "release_date": '1960-06-16',
+ "inventory": 8,
+ "external_id": 99999
+ }
+
+ post videos_path, params: video1
+
+ video2 = {
+ "title": 'Video',
+ "overview": 'Some new text',
+ "release_date": '1990-06-16',
+ "inventory": 4,
+ "external_id": 99999
+ }
+
+ expect {
+ post videos_path, params: video2
+ }.wont_differ "Video.count"
+ end
+ end
+
end
diff --git a/test/models/video_test.rb b/test/models/video_test.rb
index b440a490..5abfeda8 100644
--- a/test/models/video_test.rb
+++ b/test/models/video_test.rb
@@ -1,34 +1,46 @@
require 'test_helper'
class VideoTest < ActiveSupport::TestCase
- let (:video_data) {
+ let (:video_data1) {
{
- "title": "Hidden Figures",
- "overview": "Some text",
- "release_date": "1960-06-16",
- "inventory": 8
+ "title": 'Hidden Figures',
+ "overview": 'Some text',
+ "release_date": '1960-06-16',
+ "inventory": 8,
+ "external_id": 99999
+ }
+ }
+
+ let (:video_data2) {
+ {
+ "title": 'Video',
+ "overview": 'Some new text',
+ "release_date": '1990-06-16',
+ "inventory": 3,
+ "external_id": 99999
}
}
before do
- @video = Video.new(video_data)
+ @video = Video.new(video_data1)
+ @video2 = Video.new(video_data2)
end
- describe "Constructor" do
- it "Can be created" do
- Video.create!(video_data)
+ describe 'Constructor' do
+ it 'Can be created' do
+ Video.create!(video_data1)
end
- it "Has rentals" do
+ it 'Has rentals' do
expect(@video).must_respond_to :rentals
end
- it "Has customers" do
+ it 'Has customers' do
expect(@video).must_respond_to :customers
end
end
- describe "available_inventory" do
+ describe 'available_inventory' do
it "Matches inventory if the video isn't checked out" do
# Make sure no videos are checked out
Rental.destroy_all
@@ -37,7 +49,7 @@ class VideoTest < ActiveSupport::TestCase
end
end
- it "Decreases when a video is checked out" do
+ it 'Decreases when a video is checked out' do
Rental.destroy_all
video = videos(:one)
@@ -55,7 +67,7 @@ class VideoTest < ActiveSupport::TestCase
expect(after_ai).must_equal before_ai - 1
end
- it "Increases when a video is checked in" do
+ it 'Increases when a video is checked in' do
Rental.destroy_all
video = videos(:one)
@@ -78,4 +90,20 @@ class VideoTest < ActiveSupport::TestCase
expect(after_ai).must_equal before_ai + 1
end
end
+
+ describe 'validations' do
+ it 'external ids must be unique' do
+ video1 = Video.create(video_data1)
+ video2 = Video.create(video_data2)
+ expect(video1.valid?).must_equal true
+ expect(video2.valid?).must_equal false
+
+ end
+
+ it 'title must not be blank' do
+ @video.title = ''
+ assert_not @video.valid?
+ end
+
+ end
end