From e47cbe2a10618c772a2d40049d1e9251ea8df146 Mon Sep 17 00:00:00 2001 From: Marko Lovic Date: Mon, 9 Jul 2018 17:06:12 +0200 Subject: [PATCH 1/7] Extract "supported headings" logic to User method In preparation to use this method from views where it doesn't make sense for it to be associated with a specific investment. --- app/models/budget/investment.rb | 4 ++-- app/models/user.rb | 5 +++++ spec/models/user_spec.rb | 29 +++++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 1b528a9cb..fc157a999 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -257,7 +257,7 @@ class Budget end def can_vote_in_another_heading?(user) - headings_voted_by_user(user).count < group.max_votable_headings + user.headings_voted_within_group(group).count < group.max_votable_headings end def headings_voted_by_user(user) @@ -265,7 +265,7 @@ class Budget end def voted_in?(heading, user) - headings_voted_by_user(user).include?(heading.id) + user.headings_voted_within_group(group).where(id: heading.id).exists? end def ballotable_by?(user) diff --git a/app/models/user.rb b/app/models/user.rb index 3a274f056..6aaf634ef 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -127,6 +127,11 @@ class User < ActiveRecord::Base votes.for_budget_investments(Budget::Investment.where(group: group)).exists? end + def headings_voted_within_group(group) + voted_investments = votes.for_budget_investments(Budget::Investment.by_group(group.id)).votables + Budget::Heading.where(id: voted_investments.map(&:heading_id).uniq) + end + def administrator? administrator.present? end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 1d860e121..d32b8fa17 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -2,6 +2,35 @@ require 'rails_helper' describe User do + describe '#headings_voted_within_group' do + it "returns the headings voted by a user" do + user1 = create(:user) + user2 = create(:user) + + budget = create(:budget) + group = create(:budget_group, budget: budget) + + new_york = create(:budget_heading, group: group) + san_franciso = create(:budget_heading, group: group) + another_heading = create(:budget_heading, group: group) + + new_york_investment = create(:budget_investment, heading: new_york) + san_franciso_investment = create(:budget_investment, heading: san_franciso) + another_investment = create(:budget_investment, heading: san_franciso) + + create(:vote, votable: new_york_investment, voter: user1) + create(:vote, votable: san_franciso_investment, voter: user1) + + expect(user1.headings_voted_within_group(group)).to include(new_york) + expect(user1.headings_voted_within_group(group)).to include(san_franciso) + expect(user1.headings_voted_within_group(group)).to_not include(another_heading) + + expect(user2.headings_voted_within_group(group)).to_not include(new_york) + expect(user2.headings_voted_within_group(group)).to_not include(san_franciso) + expect(user2.headings_voted_within_group(group)).to_not include(another_heading) + end + end + describe "#debate_votes" do let(:user) { create(:user) } From 4a2fae5e905e8c28b03e531eabf8090a6a8b0aa0 Mon Sep 17 00:00:00 2001 From: Marko Lovic Date: Mon, 9 Jul 2018 17:33:00 +0200 Subject: [PATCH 2/7] Add headings to "headings limit reached" alert msg --- app/views/budgets/investments/_votes.html.erb | 5 +++-- config/locales/en/general.yml | 4 ++-- config/locales/es/general.yml | 4 ++-- spec/features/budgets/votes_spec.rb | 4 ++-- 4 files changed, 9 insertions(+), 8 deletions(-) diff --git a/app/views/budgets/investments/_votes.html.erb b/app/views/budgets/investments/_votes.html.erb index 491664663..7d1593a05 100644 --- a/app/views/budgets/investments/_votes.html.erb +++ b/app/views/budgets/investments/_votes.html.erb @@ -35,8 +35,9 @@ count: investment.group.max_votable_headings, verify_account: link_to(t("votes.verify_account"), verification_path), signin: link_to(t("votes.signin"), new_user_session_path), - signup: link_to(t("votes.signup"), new_user_registration_path) - ).html_safe %> + signup: link_to(t("votes.signup"), new_user_registration_path), + supported_headings: (current_user && current_user.headings_voted_within_group(investment.group).map(&:name).to_sentence) + ).html_safe %>

diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index 35781e16a..3d2db791e 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -771,8 +771,8 @@ en: unfeasible: Unfeasible investment projects can not be supported not_voting_allowed: Voting phase is closed different_heading_assigned: - one: "You can only support investment projects in %{count} district" - other: "You can only support investment projects in %{count} districts" + one: "You can only support investment projects in %{count} district. You have already supported investments in %{supported_headings}." + other: "You can only support investment projects in %{count} districts. You have already supported investments in %{supported_headings}." welcome: feed: most_active: diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 02b56b8da..0802979b9 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -770,8 +770,8 @@ es: unfeasible: No se pueden votar propuestas inviables. not_voting_allowed: El periodo de votación está cerrado. different_heading_assigned: - one: "Sólo puedes apoyar proyectos de gasto de %{count} distrito" - other: "Sólo puedes apoyar proyectos de gasto de %{count} distritos" + one: "Sólo puedes apoyar proyectos de gasto de %{count} distrito. Ya has apoyado en %{supported_headings}." + other: "Sólo puedes apoyar proyectos de gasto de %{count} distritos. Ya has apoyado en %{supported_headings}." welcome: feed: most_active: diff --git a/spec/features/budgets/votes_spec.rb b/spec/features/budgets/votes_spec.rb index 85f2dfbb0..5ab1550e7 100644 --- a/spec/features/budgets/votes_spec.rb +++ b/spec/features/budgets/votes_spec.rb @@ -142,7 +142,7 @@ feature 'Votes' do within("#budget_investment_#{third_heading_investment.id}") do find('.in-favor a').click - expect(page).to have_content "You can only support investment projects in 2 districts" + expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in #{new_york.name} and #{san_francisco.name}" expect(page).not_to have_content "1 support" expect(page).not_to have_content "You have already supported this investment project. Share it!" @@ -165,7 +165,7 @@ feature 'Votes' do visit budget_investment_path(budget, third_heading_investment) find('.in-favor a').click - expect(page).to have_content "You can only support investment projects in 2 districts" + expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in #{new_york.name} and #{san_francisco.name}" expect(page).not_to have_content "1 support" expect(page).not_to have_content "You have already supported this investment project. Share it!" From 3c9953e9e03e4b9dd1bf98838ee7ff5ccbd2822e Mon Sep 17 00:00:00 2001 From: Marko Lovic Date: Tue, 10 Jul 2018 09:24:37 +0200 Subject: [PATCH 3/7] Make content assertion order-independent --- spec/features/budgets/votes_spec.rb | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/spec/features/budgets/votes_spec.rb b/spec/features/budgets/votes_spec.rb index 5ab1550e7..d91ad1aa7 100644 --- a/spec/features/budgets/votes_spec.rb +++ b/spec/features/budgets/votes_spec.rb @@ -142,7 +142,10 @@ feature 'Votes' do within("#budget_investment_#{third_heading_investment.id}") do find('.in-favor a').click - expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in #{new_york.name} and #{san_francisco.name}" + expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in" + + heading_names = find('.participation-not-allowed').text.match(/You have already supported investments in (.+) and (.+)\./)&.captures + expect(heading_names).to match_array [new_york.name, san_francisco.name] expect(page).not_to have_content "1 support" expect(page).not_to have_content "You have already supported this investment project. Share it!" @@ -165,7 +168,10 @@ feature 'Votes' do visit budget_investment_path(budget, third_heading_investment) find('.in-favor a').click - expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in #{new_york.name} and #{san_francisco.name}" + expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in" + + heading_names = find('.participation-not-allowed').text.match(/You have already supported investments in (.+) and (.+)\./)&.captures + expect(heading_names).to match_array [new_york.name, san_francisco.name] expect(page).not_to have_content "1 support" expect(page).not_to have_content "You have already supported this investment project. Share it!" From 264c4e747b92c0b5869e883ad044793866930bf5 Mon Sep 17 00:00:00 2001 From: Marko Lovic Date: Tue, 10 Jul 2018 09:36:27 +0200 Subject: [PATCH 4/7] Improve User#headings_supported_within_group performance Performs a single DB call instead of 3 --- app/models/user.rb | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 6aaf634ef..37ddebbd0 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -128,8 +128,13 @@ class User < ActiveRecord::Base end def headings_voted_within_group(group) - voted_investments = votes.for_budget_investments(Budget::Investment.by_group(group.id)).votables - Budget::Heading.where(id: voted_investments.map(&:heading_id).uniq) + Budget::Heading.where(id: + votes.where(votable_type: Budget::Investment) + .joins(:budget_investment) + .where(budget_investments: {group_id: group.id}) + .distinct + .select('budget_investments.heading_id') + ) end def administrator? From f4b8099703b9354de1d306a5a27bc52a7c571a32 Mon Sep 17 00:00:00 2001 From: voodoorai2000 Date: Wed, 6 Feb 2019 13:58:14 +0100 Subject: [PATCH 5/7] Simplify sql query --- app/models/user.rb | 12 +++++------- config/initializers/vote_extensions.rb | 2 +- 2 files changed, 6 insertions(+), 8 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 37ddebbd0..4ac60773b 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -128,13 +128,11 @@ class User < ActiveRecord::Base end def headings_voted_within_group(group) - Budget::Heading.where(id: - votes.where(votable_type: Budget::Investment) - .joins(:budget_investment) - .where(budget_investments: {group_id: group.id}) - .distinct - .select('budget_investments.heading_id') - ) + Budget::Heading.where(id: voted_investments.by_group(group).pluck(:heading_id)) + end + + def voted_investments + Budget::Investment.where(id: votes.for_budget_investments.pluck(:votable_id)) end def administrator? diff --git a/config/initializers/vote_extensions.rb b/config/initializers/vote_extensions.rb index 4df338752..87fa34c4e 100644 --- a/config/initializers/vote_extensions.rb +++ b/config/initializers/vote_extensions.rb @@ -28,7 +28,7 @@ ActsAsVotable::Vote.class_eval do where(votable_type: 'SpendingProposal', votable_id: spending_proposals) end - def self.for_budget_investments(budget_investments) + def self.for_budget_investments(budget_investments=Budget::Investment.all) where(votable_type: 'Budget::Investment', votable_id: budget_investments) end From 3471cbb97977e0a65a894256db11ef089bd04445 Mon Sep 17 00:00:00 2001 From: decabeza Date: Tue, 12 Feb 2019 11:17:57 +0100 Subject: [PATCH 6/7] Fix hound warnings --- spec/features/budgets/votes_spec.rb | 112 ++++++++++++++++------------ spec/models/user_spec.rb | 59 +++++++-------- 2 files changed, 92 insertions(+), 79 deletions(-) diff --git a/spec/features/budgets/votes_spec.rb b/spec/features/budgets/votes_spec.rb index d91ad1aa7..8513ec420 100644 --- a/spec/features/budgets/votes_spec.rb +++ b/spec/features/budgets/votes_spec.rb @@ -1,72 +1,70 @@ -require 'rails_helper' +require "rails_helper" -feature 'Votes' do - - background do - @manuela = create(:user, verified_at: Time.current) - end - - feature 'Investments' do +feature "Votes" do + feature "Investments" do + let(:manuela) { create(:user, verified_at: Time.current) } let(:budget) { create(:budget, phase: "selecting") } let(:group) { create(:budget_group, budget: budget) } let(:heading) { create(:budget_heading, group: group) } - background { login_as(@manuela) } + background { login_as(manuela) } - feature 'Index' do + feature "Index" do scenario "Index shows user votes on proposals" do investment1 = create(:budget_investment, heading: heading) investment2 = create(:budget_investment, heading: heading) investment3 = create(:budget_investment, heading: heading) - create(:vote, voter: @manuela, votable: investment1, vote_flag: true) + create(:vote, voter: manuela, votable: investment1, vote_flag: true) visit budget_investments_path(budget, heading_id: heading.id) within("#budget-investments") do within("#budget_investment_#{investment1.id}_votes") do - expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).to have_content "You have already supported this investment project. "\ + "Share it!" end within("#budget_investment_#{investment2.id}_votes") do - expect(page).not_to have_content "You have already supported this investment project. Share it!" + expect(page).not_to have_content "You have already supported this investment project. "\ + "Share it!" end within("#budget_investment_#{investment3.id}_votes") do - expect(page).not_to have_content "You have already supported this investment project. Share it!" + expect(page).not_to have_content "You have already supported this investment project. "\ + "Share it!" end end end - scenario 'Create from spending proposal index', :js do - investment = create(:budget_investment, heading: heading, budget: budget) + scenario "Create from spending proposal index", :js do + create(:budget_investment, heading: heading, budget: budget) visit budget_investments_path(budget, heading_id: heading.id) - within('.supports') do + within(".supports") do find(".in-favor a").click expect(page).to have_content "1 support" - expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).to have_content "You have already supported this investment project. "\ + "Share it!" end end end - feature 'Single spending proposal' do - background do - @investment = create(:budget_investment, budget: budget, heading: heading) - end + feature "Single spending proposal" do + let(:investment) { create(:budget_investment, budget: budget, heading: heading)} - scenario 'Show no votes' do - visit budget_investment_path(budget, @investment) + scenario "Show no votes" do + visit budget_investment_path(budget, investment) expect(page).to have_content "No supports" end - scenario 'Trying to vote multiple times', :js do - visit budget_investment_path(budget, @investment) + scenario "Trying to vote multiple times", :js do + visit budget_investment_path(budget, investment) - within('.supports') do + within(".supports") do find(".in-favor a").click expect(page).to have_content "1 support" @@ -74,20 +72,24 @@ feature 'Votes' do end end - scenario 'Create from proposal show', :js do - visit budget_investment_path(budget, @investment) + scenario "Create from proposal show", :js do + visit budget_investment_path(budget, investment) - within('.supports') do + within(".supports") do find(".in-favor a").click expect(page).to have_content "1 support" - expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).to have_content "You have already supported this investment project. "\ + "Share it!" end end end - scenario 'Disable voting on spending proposals', :js do - login_as(@manuela) + scenario "Disable voting on spending proposals", :js do + manuela = create(:user, verified_at: Time.current) + + login_as(manuela) + budget.update(phase: "reviewing") investment = create(:budget_investment, budget: budget, heading: heading) @@ -122,59 +124,71 @@ feature 'Votes' do visit budget_investments_path(budget, heading_id: new_york.id) within("#budget_investment_#{new_york_investment.id}") do - accept_confirm { find('.in-favor a').click } + accept_confirm { find(".in-favor a").click } expect(page).to have_content "1 support" - expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).to have_content "You have already supported this investment project. "\ + "Share it!" end visit budget_investments_path(budget, heading_id: san_francisco.id) within("#budget_investment_#{san_francisco_investment.id}") do - find('.in-favor a').click + find(".in-favor a").click expect(page).to have_content "1 support" - expect(page).to have_content "You have already supported this investment project. Share it!" + expect(page).to have_content "You have already supported this investment project. "\ + "Share it!" end visit budget_investments_path(budget, heading_id: third_heading.id) within("#budget_investment_#{third_heading_investment.id}") do - find('.in-favor a').click + find(".in-favor a").click - expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in" + expect(page).to have_content "You can only support investment projects in 2 districts. "\ + "You have already supported investments in" - heading_names = find('.participation-not-allowed').text.match(/You have already supported investments in (.+) and (.+)\./)&.captures - expect(heading_names).to match_array [new_york.name, san_francisco.name] + participation = find(".participation-not-allowed") + headings = participation.text + .match(/You have already supported investments in (.+) and (.+)\./)&.captures + + expect(headings).to match_array [new_york.name, san_francisco.name] expect(page).not_to have_content "1 support" - expect(page).not_to have_content "You have already supported this investment project. Share it!" + expect(page).not_to have_content "You have already supported this investment project. "\ + "Share it!" end end scenario "From show", :js do visit budget_investment_path(budget, new_york_investment) - accept_confirm { find('.in-favor a').click } + accept_confirm { find(".in-favor a").click } expect(page).to have_content "1 support" expect(page).to have_content "You have already supported this investment project. Share it!" visit budget_investment_path(budget, san_francisco_investment) - find('.in-favor a').click + find(".in-favor a").click expect(page).to have_content "1 support" expect(page).to have_content "You have already supported this investment project. Share it!" visit budget_investment_path(budget, third_heading_investment) - find('.in-favor a').click - expect(page).to have_content "You can only support investment projects in 2 districts. You have already supported investments in" + find(".in-favor a").click + expect(page).to have_content "You can only support investment projects in 2 districts. "\ + "You have already supported investments in" - heading_names = find('.participation-not-allowed').text.match(/You have already supported investments in (.+) and (.+)\./)&.captures - expect(heading_names).to match_array [new_york.name, san_francisco.name] + participation = find(".participation-not-allowed") + headings = participation.text + .match(/You have already supported investments in (.+) and (.+)\./)&.captures + + expect(headings).to match_array [new_york.name, san_francisco.name] expect(page).not_to have_content "1 support" - expect(page).not_to have_content "You have already supported this investment project. Share it!" + expect(page).not_to have_content "You have already supported this investment project. "\ + "Share it!" end end diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index d32b8fa17..3e835de7e 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -1,8 +1,8 @@ -require 'rails_helper' +require "rails_helper" describe User do - describe '#headings_voted_within_group' do + describe "#headings_voted_within_group" do it "returns the headings voted by a user" do user1 = create(:user) user2 = create(:user) @@ -16,18 +16,17 @@ describe User do new_york_investment = create(:budget_investment, heading: new_york) san_franciso_investment = create(:budget_investment, heading: san_franciso) - another_investment = create(:budget_investment, heading: san_franciso) create(:vote, votable: new_york_investment, voter: user1) create(:vote, votable: san_franciso_investment, voter: user1) expect(user1.headings_voted_within_group(group)).to include(new_york) expect(user1.headings_voted_within_group(group)).to include(san_franciso) - expect(user1.headings_voted_within_group(group)).to_not include(another_heading) + expect(user1.headings_voted_within_group(group)).not_to include(another_heading) - expect(user2.headings_voted_within_group(group)).to_not include(new_york) - expect(user2.headings_voted_within_group(group)).to_not include(san_franciso) - expect(user2.headings_voted_within_group(group)).to_not include(another_heading) + expect(user2.headings_voted_within_group(group)).not_to include(new_york) + expect(user2.headings_voted_within_group(group)).not_to include(san_franciso) + expect(user2.headings_voted_within_group(group)).not_to include(another_heading) end end @@ -101,39 +100,39 @@ describe User do end end - describe 'preferences' do - describe 'email_on_comment' do - it 'is false by default' do + describe "preferences" do + describe "email_on_comment" do + it "is false by default" do expect(subject.email_on_comment).to eq(false) end end - describe 'email_on_comment_reply' do - it 'is false by default' do + describe "email_on_comment_reply" do + it "is false by default" do expect(subject.email_on_comment_reply).to eq(false) end end - describe 'subscription_to_website_newsletter' do - it 'is true by default' do + describe "subscription_to_website_newsletter" do + it "is true by default" do expect(subject.newsletter).to eq(true) end end - describe 'email_digest' do - it 'is true by default' do + describe "email_digest" do + it "is true by default" do expect(subject.email_digest).to eq(true) end end - describe 'email_on_direct_message' do - it 'is true by default' do + describe "email_on_direct_message" do + it "is true by default" do expect(subject.email_on_direct_message).to eq(true) end end - describe 'official_position_badge' do - it 'is false by default' do + describe "official_position_badge" do + it "is false by default" do expect(subject.official_position_badge).to eq(false) end end @@ -204,7 +203,7 @@ describe User do expect(subject.organization?).to be false end - describe 'when it is an organization' do + describe "when it is an organization" do before { create(:organization, user: subject) } it "is true when the user is an organization" do @@ -222,7 +221,7 @@ describe User do expect(subject).not_to be_verified_organization end - describe 'when it is an organization' do + describe "when it is an organization" do before { create(:organization, user: subject) } it "is false when the user is not a verified organization" do @@ -237,12 +236,12 @@ describe User do end describe "organization_attributes" do - before { subject.organization_attributes = {name: 'org', responsible_name: 'julia'} } + before { subject.organization_attributes = {name: "org", responsible_name: "julia"} } it "triggers the creation of an associated organization" do expect(subject.organization).to be - expect(subject.organization.name).to eq('org') - expect(subject.organization.responsible_name).to eq('julia') + expect(subject.organization.name).to eq("org") + expect(subject.organization.responsible_name).to eq("julia") end it "deactivates the validation of username, and activates the validation of organization" do @@ -321,7 +320,7 @@ describe User do # We will use empleados.madrid.es as the officials' domain # Subdomains are also accepted - Setting['email_domain_for_officials'] = 'officials.madrid.es' + Setting["email_domain_for_officials"] = "officials.madrid.es" user1 = create(:user, email: "john@officials.madrid.es", confirmed_at: Time.current) user2 = create(:user, email: "john@yes.officials.madrid.es", confirmed_at: Time.current) user3 = create(:user, email: "john@unofficials.madrid.es", confirmed_at: Time.current) @@ -333,7 +332,7 @@ describe User do expect(user4.has_official_email?).to eq(false) # We reset the officials' domain setting - Setting.find_by(key: 'email_domain_for_officials').update(value: '') + Setting.find_by(key: "email_domain_for_officials").update(value: "") end end @@ -490,10 +489,10 @@ describe User do reset_password_token: "token2", email_verification_token: "token3") - user.erase('a test') + user.erase("a test") user.reload - expect(user.erase_reason).to eq('a test') + expect(user.erase_reason).to eq("a test") expect(user.erased_at).to be expect(user.username).to be_nil @@ -524,7 +523,7 @@ describe User do user = create(:user) identity = create(:identity, user: user) - user.erase('an identity test') + user.erase("an identity test") expect(Identity.exists?(identity.id)).not_to be end From 73a0f999adaea3e8feb038576d05a13c527a11dd Mon Sep 17 00:00:00 2001 From: decabeza Date: Tue, 12 Feb 2019 11:53:03 +0100 Subject: [PATCH 7/7] Add order to voted headings names --- app/models/user.rb | 2 +- spec/models/user_spec.rb | 15 +++++++++++---- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/app/models/user.rb b/app/models/user.rb index 4ac60773b..0f58594ab 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -128,7 +128,7 @@ class User < ActiveRecord::Base end def headings_voted_within_group(group) - Budget::Heading.where(id: voted_investments.by_group(group).pluck(:heading_id)) + Budget::Heading.order("name").where(id: voted_investments.by_group(group).pluck(:heading_id)) end def voted_investments diff --git a/spec/models/user_spec.rb b/spec/models/user_spec.rb index 3e835de7e..599459324 100644 --- a/spec/models/user_spec.rb +++ b/spec/models/user_spec.rb @@ -3,26 +3,33 @@ require "rails_helper" describe User do describe "#headings_voted_within_group" do - it "returns the headings voted by a user" do + it "returns the headings voted by a user ordered by name" do user1 = create(:user) user2 = create(:user) budget = create(:budget) group = create(:budget_group, budget: budget) - new_york = create(:budget_heading, group: group) - san_franciso = create(:budget_heading, group: group) + new_york = create(:budget_heading, group: group, name: "New york") + san_franciso = create(:budget_heading, group: group, name: "San Franciso") + wyoming = create(:budget_heading, group: group, name: "Wyoming") another_heading = create(:budget_heading, group: group) new_york_investment = create(:budget_investment, heading: new_york) san_franciso_investment = create(:budget_investment, heading: san_franciso) + wyoming_investment = create(:budget_investment, heading: wyoming) - create(:vote, votable: new_york_investment, voter: user1) + create(:vote, votable: wyoming_investment, voter: user1) create(:vote, votable: san_franciso_investment, voter: user1) + create(:vote, votable: new_york_investment, voter: user1) + + headings_names = "#{new_york.name}, #{san_franciso.name}, and #{wyoming.name}" expect(user1.headings_voted_within_group(group)).to include(new_york) expect(user1.headings_voted_within_group(group)).to include(san_franciso) + expect(user1.headings_voted_within_group(group)).to include(wyoming) expect(user1.headings_voted_within_group(group)).not_to include(another_heading) + expect(user1.headings_voted_within_group(group).map(&:name).to_sentence).to eq(headings_names) expect(user2.headings_voted_within_group(group)).not_to include(new_york) expect(user2.headings_voted_within_group(group)).not_to include(san_franciso)