Skip to content

Commit

Permalink
Merge pull request #6 from Jameskcoleman/week_3_part_2
Browse files Browse the repository at this point in the history
Week 3 part 2
  • Loading branch information
Jameskcoleman committed Jul 11, 2014
2 parents 2cda3ef + e9b76e9 commit d0f3e1e
Show file tree
Hide file tree
Showing 13 changed files with 161 additions and 33 deletions.
6 changes: 4 additions & 2 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@ gem 'bcrypt-ruby', '=3.1.0'

group :development do
gem 'sqlite3'
gem 'pry'
gem 'pry-nav'
gem 'thin'
gem 'better_errors'
gem 'binding_of_caller'
Expand All @@ -24,11 +22,15 @@ group :development, :test do
gem 'rspec-rails', '2.99'
gem 'fabrication'
gem 'faker'
gem 'pry'
gem 'pry-nav'
end

group :test do
gem 'database_cleaner', '1.2.0'
gem 'shoulda-matchers'
gem 'capybara'
gem 'launchy'
end

group :production do
Expand Down
16 changes: 16 additions & 0 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ GEM
minitest (~> 5.1)
thread_safe (~> 0.1)
tzinfo (~> 1.1)
addressable (2.3.6)
arel (5.0.1.20140414130214)
bcrypt-ruby (3.1.0)
better_errors (1.0.1)
Expand All @@ -38,6 +39,12 @@ GEM
sass (~> 3.2)
bootstrap_form (2.1.1)
builder (3.2.2)
capybara (2.4.1)
mime-types (>= 1.16)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
coderay (1.1.0)
coffee-rails (4.0.1)
coffee-script (>= 2.2.0)
Expand Down Expand Up @@ -69,13 +76,18 @@ GEM
railties (>= 3.0, < 5.0)
thor (>= 0.14, < 2.0)
json (1.8.1)
launchy (2.4.2)
addressable (~> 2.3)
mail (2.5.4)
mime-types (~> 1.16)
treetop (~> 1.4.8)
method_source (0.8.2)
mime-types (1.25.1)
mini_portile (0.6.0)
minitest (5.3.4)
multi_json (1.10.1)
nokogiri (1.6.2.1)
mini_portile (= 0.6.0)
pg (0.17.0)
polyglot (0.3.5)
pry (0.9.12.3)
Expand Down Expand Up @@ -157,6 +169,8 @@ GEM
uglifier (2.3.1)
execjs (>= 0.3.0)
json (>= 1.8.0)
xpath (2.0.0)
nokogiri (~> 1.3)

PLATFORMS
ruby
Expand All @@ -167,12 +181,14 @@ DEPENDENCIES
binding_of_caller
bootstrap-sass
bootstrap_form
capybara
coffee-rails
database_cleaner (= 1.2.0)
fabrication
faker
haml-rails
jquery-rails
launchy
pg
pry
pry-nav
Expand Down
4 changes: 4 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,4 +13,8 @@ def normalize_queue_item_positions
end
end

def queued_video?(video)
queue_items.map(&:video).include?(video)
end

end
2 changes: 1 addition & 1 deletion app/views/queue_items/index.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
- @queue_items.each do |queue_item|
%tr
= hidden_field_tag("queue_items[][id]", queue_item.id)
%td= text_field_tag("queue_items[][position]", queue_item.position)
%td= text_field_tag("queue_items[][position]", queue_item.position, data: {video_id: queue_item.video.id})
%td
= link_to queue_item.video_title, queue_item.video
%td
Expand Down
2 changes: 1 addition & 1 deletion app/views/videos/show.html.haml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
%span Rating: 4.5/5.0
%p= @video.description
.actions
= link_to "+ My Queue", queue_items_path(video_id: @video.id), method: :post, class: 'btn'
= link_to "+ My Queue", queue_items_path(video_id: @video.id), method: :post, class: 'btn' unless current_user.queued_video?(@video)
%section.reviews.container
.row
.col-sm-10.col-sm-offset-1
Expand Down
58 changes: 30 additions & 28 deletions spec/controllers/queue_items_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,48 +4,47 @@
describe "GET index" do
it "sets @queue_items to the queue items of the logged in user" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
queue_item1 = Fabricate(:queue_item, user: alice)
queue_item2 = Fabricate(:queue_item, user: alice)
get :index
expect(assigns(:queue_items)).to match_array([queue_item1, queue_item2])
end

it "redirects to the sign in page for unauthenticated users" do
get :index
expect(response).to redirect_to sign_in_path
it_behaves_like "requires sign in" do
let(:action) { get :index }
end
end

describe "POST create" do
it "redirects to the my queue page" do
session[:user_id] = Fabricate(:user).id
set_current_user
video = Fabricate(:video)
post :create, video_id: video.id
expect(response).to redirect_to my_queue_path
end
it "creates a queue item" do
session[:user_id] = Fabricate(:user).id
set_current_user
video = Fabricate(:video)
post :create, video_id: video.id
expect(QueueItem.count).to eq(1)
end
it "creates the queue item that is associated with the video" do
session[:user_id] = Fabricate(:user).id
set_current_user
video = Fabricate(:video)
post :create, video_id: video.id
expect(QueueItem.first.video).to eq(video)
end
it "creates the queue item that is associated with the signed in user" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
video = Fabricate(:video)
post :create, video_id: video.id
expect(QueueItem.first.user).to eq(alice)
end
it "puts the video as the last one in the queue" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
monk = Fabricate(:video)
Fabricate(:queue_item, video: monk, user: alice)
south_park = Fabricate(:video)
Expand All @@ -55,7 +54,7 @@
end
it "does not add the video to the queue if the video is already in the queue" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
monk = Fabricate(:video)
Fabricate(:queue_item, video: monk, user: alice)
post :create, video_id: monk.id
Expand All @@ -65,26 +64,30 @@
post :create, video_id: 3
expect(response).to redirect_to sign_in_path
end

it_behaves_like "requires sign in" do
let(:action) { post :create, video_id: 3 }
end
end

describe "DELETE destroy" do
it "redirects to the my queue page" do
session[:user_id] = Fabricate(:user).id
set_current_user
queue_item = Fabricate(:queue_item)
delete :destroy, id: queue_item.id
expect(response).to redirect_to my_queue_path
end
it "deletes the queue item" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
queue_item = Fabricate(:queue_item, user: alice)
delete :destroy, id: queue_item.id
expect(QueueItem.count).to eq(0)
end

it "normalizes the remaining queue_items" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
queue_item1 = Fabricate(:queue_item, user: alice, position: 1)
queue_item2 = Fabricate(:queue_item, user: alice, position: 2)
delete :destroy, id: queue_item1.id
Expand All @@ -94,26 +97,30 @@
it "does not delete the queue item if the queue item is not in the current user's queue" do
alice = Fabricate(:user)
bob = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
queue_item = Fabricate(:queue_item, user: bob)
delete :destroy, id: queue_item.id
expect(QueueItem.count).to eq(1)
end
it "redirects to the sign in page for unauthenticated users" do
delete :destroy, id: 3
expect(response).to redirect_to sign_in_path

it_behaves_like "requires sign in" do
let(:action) { delete :destroy, id: 3 }
end
end

describe "POST update_queue" do
it_behaves_like "requires sign in" do
let(:action) do
post :update_queue, queue_items: [{id: 2, position: 3}, {id: 5, position: 2}]
end
end

context "with valid inputs" do
let(:alice) { Fabricate(:user) }
let(:video) { Fabricate(:video) }
let(:queue_item1) { Fabricate(:queue_item, user: alice, position: 1, video: video) }
let(:queue_item2) { Fabricate(:queue_item, user: alice, position: 2, video: video) }
before do
session[:user_id] = alice.id
end
before { set_current_user(alice) }
it "redirects to the my queue page" do
post :update_queue, queue_items: [{id: queue_item1.id, position: 2}, {id: queue_item2.id, position: 1}]
expect(response).to redirect_to my_queue_path
Expand All @@ -135,7 +142,7 @@
let(:queue_item1) { Fabricate(:queue_item, user: alice, position: 1, video: video) }
let(:queue_item2) { Fabricate(:queue_item, user: alice, position: 2, video: video) }
before do
session[:user_id] = alice.id
set_current_user(alice)
end

it "redirects to the my queue page" do
Expand All @@ -151,16 +158,11 @@
expect(queue_item1.reload.position).to eq(1)
end
end
context "with unauthenticated users" do
it "redirects to the sign in path" do
post :update_queue, queue_items: [{id: 2, position: 3}, {id: 5, position: 2}]
expect(response).to redirect_to sign_in_path
end
end

context "with queue items that do not belong to the current user" do
it "does not change the queue items" do
alice = Fabricate(:user)
session[:user_id] = alice.id
set_current_user(alice)
bob = Fabricate(:user)
video = Fabricate(:video)
queue_item1 = Fabricate(:queue_item, user: bob, position: 1, video: video)
Expand Down
2 changes: 1 addition & 1 deletion spec/fabricators/category_fabricator.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
Fabricator(:category) do
name { Faker::Lorem.words(1) }
name { Faker::Lorem.word }
end
61 changes: 61 additions & 0 deletions spec/features/user_interacts_with_queue_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
require 'spec_helper'

feature "User interacts with the queue" do
scenario "user adds and reorders videos in the queue" do
comedies = Fabricate(:category)
monk = Fabricate(:video, title: "Monk", category: comedies)
south_park = Fabricate(:video, title: "South Park", category: comedies)
futurama = Fabricate(:video, title: "Futurama", category: comedies)
sign_in

add_video_to_queue(monk)
expect_video_to_be_in_queue(monk)

visit video_path(monk)
expect_link_not_to_be_seen("+ My Queue")


add_video_to_queue(south_park)
add_video_to_queue(futurama)


set_video_position(monk, 3)
set_video_position(south_park, 1)
set_video_position(futurama, 2)

update_queue

expect_video_position(south_park, 1)
expect_video_position(futurama, 2)
expect_video_position(monk, 3)

end

def update_queue
click_button "Update Instant Queue"
end

def expect_video_to_be_in_queue(video)
page.should have_content(video.title)
end

def expect_link_not_to_be_seen(link_text)
page.should_not have_content(link_text)
end

def add_video_to_queue(video)
visit home_path
find("a[href='/videos/#{video.id}']").click
click_link "+ My Queue"
end

def set_video_position(video, position)
within(:xpath, "//tr[contains(.,'#{video.title}')]") do
fill_in "queue_items[][position]", with: position
end
end

def expect_video_position(video, position)
expect(find(:xpath, "//tr[contains(.,'#{video.title}')]//input[@type='text']").value).to eq(position.to_s)
end
end
9 changes: 9 additions & 0 deletions spec/features/user_sign_in_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
require 'spec_helper'

feature "user signs in" do
scenario "with valid user email and password" do
alice = Fabricate(:user)
sign_in(alice)
page.should have_content alice.full_name
end
end
14 changes: 14 additions & 0 deletions spec/models/user_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,18 @@
it { should validate_presence_of(:full_name) }
it { should validate_uniqueness_of(:email) }
it { should have_many(:queue_items).order(:position)}

describe "#queued_video?" do
it "returns true when the user queued the video" do
user = Fabricate(:user)
video = Fabricate(:video)
Fabricate(:queue_item, user: user, video: video)
user.queued_video?(video).should be true
end
it "returns false when the user has not queued the video" do
user = Fabricate(:user)
video = Fabricate(:video)
user.queued_video?(video).should be false
end
end
end
1 change: 1 addition & 0 deletions spec/spec_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
require 'capybara/rails'

# Requires supporting ruby files with custom matchers and macros, etc, in
# spec/support/ and its subdirectories. Files matching `spec/**/*_spec.rb` are
Expand Down
Loading

0 comments on commit d0f3e1e

Please sign in to comment.