From 79ea0adf89ec1475ceff13e585690b83c2ec5b80 Mon Sep 17 00:00:00 2001 From: James Coleman Date: Mon, 7 Jul 2014 11:31:30 -0400 Subject: [PATCH 1/2] Completed week 2 assignments 15 and 16 --- app/controllers/queue_items_controller.rb | 27 ++++++++ app/models/category.rb | 1 + app/models/queue_item.rb | 17 +++++ app/models/user.rb | 7 +- app/views/queue_items/index.html.haml | 30 ++++++++ app/views/videos/show.html.haml | 3 +- config/routes.rb | 4 ++ .../20140707101635_create_queue_items.rb | 9 +++ db/schema.rb | 10 ++- spec/controllers/queue_items_controller.rb | 0 .../queue_items_controller_spec.rb | 69 +++++++++++++++++++ spec/fabricators/category_fabricator.rb | 3 + spec/fabricators/queue_item_fabricator.rb | 3 + spec/models/category_spec.rb | 1 + spec/models/queue_item_spec.rb | 48 +++++++++++++ 15 files changed, 225 insertions(+), 7 deletions(-) create mode 100644 app/controllers/queue_items_controller.rb create mode 100644 app/models/queue_item.rb create mode 100644 app/views/queue_items/index.html.haml create mode 100644 db/migrate/20140707101635_create_queue_items.rb create mode 100644 spec/controllers/queue_items_controller.rb create mode 100644 spec/controllers/queue_items_controller_spec.rb create mode 100644 spec/fabricators/category_fabricator.rb create mode 100644 spec/fabricators/queue_item_fabricator.rb create mode 100644 spec/models/queue_item_spec.rb diff --git a/app/controllers/queue_items_controller.rb b/app/controllers/queue_items_controller.rb new file mode 100644 index 000000000..dd4b0ddd4 --- /dev/null +++ b/app/controllers/queue_items_controller.rb @@ -0,0 +1,27 @@ +class QueueItemsController < ApplicationController + before_filter :require_user + def index + @queue_items = current_user.queue_items + end + + def create + video = Video.find(params[:video_id]) + queue_video(video) + redirect_to my_queue_path + end + + private + + def queue_video(video) + QueueItem.create(video: video, user: current_user, position: new_queue_item_position) unless current_user_queued_video?(video) + end + + def new_queue_item_position + current_user.queue_items.count + 1 + end + + def current_user_queued_video?(video) + current_user.queue_items.map(&:video).include?(video) + end + +end \ No newline at end of file diff --git a/app/models/category.rb b/app/models/category.rb index 5feabc836..98c7f7903 100644 --- a/app/models/category.rb +++ b/app/models/category.rb @@ -1,5 +1,6 @@ class Category < ActiveRecord::Base has_many :videos, -> { order "created_at DESC" } + validates_presence_of :name def recent_videos videos.first(6) diff --git a/app/models/queue_item.rb b/app/models/queue_item.rb new file mode 100644 index 000000000..3d3d589e9 --- /dev/null +++ b/app/models/queue_item.rb @@ -0,0 +1,17 @@ +class QueueItem < ActiveRecord::Base + belongs_to :user + belongs_to :video + + delegate :category, to: :video + delegate :title, to: :video, prefix: :video + + def rating + review = Review.where(user_id: user.id, video_id: video.id).first + review.rating if review + end + + def category_name + category.name + end + +end \ No newline at end of file diff --git a/app/models/user.rb b/app/models/user.rb index 875731c28..9dbc46036 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -3,10 +3,7 @@ class User < ActiveRecord::Base validates_uniqueness_of :email has_many :reviews - # validates :email, presence: true, uniqueness: true - # validates :password, presence: true, :length => ( :minimum => 4), on: :create - # validates :password, allow_blank: true, :length => ( :minimum => 4), on: :update - # validates :full_name, presence: true - has_secure_password validations: false + + has_many :queue_items end \ No newline at end of file diff --git a/app/views/queue_items/index.html.haml b/app/views/queue_items/index.html.haml new file mode 100644 index 000000000..85ead2a78 --- /dev/null +++ b/app/views/queue_items/index.html.haml @@ -0,0 +1,30 @@ +%section.my_queue.container + .row + .col-sm-10.col-sm-offset-1 + %article + %header + %h2 My Queue + %table.table + %thead + %tr + %th(width="10%") List Order + %th(width="30%") Video Title + %th(width="10%") Play + %th(width="20%") Rating + %th(width="15%") Genre + %th(width="15%") Remove + %tbody + - @queue_items.each do |queue_item| + %tr + %td= queue_item.position + %td + = link_to queue_item.video_title, queue_item.video + %td + = button_to "Play", nil, class: "btn btn-default" + %td= queue_item.rating + %td + = link_to queue_item.category_name, queue_item.category + %td + = link_to "", method: :post do + %i.glyphicon.glyphicon-remove + = button_to "Update Instant Queue", nil, class: "btn btn-default" \ No newline at end of file diff --git a/app/views/videos/show.html.haml b/app/views/videos/show.html.haml index 52740c0b2..f3f8e460f 100644 --- a/app/views/videos/show.html.haml +++ b/app/views/videos/show.html.haml @@ -8,7 +8,8 @@ %h3= @video.title %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' %section.reviews.container .row .col-sm-10.col-sm-offset-1 diff --git a/config/routes.rb b/config/routes.rb index f9603b909..18fe80aa8 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,6 +8,10 @@ resources :reviews, only: [:create] end resources :categories + resources :queue_items, only: [:create] + + get 'my_queue', to: 'queue_items#index' + get 'ui(/:action)', controller: 'ui' get 'register', to: "users#new" get 'sign_in', to: 'sessions#new' diff --git a/db/migrate/20140707101635_create_queue_items.rb b/db/migrate/20140707101635_create_queue_items.rb new file mode 100644 index 000000000..4d453d7fb --- /dev/null +++ b/db/migrate/20140707101635_create_queue_items.rb @@ -0,0 +1,9 @@ +class CreateQueueItems < ActiveRecord::Migration + def change + create_table :queue_items do |t| + t.integer :video_id, :user_id + t.integer :position + t.timestamps + end + end +end diff --git a/db/schema.rb b/db/schema.rb index c6b70dc48..48ca69429 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20140705143740) do +ActiveRecord::Schema.define(version: 20140707101635) do create_table "categories", force: true do |t| t.string "name" @@ -19,6 +19,14 @@ t.datetime "updated_at" end + create_table "queue_items", force: true do |t| + t.integer "video_id" + t.integer "user_id" + t.integer "position" + t.datetime "created_at" + t.datetime "updated_at" + end + create_table "reviews", force: true do |t| t.integer "user_id" t.integer "video_id" diff --git a/spec/controllers/queue_items_controller.rb b/spec/controllers/queue_items_controller.rb new file mode 100644 index 000000000..e69de29bb diff --git a/spec/controllers/queue_items_controller_spec.rb b/spec/controllers/queue_items_controller_spec.rb new file mode 100644 index 000000000..45527a77c --- /dev/null +++ b/spec/controllers/queue_items_controller_spec.rb @@ -0,0 +1,69 @@ +require 'spec_helper' + +describe QueueItemsController do + 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 + 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 + end + end + + describe "POST create" do + it "redirects to the my queue page" do + session[:user_id] = Fabricate(:user).id + 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 + 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 + 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 + 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 + monk = Fabricate(:video) + Fabricate(:queue_item, video: monk, user: alice) + south_park = Fabricate(:video) + post :create, video_id: south_park.id + south_park_queue_item = QueueItem.where(video_id: south_park.id, user_id: alice.id).first + expect(south_park_queue_item.position).to eq(2) + 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 + monk = Fabricate(:video) + Fabricate(:queue_item, video: monk, user: alice) + post :create, video_id: monk.id + expect(alice.queue_items.count).to eq(1) + end + it "redirects to the sign in page for unauthenticated users" do + post :create, video_id: 3 + expect(response).to redirect_to sign_in_path + end + end +end \ No newline at end of file diff --git a/spec/fabricators/category_fabricator.rb b/spec/fabricators/category_fabricator.rb new file mode 100644 index 000000000..fb3ef3696 --- /dev/null +++ b/spec/fabricators/category_fabricator.rb @@ -0,0 +1,3 @@ +Fabricator(:category) do + name { Faker::Lorem.words(1) } +end \ No newline at end of file diff --git a/spec/fabricators/queue_item_fabricator.rb b/spec/fabricators/queue_item_fabricator.rb new file mode 100644 index 000000000..b0dc1adc1 --- /dev/null +++ b/spec/fabricators/queue_item_fabricator.rb @@ -0,0 +1,3 @@ +Fabricator(:queue_item) do + +end \ No newline at end of file diff --git a/spec/models/category_spec.rb b/spec/models/category_spec.rb index c7d92007e..a0ca00b12 100644 --- a/spec/models/category_spec.rb +++ b/spec/models/category_spec.rb @@ -2,6 +2,7 @@ describe Category do it { should have_many(:videos) } + it { should validate_presence_of(:name) } describe "#recent_videos" do it "returns the videos in reverse chronological order by created_at" do diff --git a/spec/models/queue_item_spec.rb b/spec/models/queue_item_spec.rb new file mode 100644 index 000000000..0987c80ec --- /dev/null +++ b/spec/models/queue_item_spec.rb @@ -0,0 +1,48 @@ +require 'spec_helper' + +describe QueueItem do + it { should belong_to(:user) } + it { should belong_to(:video) } + + describe "#video_title" do + it "returns the title of the associated video" do + video = Fabricate(:video, title: 'Monk') + queue_item = Fabricate(:queue_item, video: video) + expect(queue_item.video_title).to eq('Monk') + end + + describe "#rating" do + it "returns the rating from the review when the review is present" do + video = Fabricate(:video) + user = Fabricate(:user) + review = Fabricate(:review, user: user, video: video, rating: 4) + queue_item = Fabricate(:queue_item, user: user, video: video) + expect(queue_item.rating).to eq(4) + end + it "returns nil when the review is not present" do + video = Fabricate(:video) + user = Fabricate(:user) + queue_item = Fabricate(:queue_item, user: user, video: video) + expect(queue_item.rating).to eq(nil) + end + end + + describe "#category_name" do + it "returns the category name of the video" do + category = Fabricate(:category, name: "comedies") + video = Fabricate(:video, category: category) + queue_item = Fabricate(:queue_item, video: video) + expect(queue_item.category_name).to eq("comedies") + end + end + + describe "#category" do + it "returns the category of the video" do + category = Fabricate(:category, name: "comedies") + video = Fabricate(:video, category: category) + queue_item = Fabricate(:queue_item, video: video) + expect(queue_item.category).to eq(category) + end + end + end +end \ No newline at end of file From 394f9c72fab9a5c9f52727a46f613f0f17968c49 Mon Sep 17 00:00:00 2001 From: James Coleman Date: Mon, 7 Jul 2014 13:07:37 -0400 Subject: [PATCH 2/2] Finished Week 2 --- app/controllers/queue_items_controller.rb | 6 ++++ app/views/queue_items/index.html.haml | 2 +- config/routes.rb | 2 +- .../queue_items_controller_spec.rb | 28 +++++++++++++++++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/app/controllers/queue_items_controller.rb b/app/controllers/queue_items_controller.rb index dd4b0ddd4..e406b1204 100644 --- a/app/controllers/queue_items_controller.rb +++ b/app/controllers/queue_items_controller.rb @@ -10,6 +10,12 @@ def create redirect_to my_queue_path end + def destroy + queue_item = QueueItem.find(params[:id]) + queue_item.destroy if current_user.queue_items.include?(queue_item) + redirect_to my_queue_path + end + private def queue_video(video) diff --git a/app/views/queue_items/index.html.haml b/app/views/queue_items/index.html.haml index 85ead2a78..4a5d7262e 100644 --- a/app/views/queue_items/index.html.haml +++ b/app/views/queue_items/index.html.haml @@ -25,6 +25,6 @@ %td = link_to queue_item.category_name, queue_item.category %td - = link_to "", method: :post do + = link_to queue_item, method: :delete do %i.glyphicon.glyphicon-remove = button_to "Update Instant Queue", nil, class: "btn btn-default" \ No newline at end of file diff --git a/config/routes.rb b/config/routes.rb index 18fe80aa8..8efa5b1d1 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -8,7 +8,7 @@ resources :reviews, only: [:create] end resources :categories - resources :queue_items, only: [:create] + resources :queue_items, only: [:create, :destroy] get 'my_queue', to: 'queue_items#index' diff --git a/spec/controllers/queue_items_controller_spec.rb b/spec/controllers/queue_items_controller_spec.rb index 45527a77c..645c2367a 100644 --- a/spec/controllers/queue_items_controller_spec.rb +++ b/spec/controllers/queue_items_controller_spec.rb @@ -66,4 +66,32 @@ expect(response).to redirect_to sign_in_path end end + + describe "DELETE destroy" do + it "redirects to the my queue page" do + session[:user_id] = Fabricate(:user).id + 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 + queue_item = Fabricate(:queue_item, user: alice) + delete :destroy, id: queue_item.id + expect(QueueItem.count).to eq(0) + end + 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 + 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 + end + end end \ No newline at end of file