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 }
|
validates :phase, inclusion: { in: VALID_PHASES }
|
||||||
|
|
||||||
has_many :investments
|
has_many :investments, dependent: :destroy
|
||||||
has_many :ballots
|
has_many :ballots, dependent: :destroy
|
||||||
has_many :headings
|
has_many :groups, dependent: :destroy
|
||||||
|
has_many :headings, through: :groups
|
||||||
|
has_many :investments, through: :headings
|
||||||
|
|
||||||
def on_hold?
|
def on_hold?
|
||||||
phase == "on_hold"
|
phase == "on_hold"
|
||||||
@@ -29,7 +31,6 @@ class Budget < ActiveRecord::Base
|
|||||||
end
|
end
|
||||||
|
|
||||||
def heading_price(heading)
|
def heading_price(heading)
|
||||||
return price unless heading.present?
|
|
||||||
heading_ids.include?(heading.id) ? heading.price : -1
|
heading_ids.include?(heading.id) ? heading.price : -1
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ class Budget
|
|||||||
end
|
end
|
||||||
|
|
||||||
def amount_available(heading)
|
def amount_available(heading)
|
||||||
budget.heading_price(heading) - amount_spent(heading.try(:id))
|
budget.heading_price(heading) - amount_spent(heading.id)
|
||||||
end
|
end
|
||||||
end
|
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 Budget
|
||||||
class Heading < ActiveRecord::Base
|
class Heading < ActiveRecord::Base
|
||||||
belongs_to :budget
|
belongs_to :group
|
||||||
belongs_to :geozone
|
belongs_to :geozone
|
||||||
|
|
||||||
has_many :investments
|
has_many :investments
|
||||||
|
|
||||||
validates :budget_id, presence: true
|
validates :group_id, presence: true
|
||||||
validates :name, presence: true
|
validates :name, presence: true
|
||||||
validates :price, presence: true
|
validates :price, presence: true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -10,7 +10,6 @@ class Budget
|
|||||||
acts_as_paranoid column: :hidden_at
|
acts_as_paranoid column: :hidden_at
|
||||||
include ActsAsParanoidAliases
|
include ActsAsParanoidAliases
|
||||||
|
|
||||||
belongs_to :budget
|
|
||||||
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
belongs_to :author, -> { with_hidden }, class_name: 'User', foreign_key: 'author_id'
|
||||||
belongs_to :heading
|
belongs_to :heading
|
||||||
belongs_to :administrator
|
belongs_to :administrator
|
||||||
@@ -43,7 +42,6 @@ class Budget
|
|||||||
scope :with_supports, -> { where('cached_votes_up > 0') }
|
scope :with_supports, -> { where('cached_votes_up > 0') }
|
||||||
|
|
||||||
scope :by_heading, -> (heading_id) { where(heading_id: heading_id) }
|
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_admin, -> (admin_id) { where(administrator_id: admin_id) }
|
||||||
scope :by_tag, -> (tag_name) { tagged_with(tag_name) }
|
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) }
|
scope :by_valuator, -> (valuator_id) { where("budget_valuator_assignments.valuator_id = ?", valuator_id).joins(:valuator_assignments) }
|
||||||
@@ -61,8 +59,7 @@ class Budget
|
|||||||
end
|
end
|
||||||
|
|
||||||
def self.scoped_filter(params, current_filter)
|
def self.scoped_filter(params, current_filter)
|
||||||
budget = Budget.find!(params[:budget_id])
|
results = budget.investments
|
||||||
results = self.by_budget(params[:budget_id])
|
|
||||||
if params[:max_for_no_heading].present? || params[:max_per_heading].present?
|
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)
|
results = limit_results(results, budget, params[:max_per_heading].to_i, params[:max_for_no_heading].to_i)
|
||||||
end
|
end
|
||||||
@@ -118,6 +115,10 @@ class Budget
|
|||||||
where(heading_id: heading == 'all' ? nil : heading.presence)
|
where(heading_id: heading == 'all' ? nil : heading.presence)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def budget
|
||||||
|
heading.group.budget
|
||||||
|
end
|
||||||
|
|
||||||
def undecided?
|
def undecided?
|
||||||
feasibility == "undecided"
|
feasibility == "undecided"
|
||||||
end
|
end
|
||||||
@@ -139,7 +140,7 @@ class Budget
|
|||||||
end
|
end
|
||||||
|
|
||||||
def code
|
def code
|
||||||
"B#{budget_id}I#{id}"
|
"B#{budget.id}I#{id}"
|
||||||
end
|
end
|
||||||
|
|
||||||
def reason_for_not_being_selectable_by(user)
|
def reason_for_not_being_selectable_by(user)
|
||||||
|
|||||||
@@ -300,18 +300,21 @@ puts "Creating Budgets"
|
|||||||
(1..10).each do |i|
|
(1..10).each do |i|
|
||||||
budget = Budget.create!(name: (Date.today.year - 10 + i).to_s,
|
budget = Budget.create!(name: (Date.today.year - 10 + i).to_s,
|
||||||
description: "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>",
|
description: "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>",
|
||||||
price: rand(1 .. 100) * 100000,
|
|
||||||
phase: %w{on_hold accepting selecting balloting finished}.sample,
|
phase: %w{on_hold accepting selecting balloting finished}.sample,
|
||||||
valuating: [false, true].sample)
|
valuating: [false, true].sample)
|
||||||
puts budget.name
|
puts budget.name
|
||||||
puts " "
|
|
||||||
geozones = Geozone.reorder("RANDOM()").limit(10)
|
(1..[1,2,3].sample).each do |i|
|
||||||
geozones.each do |geozone|
|
group = budget.groups.create!(name: Faker::StarWars.planet)
|
||||||
heading = budget.headings.create!(name: geozone.name,
|
|
||||||
geozone: geozone,
|
geozones = Geozone.reorder("RANDOM()").limit([2,5,6,7].sample)
|
||||||
price: rand(1 .. 100) * 10000)
|
geozones.each do |geozone|
|
||||||
budget.headings << heading
|
group.headings << group.headings.create!(name: geozone.name,
|
||||||
print "heading.name "
|
geozone: geozone,
|
||||||
|
price: rand(1 .. 100) * 10000)
|
||||||
|
|
||||||
|
end
|
||||||
|
print "#{group.name} "
|
||||||
end
|
end
|
||||||
puts ""
|
puts ""
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
class CreateBudgetHeading < ActiveRecord::Migration
|
class CreateBudgetHeading < ActiveRecord::Migration
|
||||||
def change
|
def change
|
||||||
create_table :budget_headings do |t|
|
create_table :budget_headings do |t|
|
||||||
t.references :budget
|
t.references :group, index: true
|
||||||
t.references :geozone
|
t.references :geozone
|
||||||
t.string :name, limit: 50
|
t.string :name, limit: 50
|
||||||
t.integer :price, limit: 8
|
t.integer :price, limit: 8
|
||||||
end
|
end
|
||||||
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.
|
# 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
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
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", ["legislation_id"], name: "index_annotations_on_legislation_id", using: :btree
|
||||||
add_index "annotations", ["user_id"], name: "index_annotations_on_user_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|
|
create_table "budget_ballot_lines", force: :cascade do |t|
|
||||||
t.integer "ballot_id"
|
t.integer "ballot_id"
|
||||||
t.integer "investment_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
|
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.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.integer "geozone_id"
|
||||||
t.string "name", limit: 50
|
t.string "name", limit: 50
|
||||||
t.integer "price", limit: 8
|
t.integer "price", limit: 8
|
||||||
end
|
end
|
||||||
|
|
||||||
|
add_index "budget_headings", ["group_id"], name: "index_budget_headings_on_group_id", using: :btree
|
||||||
|
|
||||||
create_table "budget_investments", force: :cascade do |t|
|
create_table "budget_investments", force: :cascade do |t|
|
||||||
t.integer "author_id"
|
t.integer "author_id"
|
||||||
t.integer "administrator_id"
|
t.integer "administrator_id"
|
||||||
@@ -114,13 +138,11 @@ ActiveRecord::Schema.define(version: 20160531102008) do
|
|||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.integer "heading_id"
|
t.integer "heading_id"
|
||||||
t.integer "budget_id"
|
|
||||||
t.string "responsible_name"
|
t.string "responsible_name"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree
|
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", ["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", ["heading_id"], name: "index_budget_investments_on_heading_id", using: :btree
|
||||||
add_index "budget_investments", ["tsv"], name: "index_budget_investments_on_tsv", using: :gin
|
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.boolean "valuating", default: false
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.integer "price"
|
|
||||||
end
|
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|
|
create_table "campaigns", force: :cascade do |t|
|
||||||
t.string "name"
|
t.string "name"
|
||||||
t.string "track_id"
|
t.string "track_id"
|
||||||
@@ -204,10 +210,10 @@ ActiveRecord::Schema.define(version: 20160531102008) do
|
|||||||
t.string "visit_id"
|
t.string "visit_id"
|
||||||
t.datetime "hidden_at"
|
t.datetime "hidden_at"
|
||||||
t.integer "flags_count", default: 0
|
t.integer "flags_count", default: 0
|
||||||
|
t.datetime "ignored_flag_at"
|
||||||
t.integer "cached_votes_total", default: 0
|
t.integer "cached_votes_total", default: 0
|
||||||
t.integer "cached_votes_up", default: 0
|
t.integer "cached_votes_up", default: 0
|
||||||
t.integer "cached_votes_down", default: 0
|
t.integer "cached_votes_down", default: 0
|
||||||
t.datetime "ignored_flag_at"
|
|
||||||
t.integer "comments_count", default: 0
|
t.integer "comments_count", default: 0
|
||||||
t.datetime "confirmed_hide_at"
|
t.datetime "confirmed_hide_at"
|
||||||
t.integer "cached_anonymous_votes_total", default: 0
|
t.integer "cached_anonymous_votes_total", default: 0
|
||||||
|
|||||||
@@ -191,7 +191,6 @@ FactoryGirl.define do
|
|||||||
factory :budget do
|
factory :budget do
|
||||||
sequence(:name) { |n| "Budget #{n}" }
|
sequence(:name) { |n| "Budget #{n}" }
|
||||||
currency_symbol "€"
|
currency_symbol "€"
|
||||||
price 10000
|
|
||||||
phase 'on_hold'
|
phase 'on_hold'
|
||||||
|
|
||||||
trait :selecting do
|
trait :selecting do
|
||||||
@@ -207,15 +206,20 @@ FactoryGirl.define do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :budget_heading, class: 'Budget::Heading' do
|
factory :budget_group, class: 'Budget::Group' do
|
||||||
budget
|
budget
|
||||||
|
sequence(:name) { |n| "Group #{n}" }
|
||||||
|
end
|
||||||
|
|
||||||
|
factory :budget_heading, class: 'Budget::Heading' do
|
||||||
|
association :group, factory: :budget_group
|
||||||
sequence(:name) { |n| "Heading #{n}" }
|
sequence(:name) { |n| "Heading #{n}" }
|
||||||
price 1000000
|
price 1000000
|
||||||
end
|
end
|
||||||
|
|
||||||
factory :budget_investment, class: 'Budget::Investment' do
|
factory :budget_investment, class: 'Budget::Investment' do
|
||||||
sequence(:title) { |n| "Budget Investment #{n} title" }
|
sequence(:title) { |n| "Budget Investment #{n} title" }
|
||||||
association :budget
|
association :heading, factory: :budget_heading
|
||||||
association :author, factory: :user
|
association :author, factory: :user
|
||||||
description 'Spend money on this'
|
description 'Spend money on this'
|
||||||
unfeasibility_explanation ''
|
unfeasibility_explanation ''
|
||||||
|
|||||||
@@ -65,7 +65,13 @@ describe "Abilities::Administrator" do
|
|||||||
it { should be_able_to(:update, Budget::Investment) }
|
it { should be_able_to(:update, Budget::Investment) }
|
||||||
it { should be_able_to(:hide, 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 be_able_to(:valuate, create(:budget_investment,
|
||||||
it { should_not be_able_to(:valuate, create(:budget_investment, budget: create(:budget, valuating: false))) }
|
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
|
end
|
||||||
|
|||||||
@@ -12,9 +12,16 @@ describe "Abilities::Common" do
|
|||||||
let(:accepting_budget) { create(:budget, phase: 'accepting') }
|
let(:accepting_budget) { create(:budget, phase: 'accepting') }
|
||||||
let(:selecting_budget) { create(:budget, phase: 'selecting') }
|
let(:selecting_budget) { create(:budget, phase: 'selecting') }
|
||||||
let(:balloting_budget) { create(:budget, phase: 'balloting') }
|
let(:balloting_budget) { create(:budget, phase: 'balloting') }
|
||||||
let(:investment_in_accepting_budget) { create(:budget_investment, budget: accepting_budget) }
|
let(:accepting_budget_group) { create(:budget_group, budget: accepting_budget) }
|
||||||
let(:investment_in_selecting_budget) { create(:budget_investment, budget: selecting_budget) }
|
let(:selecting_budget_group) { create(:budget_group, budget: selecting_budget) }
|
||||||
let(:investment_in_balloting_budget) { create(:budget_investment, budget: balloting_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_accepting_budget) { create(:budget_ballot, budget: accepting_budget) }
|
||||||
let(:ballot_in_selecting_budget) { create(:budget_ballot, budget: selecting_budget) }
|
let(:ballot_in_selecting_budget) { create(:budget_ballot, budget: selecting_budget) }
|
||||||
let(:ballot_in_balloting_budget) { create(:budget_ballot, budget: balloting_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(:valuator) { create(:valuator) }
|
||||||
let(:non_assigned_investment) { create(:budget_investment) }
|
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 }
|
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 }
|
before(:each) { assigned_investment_not_valuating.valuators << valuator }
|
||||||
|
|
||||||
it { should be_able_to(:read, SpendingProposal) }
|
it { should be_able_to(:read, SpendingProposal) }
|
||||||
|
|||||||
@@ -21,18 +21,15 @@ describe Budget::Ballot do
|
|||||||
heading = create(:budget_heading)
|
heading = create(:budget_heading)
|
||||||
inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading)
|
inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading)
|
||||||
inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading))
|
inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading))
|
||||||
inv3 = create(:budget_investment, :feasible, price: 25000)
|
inv3 = create(:budget_investment, :feasible, price: 40000, heading: heading)
|
||||||
inv4 = create(:budget_investment, :feasible, price: 40000, heading: heading)
|
|
||||||
|
|
||||||
ballot = create(:budget_ballot)
|
ballot = create(:budget_ballot)
|
||||||
ballot.investments << inv1
|
ballot.investments << inv1
|
||||||
ballot.investments << inv2
|
ballot.investments << inv2
|
||||||
ballot.investments << inv3
|
|
||||||
|
|
||||||
expect(ballot.amount_spent(heading.id)).to eq 10000
|
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
|
expect(ballot.amount_spent(heading.id)).to eq 50000
|
||||||
end
|
end
|
||||||
@@ -40,28 +37,22 @@ describe Budget::Ballot do
|
|||||||
|
|
||||||
describe "#amount_available" do
|
describe "#amount_available" do
|
||||||
it "returns how much is left after taking some investments" do
|
it "returns how much is left after taking some investments" do
|
||||||
budget = create(:budget, price: 200000)
|
budget = create(:budget)
|
||||||
heading = create(:budget_heading, budget: budget)
|
group = create(:budget_group, budget: budget)
|
||||||
inv1 = create(:budget_investment, :feasible, price: 10000, heading: heading)
|
heading = create(:budget_heading, group: group, price: 1000)
|
||||||
inv2 = create(:budget_investment, :feasible, price: 20000, heading: create(:budget_heading))
|
inv1 = create(:budget_investment, :feasible, price: 100, heading: heading)
|
||||||
inv3 = create(:budget_investment, :feasible, price: 25000)
|
inv2 = create(:budget_investment, :feasible, price: 200, heading: create(:budget_heading))
|
||||||
inv4 = create(:budget_investment, :feasible, price: 40000, heading: heading)
|
inv3 = create(:budget_investment, :feasible, price: 400, heading: heading)
|
||||||
|
|
||||||
inv1 = create(:budget_investment, :feasible, price: 10000)
|
|
||||||
inv2 = create(:budget_investment, :feasible, price: 20000)
|
|
||||||
|
|
||||||
ballot = create(:budget_ballot, budget: budget)
|
ballot = create(:budget_ballot, budget: budget)
|
||||||
ballot.investments << inv1
|
ballot.investments << inv1
|
||||||
ballot.investments << inv2
|
ballot.investments << inv2
|
||||||
|
|
||||||
expect(ballot.amount_available(heading)).to eq 1000000
|
expect(ballot.amount_available(heading)).to eq 900
|
||||||
expect(ballot.amount_available(nil)).to eq 170000
|
|
||||||
|
|
||||||
ballot.investments << inv3
|
ballot.investments << inv3
|
||||||
ballot.investments << inv4
|
|
||||||
|
|
||||||
expect(ballot.amount_available(heading)).to eq 960000
|
expect(ballot.amount_available(heading)).to eq 500
|
||||||
expect(ballot.amount_available(nil)).to eq 145000
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -190,38 +190,33 @@ describe Budget::Investment do
|
|||||||
|
|
||||||
describe 'Permissions' do
|
describe 'Permissions' do
|
||||||
let(:budget) { create(:budget) }
|
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(:user) { create(:user, :level_two) }
|
||||||
let(:luser) { create(:user) }
|
let(:luser) { create(:user) }
|
||||||
let(:city_sp) { create(:budget_investment, budget: budget) }
|
let(:district_sp) { create(:budget_investment, heading: heading) }
|
||||||
let(:district_sp) { create(:budget_investment, budget: budget, heading: heading) }
|
|
||||||
|
|
||||||
describe '#reason_for_not_being_selectable_by' do
|
describe '#reason_for_not_being_selectable_by' do
|
||||||
it "rejects not logged in users" 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)
|
expect(district_sp.reason_for_not_being_selectable_by(nil)).to eq(:not_logged_in)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects not verified users" do
|
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)
|
expect(district_sp.reason_for_not_being_selectable_by(luser)).to eq(:not_verified)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects organizations" do
|
it "rejects organizations" do
|
||||||
create(:organization, user: user)
|
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)
|
expect(district_sp.reason_for_not_being_selectable_by(user)).to eq(:organization)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects selections when selecting is not allowed (via admin setting)" do
|
it "rejects selections when selecting is not allowed (via admin setting)" do
|
||||||
budget.phase = "on_hold"
|
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)
|
expect(district_sp.reason_for_not_being_selectable_by(user)).to eq(:no_selecting_allowed)
|
||||||
end
|
end
|
||||||
|
|
||||||
it "accepts valid selections when selecting is allowed" do
|
it "accepts valid selections when selecting is allowed" do
|
||||||
budget.phase = "selecting"
|
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
|
expect(district_sp.reason_for_not_being_selectable_by(user)).to be_nil
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@@ -274,7 +269,9 @@ describe Budget::Investment do
|
|||||||
describe "total votes" do
|
describe "total votes" do
|
||||||
it "takes into account physical votes in addition to web votes" do
|
it "takes into account physical votes in addition to web votes" do
|
||||||
b = create(:budget, :selecting)
|
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))
|
sp.register_selection(create(:user, :level_two))
|
||||||
expect(sp.total_votes).to eq(1)
|
expect(sp.total_votes).to eq(1)
|
||||||
@@ -299,56 +296,52 @@ describe Budget::Investment do
|
|||||||
|
|
||||||
describe 'Permissions' do
|
describe 'Permissions' do
|
||||||
let(:budget) { create(:budget) }
|
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(:user) { create(:user, :level_two) }
|
||||||
let(:luser) { create(:user) }
|
let(:luser) { create(:user) }
|
||||||
let(:ballot) { create(:budget_ballot, budget: budget) }
|
let(:ballot) { create(:budget_ballot, budget: budget) }
|
||||||
let(:city_sp) { create(:budget_investment, budget: budget) }
|
let(:investment) { create(:budget_investment, heading: heading) }
|
||||||
let(:district_sp) { create(:budget_investment, budget: budget, heading: heading) }
|
|
||||||
|
|
||||||
describe '#reason_for_not_being_ballotable_by' do
|
describe '#reason_for_not_being_ballotable_by' do
|
||||||
it "rejects not logged in users" 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(investment.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)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects not verified users" do
|
it "rejects not verified users" do
|
||||||
expect(city_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)
|
||||||
expect(district_sp.reason_for_not_being_ballotable_by(luser, ballot)).to eq(:not_verified)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects organizations" do
|
it "rejects organizations" do
|
||||||
create(:organization, user: user)
|
create(:organization, user: user)
|
||||||
expect(city_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)
|
||||||
expect(district_sp.reason_for_not_being_ballotable_by(user, ballot)).to eq(:organization)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "rejects votes when voting is not allowed (via admin setting)" do
|
it "rejects votes when voting is not allowed (via admin setting)" do
|
||||||
budget.phase = "on_hold"
|
budget.phase = "on_hold"
|
||||||
expect(city_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)
|
||||||
expect(district_sp.reason_for_not_being_ballotable_by(user, ballot)).to eq(:no_ballots_allowed)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "accepts valid ballots when voting is allowed" do
|
it "accepts valid ballots when voting is allowed" do
|
||||||
budget.phase = "balloting"
|
budget.phase = "balloting"
|
||||||
expect(city_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
|
||||||
expect(district_sp.reason_for_not_being_ballotable_by(user, ballot)).to be_nil
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "accepts valid district selections" do
|
it "accepts valid district selections" do
|
||||||
budget.phase = "selecting"
|
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
|
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
|
end
|
||||||
|
|
||||||
it "rejects users with different headings" do
|
it "rejects users with different headings" do
|
||||||
budget.phase = "balloting"
|
budget.phase = "balloting"
|
||||||
california = create(:budget_heading, budget: budget)
|
group = create(:budget_group, budget: budget)
|
||||||
new_york = create(:budget_heading, budget: budget)
|
california = create(:budget_heading, group: group)
|
||||||
|
new_york = create(:budget_heading, group: group)
|
||||||
|
|
||||||
sp1 = create(:budget_investment, :feasible, heading: california, budget: budget)
|
sp1 = create(:budget_investment, :feasible, heading: california)
|
||||||
sp2 = create(:budget_investment, :feasible, heading: new_york, budget: budget)
|
sp2 = create(:budget_investment, :feasible, heading: new_york)
|
||||||
b = create(:budget_ballot, user: user, heading: california, investments: [sp1])
|
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)
|
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
|
it "rejects proposals with price higher than current available money" do
|
||||||
budget.phase = "balloting"
|
budget.phase = "balloting"
|
||||||
carabanchel = create(:budget_heading, budget: budget, price: 35)
|
distritos = create(:budget_group, budget: budget)
|
||||||
sp1 = create(:budget_investment, :feasible, heading: carabanchel, price: 30, budget: budget)
|
carabanchel = create(:budget_heading, group: distritos, price: 35)
|
||||||
sp2 = create(:budget_investment, :feasible, heading: carabanchel, price: 10, budget: budget)
|
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])
|
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)
|
expect(sp2.reason_for_not_being_ballotable_by(user, ballot)).to eq(:not_enough_money)
|
||||||
|
|||||||
@@ -33,14 +33,11 @@ describe Budget do
|
|||||||
end
|
end
|
||||||
|
|
||||||
describe "heading_price" do
|
describe "heading_price" do
|
||||||
let(:budget) { create(:budget, price: 1000) }
|
let(:budget) { create(:budget) }
|
||||||
|
let(:group) { create(:budget_group, budget: budget) }
|
||||||
it "returns the budget price if no heading is provided" do
|
|
||||||
expect(budget.heading_price(nil)).to eq(1000)
|
|
||||||
end
|
|
||||||
|
|
||||||
it "returns the heading price if the heading provided is part of the budget" do
|
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)
|
expect(budget.heading_price(heading)).to eq(100)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user