diff --git a/app/components/budgets/investments/votes_component.html.erb b/app/components/budgets/investments/votes_component.html.erb index 3c9937de1..0aedbe37e 100644 --- a/app/components/budgets/investments/votes_component.html.erb +++ b/app/components/budgets/investments/votes_component.html.erb @@ -5,19 +5,28 @@
<%= t("budgets.supports_info.next") %>
-<%= sanitize(t("budgets.supports_info.remember")) %>
<%= t("budgets.supports_info.different") %>
diff --git a/app/controllers/budgets/investments/votes_controller.rb b/app/controllers/budgets/investments/votes_controller.rb index 26921d437..5b30a17c7 100644 --- a/app/controllers/budgets/investments/votes_controller.rb +++ b/app/controllers/budgets/investments/votes_controller.rb @@ -3,6 +3,7 @@ module Budgets class VotesController < ApplicationController load_and_authorize_resource :budget load_and_authorize_resource :investment, through: :budget, class: "Budget::Investment" + load_and_authorize_resource through: :investment, through_association: :votes_for, only: :destroy def create @investment.register_selection(current_user) @@ -13,7 +14,15 @@ module Budgets notice: t("flash.actions.create.support") end - format.js + format.js { render :show } + end + end + + def destroy + @investment.unliked_by(current_user) + + respond_to do |format| + format.js { render :show } end end end diff --git a/app/controllers/management/budgets/investments/votes_controller.rb b/app/controllers/management/budgets/investments/votes_controller.rb index f96ec1ed6..1ab8f8056 100644 --- a/app/controllers/management/budgets/investments/votes_controller.rb +++ b/app/controllers/management/budgets/investments/votes_controller.rb @@ -1,6 +1,7 @@ class Management::Budgets::Investments::VotesController < Management::BaseController load_resource :budget, find_by: :slug_or_id load_resource :investment, through: :budget, class: "Budget::Investment" + load_and_authorize_resource through: :investment, through_association: :votes_for, only: :destroy def create @investment.register_selection(managed_user) @@ -11,7 +12,15 @@ class Management::Budgets::Investments::VotesController < Management::BaseContro notice: t("flash.actions.create.support") end - format.js + format.js { render :show } + end + end + + def destroy + @investment.unliked_by(managed_user) + + respond_to do |format| + format.js { render :show } end end end diff --git a/app/models/abilities/common.rb b/app/models/abilities/common.rb index 24f86638f..8e341a39d 100644 --- a/app/models/abilities/common.rb +++ b/app/models/abilities/common.rb @@ -99,7 +99,7 @@ module Abilities can :update, Budget::Investment, budget: { phase: "accepting" }, author_id: user.id can :suggest, Budget::Investment, budget: { phase: "accepting" } can :destroy, Budget::Investment, budget: { phase: ["accepting", "reviewing"] }, author_id: user.id - can :create, ActsAsVotable::Vote, + can [:create, :destroy], ActsAsVotable::Vote, voter_id: user.id, votable_type: "Budget::Investment", votable: { budget: { phase: "selecting" }} diff --git a/app/views/budgets/investments/votes/create.js.erb b/app/views/budgets/investments/votes/show.js.erb similarity index 100% rename from app/views/budgets/investments/votes/create.js.erb rename to app/views/budgets/investments/votes/show.js.erb diff --git a/app/views/management/budgets/investments/votes/create.js.erb b/app/views/management/budgets/investments/votes/show.js.erb similarity index 100% rename from app/views/management/budgets/investments/votes/create.js.erb rename to app/views/management/budgets/investments/votes/show.js.erb diff --git a/config/locales/en/budgets.yml b/config/locales/en/budgets.yml index 4cafad9e4..e2c8e65fd 100644 --- a/config/locales/en/budgets.yml +++ b/config/locales/en/budgets.yml @@ -172,6 +172,8 @@ en: confirm_group: one: "You can only support investments in %{count} district. If you continue you cannot change the election of your district. Are you sure?" other: "You can only support investments in %{count} districts. If you continue you cannot change the election of your district. Are you sure?" + remove_support: "Remove your support" + remove_support_label: "Remove your support to %{investment}" support: "Support" support_label: "Support %{investment}" investments_list: @@ -186,7 +188,6 @@ en: supports_info: different: "You may support on as many different projects as you would like." next: "Support the projects you would like to see move on to the next phase." - remember: "Remember! You can only cast your support once for each project and each support is irreversible." scrolling: "Keep scrolling to see all ideas" share: "You can share the projects you have supported on through social media and attract more attention and support to them!" supported: diff --git a/config/locales/es/budgets.yml b/config/locales/es/budgets.yml index b03967178..3f232f6f2 100644 --- a/config/locales/es/budgets.yml +++ b/config/locales/es/budgets.yml @@ -172,6 +172,8 @@ es: confirm_group: one: "Sólo puedes apoyar proyectos en %{count} distrito. Si sigues adelante no podrás cambiar la elección de este distrito. ¿Estás seguro/a?" other: "Sólo puedes apoyar proyectos en %{count} distritos. Si sigues adelante no podrás cambiar la elección de este distrito. ¿Estás seguro/a?" + remove_support: "Eliminar apoyo" + remove_support_label: "Eliminar tu apoyo a %{investment}" support: "Apoyar" support_label: "Apoyar %{investment}" investments_list: @@ -186,7 +188,6 @@ es: supports_info: different: "Puedes apoyar tantos proyectos diferentes como quieras." next: "Apoya proyectos que te gustaría ver en la siguiente fase." - remember: "¡Recuerda! Solo puedes emitir tu apoyo una vez por cada proyecto y cada apoyo es irreversible." scrolling: "Sigue desplazándote para ver todas las ideas" share: "Puedes compartir los proyectos que has apoyado en las redes sociales y ¡atraer más atención y apoyos para ellos!" supported: diff --git a/config/routes/budget.rb b/config/routes/budget.rb index 82794855f..416bdf88e 100644 --- a/config/routes/budget.rb +++ b/config/routes/budget.rb @@ -8,7 +8,7 @@ resources :budgets, only: [:show, :index] do collection { get :suggest } - resources :votes, controller: "budgets/investments/votes", only: :create + resources :votes, controller: "budgets/investments/votes", only: [:create, :destroy] end resource :ballot, only: :show, controller: "budgets/ballots" do diff --git a/config/routes/management.rb b/config/routes/management.rb index 77afca888..9de4ef731 100644 --- a/config/routes/management.rb +++ b/config/routes/management.rb @@ -41,7 +41,7 @@ namespace :management do resources :investments, only: [:index, :new, :create, :show, :destroy], controller: "budgets/investments" do get :print, on: :collection - resources :votes, controller: "budgets/investments/votes", only: :create + resources :votes, controller: "budgets/investments/votes", only: [:create, :destroy] end end end diff --git a/spec/components/budgets/investments/votes_component_spec.rb b/spec/components/budgets/investments/votes_component_spec.rb index c1f44f50e..a3b3fdae0 100644 --- a/spec/components/budgets/investments/votes_component_spec.rb +++ b/spec/components/budgets/investments/votes_component_spec.rb @@ -23,8 +23,21 @@ describe Budgets::Investments::VotesComponent, type: :component do render_inline component + expect(page).to have_button count: 1, disabled: :all expect(page).to have_button "Support", disabled: true end + + it "shows the button to remove support when users have supported the investment" do + user = create(:user) + user.up_votes(investment) + allow(controller).to receive(:current_user).and_return(user) + + render_inline component + + expect(page).to have_button count: 1, disabled: :all + expect(page).to have_button "Remove your support" + expect(page).to have_button "Remove your support to Renovate sidewalks in Main Street" + end end end end diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index fc1bd62eb..8cce034f2 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -251,6 +251,9 @@ describe Abilities::Common do it { should be_able_to(:create, user.votes.build(votable: investment_in_selecting_budget)) } it { should_not be_able_to(:create, user.votes.build(votable: investment_in_accepting_budget)) } it { should_not be_able_to(:create, user.votes.build(votable: investment_in_balloting_budget)) } + it { should be_able_to(:destroy, create(:vote, voter: user, votable: investment_in_selecting_budget)) } + it { should_not be_able_to(:destroy, create(:vote, voter: user, votable: investment_in_accepting_budget)) } + it { should_not be_able_to(:destroy, create(:vote, voter: user, votable: investment_in_balloting_budget)) } it { should_not be_able_to(:destroy, investment_in_accepting_budget) } it { should_not be_able_to(:destroy, investment_in_reviewing_budget) } diff --git a/spec/system/budgets/budgets_spec.rb b/spec/system/budgets/budgets_spec.rb index 9aa52b13e..9214ff311 100644 --- a/spec/system/budgets/budgets_spec.rb +++ b/spec/system/budgets/budgets_spec.rb @@ -432,6 +432,42 @@ describe "Budgets" do expect(page).to have_content "It's time to support projects!" expect(page).to have_content "So far you've supported 3 projects." end + + scenario "Show supports only if the support has not been removed" do + voter = create(:user, :level_two) + budget = create(:budget, phase: "selecting") + investment = create(:budget_investment, :selected, budget: budget) + + login_as(voter) + + visit budget_path(budget) + + expect(page).to have_content "So far you've supported 0 projects." + + visit budget_investment_path(budget, investment) + + within("#budget_investment_#{investment.id}_votes") do + click_button "Support" + + expect(page).to have_content "You have already supported this investment project." + end + + visit budget_path(budget) + + expect(page).to have_content "So far you've supported 1 project." + + visit budget_investment_path(budget, investment) + + within("#budget_investment_#{investment.id}_votes") do + click_button "Remove your support" + + expect(page).to have_content "No supports" + end + + visit budget_path(budget) + + expect(page).to have_content "So far you've supported 0 projects." + end end context "In Drafting phase" do diff --git a/spec/system/budgets/investments_spec.rb b/spec/system/budgets/investments_spec.rb index 2b1d3ae48..ea9075c93 100644 --- a/spec/system/budgets/investments_spec.rb +++ b/spec/system/budgets/investments_spec.rb @@ -1177,6 +1177,48 @@ describe "Budget Investments" do expect(page).to have_content "SUPPORTS" end end + + scenario "Remove a support from show view" do + investment = create(:budget_investment, budget: budget) + + login_as(author) + visit budget_investment_path(budget, investment) + + within("aside") do + expect(page).to have_content "No supports" + + click_button "Support" + + expect(page).to have_content "1 support" + expect(page).to have_content "You have already supported this investment project." + + click_button "Remove your support" + + expect(page).to have_content "No supports" + expect(page).to have_button "Support" + end + end + + scenario "Remove a support from index view" do + investment = create(:budget_investment, budget: budget) + + login_as(author) + visit budget_investments_path(budget) + + within("#budget_investment_#{investment.id}") do + expect(page).to have_content "No supports" + + click_button "Support" + + expect(page).to have_content "1 support" + expect(page).to have_content "You have already supported this investment project." + + click_button "Remove your support" + + expect(page).to have_content "No supports" + expect(page).to have_button "Support" + end + end end context "Evaluating Phase" do diff --git a/spec/system/management/budget_investments_spec.rb b/spec/system/management/budget_investments_spec.rb index 382ff4a63..b814066e8 100644 --- a/spec/system/management/budget_investments_spec.rb +++ b/spec/system/management/budget_investments_spec.rb @@ -333,6 +333,56 @@ describe "Budget Investments" do expect(page).to have_content "CONSUL\nMANAGEMENT" end + scenario "Remove support on behalf of someone else in index view" do + create(:budget_investment, heading: heading) + + login_managed_user(user) + login_as_manager(manager) + + visit management_budget_investments_path(budget) + click_button "Support" + + expect(page).to have_content "1 support" + expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).not_to have_button "Support" + + click_button "Remove your support" + + expect(page).to have_content "No supports" + expect(page).to have_button "Support" + expect(page).not_to have_button "Remove your support" + end + + scenario "Remove support on behalf of someone else in show view" do + create(:budget_investment, heading: heading, title: "Don't support me!") + + login_managed_user(user) + login_as_manager(manager) + + visit management_budget_investments_path(budget) + click_link "Don't support me!" + + expect(page).to have_css "h1", exact_text: "Don't support me!" + + click_button "Support" + + expect(page).to have_content "1 support" + expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).not_to have_button "Support" + + click_button "Remove your support" + + expect(page).to have_content "No supports" + expect(page).to have_button "Support" + expect(page).not_to have_button "Remove your support" + + refresh + + expect(page).to have_content "No supports" + expect(page).to have_button "Support" + expect(page).not_to have_button "Remove your support" + end + scenario "Should not allow unverified users to vote proposals" do login_managed_user(create(:user)) create(:budget_investment, budget: budget)