Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fire - Kalki & Noor - Video-Store-Consumer-Api #25

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,8 @@
.node_modules
package-lock.json
node_modules
.idea
.env
.Gemfile
.Gemfile.lock

12 changes: 5 additions & 7 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ GEM
coderay (1.1.3)
concurrent-ruby (1.1.7)
crass (1.0.6)
debase (0.2.4.1)
debase-ruby_core_source (>= 0.10.2)
debase (2.3.0)
debase-ruby_core_source (~> 0.10.10)
debase-ruby_core_source (0.10.12)
dotenv (2.7.6)
dotenv-rails (2.7.6)
Expand Down Expand Up @@ -126,7 +126,6 @@ GEM
mime-types-data (3.2020.1104)
mimemagic (0.3.5)
mini_mime (1.0.2)
mini_portile2 (2.5.0)
minitest (5.14.3)
minitest-rails (6.1.0)
minitest (~> 5.10)
Expand All @@ -140,8 +139,7 @@ GEM
multi_xml (0.6.0)
nenv (0.3.0)
nio4r (2.5.4)
nokogiri (1.11.1)
mini_portile2 (~> 2.5.0)
nokogiri (1.11.1-x86_64-darwin)
racc (~> 1.4)
notiffany (0.1.3)
nenv (~> 0.1)
Expand Down Expand Up @@ -190,8 +188,8 @@ GEM
rb-fsevent (0.10.4)
rb-inotify (0.10.1)
ffi (~> 1.0)
ruby-debug-ide (0.7.2)
rake (>= 0.8.1)
ruby-debug-ide (2.3.0)
debase (~> 2.3.0)
ruby-progressbar (1.11.0)
shellany (0.0.1)
spring (2.1.1)
Expand Down
14 changes: 14 additions & 0 deletions app/controllers/videos_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,16 @@ def show
)
end

def create
video = Video.new(video_params)
if video.save
render json: video.as_json(only: [:title, :overview, :release_date, :image_url, :external_id]), status: :created
return
else
render json: {errors: video.errors.messages}, status: :bad_request
end
end

private

def require_video
Expand All @@ -29,4 +39,8 @@ def require_video
render status: :not_found, json: { errors: { title: ["No video with title #{params["title"]}"] } }
end
end

def video_params
params.permit(:title, :overview, :release_date, :image_url, :external_id, :inventory)
end
end
2 changes: 2 additions & 0 deletions app/models/video.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ class Video < ApplicationRecord
has_many :rentals
has_many :customers, through: :rentals

validates :title, presence: true, uniqueness: true

def available_inventory
self.inventory - self.rentals.where(returned: false).length
end
Expand Down
2 changes: 1 addition & 1 deletion config/routes.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down
104 changes: 83 additions & 21 deletions test/controllers/videos_controller_test.rb
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
require 'test_helper'

class VideosControllerTest < ActionDispatch::IntegrationTest
describe "index" do
it "returns a JSON array" do
describe 'index' do
it 'returns a JSON array' do
get videos_url
assert_response :success
expect(@response.headers['Content-Type']).must_include 'json'
Expand All @@ -12,18 +12,18 @@ class VideosControllerTest < ActionDispatch::IntegrationTest
expect(data).must_be_kind_of Array
end

it "should return many video fields" do
it 'should return many video fields' do
get videos_url
assert_response :success

data = JSON.parse @response.body
data.each do |video|
expect(video).must_include "title"
expect(video).must_include "release_date"
expect(video).must_include 'title'
expect(video).must_include 'release_date'
end
end

it "returns all videos when no query params are given" do
it 'returns all videos when no query params are given' do
get videos_url
assert_response :success

Expand All @@ -32,21 +32,21 @@ class VideosControllerTest < ActionDispatch::IntegrationTest

expected_names = {}
Video.all.each do |video|
expected_names[video["title"]] = false
expected_names[video['title']] = false
end

data.each do |video|
expect(
expected_names[video["title"]]
expected_names[video['title']]
).must_equal false, "Got back duplicate video #{video["title"]}"

expected_names[video["title"]] = true
expected_names[video['title']] = true
end
end
end

describe "show" do
it "Returns a JSON object" do
describe 'show' do
it 'Returns a JSON object' do
get video_url(title: videos(:one).title)
assert_response :success
expect(@response.headers['Content-Type']).must_include 'json'
Expand All @@ -56,25 +56,87 @@ class VideosControllerTest < ActionDispatch::IntegrationTest
expect(data).must_be_kind_of Hash
end

it "Returns expected fields" do
it 'Returns expected fields' do
get video_url(title: videos(:one).title)
assert_response :success

video = JSON.parse @response.body
expect(video).must_include "title"
expect(video).must_include "overview"
expect(video).must_include "release_date"
expect(video).must_include "inventory"
expect(video).must_include "available_inventory"
expect(video).must_include 'title'
expect(video).must_include 'overview'
expect(video).must_include 'release_date'
expect(video).must_include 'inventory'
expect(video).must_include 'available_inventory'
end

it "Returns an error when the video doesn't exist" do
get video_url(title: "does_not_exist")
get video_url(title: 'does_not_exist')
assert_response :not_found

data = JSON.parse @response.body
expect(data).must_include "errors"
expect(data["errors"]).must_include "title"
expect(data).must_include 'errors'
expect(data['errors']).must_include 'title'
end
end
end

describe 'create' do
before do
# Arrange
@video_hash = {
title: 'Test Movie',
overview: 'A movie about testing code',
release_date: 'January 1, 2021',
inventory: 5,
image_url: 'https://upload.wikimedia.org/wikipedia/en/9/95/Test_image.jpg',
external_id: 112233
}
end
it 'can create a valid video' do
# Assert
expect {
post videos_path, params: @video_hash
}.must_change 'Video.count', 1

must_respond_with :created
end

it 'will respond with bad request and errors for an invalid movie' do
# Arrange
@video_hash[:title] = nil

# Assert
expect {
post videos_path, params: @video_hash
}.wont_change "Video.count"
body = JSON.parse(response.body)

expect(body.keys).must_include "errors"
expect(body["errors"].keys).must_include "title"
expect(body["errors"]["title"]).must_include "can't be blank"

must_respond_with :bad_request
end

it 'will not add video that is not in the db' do
# TODO
end

it 'will not add the same video twice' do
same_video = {
title: 'Test Movie',
overview: 'A movie about testing code',
release_date: 'January 1, 2021',
inventory: 5,
image_url: 'https://upload.wikimedia.org/wikipedia/en/9/95/Test_image.jpg',
external_id: 112233
}

expect {
post videos_path, params: @video_hash
}.must_change 'Video.count', 1

expect {
post videos_path, params: same_video
}.wont_change "Video.count"
end
end
end