diff --git a/app/controllers/carts_controller.rb b/app/controllers/carts_controller.rb index f535814f..16faee71 100644 --- a/app/controllers/carts_controller.rb +++ b/app/controllers/carts_controller.rb @@ -1,11 +1,18 @@ class CartsController < ApplicationController before_action :require_customer + + def update + @cart.update_quantity(params[:item_id], params[:quantity].to_i) + redirect_to cart_path + end + + def destroy session[:cart] = {} redirect_to cart_path end - + def show @items = {} @cart.contents.each do |item_id, quantity| diff --git a/app/models/cart.rb b/app/models/cart.rb index db793dd8..8595f5e4 100644 --- a/app/models/cart.rb +++ b/app/models/cart.rb @@ -16,4 +16,13 @@ def add_item(item_id) def total_count @contents.values.sum end + + def update_quantity(item_id, quantity) + if quantity == 0 + @contents.delete(item_id) + else + @contents[item_id] = quantity + end + end + end diff --git a/app/views/carts/_cart_item.html.erb b/app/views/carts/_cart_item.html.erb index 949d124c..7ee96d49 100644 --- a/app/views/carts/_cart_item.html.erb +++ b/app/views/carts/_cart_item.html.erb @@ -1,7 +1,16 @@
> -
<%=item.name%>
+
Item Name: <%=item.name%>
<%=item.user.name%>
<%=item.current_price%>
-
<%=quantity%>
-
<%=quantity*item.current_price%>
+ height=20px width=20px/> +
+ <%= form_tag cart_path(item_id: item.id), method: :patch do %> + <%= select_tag "quantity", options_for_select((0..item.quantity).to_a, selected: quantity) %> + + <%= submit_tag "Update Quantity"%> + <%end%> + <%= button_to "Remove Item", cart_path(item_id: item.id, quantity:0), method: :patch %> +
+
<%=(quantity*item.current_price).round(2)%>
+
diff --git a/app/views/carts/show.html.erb b/app/views/carts/show.html.erb index fa8d27c0..d26ef5b5 100644 --- a/app/views/carts/show.html.erb +++ b/app/views/carts/show.html.erb @@ -6,4 +6,14 @@ Your cart is empty. <%end%>
<%=@total%>
<%= button_to "Empty Cart", cart_path, method: :delete%> + +
+ <% if current_user %> + <%= button_to "Checkout" %> + <% else %> + You must register or log in to checkout + <%= link_to "Log In", login_path %> <%= link_to "Register", register_path %> + <%end%> +
+ <%end%> diff --git a/config/routes.rb b/config/routes.rb index 24e440f1..2faaaeed 100644 --- a/config/routes.rb +++ b/config/routes.rb @@ -25,6 +25,7 @@ get '/profile', to: "users#show" get '/cart', to: 'carts#show' delete '/cart', to: 'carts#destroy' + patch '/cart', to: 'carts#update' resources :carts, only: [:create] get '/merchants', to: "merchants#index" diff --git a/spec/features/cart/show_cart_spec.rb b/spec/features/cart/show_cart_spec.rb index f4aa3555..1e22af42 100644 --- a/spec/features/cart/show_cart_spec.rb +++ b/spec/features/cart/show_cart_spec.rb @@ -57,6 +57,86 @@ expect(page).to have_selector('div', id:"total", text:total.round(2)) end + it 'can update quantities of items in the cart' do + visit item_path(@item_1) + click_button "Add to Cart" + visit cart_path + + select 3, from: "quantity" + click_button "Update Quantity" + + expect(current_path).to eq(cart_path) + expect(page).to have_field('quantity', with:3 ) + end + + it 'upon updating a quantity to 0, that item is removed from the cart' do + visit item_path(@item_1) + click_button "Add to Cart" + visit cart_path + select 0, from: "quantity" + click_button "Update Quantity" + + expect(current_path).to eq(cart_path) + expect(page).to have_content(@empty_cart_message) + end + + it 'upon clicking Remove Item, that item is removed from the cart' do + visit item_path(@item_1) + click_button "Add to Cart" + visit cart_path + click_button "Remove Item" + + expect(current_path).to eq(cart_path) + expect(page).to have_content(@empty_cart_message) + end + + it 'clicking remove item does not remove the other items' do + visit item_path(@item_1) + click_button "Add to Cart" + visit item_path(@item_2) + click_button "Add to Cart" + visit cart_path + + within "#cart-item-#{@item_1.id}" do + click_button "Remove Item" + end + + expect(page).to have_content(@item_2.name) + expect(page).not_to have_content(@item_1.name) + end + + it 'tests for sad path of quantity being entered maliciously greater than qty available or less than 0' + + it 'says you must register / log in if you are browsing as a user' do + visit item_path(@item_1) + click_button "Add to Cart" + visit cart_path + + within '#checkout' do + expect(page).to have_content("You must register or log in to checkout") + expect(page).to have_link("Log In", href: login_path) + expect(page).to have_link("Register", href: register_path) + + expect(page).not_to have_button("Checkout") + end + end + + it 'gives the option to checkout as a logged in user' do + user = create(:user) + allow_any_instance_of(ApplicationController).to receive(:current_user).and_return(user) + visit item_path(@item_1) + click_button "Add to Cart" + visit cart_path + save_and_open_page + within '#checkout' do + expect(page).not_to have_content("You must register or log in to checkout") + expect(page).not_to have_link("Log In", href: login_path) + expect(page).not_to have_link("Register", href: register_path) + + expect(page).to have_button("Checkout") + end + end + end RSpec.describe 'partial for items in cart' ,type: :view do @@ -70,6 +150,14 @@ expect(rendered).to have_selector('div', id:"item-merchant", text:item.user.name) expect(rendered).to have_selector('div', id:"item-price", text:item.current_price) expect(rendered).to have_selector('div', id:"item-quantity", text:quantity) + + expect(rendered).to have_xpath("//img[@src='#{item.image_url}']") + expect(rendered).to have_field('quantity', with:quantity) + expect(rendered).to have_button("Update Quantity") + expect(rendered).to have_button("Remove Item") + + + expect(rendered).to have_selector('div', id:"subtotal", text:"#{item.current_price * quantity}") end end diff --git a/spec/models/cart_spec.rb b/spec/models/cart_spec.rb index a07436ce..af87d773 100644 --- a/spec/models/cart_spec.rb +++ b/spec/models/cart_spec.rb @@ -17,4 +17,15 @@ expect(cart.contents).to eq(expected) end + it "#update_quantity(item_id, quantity), updates the correct item quantity, deleting item if appropriate" do + cart = Cart.new({"5"=> 3, "3" => 4}) + cart.update_quantity("5", 6) + expected = {"5"=>6, "3"=>4} + expect(cart.contents).to eq(expected) + + cart.update_quantity("3",0) + expected = {"5"=>6} + expect(cart.contents).to eq(expected) + end + end