From b5a6828e415394d8f6cc45e10fa63fdcf6cde24c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baz=C3=A1n?= Date: Thu, 9 Jun 2016 18:00:06 +0200 Subject: [PATCH] adds Budget::Group model to group headings many refactors through budget related models --- app/models/budget.rb | 9 +-- app/models/budget/ballot.rb | 2 +- app/models/budget/group.rb | 10 ++++ app/models/budget/heading.rb | 4 +- app/models/budget/investment.rb | 11 ++-- db/dev_seeds.rb | 21 ++++--- .../20160520111735_create_budget_heading.rb | 4 +- .../20160609110023_create_budget_group.rb | 10 ++++ ...20160609142017_remove_price_from_budget.rb | 5 ++ ...52026_remove_budget_id_from_investments.rb | 5 ++ db/schema.rb | 48 +++++++++------- spec/factories.rb | 10 +++- spec/models/abilities/administrator_spec.rb | 10 +++- spec/models/abilities/common_spec.rb | 13 ++++- spec/models/abilities/valuator_spec.rb | 10 +++- spec/models/budget/ballot_spec.rb | 29 ++++------ spec/models/budget/investment_spec.rb | 56 +++++++++---------- spec/models/budget_spec.rb | 9 +-- 18 files changed, 156 insertions(+), 110 deletions(-) create mode 100644 app/models/budget/group.rb create mode 100644 db/migrate/20160609110023_create_budget_group.rb create mode 100644 db/migrate/20160609142017_remove_price_from_budget.rb create mode 100644 db/migrate/20160609152026_remove_budget_id_from_investments.rb diff --git a/app/models/budget.rb b/app/models/budget.rb index b234a8b73..ea22a4615 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -4,9 +4,11 @@ class Budget < ActiveRecord::Base validates :phase, inclusion: { in: VALID_PHASES } - has_many :investments - has_many :ballots - has_many :headings + has_many :investments, dependent: :destroy + has_many :ballots, dependent: :destroy + has_many :groups, dependent: :destroy + has_many :headings, through: :groups + has_many :investments, through: :headings def on_hold? phase == "on_hold" @@ -29,7 +31,6 @@ class Budget < ActiveRecord::Base end def heading_price(heading) - return price unless heading.present? heading_ids.include?(heading.id) ? heading.price : -1 end end diff --git a/app/models/budget/ballot.rb b/app/models/budget/ballot.rb index 9b9a089d6..560075f97 100644 --- a/app/models/budget/ballot.rb +++ b/app/models/budget/ballot.rb @@ -16,7 +16,7 @@ class Budget end def amount_available(heading) - budget.heading_price(heading) - amount_spent(heading.try(:id)) + budget.heading_price(heading) - amount_spent(heading.id) end end end diff --git a/app/models/budget/group.rb b/app/models/budget/group.rb new file mode 100644 index 000000000..dd7910950 --- /dev/null +++ b/app/models/budget/group.rb @@ -0,0 +1,10 @@ +class Budget + class Group < ActiveRecord::Base + belongs_to :budget + + has_many :headings, dependent: :destroy + + validates :budget_id, presence: true + validates :name, presence: true + end +end \ No newline at end of file diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb index e79c5b7c8..830596912 100644 --- a/app/models/budget/heading.rb +++ b/app/models/budget/heading.rb @@ -1,11 +1,11 @@ class Budget class Heading < ActiveRecord::Base - belongs_to :budget + belongs_to :group belongs_to :geozone has_many :investments - validates :budget_id, presence: true + validates :group_id, presence: true validates :name, presence: true validates :price, presence: true end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 329c2fce2..1e0d368f3 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -10,7 +10,6 @@ class Budget acts_as_paranoid column: :hidden_at include ActsAsParanoidAliases - belongs_to :budget belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id' belongs_to :heading belongs_to :administrator @@ -43,7 +42,6 @@ class Budget scope :with_supports, -> { where('cached_votes_up > 0') } scope :by_heading, -> (heading_id) { where(heading_id: heading_id) } - scope :by_budget, -> (budget_id) { where(budget_id: budget_id) } scope :by_admin, -> (admin_id) { where(administrator_id: admin_id) } scope :by_tag, -> (tag_name) { tagged_with(tag_name) } scope :by_valuator, -> (valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) } @@ -61,8 +59,7 @@ class Budget end def self.scoped_filter(params, current_filter) - budget = Budget.find!(params[:budget_id]) - results = self.by_budget(params[:budget_id]) + results = budget.investments if params[:max_for_no_heading].present? || params[:max_per_heading].present? results = limit_results(results, budget, params[:max_per_heading].to_i, params[:max_for_no_heading].to_i) end @@ -118,6 +115,10 @@ class Budget where(heading_id: heading == 'all' ? nil : heading.presence) end + def budget + heading.group.budget + end + def undecided? feasibility == "undecided" end @@ -139,7 +140,7 @@ class Budget end def code - "B#{budget_id}I#{id}" + "B#{budget.id}I#{id}" end def reason_for_not_being_selectable_by(user) diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index ee63987c4..a223e1f16 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -300,18 +300,21 @@ puts "Creating Budgets" (1..10).each do |i| budget = Budget.create!(name: (Date.today.year - 10 + i).to_s, description: "

#{Faker::Lorem.paragraphs.join('

')}

", - price: rand(1 .. 100) * 100000, phase: %w{on_hold accepting selecting balloting finished}.sample, valuating: [false, true].sample) puts budget.name - puts " " - geozones = Geozone.reorder("RANDOM()").limit(10) - geozones.each do |geozone| - heading = budget.headings.create!(name: geozone.name, - geozone: geozone, - price: rand(1 .. 100) * 10000) - budget.headings << heading - print "heading.name " + + (1..[1,2,3].sample).each do |i| + group = budget.groups.create!(name: Faker::StarWars.planet) + + geozones = Geozone.reorder("RANDOM()").limit([2,5,6,7].sample) + geozones.each do |geozone| + group.headings << group.headings.create!(name: geozone.name, + geozone: geozone, + price: rand(1 .. 100) * 10000) + + end + print "#{group.name} " end puts "" end diff --git a/db/migrate/20160520111735_create_budget_heading.rb b/db/migrate/20160520111735_create_budget_heading.rb index e9ca935c6..bd9291d2f 100644 --- a/db/migrate/20160520111735_create_budget_heading.rb +++ b/db/migrate/20160520111735_create_budget_heading.rb @@ -1,9 +1,9 @@ class CreateBudgetHeading < ActiveRecord::Migration def change create_table :budget_headings do |t| - t.references :budget + t.references :group, index: true t.references :geozone - t.string :name, limit: 50 + t.string :name, limit: 50 t.integer :price, limit: 8 end end diff --git a/db/migrate/20160609110023_create_budget_group.rb b/db/migrate/20160609110023_create_budget_group.rb new file mode 100644 index 000000000..fb6cbcd1c --- /dev/null +++ b/db/migrate/20160609110023_create_budget_group.rb @@ -0,0 +1,10 @@ +class CreateBudgetGroup < ActiveRecord::Migration + def change + create_table :budget_groups do |t| + t.references :budget + t.string :name, limit: 50 + end + + add_index :budget_groups, :budget_id + end +end diff --git a/db/migrate/20160609142017_remove_price_from_budget.rb b/db/migrate/20160609142017_remove_price_from_budget.rb new file mode 100644 index 000000000..366fdef5f --- /dev/null +++ b/db/migrate/20160609142017_remove_price_from_budget.rb @@ -0,0 +1,5 @@ +class RemovePriceFromBudget < ActiveRecord::Migration + def change + remove_column :budgets, :price, :integer + end +end diff --git a/db/migrate/20160609152026_remove_budget_id_from_investments.rb b/db/migrate/20160609152026_remove_budget_id_from_investments.rb new file mode 100644 index 000000000..69890c2e9 --- /dev/null +++ b/db/migrate/20160609152026_remove_budget_id_from_investments.rb @@ -0,0 +1,5 @@ +class RemoveBudgetIdFromInvestments < ActiveRecord::Migration + def change + remove_column :budget_investments, :budget_id, :integer + end +end diff --git a/db/schema.rb b/db/schema.rb index 1f5cbe6a0..8cd96edfd 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: 20160531102008) do +ActiveRecord::Schema.define(version: 20160609152026) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -63,6 +63,21 @@ ActiveRecord::Schema.define(version: 20160531102008) do add_index "annotations", ["legislation_id"], name: "index_annotations_on_legislation_id", using: :btree add_index "annotations", ["user_id"], name: "index_annotations_on_user_id", using: :btree + create_table "banners", force: :cascade do |t| + t.string "title", limit: 80 + t.string "description" + t.string "target_url" + t.string "style" + t.string "image" + t.date "post_started_at" + t.date "post_ended_at" + t.datetime "hidden_at" + t.datetime "created_at", null: false + t.datetime "updated_at", null: false + end + + add_index "banners", ["hidden_at"], name: "index_banners_on_hidden_at", using: :btree + create_table "budget_ballot_lines", force: :cascade do |t| t.integer "ballot_id" t.integer "investment_id" @@ -83,13 +98,22 @@ ActiveRecord::Schema.define(version: 20160531102008) do add_index "budget_ballots", ["heading_id"], name: "index_budget_ballots_on_heading_id", using: :btree - create_table "budget_headings", force: :cascade do |t| + create_table "budget_groups", force: :cascade do |t| t.integer "budget_id" + t.string "name", limit: 50 + end + + add_index "budget_groups", ["budget_id"], name: "index_budget_groups_on_budget_id", using: :btree + + create_table "budget_headings", force: :cascade do |t| + t.integer "group_id" t.integer "geozone_id" t.string "name", limit: 50 t.integer "price", limit: 8 end + add_index "budget_headings", ["group_id"], name: "index_budget_headings_on_group_id", using: :btree + create_table "budget_investments", force: :cascade do |t| t.integer "author_id" t.integer "administrator_id" @@ -114,13 +138,11 @@ ActiveRecord::Schema.define(version: 20160531102008) do t.datetime "created_at", null: false t.datetime "updated_at", null: false t.integer "heading_id" - t.integer "budget_id" t.string "responsible_name" end add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree add_index "budget_investments", ["author_id"], name: "index_budget_investments_on_author_id", using: :btree - add_index "budget_investments", ["budget_id"], name: "index_budget_investments_on_budget_id", using: :btree add_index "budget_investments", ["heading_id"], name: "index_budget_investments_on_heading_id", using: :btree add_index "budget_investments", ["tsv"], name: "index_budget_investments_on_tsv", using: :gin @@ -141,24 +163,8 @@ ActiveRecord::Schema.define(version: 20160531102008) do t.boolean "valuating", default: false t.datetime "created_at", null: false t.datetime "updated_at", null: false - t.integer "price" end - create_table "banners", force: :cascade do |t| - t.string "title", limit: 80 - t.string "description" - t.string "target_url" - t.string "style" - t.string "image" - t.date "post_started_at" - t.date "post_ended_at" - t.datetime "hidden_at" - t.datetime "created_at", null: false - t.datetime "updated_at", null: false - end - - add_index "banners", ["hidden_at"], name: "index_banners_on_hidden_at", using: :btree - create_table "campaigns", force: :cascade do |t| t.string "name" t.string "track_id" @@ -204,10 +210,10 @@ ActiveRecord::Schema.define(version: 20160531102008) do t.string "visit_id" t.datetime "hidden_at" t.integer "flags_count", default: 0 + t.datetime "ignored_flag_at" t.integer "cached_votes_total", default: 0 t.integer "cached_votes_up", default: 0 t.integer "cached_votes_down", default: 0 - t.datetime "ignored_flag_at" t.integer "comments_count", default: 0 t.datetime "confirmed_hide_at" t.integer "cached_anonymous_votes_total", default: 0 diff --git a/spec/factories.rb b/spec/factories.rb index 37befbddc..d20cfa84f 100644 --- a/spec/factories.rb +++ b/spec/factories.rb @@ -191,7 +191,6 @@ FactoryGirl.define do factory :budget do sequence(:name) { |n| "Budget #{n}" } currency_symbol "€" - price 10000 phase 'on_hold' trait :selecting do @@ -207,15 +206,20 @@ FactoryGirl.define do end end - factory :budget_heading, class: 'Budget::Heading' do + factory :budget_group, class: 'Budget::Group' do budget + sequence(:name) { |n| "Group #{n}" } + end + + factory :budget_heading, class: 'Budget::Heading' do + association :group, factory: :budget_group sequence(:name) { |n| "Heading #{n}" } price 1000000 end factory :budget_investment, class: 'Budget::Investment' do sequence(:title) { |n| "Budget Investment #{n} title" } - association :budget + association :heading, factory: :budget_heading association :author, factory: :user description 'Spend money on this' unfeasibility_explanation '' diff --git a/spec/models/abilities/administrator_spec.rb b/spec/models/abilities/administrator_spec.rb index 8170d3434..d2313dea5 100644 --- a/spec/models/abilities/administrator_spec.rb +++ b/spec/models/abilities/administrator_spec.rb @@ -65,7 +65,13 @@ describe "Abilities::Administrator" do it { should be_able_to(:update, Budget::Investment) } it { should be_able_to(:hide, Budget::Investment) } - it { should be_able_to(:valuate, create(:budget_investment, budget: create(:budget, valuating: true))) } - it { should_not be_able_to(:valuate, create(:budget_investment, budget: create(:budget, valuating: false))) } + it { should be_able_to(:valuate, create(:budget_investment, + heading: create(:budget_heading, + group: create(:budget_group, + budget: create(:budget, valuating: true))))) } + it { should_not be_able_to(:valuate, create(:budget_investment, + heading: create(:budget_heading, + group: create(:budget_group, + budget: create(:budget, valuating: false))))) } end diff --git a/spec/models/abilities/common_spec.rb b/spec/models/abilities/common_spec.rb index 6fd751c9f..d2276aa84 100644 --- a/spec/models/abilities/common_spec.rb +++ b/spec/models/abilities/common_spec.rb @@ -12,9 +12,16 @@ describe "Abilities::Common" do let(:accepting_budget) { create(:budget, phase: 'accepting') } let(:selecting_budget) { create(:budget, phase: 'selecting') } let(:balloting_budget) { create(:budget, phase: 'balloting') } - let(:investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget) } - let(:investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget) } - let(:investment_in_balloting_budget) { create(:budget_investment, budget: balloting_budget) } + let(:accepting_budget_group) { create(:budget_group, budget: accepting_budget) } + let(:selecting_budget_group) { create(:budget_group, budget: selecting_budget) } + let(:balloting_budget_group) { create(:budget_group, budget: balloting_budget) } + let(:accepting_budget_heading) { create(:budget_heading, group: accepting_budget_group) } + let(:selecting_budget_heading) { create(:budget_heading, group: selecting_budget_group) } + let(:balloting_budget_heading) { create(:budget_heading, group: balloting_budget_group) } + + let(:investment_in_accepting_budget) { create(:budget_investment, heading: accepting_budget_heading) } + let(:investment_in_selecting_budget) { create(:budget_investment, heading: selecting_budget_heading) } + let(:investment_in_balloting_budget) { create(:budget_investment, heading: balloting_budget_heading) } let(:ballot_in_accepting_budget) { create(:budget_ballot, budget: accepting_budget) } let(:ballot_in_selecting_budget) { create(:budget_ballot, budget: selecting_budget) } let(:ballot_in_balloting_budget) { create(:budget_ballot, budget: balloting_budget) } diff --git a/spec/models/abilities/valuator_spec.rb b/spec/models/abilities/valuator_spec.rb index 9fa285f19..add938a9d 100644 --- a/spec/models/abilities/valuator_spec.rb +++ b/spec/models/abilities/valuator_spec.rb @@ -7,10 +7,16 @@ describe "Abilities::Valuator" do let(:valuator) { create(:valuator) } let(:non_assigned_investment) { create(:budget_investment) } - let(:assigned_investment) { create(:budget_investment, budget: create(:budget, valuating: true)) } + let(:assigned_investment) { create(:budget_investment, + heading: create(:budget_heading, + group: create(:budget_group, + budget: create(:budget, valuating: true)))) } before(:each) { assigned_investment.valuators << valuator } - let(:assigned_investment_not_valuating) { create(:budget_investment, budget: create(:budget, valuating: false)) } + let(:assigned_investment_not_valuating) { create(:budget_investment, + heading: create(:budget_heading, + group: create(:budget_group, + budget: create(:budget, valuating: false)))) } before(:each) { assigned_investment_not_valuating.valuators << valuator } it { should be_able_to(:read, SpendingProposal) } diff --git a/spec/models/budget/ballot_spec.rb b/spec/models/budget/ballot_spec.rb index ee6be74f1..a0997a1c3 100644 --- a/spec/models/budget/ballot_spec.rb +++ b/spec/models/budget/ballot_spec.rb @@ -21,18 +21,15 @@ describe Budget::Ballot do heading = create(:budget_heading) inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading) inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading)) - inv3 = create(:budget_investment, :feasible, price: 25000) - inv4 = create(:budget_investment, :feasible, price: 40000, heading: heading) + inv3 = create(:budget_investment, :feasible, price: 40000, heading: heading) ballot = create(:budget_ballot) ballot.investments << inv1 ballot.investments << inv2 - ballot.investments << inv3 expect(ballot.amount_spent(heading.id)).to eq 10000 - expect(ballot.amount_spent(nil)).to eq 25000 - ballot.investments << inv4 + ballot.investments << inv3 expect(ballot.amount_spent(heading.id)).to eq 50000 end @@ -40,28 +37,22 @@ describe Budget::Ballot do describe "#amount_available" do it "returns how much is left after taking some investments" do - budget = create(:budget, price: 200000) - heading = create(:budget_heading, budget: budget) - inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading) - inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading)) - inv3 = create(:budget_investment, :feasible, price: 25000) - inv4 = create(:budget_investment, :feasible, price: 40000, heading: heading) - - inv1 = create(:budget_investment, :feasible, price: 10000) - inv2 = create(:budget_investment, :feasible, price: 20000) + budget = create(:budget) + group = create(:budget_group, budget: budget) + heading = create(:budget_heading, group: group, price: 1000) + inv1 = create(:budget_investment, :feasible, price: 100, heading: heading) + inv2 = create(:budget_investment, :feasible, price: 200, heading: create(:budget_heading)) + inv3 = create(:budget_investment, :feasible, price: 400, heading: heading) ballot = create(:budget_ballot, budget: budget) ballot.investments << inv1 ballot.investments << inv2 - expect(ballot.amount_available(heading)).to eq 1000000 - expect(ballot.amount_available(nil)).to eq 170000 + expect(ballot.amount_available(heading)).to eq 900 ballot.investments << inv3 - ballot.investments << inv4 - expect(ballot.amount_available(heading)).to eq 960000 - expect(ballot.amount_available(nil)).to eq 145000 + expect(ballot.amount_available(heading)).to eq 500 end end diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index eb4cab3ac..ac79fad78 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -190,38 +190,33 @@ describe Budget::Investment do describe 'Permissions' do let(:budget) { create(:budget) } - let(:heading) { create(:budget_heading, budget: budget) } + let(:group) { create(:budget_group, budget: budget) } + let(:heading) { create(:budget_heading, group: group) } let(:user) { create(:user, :level_two) } let(:luser) { create(:user) } - let(:city_sp) { create(:budget_investment, budget: budget) } - let(:district_sp) { create(:budget_investment, budget: budget, heading: heading) } + let(:district_sp) { create(:budget_investment, heading: heading) } describe '#reason_for_not_being_selectable_by' do it "rejects not logged in users" do - expect(city_sp.reason_for_not_being_selectable_by(nil)).to eq(:not_logged_in) expect(district_sp.reason_for_not_being_selectable_by(nil)).to eq(:not_logged_in) end it "rejects not verified users" do - expect(city_sp.reason_for_not_being_selectable_by(luser)).to eq(:not_verified) expect(district_sp.reason_for_not_being_selectable_by(luser)).to eq(:not_verified) end it "rejects organizations" do create(:organization, user: user) - expect(city_sp.reason_for_not_being_selectable_by(user)).to eq(:organization) expect(district_sp.reason_for_not_being_selectable_by(user)).to eq(:organization) end it "rejects selections when selecting is not allowed (via admin setting)" do budget.phase = "on_hold" - expect(city_sp.reason_for_not_being_selectable_by(user)).to eq(:no_selecting_allowed) expect(district_sp.reason_for_not_being_selectable_by(user)).to eq(:no_selecting_allowed) end it "accepts valid selections when selecting is allowed" do budget.phase = "selecting" - expect(city_sp.reason_for_not_being_selectable_by(user)).to be_nil expect(district_sp.reason_for_not_being_selectable_by(user)).to be_nil end end @@ -274,7 +269,9 @@ describe Budget::Investment do describe "total votes" do it "takes into account physical votes in addition to web votes" do b = create(:budget, :selecting) - sp = create(:budget_investment, budget: b) + g = create(:budget_group, budget: b) + h = create(:budget_heading, group: g) + sp = create(:budget_investment, heading: h) sp.register_selection(create(:user, :level_two)) expect(sp.total_votes).to eq(1) @@ -299,56 +296,52 @@ describe Budget::Investment do describe 'Permissions' do let(:budget) { create(:budget) } - let(:heading) { create(:budget_heading, budget: budget) } + let(:group) { create(:budget_group, budget: budget) } + let(:heading) { create(:budget_heading, group: group) } let(:user) { create(:user, :level_two) } let(:luser) { create(:user) } let(:ballot) { create(:budget_ballot, budget: budget) } - let(:city_sp) { create(:budget_investment, budget: budget) } - let(:district_sp) { create(:budget_investment, budget: budget, heading: heading) } + let(:investment) { create(:budget_investment, heading: heading) } describe '#reason_for_not_being_ballotable_by' do it "rejects not logged in users" do - expect(city_sp.reason_for_not_being_ballotable_by(nil, ballot)).to eq(:not_logged_in) - expect(district_sp.reason_for_not_being_ballotable_by(nil, ballot)).to eq(:not_logged_in) + expect(investment.reason_for_not_being_ballotable_by(nil, ballot)).to eq(:not_logged_in) end it "rejects not verified users" do - expect(city_sp.reason_for_not_being_ballotable_by(luser, ballot)).to eq(:not_verified) - expect(district_sp.reason_for_not_being_ballotable_by(luser, ballot)).to eq(:not_verified) + expect(investment.reason_for_not_being_ballotable_by(luser, ballot)).to eq(:not_verified) end it "rejects organizations" do create(:organization, user: user) - expect(city_sp.reason_for_not_being_ballotable_by(user, ballot)).to eq(:organization) - expect(district_sp.reason_for_not_being_ballotable_by(user, ballot)).to eq(:organization) + expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to eq(:organization) end it "rejects votes when voting is not allowed (via admin setting)" do budget.phase = "on_hold" - expect(city_sp.reason_for_not_being_ballotable_by(user, ballot)).to eq(:no_ballots_allowed) - expect(district_sp.reason_for_not_being_ballotable_by(user, ballot)).to eq(:no_ballots_allowed) + expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to eq(:no_ballots_allowed) end it "accepts valid ballots when voting is allowed" do budget.phase = "balloting" - expect(city_sp.reason_for_not_being_ballotable_by(user, ballot)).to be_nil - expect(district_sp.reason_for_not_being_ballotable_by(user, ballot)).to be_nil + expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to be_nil end it "accepts valid district selections" do budget.phase = "selecting" - expect(district_sp.reason_for_not_being_selectable_by(user)).to be_nil + expect(investment.reason_for_not_being_selectable_by(user)).to be_nil ballot.heading_id = heading.id - expect(district_sp.reason_for_not_being_selectable_by(user)).to be_nil + expect(investment.reason_for_not_being_selectable_by(user)).to be_nil end it "rejects users with different headings" do budget.phase = "balloting" - california = create(:budget_heading, budget: budget) - new_york = create(:budget_heading, budget: budget) + group = create(:budget_group, budget: budget) + california = create(:budget_heading, group: group) + new_york = create(:budget_heading, group: group) - sp1 = create(:budget_investment, :feasible, heading: california, budget: budget) - sp2 = create(:budget_investment, :feasible, heading: new_york, budget: budget) + sp1 = create(:budget_investment, :feasible, heading: california) + sp2 = create(:budget_investment, :feasible, heading: new_york) b = create(:budget_ballot, user: user, heading: california, investments: [sp1]) expect(sp2.reason_for_not_being_ballotable_by(user, b)).to eq(:different_heading_assigned) @@ -356,9 +349,10 @@ describe Budget::Investment do it "rejects proposals with price higher than current available money" do budget.phase = "balloting" - carabanchel = create(:budget_heading, budget: budget, price: 35) - sp1 = create(:budget_investment, :feasible, heading: carabanchel, price: 30, budget: budget) - sp2 = create(:budget_investment, :feasible, heading: carabanchel, price: 10, budget: budget) + distritos = create(:budget_group, budget: budget) + carabanchel = create(:budget_heading, group: distritos, price: 35) + sp1 = create(:budget_investment, :feasible, heading: carabanchel, price: 30) + sp2 = create(:budget_investment, :feasible, heading: carabanchel, price: 10) ballot = create(:budget_ballot, user: user, heading: carabanchel, investments: [sp1]) expect(sp2.reason_for_not_being_ballotable_by(user, ballot)).to eq(:not_enough_money) diff --git a/spec/models/budget_spec.rb b/spec/models/budget_spec.rb index 398bb1cff..b238717ef 100644 --- a/spec/models/budget_spec.rb +++ b/spec/models/budget_spec.rb @@ -33,14 +33,11 @@ describe Budget do end describe "heading_price" do - let(:budget) { create(:budget, price: 1000) } - - it "returns the budget price if no heading is provided" do - expect(budget.heading_price(nil)).to eq(1000) - end + let(:budget) { create(:budget) } + let(:group) { create(:budget_group, budget: budget) } it "returns the heading price if the heading provided is part of the budget" do - heading = create(:budget_heading, price: 100, budget: budget) + heading = create(:budget_heading, price: 100, group: group) expect(budget.heading_price(heading)).to eq(100) end