adds Budget::Group model to group headings
many refactors through budget related models
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
10
app/models/budget/group.rb
Normal file
10
app/models/budget/group.rb
Normal file
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -300,18 +300,21 @@ puts "Creating Budgets"
|
||||
(1..10).each do |i|
|
||||
budget = Budget.create!(name: (Date.today.year - 10 + i).to_s,
|
||||
description: "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>",
|
||||
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
|
||||
|
||||
@@ -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
|
||||
|
||||
10
db/migrate/20160609110023_create_budget_group.rb
Normal file
10
db/migrate/20160609110023_create_budget_group.rb
Normal file
@@ -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
|
||||
5
db/migrate/20160609142017_remove_price_from_budget.rb
Normal file
5
db/migrate/20160609142017_remove_price_from_budget.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class RemovePriceFromBudget < ActiveRecord::Migration
|
||||
def change
|
||||
remove_column :budgets, :price, :integer
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,5 @@
|
||||
class RemoveBudgetIdFromInvestments < ActiveRecord::Migration
|
||||
def change
|
||||
remove_column :budget_investments, :budget_id, :integer
|
||||
end
|
||||
end
|
||||
48
db/schema.rb
48
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
|
||||
|
||||
@@ -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 ''
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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) }
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
Reference in New Issue
Block a user