Merge pull request #1321 from consul/budgets-melchor

Budgets melchor
This commit is contained in:
Juanjo Bazán
2017-01-02 11:50:49 +01:00
committed by GitHub
39 changed files with 289 additions and 115 deletions

View File

@@ -15,7 +15,17 @@ class Admin::BudgetsController < Admin::BaseController
end
def new
@budget = Budget.new
end
def edit
end
def update
if @budget.update(budget_params)
redirect_to admin_budget_path(@budget), notice: t('admin.budgets.update.notice')
else
render :edit
end
end
def create
@@ -30,7 +40,9 @@ class Admin::BudgetsController < Admin::BaseController
private
def budget_params
params.require(:budget).permit(:name, :description, :phase, :currency_symbol)
descriptions = Budget::PHASES.map{|p| "description_#{p}"}.map(&:to_sym)
valid_attributes = [:name, :phase, :currency_symbol] + descriptions
params.require(:budget).permit(*valid_attributes)
end
end

View File

@@ -80,7 +80,7 @@ module Budgets
end
def investment_params
params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :terms_of_service)
params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :terms_of_service, :location)
end
def load_ballot

View File

@@ -1,7 +1,7 @@
module BudgetsHelper
def budget_phases_select_options
Budget::VALID_PHASES.map { |ph| [ t("budget.phase.#{ph}"), ph ] }
Budget::PHASES.map { |ph| [ t("budget.phase.#{ph}"), ph ] }
end
def budget_currency_symbol_select_options

View File

@@ -46,7 +46,7 @@ module Abilities
can [:read, :create, :update, :destroy], Budget::Group
can [:read, :create, :update, :destroy], Budget::Heading
can [:hide, :update, :toggle_selection], Budget::Investment
can :valuate, Budget::Investment, budget: { valuating: true }
can :valuate, Budget::Investment, budget: { phase: 'valuating' }
can :create, Budget::ValuatorAssignment
can [:search, :edit, :update, :create, :index, :destroy], Banner

View File

@@ -5,7 +5,7 @@ module Abilities
def initialize(user)
valuator = user.valuator
can [:read, :update, :valuate], SpendingProposal
can [:read, :update, :valuate], Budget::Investment, id: valuator.investment_ids, budget: { valuating: true }
can [:read, :update, :valuate], Budget::Investment, id: valuator.investment_ids, budget: { phase: 'valuating' }
end
end
end

View File

@@ -1,12 +1,12 @@
class Budget < ActiveRecord::Base
include Sanitizable
include Measurable
VALID_PHASES = %W{on_hold accepting selecting balloting finished}
CURRENCY_SYMBOLS = %W{€ $ £ ¥}
PHASES = %w(accepting reviewing selecting valuating balloting reviewing_ballots finished).freeze
CURRENCY_SYMBOLS = %w(€ $ £ ¥).freeze
validates :name, presence: true
validates :phase, inclusion: { in: VALID_PHASES }
validates :phase, inclusion: { in: PHASES }
validates :currency_symbol, presence: true
has_many :investments, dependent: :destroy
@@ -14,35 +14,59 @@ class Budget < ActiveRecord::Base
has_many :groups, dependent: :destroy
has_many :headings, through: :groups
scope :on_hold, -> { where(phase: "on_hold") }
before_validation :sanitize_descriptions
scope :on_hold, -> { where(phase: %w(reviewing valuating reviewing_ballots")) }
scope :accepting, -> { where(phase: "accepting") }
scope :reviewing, -> { where(phase: "reviewing") }
scope :selecting, -> { where(phase: "selecting") }
scope :valuating, -> { where(phase: "valuating") }
scope :balloting, -> { where(phase: "balloting") }
scope :reviewing_ballots, -> { where(phase: "reviewing_ballots") }
scope :finished, -> { where(phase: "finished") }
scope :current, -> { where.not(phase: "finished") }
scope :valuating, -> { where(valuating: true) }
def on_hold?
phase == "on_hold"
def description
self.send("description_#{self.phase}").try(:html_safe)
end
def self.description_max_length
2000
end
def accepting?
phase == "accepting"
end
def reviewing?
phase == "reviewing"
end
def selecting?
phase == "selecting"
end
def valuating?
phase == "valuating"
end
def balloting?
phase == "balloting"
end
def reviewing_ballots?
phase == "reviewing_ballots"
end
def finished?
phase == "finished"
end
def on_hold?
reviewing? || valuating? || reviewing_ballots?
end
def current?
!finished?
end
@@ -69,5 +93,15 @@ class Budget < ActiveRecord::Base
def formatted_heading_amount_spent(heading)
formatted_amount(amount_spent(heading))
end
private
def sanitize_descriptions
s = WYSIWYGSanitizer.new
PHASES.each do |phase|
sanitized = s.sanitize(self.send("description_#{phase}"))
self.send("description_#{phase}=", sanitized)
end
end
end

View File

@@ -0,0 +1,18 @@
<%= form_for [:admin, @budget] do |f| %>
<%= f.text_field :name, maxlength: Budget.title_max_length %>
<% Budget::PHASES.each do |phase| %>
<%= f.cktext_area "description_#{phase}", maxlength: Budget.description_max_length, ckeditor: { language: I18n.locale } %>
<% end %>
<div class="row">
<div class="small-12 medium-9 column">
<%= f.select :phase, budget_phases_select_options %>
</div>
<div class="small-12 medium-3 column">
<%= f.select :currency_symbol, budget_currency_symbol_select_options %>
</div>
</div>
<%= f.submit nil, class: "button success" %>
<% end %>

View File

@@ -0,0 +1,7 @@
<div class="row">
<div class="small-12 medium-9 column">
<h2><%= t("admin.budgets.edit.title") %></h2>
<%= render '/admin/budgets/form' %>
</div>
</div>

View File

@@ -2,28 +2,6 @@
<div class="small-12 medium-9 column">
<h2><%= t("admin.budgets.new.title") %></h2>
<%= form_for [:admin, @budget] do |f| %>
<%= f.label :name, t("admin.budgets.new.name") %>
<%= f.text_field :name,
label: false,
maxlength: 30,
placeholder: t("admin.budgets.new.name") %>
<%= f.label :description, t("admin.budgets.new.description") %>
<%= f.text_area :description, rows: 3, maxlength: 6000, label: false, placeholder: t("admin.budgets.new.description") %>
<div class="row">
<div class="small-12 medium-9 column">
<%= f.label :description, t("admin.budgets.new.phase") %>
<%= f.select :phase, budget_phases_select_options, {label: false} %>
</div>
<div class="small-12 medium-3 column">
<%= f.label :description, t("admin.budgets.new.currency") %>
<%= f.select :currency_symbol, budget_currency_symbol_select_options, {label: false} %>
</div>
</div>
<%= f.submit t("admin.budgets.new.create"), class: "button success" %>
<% end %>
<%= render '/admin/budgets/form' %>
</div>
</div>
</div>

View File

@@ -1,8 +1,8 @@
<div class="row">
<div class="small-12 medium-9 column">
<h2><%= @budget.name %></h2>
<h2><%= @budget.name %> <small><%= link_to(t('shared.edit'), edit_admin_budget_path(@budget)) %></small></h2>
<%= simple_format(text_with_links(@budget.description), {}, sanitize: false) %>
<%= @budget.description %>
<p>
<strong><%= t('admin.budgets.show.phase') %>:</strong> <%= t("budget.phase.#{@budget.phase}") %> |
@@ -13,4 +13,4 @@
<div id="<%= dom_id @budget %>_groups" class="row">
<%= render "groups", groups: @budget.groups %>
</div>
</div>

View File

@@ -24,6 +24,11 @@
<%= f.text_field :external_url, placeholder: t("budget.investments.form.external_url"), label: false %>
</div>
<div class="small-12 column">
<%= f.label :location, t("budget.investments.form.location") %>
<%= f.text_field :location, placeholder: t("budget.investments.form.location"), label: false %>
</div>
<% unless current_user.manager? %>
<div class="small-12 column">

View File

@@ -26,10 +26,15 @@
<br>
<p id="investment_code">
<%= t("budget.investments.show.code") %>
<strong><%= investment.id %></strong>
<%= t("budget.investments.show.code_html", code: investment.id) %>
</p>
<% if investment.location.present? %>
<p id="investment_code">
<%= t("budget.investments.show.location_html", location: investment.location) %>
</p>
<% end %>
<%= safe_html_with_links investment.description.html_safe %>
<% if investment.external_url.present? %>

View File

@@ -1,12 +1,18 @@
<%= link_to @budget, class: "back" do %>
<i class="icon-angle-left"></i>
<%= t("spending_proposals.index.sidebar.back") %>
<% end %>
<div class="clear"></div>
<% if @budget.accepting? %>
<% if current_user && current_user.level_two_or_three_verified? %>
<%= link_to t("budget.investments.index.sidebar.create"), new_budget_investment_path, class: "button budget expanded" %>
<% else %>
<div class="callout warning">
<%= t("budget.investments.index.sidebar.verified_only",
verify: link_to(t("budget.investments.index.sidebar.verify_account"), verification_path)).html_safe %>
</div>
<% end %>
<% end %>
<div class="sidebar-divider"></div>
<h3 class="sidebar-title"><%= t("spending_proposals.index.sidebar.my_ballot") %></h3>
<h2 class="sidebar-title"><%= t("budget.investments.index.sidebar.my_ballot") %></h2>
<% if @heading && @ballot.investments.by_heading(@heading.id).count > 0 %>
<p>

View File

@@ -9,7 +9,8 @@
<h1><%= @budget.name %>
<small><%= t("budgets.phases.#{@budget.phase}") %></small>
</h1>
<p><%= @budget.description %></p>
<%= @budget.description %>
</div>
</div>

View File

@@ -1,4 +1,4 @@
<div class="no-bullet submenu">
<ul class="no-bullet submenu">
<% @valid_orders.each do |order| %>
<li class="inline-block">
<%= link_to current_path_with_query_params(order: order, page: 1), class: order == @current_order ? 'active' : '' do %>

View File

@@ -12,7 +12,7 @@ Devise.setup do |config|
# Configure the e-mail address which will be shown in Devise::Mailer,
# note that it will be overwritten if you use your own mailer class
# with default "from" parameter.
if Rails.env.test?
if Rails.env.test? || !ActiveRecord::Base.connection.table_exists?('settings')
config.mailer_sender = "noreply@example.org"
else
config.mailer_sender = "#{Setting['mailer_from_name']} <#{Setting['mailer_from_address']}>"

View File

@@ -41,6 +41,17 @@ en:
one: "Spending proposal"
other: "Spending proposals"
attributes:
budget:
name: "Name"
description_accepting: "Description during Accepting phase"
description_reviewing: "Description during Reviewing phase"
description_selecting: "Description during Selecting phase"
description_valuating: "Description during Valuating phase"
description_balloting: "Description during Balloting phase"
description_reviewing_ballots: "Description during Reviewing Ballots phase"
description_finished: "Description when the budget is finished"
phase: "Phase"
currency_symbol: "Currency"
budget/investment:
administrator_id: "Administrator"
description: "Description"

View File

@@ -41,6 +41,17 @@ es:
one: "Propuesta de inversión"
other: "Propuestas de inversión"
attributes:
budget:
name: "Nombre"
description_accepting: "Descripción durante la fase de aceptación"
description_reviewing: "Descripción durante la fase de revisión"
description_selecting: "Descripción durante la fase de selección"
description_valuating: "Descripción durante la fase de evaluación"
description_balloting: "Descripción duratne la fase de votación"
description_reviewing_ballots: "Descripción durante la fase de revisión de votos"
description_finished: "Descripción cuando el presupuesto ha finalizado"
phase: "Fase"
currency_symbol: "Divisa"
budget/investment:
administrator_id: "Administrador"
description: "Descripción"
@@ -111,4 +122,4 @@ es:
attributes:
document_number:
not_in_census: 'No verificado por Padrón'
already_voted: 'Ya ha votado esta propuesta'
already_voted: 'Ya ha votado esta propuesta'

View File

@@ -61,30 +61,29 @@ en:
budgets:
index:
title: Participatory budgets
new_link: Create new
new_link: Create new budget
info_link: Info
filters:
open: Open
finished: Finished
create:
notice: New participatory budget created successfully!
update:
notice: Participatory budget updated successfully
edit:
title: Edit Participatory budget
new:
title: New participatory budget
create: Create budget
name: Budget's name
description: Description
phase: Phase
currency: Currency
show:
phase: Current phase
currency: Currency
groups: Groups of budget headings
form:
group: Group's name
group: Group name
no_groups: No groups created yet. Each user will be able to vote in only one heading per group.
add_group: Add new group
create_group: Create group
heading: Heading's name
heading: Heading name
add_heading: Add heading
amount: Amount
save_heading: Save heading

View File

@@ -61,20 +61,19 @@ es:
budgets:
index:
title: Presupuestos participativos
new_link: Crear nuevo
new_link: Crear nuevo presupuesto
info_link: Info
filters:
open: Abiertos
finished: Terminados
create:
notice: ¡Nueva campaña de presupuestos participativos creada con éxito!
update:
notice: Campaña de presupuestos participativos actualizada
edit:
title: Editar campaña de presupuestos participativos
new:
title: Nuevo presupuesto ciudadano
create: Crear presupuesto
name: Nombre del presupuesto
description: Descripción
phase: Fase
currency: Divisa
show:
phase: Fase actual
currency: Divisa

View File

@@ -24,10 +24,12 @@ en:
title: Select a heading
budget:
phase:
on_hold: On hold
accepting: Accepting proposals
reviewing: Reviewing proposals
selecting: Selecting
valuating: Valuating
balloting: Balloting
reviewing_ballots: Reviewing Ballots
finished: Finished
groups:
index:
@@ -36,7 +38,7 @@ en:
none: Whole City
all: All scopes
index:
name: Budget's name
name: Budget name
phase: Phase
title: Participatory budgets
investments:
@@ -46,6 +48,7 @@ en:
description: Description
external_url: Link to additional documentation
heading: Choose if a proposed citywide or district
location: "Location"
submit_buttons:
create: Create
new: Create
@@ -79,6 +82,9 @@ en:
votes: Supports remaining
votes_district: "You can only vote in the district %{district}"
zero: You have not voted any investment project.
verified_only: "To create a new budget investment %{verify}."
verify_account: "verify your account"
create: "Create budget investment"
orders:
random: random
confidence_score: highest rated
@@ -96,7 +102,9 @@ en:
author_deleted: User deleted
price_explanation: Price explanation
unfeasibility_explanation: Unfeasibility explanation
code: 'Investment project code:'
code_html: 'Investment project code: <strong>%{code}</strong>'
location_html: 'Location: <strong>%{location}</strong>'
location: Location
share: Share
wrong_price_format: Only integer numbers
investment:

View File

@@ -24,10 +24,12 @@ es:
title: Selecciona una partida
budget:
phase:
on_hold: En pausa
accepting: Aceptando propuestas
reviewing: Revisando propuestas
selecting: Fase de selección
balloting: Fase de Votación
valuating: Fase de evaluación de propuestas
balloting: Fase de votación
reviewing_ballots: Contando resultados
finished: Terminado
groups:
index:
@@ -46,6 +48,7 @@ es:
description: Descripción detallada
external_url: Enlace a documentación adicional
heading: "Elige si es una propuesta para toda la ciudad o para un distrito"
location: "Ubicación de la propuesta"
submit_buttons:
create: Crear
new: Crear
@@ -79,6 +82,9 @@ es:
votes: Apoyos restantes
votes_district: "Solo puedes votar en el distrito %{district}"
zero: "Todavía no has votado ninguna propuesta de inversión."
verified_only: "Para crear una nueva propuesta de inversión %{verify}."
verify_account: "verifica tu cuenta"
create: "Crear propuesta de inversión"
orders:
random: Aleatorias
confidence_score: Mejor valoradas
@@ -96,7 +102,8 @@ es:
author_deleted: Usuario eliminado
price_explanation: Informe de coste
unfeasibility_explanation: Informe de inviabilidad
code: 'Código propuesta de gasto:'
code_html: 'Código propuesta de gasto: <strong>%{code}</strong>'
location_html: 'Ubicación: <strong>%{location}</strong>'
share: Compartir
wrong_price_format: Solo puede incluir caracteres numéricos
investment:

View File

@@ -441,6 +441,7 @@ en:
collective: Collective
flag: Flag as inappropriate
hide: Hide
edit: Editar
print:
print_button: Print this info
search: Search
@@ -499,11 +500,9 @@ en:
one: " containing the term '%{search_term}'"
other: " containing the term '%{search_term}'"
sidebar:
back: Volver
geozones: Scope of operation
feasibility: Feasibility
unfeasible: Unfeasible
my_ballot: My votes
start_spending_proposal: Create an investment project
new:
more_info: How do participatory budgeting works?

View File

@@ -445,6 +445,7 @@ es:
print_button: Imprimir esta información
search: Buscar
show: Mostrar
edit: Editar
suggest:
debate:
found:
@@ -499,11 +500,9 @@ es:
one: " que contiene '%{search_term}'"
other: " que contienen '%{search_term}'"
sidebar:
back: Volver
geozones: Ámbitos de actuación
feasibility: Viabilidad
unfeasible: No viables
my_ballot: Mis votos
start_spending_proposal: Crea una propuesta de inversión
new:
more_info: "¿Cómo funcionan los presupuestos participativos?"

View File

@@ -327,19 +327,23 @@ end
puts "Creating Budgets"
phases = %w{on_hold accepting selecting balloting finished}
phases.each_with_index do |phase, i|
budget = Budget.create!(name: (Date.today.year - 10 + i).to_s,
description: "<p>#{Faker::Lorem.paragraphs.join('</p><p>')}</p>",
currency_symbol: "",
phase: phase,
valuating: [false, true].sample)
Budget::PHASES.each_with_index do |phase, i|
descriptions = Hash[Budget::PHASES.map{ |p| ["description_#{p}",
"<p>#{Faker::Lorem.paragraphs(2).join('</p><p>')}</p>"] }]
budget = Budget.create!(
descriptions.merge(
name: (Date.current - 10 + i).to_s,
currency_symbol: "",
phase: phase
)
)
puts budget.name
(1..[1,2,3].sample).each do |i|
(1..([1, 2, 3].sample)).each do
group = budget.groups.create!(name: Faker::StarWars.planet)
geozones = Geozone.reorder("RANDOM()").limit([2,5,6,7].sample)
geozones = Geozone.reorder("RANDOM()").limit([2, 5, 6, 7].sample)
geozones.each do |geozone|
group.headings << group.headings.create!(name: geozone.name,
geozone: geozone,

View File

@@ -0,0 +1,5 @@
class AddLocationToBudgetInvestments < ActiveRecord::Migration
def change
add_column :budget_investments, :location, :string
end
end

View File

@@ -0,0 +1,5 @@
class RemoveValuatingFromBudgets < ActiveRecord::Migration
def change
remove_column :budgets, :valuating, :bool
end
end

View File

@@ -0,0 +1,12 @@
class ChangeBudgetDescription < ActiveRecord::Migration
def change
remove_column :budgets, :description, :text
add_column :budgets, :description_accepting, :text
add_column :budgets, :description_reviewing, :text
add_column :budgets, :description_selecting, :text
add_column :budgets, :description_valuating, :text
add_column :budgets, :description_balloting, :text
add_column :budgets, :description_reviewing_ballots, :text
add_column :budgets, :description_finished, :text
end
end

View File

@@ -0,0 +1,5 @@
class AdjustBudgetFields < ActiveRecord::Migration
def change
change_column :budgets, :phase, :string, limit: 40, default: 'accepting'
end
end

View File

@@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20161221172447) do
ActiveRecord::Schema.define(version: 20170102080432) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -142,6 +142,7 @@ ActiveRecord::Schema.define(version: 20161221172447) do
t.integer "budget_id"
t.integer "group_id"
t.boolean "selected", default: false
t.string "location"
end
add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree
@@ -159,13 +160,18 @@ ActiveRecord::Schema.define(version: 20161221172447) do
add_index "budget_valuator_assignments", ["investment_id"], name: "index_budget_valuator_assignments_on_investment_id", using: :btree
create_table "budgets", force: :cascade do |t|
t.string "name", limit: 30
t.text "description"
t.string "currency_symbol", limit: 10
t.string "phase", limit: 15, default: "on_hold"
t.boolean "valuating", default: false
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.string "name", limit: 30
t.string "currency_symbol", limit: 10
t.string "phase", limit: 40, default: "accepting"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.text "description_accepting"
t.text "description_reviewing"
t.text "description_selecting"
t.text "description_valuating"
t.text "description_balloting"
t.text "description_reviewing_ballots"
t.text "description_finished"
end
create_table "campaigns", force: :cascade do |t|
@@ -572,7 +578,7 @@ ActiveRecord::Schema.define(version: 20161221172447) do
t.boolean "email_digest", default: true
t.boolean "email_on_direct_message", default: true
t.boolean "official_position_badge", default: false
t.datetime "password_changed_at", default: '2016-12-21 17:55:08', null: false
t.datetime "password_changed_at", default: '2016-11-02 13:51:14', null: false
t.boolean "created_from_signature", default: false
end

View File

@@ -195,20 +195,39 @@ FactoryGirl.define do
factory :budget do
sequence(:name) { |n| "Budget #{n}" }
currency_symbol ""
phase 'on_hold'
phase 'accepting'
description_accepting "This budget is accepting"
description_reviewing "This budget is reviewing"
description_selecting "This budget is selecting"
description_valuating "This budget is valuating"
description_balloting "This budget is balloting"
description_reviewing_ballots "This budget is reviewing ballots"
description_finished "This budget is finished"
trait :accepting do
phase 'accepting'
end
trait :reviewing do
phase 'reviewing'
end
trait :selecting do
phase 'selecting'
end
trait :valuating do
phase 'valuating'
end
trait :balloting do
phase 'balloting'
end
trait :reviewing_ballots do
phase 'reviewing_ballots'
end
trait :finished do
phase 'finished'
end

View File

@@ -80,13 +80,13 @@ feature 'Admin budgets' do
scenario 'Create budget' do
visit admin_budgets_path
click_link 'Create new'
click_link 'Create new budget'
fill_in 'budget_name', with: 'M30 - Summer campaign'
fill_in 'budget_description', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30'
fill_in 'budget_description_accepting', with: 'Budgeting for summer 2017 maintenance and improvements of the road M-30'
select 'Accepting proposals', from: 'budget[phase]'
click_button 'Create budget'
click_button 'Create Participatory budget'
expect(page).to have_content 'New participatory budget created successfully!'
expect(page).to have_content 'M30 - Summer campaign'
@@ -94,10 +94,10 @@ feature 'Admin budgets' do
scenario 'Name is mandatory' do
visit new_admin_budget_path
click_button 'Create budget'
click_button 'Create Participatory budget'
expect(page).to_not have_content 'New participatory budget created successfully!'
expect(page).to have_css("label.error", text: "Budget's name")
expect(page).to have_css("label.error", text: "Name")
end
end

View File

@@ -582,7 +582,7 @@ feature 'Ballots' do
end
scenario "Balloting is disabled when budget isn't in the balotting phase", :js do
budget.update(phase: 'on_hold')
budget.update(phase: 'accepting')
bi1 = create(:budget_investment, :selected, heading: california, price: 600)

View File

@@ -88,7 +88,7 @@ feature 'Votes' do
scenario 'Disable voting on spending proposals', :js do
login_as(@manuela)
budget.update(phase: "on_hold")
budget.update(phase: "reviewing")
investment = create(:budget_investment, budget: budget, heading: heading)
visit budget_investments_path(budget, heading_id: heading.id)

View File

@@ -5,7 +5,7 @@ feature 'Valuation budget investments' do
background do
@valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@valuators.org'))
login_as(@valuator.user)
@budget = create(:budget, valuating: true)
@budget = create(:budget, :valuating)
end
scenario 'Disabled with a feature flag' do
@@ -392,4 +392,4 @@ feature 'Valuation budget investments' do
expect(page).to have_content('Only integer numbers', count: 2)
end
end
end
end

View File

@@ -65,7 +65,7 @@ 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, budget: create(:budget, phase: 'valuating'))) }
it { should_not be_able_to(:valuate, create(:budget_investment, budget: create(:budget, phase: 'finished'))) }
end

View File

@@ -7,10 +7,10 @@ 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, budget: create(:budget, phase: 'valuating')) }
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, budget: create(:budget, phase: 'finished')) }
before(:each) { assigned_investment_not_valuating.valuators << valuator }
it { should be_able_to(:read, SpendingProposal) }

View File

@@ -318,8 +318,8 @@ describe Budget::Investment do
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"
it "rejects votes when voting is not allowed (wrong phase)" do
budget.phase = "reviewing"
expect(investment.reason_for_not_being_ballotable_by(user, ballot)).to eq(:no_ballots_allowed)
end

View File

@@ -1,11 +1,24 @@
require 'rails_helper'
describe Budget do
describe "description" do
it "changes depending on the phase" do
budget = create(:budget)
Budget::PHASES.each do |phase|
budget.phase = phase
expect(budget.description).to eq(budget.send("description_#{phase}"))
expect(budget.description).to be_html_safe
end
end
end
describe "phase" do
let(:budget) { create(:budget) }
it "is validated" do
Budget::VALID_PHASES.each do |phase|
Budget::PHASES.each do |phase|
budget.phase = phase
expect(budget).to be_valid
end
@@ -15,18 +28,24 @@ describe Budget do
end
it "produces auxiliary methods" do
budget.phase = "on_hold"
expect(budget).to be_on_hold
budget.phase = "accepting"
expect(budget).to be_accepting
budget.phase = "reviewing"
expect(budget).to be_reviewing
budget.phase = "selecting"
expect(budget).to be_selecting
budget.phase = "valuating"
expect(budget).to be_valuating
budget.phase = "balloting"
expect(budget).to be_balloting
budget.phase = "reviewing_ballots"
expect(budget).to be_reviewing_ballots
budget.phase = "finished"
expect(budget).to be_finished
end