Merge branch 'master' into budgets-ui

This commit is contained in:
decabeza
2018-01-11 17:05:28 +01:00
58 changed files with 861 additions and 610 deletions

View File

@@ -8,10 +8,12 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
### Added
- Added Drafting phase to Budgets https://github.com/consul/consul/pull/2285
- Added 'Publish investments price' phase to Budgets https://github.com/consul/consul/pull/2296
- Allow admins to destroy budgets without investments https://github.com/consul/consul/pull/2283
- Added rubocop-rspec gem, enabled cops one by one fixing offenses.
- Added CSV download link to budget_investments https://github.com/consul/consul/pull/2147
- Added Capistrano task to automate maintenance mode https://github.com/consul/consul/pull/1932
- Added actions to edit and delete a budget's headings https://github.com/consul/consul/pull/1917
### Changed
- Updated multiple minor & patch gem versions thanks to [Depfu](https://depfu.com)
@@ -21,6 +23,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Redirect admin to budget lists after edit https://github.com/consul/consul/pull/2284
- Improve budget investment form https://github.com/consul/consul/pull/2280
- Prevent edition of investments if budget is in the final phase https://github.com/consul/consul/pull/2223
- Split 'routes.rb' file into multiple small files https://github.com/consul/consul/pull/1908
### Deprecated

View File

@@ -3,12 +3,33 @@ class Admin::BudgetHeadingsController < Admin::BaseController
feature_flag :budgets
def create
@budget = Budget.find params[:budget_id]
@budget_group = @budget.groups.find params[:budget_group_id]
@budget = Budget.find(params[:budget_id])
@budget_group = @budget.groups.find(params[:budget_group_id])
@budget_group.headings.create(budget_heading_params)
@headings = @budget_group.headings
end
def edit
@budget = Budget.find(params[:budget_id])
@budget_group = @budget.groups.find(params[:budget_group_id])
@heading = Budget::Heading.find(params[:id])
end
def update
@budget = Budget.find(params[:budget_id])
@budget_group = @budget.groups.find(params[:budget_group_id])
@heading = Budget::Heading.find(params[:id])
@heading.assign_attributes(budget_heading_params)
render :edit unless @heading.save
end
def destroy
@heading = Budget::Heading.find(params[:id])
@heading.destroy
@budget = Budget.find(params[:budget_id])
redirect_to admin_budget_path(@budget)
end
private
def budget_heading_params

View File

@@ -16,7 +16,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController
respond_to do |format|
format.html
format.csv do
send_data Budget::Investment.to_csv(@investments, {headers: true}),
send_data Budget::Investment.to_csv(@investments, headers: true),
filename: 'budget_investments.csv'
end
end

View File

@@ -6,26 +6,6 @@ module BudgetsHelper
csv_params
end
def investment_selected_link(investment)
options = investment_selected_link_options(investment)
path = toggle_selection_admin_budget_budget_investment_path(@budget,
investment, filter: params[:filter], page: params[:page])
link_options = {method: :patch, remote: true, class: options[:link_class]}
link_to options[:text], path, link_options
end
def investment_selected_link_options(investment)
if investment.selected?
{link_class: "button small expanded",
text: t("admin.budget_investments.index.selected") }
elsif investment.feasible? && investment.valuation_finished?
{link_class: "button small hollow expanded",
text: t("admin.budget_investments.index.select")}
else
{}
end
end
def budget_phases_select_options
Budget::PHASES.map { |ph| [ t("budgets.phase.#{ph}"), ph ] }
end

View File

@@ -3,8 +3,11 @@ class Budget < ActiveRecord::Base
include Measurable
include Sluggable
PHASES = %w(drafting accepting reviewing selecting valuating balloting
reviewing_ballots finished).freeze
PHASES = %w(drafting accepting reviewing selecting valuating publishing_prices
balloting reviewing_ballots finished).freeze
ON_HOLD_PHASES = %w(reviewing valuating publishing_prices reviewing_ballots).freeze
PUBLISHED_PRICES_PHASES = %w(publishing_prices balloting reviewing_ballots finished).freeze
CURRENCY_SYMBOLS = %w(€ $ £ ¥).freeze
validates :name, presence: true, uniqueness: true
@@ -19,17 +22,18 @@ class Budget < ActiveRecord::Base
before_validation :sanitize_descriptions
scope :on_hold, -> { where(phase: %w(reviewing valuating reviewing_ballots")) }
scope :drafting, -> { where(phase: "drafting") }
scope :on_hold, -> { where(phase: ON_HOLD_PHASES) }
scope :drafting, -> { where(phase: "drafting") }
scope :accepting, -> { where(phase: "accepting") }
scope :reviewing, -> { where(phase: "reviewing") }
scope :selecting, -> { where(phase: "selecting") }
scope :valuating, -> { where(phase: "valuating") }
scope :publishing_prices, -> { where(phase: "publishing_prices") }
scope :balloting, -> { where(phase: "balloting") }
scope :reviewing_ballots, -> { where(phase: "reviewing_ballots") }
scope :finished, -> { where(phase: "finished") }
scope :finished, -> { where(phase: "finished") }
scope :current, -> { where.not(phase: "finished") }
scope :current, -> { where.not(phase: "finished") }
def description
send("description_#{phase}").try(:html_safe)
@@ -63,6 +67,10 @@ class Budget < ActiveRecord::Base
phase == "valuating"
end
def publishing_prices?
phase == "publishing_prices"
end
def balloting?
phase == "balloting"
end
@@ -75,6 +83,10 @@ class Budget < ActiveRecord::Base
phase == "finished"
end
def published_prices?
PUBLISHED_PRICES_PHASES.include?(phase)
end
def balloting_process?
balloting? || reviewing_ballots?
end
@@ -84,7 +96,7 @@ class Budget < ActiveRecord::Base
end
def on_hold?
reviewing? || valuating? || reviewing_ballots?
ON_HOLD_PHASES.include?(phase)
end
def current?
@@ -118,7 +130,7 @@ class Budget < ActiveRecord::Base
case phase
when 'accepting', 'reviewing'
%w{random}
when 'balloting', 'reviewing_ballots'
when 'publishing_prices', 'balloting', 'reviewing_ballots'
%w{random price}
else
%w{random confidence_score}

View File

@@ -21,7 +21,11 @@ class Budget
end
def name_exists_in_budget_headings
group.budget.headings.where(name: name).any?
group.budget.headings.where(name: name).where.not(id: id).any?
end
def can_be_deleted?
investments.empty?
end
end

View File

@@ -240,15 +240,11 @@ class Budget
end
def should_show_price?
feasible? &&
selected? &&
(budget.reviewing_ballots? || budget.finished?)
selected? && price.present? && budget.published_prices?
end
def should_show_price_info?
feasible? &&
price_explanation.present? &&
(budget.balloting? || budget.reviewing_ballots? || budget.finished?)
def should_show_price_explanation?
should_show_price? && price_explanation.present?
end
def formatted_price

View File

@@ -0,0 +1,7 @@
<div id='error_explanation' class='callout alert'>
<ul>
<% errors.each do |error| %>
<li><%= error %></li>
<% end %>
</ul>
</div>

View File

@@ -0,0 +1 @@
$("#heading-<%=@heading.id%>").html("<td colspan='4'><%= j render("admin/budgets/heading_form", group: @budget_group, budget: @budget, heading: @heading) %></td>");

View File

@@ -0,0 +1 @@
$("#<%= dom_id(@budget_group) %>").html('<%= j render("admin/budgets/group", group: @budget_group, headings: @budget_group.headings) %>');

View File

@@ -3,7 +3,8 @@
class: "float-right small" %>
<% if @investments.any? %>
<h3 class="inline-block"><%= page_entries_info @investments %></h3>
<h3><%= page_entries_info @investments %></h3>
<table>
<thead>
<tr>
@@ -28,14 +29,20 @@
<strong><%= investment.id %></strong>
</td>
<td>
<%= link_to investment.title, admin_budget_budget_investment_path(budget_id: @budget.id, id: investment.id, params: Budget::Investment.filter_params(params)) %>
<%= link_to investment.title,
admin_budget_budget_investment_path(budget_id: @budget.id,
id: investment.id,
params: Budget::Investment.filter_params(params)),
target: "_blank" %>
</td>
<td class="text-center">
<%= investment.total_votes %>
</td>
<td class="small">
<% if investment.administrator.present? %>
<span title="<%= t('admin.budget_investments.index.assigned_admin') %>"><%= investment.administrator.name %></span>
<span title="<%= t('admin.budget_investments.index.assigned_admin') %>">
<%= investment.administrator.name %>
</span>
<% else %>
<%= t("admin.budget_investments.index.no_admin_assigned") %>
<% end %>
@@ -59,7 +66,27 @@
<%= investment.valuation_finished? ? t('shared.yes'): t('shared.no') %>
</td>
<td class="small">
<%= investment_selected_link(investment) %>
<% if investment.selected? %>
<%= link_to_unless investment.budget.finished?,
t("admin.budget_investments.index.selected"),
toggle_selection_admin_budget_budget_investment_path(@budget,
investment,
filter: params[:filter],
page: params[:page]),
method: :patch,
remote: true,
class: "button small expanded" %>
<% elsif investment.feasible? && investment.valuation_finished? %>
<%= link_to_unless investment.budget.finished?,
t("admin.budget_investments.index.select"),
toggle_selection_admin_budget_budget_investment_path(@budget,
investment,
filter: params[:filter],
page: params[:page]),
method: :patch,
remote: true,
class: "button small hollow expanded" %>
<% end %>
</td>
<% if params[:filter] == 'selected' %>
<td class="small text-center">

View File

@@ -1,7 +1,7 @@
<table>
<thead>
<tr>
<th colspan="3" class="with-button">
<th colspan="4" class="with-button">
<%= group.name %>
<%= link_to t("admin.budgets.form.add_heading"), "#", class: "button float-right js-toggle-link", data: { "toggle-selector" => "#group-#{group.id}-new-heading-form" } %>
</th>
@@ -11,7 +11,7 @@
</thead>
<tbody>
<tr>
<td colspan="3">
<td colspan="4">
<div class="callout primary">
<%= t("admin.budgets.form.no_heading") %>
</div>
@@ -22,6 +22,7 @@
<th><%= t("admin.budgets.form.table_heading") %></th>
<th><%= t("admin.budgets.form.table_amount") %></th>
<th><%= t("admin.budgets.form.table_population") %></th>
<th><%= t("admin.actions.actions") %></th>
</tr>
</thead>
<tbody>
@@ -29,62 +30,14 @@
<!-- new heading form -->
<tr id="group-<%= group.id %>-new-heading-form" style="display:none">
<td colspan="3">
<%= form_for [:admin, @budget, group, Budget::Heading.new], remote: true do |f| %>
<label><%= t("admin.budgets.form.heading") %></label>
<%= f.text_field :name,
label: false,
maxlength: 50,
placeholder: t("admin.budgets.form.heading") %>
<div class="row">
<div class="small-12 medium-6 column">
<label><%= t("admin.budgets.form.amount") %></label>
<%= f.text_field :price,
label: false,
maxlength: 8,
placeholder: t("admin.budgets.form.amount") %>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 column">
<label><%= t("admin.budgets.form.population") %></label>
<p class="help-text" id="budgets-population-help-text">
<%= t("admin.budgets.form.population_help_text") %>
</p>
<%= f.number_field :population,
label: false,
maxlength: 8,
min: 1,
placeholder: t("admin.budgets.form.population"),
data: {toggle_focus: "population-info"},
aria: {describedby: "budgets-population-help-text"} %>
</div>
<div class="small-12 medium-6 column " >
<div id="population-info" class="is-hidden" data-toggler="is-hidden">
<%= t("admin.budgets.form.population_info") %>
</div>
</div>
</div>
<%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %>
<% end %>
<td colspan="4">
<%= render "admin/budgets/heading_form", group: group, budget: @budget, heading: Budget::Heading.new %>
</td>
</tr>
<!-- /. new heading form -->
<!-- headings list -->
<% headings.each do |heading| %>
<tr>
<td>
<%= heading.name %>
</td>
<td>
<%= heading.price %>
</td>
<td>
<%= heading.population %>
</td>
</tr>
<%= render "admin/budgets/heading", group: group, budget: @budget, heading: heading %>
<% end %>
<!-- /. headings list -->
</tbody>

View File

@@ -0,0 +1,27 @@
<tr id="heading-<%=heading.id%>">
<td>
<%= heading.name %>
</td>
<td>
<%= heading.price %>
</td>
<td>
<%= heading.population %>
</td>
<td>
<%= link_to t("admin.actions.edit"),
edit_admin_budget_budget_group_budget_heading_path(budget_id: group.budget.id, budget_group_id: group.id, id: heading.id),
class: "button hollow",
remote: true %>
<%= link_to t("admin.budget_investments.index.title"),
admin_budget_budget_investments_path(budget_id: group.budget.id, heading_id: heading.id),
class: "button hollow" %>
<% if heading.can_be_deleted? %>
<%= link_to t('admin.administrators.administrator.delete'),
#admin_budget_budget_group_budget_headings_path(group.budget.id, group.id),
[:admin, group.budget, group, heading],
method: :delete,
class: "button hollow alert" %>
<% end %>
</td>
</tr>

View File

@@ -0,0 +1,35 @@
<%= form_for [:admin, budget, group, heading], remote: true do |f| %>
<%= render 'shared/errors', resource: heading %>
<label><%= t("admin.budgets.form.heading") %></label>
<%= f.text_field :name,
label: false,
maxlength: 50,
placeholder: t("admin.budgets.form.heading") %>
<div class="row">
<div class="small-12 medium-6 column">
<label><%= t("admin.budgets.form.amount") %></label>
<%= f.text_field :price,
label: false,
maxlength: 8,
placeholder: t("admin.budgets.form.amount") %>
</div>
</div>
<div class="row">
<div class="small-12 medium-6 column">
<label><%= t("admin.budgets.form.population") %></label>
<%= f.text_field :population,
label: false,
maxlength: 8,
placeholder: t("admin.budgets.form.population"),
data: {toggle_focus: "population-info"} %>
</div>
<div class="small-12 medium-6 column " >
<div id="population-info" class="is-hidden" data-toggler="is-hidden">
<%= t("admin.budgets.form.population_info") %>
</div>
</div>
</div>
<%= f.submit t("admin.budgets.form.save_heading"), class: "button success" %>
<% end %>

View File

@@ -64,7 +64,7 @@
<p><%= investment.unfeasibility_explanation %></p>
<% end %>
<% if investment.should_show_price_info? %>
<% if investment.should_show_price_explanation? %>
<h2><%= t('budgets.investments.show.price_explanation') %></h2>
<p><%= investment.price_explanation %></p>
<% end %>

View File

@@ -0,0 +1,5 @@
class ActionDispatch::Routing::Mapper
def draw(route_file)
instance_eval(File.read(Rails.root.join("config/routes/#{route_file}.rb")))
end
end

View File

@@ -125,6 +125,10 @@ en:
title: "Title"
description: "Description"
publication_date: "Publication date"
budget/heading:
name: "Heading name"
price: "Price"
population: "Population"
comment:
body: "Comment"
user: "User"

View File

@@ -141,6 +141,7 @@ en:
undecided: "Undecided"
selected: "Selected"
select: "Select"
download_current_selection: "Download current selection"
table_id: "ID"
table_title: "Title"
table_supports: "Supports"

View File

@@ -34,6 +34,7 @@ en:
reviewing: Reviewing projects
selecting: Selecting projects
valuating: Valuating projects
publishing_prices: Publishing projects prices
balloting: Balloting projects
reviewing_ballots: Reviewing Ballots
finished: Finished budget

View File

@@ -177,6 +177,7 @@ en:
proposal_notification: "Notification"
spending_proposal: Spending proposal
budget/investment: Investment
budget/heading: Budget Heading
poll/shift: Shift
poll/question/answer: Answer
user: Account

View File

@@ -116,6 +116,10 @@ es:
organization_name: "Si estás proponiendo en nombre de una organización o colectivo, escribe su nombre"
image: "Imagen descriptiva de la propuesta de inversión"
image_title: "Título de la imagen"
budget/heading:
name: "Nombre de la partida"
price: "Cantidad"
population: "Población"
budget/investment/milestone:
title: "Título"
description: "Descripción"

View File

@@ -141,6 +141,7 @@ es:
undecided: "Sin decidir"
selected: "Seleccionada"
select: "Seleccionar"
download_current_selection: "Descargar selección actual"
table_id: "ID"
table_title: "Título"
table_supports: "Apoyos"

View File

@@ -34,6 +34,7 @@ es:
reviewing: Revisión interna de proyectos
selecting: Fase de apoyos
valuating: Evaluación de proyectos
publishing_prices: Publicación de precios
balloting: Votación final
reviewing_ballots: Votación finalizada
finished: Resultados

View File

@@ -177,6 +177,7 @@ es:
proposal_notification: "la notificación"
spending_proposal: la propuesta de gasto
budget/investment: la propuesta de inversión
budget/heading: la partida presupuestaria
poll/shift: el turno
poll/question/answer: la respuesta
user: la cuenta

View File

@@ -5,484 +5,47 @@ Rails.application.routes.draw do
get '/sandbox/*template' => 'sandbox#show'
end
devise_for :users, controllers: {
registrations: 'users/registrations',
sessions: 'users/sessions',
confirmations: 'users/confirmations',
omniauth_callbacks: 'users/omniauth_callbacks'
}
devise_for :organizations, class_name: 'User',
controllers: {
registrations: 'organizations/registrations',
sessions: 'devise/sessions'
},
skip: [:omniauth_callbacks]
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
devise_scope :organization do
get 'organizations/sign_up/success', to: 'organizations/registrations#success'
end
devise_scope :user do
patch '/user/confirmation', to: 'users/confirmations#update', as: :update_user_confirmation
get '/user/registrations/check_username', to: 'users/registrations#check_username'
get 'users/sign_up/success', to: 'users/registrations#success'
get 'users/registrations/delete_form', to: 'users/registrations#delete_form'
delete 'users/registrations', to: 'users/registrations#delete'
get :finish_signup, to: 'users/registrations#finish_signup'
patch :do_finish_signup, to: 'users/registrations#do_finish_signup'
end
draw :account
draw :admin
draw :annotation
draw :budget
draw :comment
draw :community
draw :debate
draw :devise
draw :direct_upload
draw :document
draw :graphql
draw :legislation
draw :management
draw :moderation
draw :notification
draw :officing
draw :poll
draw :proposal
draw :related_content
draw :tag
draw :user
draw :valuation
draw :verification
root 'welcome#index'
get '/welcome', to: 'welcome#welcome'
get '/cuentasegura', to: 'welcome#verification', as: :cuentasegura
get '/consul.json', to: "installation#details"
resources :debates do
member do
post :vote
put :flag
put :unflag
put :mark_featured
put :unmark_featured
end
collection do
get :map
get :suggest
end
end
resources :proposals do
member do
post :vote
post :vote_featured
put :flag
put :unflag
get :retire_form
get :share
patch :retire
end
collection do
get :map
get :suggest
get :summary
end
end
resources :comments, only: [:create, :show], shallow: true do
member do
post :vote
put :flag
put :unflag
end
end
resources :budgets, only: [:show, :index] do
resources :groups, controller: "budgets/groups", only: [:show]
resources :investments, controller: "budgets/investments", only: [:index, :new, :create, :show, :destroy] do
member do
post :vote
end
collection { get :suggest }
end
resource :ballot, only: :show, controller: "budgets/ballots" do
resources :lines, controller: "budgets/ballot/lines", only: [:create, :destroy]
end
resource :results, only: :show, controller: "budgets/results"
end
scope '/participatory_budget' do
resources :spending_proposals, only: [:index, :new, :create, :show, :destroy], path: 'investment_projects' do
post :vote, on: :member
end
end
resources :stats, only: [:index]
resources :images, only: [:destroy]
resources :documents, only: [:destroy]
resources :follows, only: [:create, :destroy]
resources :documents, only: [:destroy]
resources :images, only: [:destroy]
resources :direct_uploads, only: [:create]
delete "direct_uploads/destroy", to: "direct_uploads#destroy", as: :direct_upload_destroy
resources :stats, only: [:index]
resources :legacy_legislations, only: [:show], path: 'legislations'
resources :annotations do
get :search, on: :collection
end
resources :polls, only: [:show, :index] do
member do
get :stats
get :results
end
resources :questions, controller: 'polls/questions', shallow: true do
post :answer, on: :member
end
end
namespace :legislation do
resources :processes, only: [:index, :show] do
member do
get :debate
get :draft_publication
get :allegations
get :result_publication
get :proposals
end
resources :questions, only: [:show] do
resources :answers, only: [:create]
end
resources :proposals do
member do
post :vote
put :flag
put :unflag
end
collection do
get :map
get :suggest
end
end
resources :draft_versions, only: [:show] do
get :go_to_version, on: :collection
get :changes
resources :annotations do
get :search, on: :collection
get :comments
post :new_comment
end
end
end
end
resources :users, only: [:show] do
resources :direct_messages, only: [:new, :create, :show]
end
resource :account, controller: "account", only: [:show, :update, :delete] do
get :erase, on: :collection
end
resources :notifications, only: [:index, :show] do
put :mark_all_as_read, on: :collection
end
resources :proposal_notifications, only: [:new, :create, :show]
resource :verification, controller: "verification", only: [:show]
resources :communities, only: [:show] do
resources :topics
end
scope module: :verification do
resource :residence, controller: "residence", only: [:new, :create]
resource :sms, controller: "sms", only: [:new, :create, :edit, :update]
resource :verified_user, controller: "verified_user", only: [:show]
resource :email, controller: "email", only: [:new, :show, :create]
resource :letter, controller: "letter", only: [:new, :create, :show, :edit, :update]
end
resources :tags do
collection do
get :suggest
end
end
namespace :admin do
root to: "dashboard#index"
resources :organizations, only: :index do
get :search, on: :collection
member do
put :verify
put :reject
end
end
resources :hidden_users, only: [:index, :show] do
member do
put :restore
put :confirm_hide
end
end
resources :debates, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :proposals, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :spending_proposals, only: [:index, :show, :edit, :update] do
member do
patch :assign_admin
patch :assign_valuators
end
get :summary, on: :collection
end
resources :budgets do
member do
put :calculate_winners
end
resources :budget_groups do
resources :budget_headings do
end
end
resources :budget_investments, only: [:index, :show, :edit, :update] do
resources :budget_investment_milestones
member { patch :toggle_selection }
end
end
resources :signature_sheets, only: [:index, :new, :create, :show]
resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do
collection { get :search}
end
resources :comments, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :tags, only: [:index, :create, :update, :destroy]
resources :officials, only: [:index, :edit, :update, :destroy] do
get :search, on: :collection
end
resources :settings, only: [:index, :update]
put :update_map, to: "settings#update_map"
resources :moderators, only: [:index, :create, :destroy] do
get :search, on: :collection
end
resources :valuators, only: [:index, :create, :destroy] do
get :search, on: :collection
get :summary, on: :collection
end
resources :managers, only: [:index, :create, :destroy] do
get :search, on: :collection
end
resources :administrators, only: [:index, :create, :destroy] do
get :search, on: :collection
end
resources :users, only: [:index, :show]
scope module: :poll do
resources :polls do
get :booth_assignments, on: :collection
patch :add_question, on: :member
resources :booth_assignments, only: [:index, :show, :create, :destroy] do
get :search_booths, on: :collection
get :manage, on: :collection
end
resources :officer_assignments, only: [:index, :create, :destroy] do
get :search_officers, on: :collection
get :by_officer, on: :collection
end
resources :recounts, only: :index
resources :results, only: :index
end
resources :officers do
get :search, on: :collection
end
resources :booths do
get :available, on: :collection
resources :shifts do
get :search_officers, on: :collection
end
end
resources :questions, shallow: true do
resources :answers, except: [:index, :destroy], controller: 'questions/answers', shallow: true do
resources :images, controller: 'questions/answers/images'
resources :videos, controller: 'questions/answers/videos'
get :documents, to: 'questions/answers#documents'
end
post '/answers/order_answers', to: 'questions/answers#order_answers'
end
end
resources :verifications, controller: :verifications, only: :index do
get :search, on: :collection
end
resource :activity, controller: :activity, only: :show
resources :newsletters, only: :index do
get :users, on: :collection
end
resource :stats, only: :show do
get :proposal_notifications, on: :collection
get :direct_messages, on: :collection
get :polls, on: :collection
end
namespace :legislation do
resources :processes do
resources :questions
resources :proposals
resources :draft_versions
end
end
namespace :api do
resource :stats, only: :show
end
resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy]
namespace :site_customization do
resources :pages, except: [:show]
resources :images, only: [:index, :update, :destroy]
resources :content_blocks, except: [:show]
end
end
namespace :moderation do
root to: "dashboard#index"
resources :users, only: :index do
member do
put :hide
put :hide_in_moderation_screen
end
end
resources :debates, only: :index do
put :hide, on: :member
put :moderate, on: :collection
end
resources :proposals, only: :index do
put :hide, on: :member
put :moderate, on: :collection
end
resources :comments, only: :index do
put :hide, on: :member
put :moderate, on: :collection
end
end
namespace :valuation do
root to: "budgets#index"
resources :spending_proposals, only: [:index, :show, :edit] do
patch :valuate, on: :member
end
resources :budgets, only: :index do
resources :budget_investments, only: [:index, :show, :edit] do
patch :valuate, on: :member
end
end
end
namespace :management do
root to: "dashboard#index"
resources :document_verifications, only: [:index, :new, :create] do
post :check, on: :collection
end
resources :email_verifications, only: [:new, :create]
resources :user_invites, only: [:new, :create]
resources :users, only: [:new, :create] do
collection do
delete :logout
delete :erase
end
end
resource :account, controller: "account", only: [:show]
get 'sign_in', to: 'sessions#create', as: :sign_in
resource :session, only: [:create, :destroy]
resources :proposals, only: [:index, :new, :create, :show] do
post :vote, on: :member
get :print, on: :collection
end
resources :spending_proposals, only: [:index, :new, :create, :show] do
post :vote, on: :member
get :print, on: :collection
end
resources :budgets, only: :index do
collection do
get :create_investments
get :support_investments
get :print_investments
end
resources :investments, only: [:index, :new, :create, :show, :destroy], controller: 'budgets/investments' do
post :vote, on: :member
get :print, on: :collection
end
end
end
namespace :officing do
resources :polls, only: [:index] do
get :final, on: :collection
resources :results, only: [:new, :create, :index]
end
resource :residence, controller: "residence", only: [:new, :create]
resources :voters, only: [:new, :create]
root to: "dashboard#index"
end
resources :related_contents, only: [:create] do
member do
put :score_positive
put :score_negative
end
end
# GraphQL
get '/graphql', to: 'graphql#query'
post '/graphql', to: 'graphql#query'
mount LetterOpenerWeb::Engine, at: "/letter_opener" if Rails.env.development?
mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql'
# more info pages
# More info pages
get 'more-information', to: 'pages#show', id: 'more_info/index', as: 'more_info'
get 'more-information/how-to-use', to: 'pages#show', id: 'more_info/how_to_use/index', as: 'how_to_use'
get 'more-information/faq', to: 'pages#show', id: 'more_info/faq/index', as: 'faq'
# static pages
# Static pages
get '/blog' => redirect("http://blog.consul/")
resources :pages, path: '/', only: [:show]
end

3
config/routes/account.rb Normal file
View File

@@ -0,0 +1,3 @@
resource :account, controller: "account", only: [:show, :update, :delete] do
get :erase, on: :collection
end

172
config/routes/admin.rb Normal file
View File

@@ -0,0 +1,172 @@
namespace :admin do
root to: "dashboard#index"
resources :organizations, only: :index do
get :search, on: :collection
member do
put :verify
put :reject
end
end
resources :hidden_users, only: [:index, :show] do
member do
put :restore
put :confirm_hide
end
end
resources :debates, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :proposals, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :spending_proposals, only: [:index, :show, :edit, :update] do
member do
patch :assign_admin
patch :assign_valuators
end
get :summary, on: :collection
end
resources :budgets do
member do
put :calculate_winners
end
resources :budget_groups do
resources :budget_headings
end
resources :budget_investments, only: [:index, :show, :edit, :update] do
resources :budget_investment_milestones
member { patch :toggle_selection }
end
end
resources :signature_sheets, only: [:index, :new, :create, :show]
resources :banners, only: [:index, :new, :create, :edit, :update, :destroy] do
collection { get :search }
end
resources :comments, only: :index do
member do
put :restore
put :confirm_hide
end
end
resources :tags, only: [:index, :create, :update, :destroy]
resources :officials, only: [:index, :edit, :update, :destroy] do
get :search, on: :collection
end
resources :settings, only: [:index, :update]
put :update_map, to: "settings#update_map"
resources :moderators, only: [:index, :create, :destroy] do
get :search, on: :collection
end
resources :valuators, only: [:index, :create, :destroy] do
get :search, on: :collection
get :summary, on: :collection
end
resources :managers, only: [:index, :create, :destroy] do
get :search, on: :collection
end
resources :administrators, only: [:index, :create, :destroy] do
get :search, on: :collection
end
resources :users, only: [:index, :show]
scope module: :poll do
resources :polls do
get :booth_assignments, on: :collection
patch :add_question, on: :member
resources :booth_assignments, only: [:index, :show, :create, :destroy] do
get :search_booths, on: :collection
get :manage, on: :collection
end
resources :officer_assignments, only: [:index, :create, :destroy] do
get :search_officers, on: :collection
get :by_officer, on: :collection
end
resources :recounts, only: :index
resources :results, only: :index
end
resources :officers do
get :search, on: :collection
end
resources :booths do
get :available, on: :collection
resources :shifts do
get :search_officers, on: :collection
end
end
resources :questions, shallow: true do
resources :answers, except: [:index, :destroy], controller: 'questions/answers' do
resources :images, controller: 'questions/answers/images'
resources :videos, controller: 'questions/answers/videos'
get :documents, to: 'questions/answers#documents'
end
post '/answers/order_answers', to: 'questions/answers#order_answers'
end
end
resources :verifications, controller: :verifications, only: :index do
get :search, on: :collection
end
resource :activity, controller: :activity, only: :show
resources :newsletters, only: :index do
get :users, on: :collection
end
resource :stats, only: :show do
get :proposal_notifications, on: :collection
get :direct_messages, on: :collection
get :polls, on: :collection
end
namespace :legislation do
resources :processes do
resources :questions
resources :proposals
resources :draft_versions
end
end
namespace :api do
resource :stats, only: :show
end
resources :geozones, only: [:index, :new, :create, :edit, :update, :destroy]
namespace :site_customization do
resources :pages, except: [:show]
resources :images, only: [:index, :update, :destroy]
resources :content_blocks, except: [:show]
end
end

View File

@@ -0,0 +1,3 @@
resources :annotations do
get :search, on: :collection
end

19
config/routes/budget.rb Normal file
View File

@@ -0,0 +1,19 @@
resources :budgets, only: [:show, :index] do
resources :groups, controller: "budgets/groups", only: [:show]
resources :investments, controller: "budgets/investments", only: [:index, :new, :create, :show, :destroy] do
member { post :vote }
collection { get :suggest }
end
resource :ballot, only: :show, controller: "budgets/ballots" do
resources :lines, controller: "budgets/ballot/lines", only: [:create, :destroy]
end
resource :results, only: :show, controller: "budgets/results"
end
scope '/participatory_budget' do
resources :spending_proposals, only: [:index, :new, :create, :show, :destroy], path: 'investment_projects' do
post :vote, on: :member
end
end

7
config/routes/comment.rb Normal file
View File

@@ -0,0 +1,7 @@
resources :comments, only: [:create, :show], shallow: true do
member do
post :vote
put :flag
put :unflag
end
end

View File

@@ -0,0 +1,3 @@
resources :communities, only: [:show] do
resources :topics
end

14
config/routes/debate.rb Normal file
View File

@@ -0,0 +1,14 @@
resources :debates do
member do
post :vote
put :flag
put :unflag
put :mark_featured
put :unmark_featured
end
collection do
get :map
get :suggest
end
end

27
config/routes/devise.rb Normal file
View File

@@ -0,0 +1,27 @@
devise_for :users, controllers: {
registrations: 'users/registrations',
sessions: 'users/sessions',
confirmations: 'users/confirmations',
omniauth_callbacks: 'users/omniauth_callbacks'
}
devise_scope :user do
patch '/user/confirmation', to: 'users/confirmations#update', as: :update_user_confirmation
get '/user/registrations/check_username', to: 'users/registrations#check_username'
get 'users/sign_up/success', to: 'users/registrations#success'
get 'users/registrations/delete_form', to: 'users/registrations#delete_form'
delete 'users/registrations', to: 'users/registrations#delete'
get :finish_signup, to: 'users/registrations#finish_signup'
patch :do_finish_signup, to: 'users/registrations#do_finish_signup'
end
devise_for :organizations, class_name: 'User',
controllers: {
registrations: 'organizations/registrations',
sessions: 'devise/sessions',
},
skip: [:omniauth_callbacks]
devise_scope :organization do
get 'organizations/sign_up/success', to: 'organizations/registrations#success'
end

View File

@@ -0,0 +1,2 @@
resources :direct_uploads, only: [:create]
delete "direct_uploads/destroy", to: "direct_uploads#destroy", as: :direct_upload_destroy

View File

@@ -0,0 +1,7 @@
resources :documents, only: [:new, :create, :destroy] do
collection do
get :new_nested
delete :destroy_upload
post :upload
end
end

3
config/routes/graphql.rb Normal file
View File

@@ -0,0 +1,3 @@
get '/graphql', to: 'graphql#query'
post '/graphql', to: 'graphql#query'
mount GraphiQL::Rails::Engine, at: '/graphiql', graphql_path: '/graphql'

View File

@@ -0,0 +1,37 @@
namespace :legislation do
resources :processes, only: [:index, :show] do
member do
get :debate
get :draft_publication
get :allegations
get :result_publication
get :proposals
end
resources :questions, only: [:show] do
resources :answers, only: [:create]
end
resources :proposals do
member do
post :vote
put :flag
put :unflag
end
collection do
get :map
get :suggest
end
end
resources :draft_versions, only: [:show] do
get :go_to_version, on: :collection
get :changes
resources :annotations do
get :search, on: :collection
get :comments
post :new_comment
end
end
end
end

View File

@@ -0,0 +1,44 @@
namespace :management do
root to: "dashboard#index"
resources :document_verifications, only: [:index, :new, :create] do
post :check, on: :collection
end
resources :email_verifications, only: [:new, :create]
resources :user_invites, only: [:new, :create]
resources :users, only: [:new, :create] do
collection do
delete :logout
delete :erase
end
end
resource :account, controller: "account", only: [:show]
resource :session, only: [:create, :destroy]
get 'sign_in', to: 'sessions#create', as: :sign_in
resources :proposals, only: [:index, :new, :create, :show] do
post :vote, on: :member
get :print, on: :collection
end
resources :spending_proposals, only: [:index, :new, :create, :show] do
post :vote, on: :member
get :print, on: :collection
end
resources :budgets, only: :index do
collection do
get :create_investments
get :support_investments
get :print_investments
end
resources :investments, only: [:index, :new, :create, :show, :destroy], controller: 'budgets/investments' do
post :vote, on: :member
get :print, on: :collection
end
end
end

View File

@@ -0,0 +1,25 @@
namespace :moderation do
root to: "dashboard#index"
resources :users, only: :index do
member do
put :hide
put :hide_in_moderation_screen
end
end
resources :debates, only: :index do
put :hide, on: :member
put :moderate, on: :collection
end
resources :proposals, only: :index do
put :hide, on: :member
put :moderate, on: :collection
end
resources :comments, only: :index do
put :hide, on: :member
put :moderate, on: :collection
end
end

View File

@@ -0,0 +1,5 @@
resources :notifications, only: [:index, :show] do
put :mark_all_as_read, on: :collection
end
resources :proposal_notifications, only: [:new, :create, :show]

10
config/routes/officing.rb Normal file
View File

@@ -0,0 +1,10 @@
namespace :officing do
resources :polls, only: [:index] do
get :final, on: :collection
resources :results, only: [:new, :create, :index]
end
resource :residence, controller: "residence", only: [:new, :create]
resources :voters, only: [:new, :create]
root to: "dashboard#index"
end

10
config/routes/poll.rb Normal file
View File

@@ -0,0 +1,10 @@
resources :polls, only: [:show, :index] do
member do
get :stats
get :results
end
resources :questions, controller: 'polls/questions', shallow: true do
post :answer, on: :member
end
end

17
config/routes/proposal.rb Normal file
View File

@@ -0,0 +1,17 @@
resources :proposals do
member do
post :vote
post :vote_featured
put :flag
put :unflag
get :retire_form
get :share
patch :retire
end
collection do
get :map
get :suggest
get :summary
end
end

View File

@@ -0,0 +1,6 @@
resources :related_contents, only: [:create] do
member do
put :score_positive
put :score_negative
end
end

5
config/routes/tag.rb Normal file
View File

@@ -0,0 +1,5 @@
resources :tags do
collection do
get :suggest
end
end

3
config/routes/user.rb Normal file
View File

@@ -0,0 +1,3 @@
resources :users, only: [:show] do
resources :direct_messages, only: [:new, :create, :show]
end

View File

@@ -0,0 +1,13 @@
namespace :valuation do
root to: "budgets#index"
resources :spending_proposals, only: [:index, :show, :edit] do
patch :valuate, on: :member
end
resources :budgets, only: :index do
resources :budget_investments, only: [:index, :show, :edit] do
patch :valuate, on: :member
end
end
end

View File

@@ -0,0 +1,9 @@
scope module: :verification do
resource :residence, controller: "residence", only: [:new, :create]
resource :sms, controller: "sms", only: [:new, :create, :edit, :update]
resource :verified_user, controller: "verified_user", only: [:show]
resource :email, controller: "email", only: [:new, :show, :create]
resource :letter, controller: "letter", only: [:new, :create, :show, :edit, :update]
end
resource :verification, controller: "verification", only: [:show]

View File

@@ -535,41 +535,29 @@ end
section "Creating polls" do
Poll.create(name: "Current Poll",
# TODO: Uncomment when Poll get slugs
# slug: "current-poll",
starts_at: 7.days.ago,
ends_at: 7.days.from_now,
geozone_restricted: false)
Poll.create(name: "Current Poll Geozone Restricted",
# TODO: Uncomment when Poll get slugs
# slug: "current-poll-geozone-restricted",
starts_at: 5.days.ago,
ends_at: 5.days.from_now,
geozone_restricted: true,
geozones: Geozone.reorder("RANDOM()").limit(3))
Poll.create(name: "Incoming Poll",
# TODO: Uncomment when Poll get slugs
# slug: "incoming-poll",
starts_at: 1.month.from_now,
ends_at: 2.months.from_now)
Poll.create(name: "Recounting Poll",
# TODO: Uncomment when Poll get slugs
# slug: "recounting-poll",
starts_at: 15.days.ago,
ends_at: 2.days.ago)
Poll.create(name: "Expired Poll without Stats & Results",
# TODO: Uncomment when Poll get slugs
# slug: "expired-poll-without-stats-and-results",
starts_at: 2.months.ago,
ends_at: 1.month.ago)
Poll.create(name: "Expired Poll with Stats & Results",
# TODO: Uncomment when Poll get slugs
# slug: "expired-poll-with-stats-and-results",
starts_at: 2.months.ago,
ends_at: 1.month.ago,
results_enabled: true,

View File

@@ -0,0 +1,5 @@
class AddPublishingPricesPhaseToBudget < ActiveRecord::Migration
def change
add_column :budgets, :description_publishing_prices, :text
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: 20180108182839) do
ActiveRecord::Schema.define(version: 20180109175851) do
# These are extensions that must be enabled in order to support this database
enable_extension "plpgsql"
@@ -202,6 +202,7 @@ ActiveRecord::Schema.define(version: 20180108182839) do
t.text "description_finished"
t.string "slug"
t.text "description_drafting"
t.text "description_publishing_prices"
end
create_table "campaigns", force: :cascade do |t|

View File

@@ -228,6 +228,7 @@ FactoryBot.define do
description_reviewing "This budget is reviewing"
description_selecting "This budget is selecting"
description_valuating "This budget is valuating"
description_publishing_prices "This budget is publishing prices"
description_balloting "This budget is balloting"
description_reviewing_ballots "This budget is reviewing ballots"
description_finished "This budget is finished"
@@ -252,6 +253,10 @@ FactoryBot.define do
phase 'valuating'
end
trait :publishing_prices do
phase 'publishing_prices'
end
trait :balloting do
phase 'balloting'
end
@@ -313,7 +318,6 @@ FactoryBot.define do
selected true
feasibility "feasible"
valuation_finished true
end
trait :winner do
@@ -326,6 +330,12 @@ FactoryBot.define do
incompatible true
end
trait :selected_with_price do
selected
price 1000
price_explanation 'Because of reasons'
end
trait :unselected do
selected false
feasibility "feasible"

View File

@@ -47,7 +47,7 @@ feature 'Admin budget investments' do
expect(page).to have_content(budget_investment.heading.name)
expect(page).to have_content(budget_investment.id)
expect(page).to have_content(budget_investment.total_votes)
expect(page).to_not have_link("Selected")
expect(page).not_to have_link("Selected")
end
end
@@ -339,9 +339,9 @@ feature 'Admin budget investments' do
click_link budget_investment.title
expect(page).to_not have_link "Edit"
expect(page).to_not have_link "Edit classification"
expect(page).to_not have_link "Edit dossier"
expect(page).not_to have_link "Edit"
expect(page).not_to have_link "Edit classification"
expect(page).not_to have_link "Edit dossier"
expect(page).to have_link "Create new milestone"
end
end
@@ -639,7 +639,10 @@ feature 'Admin budget investments' do
admin = create(:administrator, user: create(:user, username: 'Gema'))
investment.update(administrator_id: admin.id)
visit admin_budget_budget_investments_path(@budget, format: :csv)
visit admin_budget_budget_investments_path(@budget)
within('#filter-subnav') { click_link 'All' }
click_link "Download current selection"
header = page.response_headers['Content-Disposition']
expect(header).to match(/^attachment/)
@@ -666,15 +669,18 @@ feature 'Admin budget investments' do
title: 'compatible')
investment2 = create(:budget_investment, :finished, budget: @budget,
title: 'finished')
visit admin_budget_budget_investments_path(@budget, format: :csv,
filter: :valuation_finished)
visit admin_budget_budget_investments_path(@budget)
within('#filter-subnav') { click_link 'Valuation finished' }
click_link "Download current selection"
header = page.response_headers['Content-Disposition']
header.should match(/^attachment/)
header.should match(/filename="budget_investments.csv"$/)
expect(page).to have_content investment2.title
expect(page).to_not have_content investment1.title
expect(page).not_to have_content investment1.title
end
end

View File

@@ -244,5 +244,43 @@ feature 'Admin budgets' do
end
end
scenario 'Update heading', :js do
budget = create(:budget, name: 'Yearly participatory budget')
group = create(:budget_group, budget: budget, name: 'Districts improvments')
heading = create(:budget_heading, group: group, name: "District 1")
heading = create(:budget_heading, group: group, name: "District 3")
visit admin_budget_path(budget)
within("#heading-#{heading.id}") do
click_link 'Edit'
fill_in 'budget_heading_name', with: 'District 2'
fill_in 'budget_heading_price', with: '10000'
fill_in 'budget_heading_population', with: '6000'
click_button 'Save heading'
end
expect(page).to have_content 'District 2'
expect(page).to have_content '10000'
expect(page).to have_content '6000'
end
scenario 'Delete heading', :js do
budget = create(:budget, name: 'Yearly participatory budget')
group = create(:budget_group, budget: budget, name: 'Districts improvments')
heading = create(:budget_heading, group: group, name: "District 1")
visit admin_budget_path(budget)
expect(page).to have_content 'District 1'
within("#heading-#{heading.id}") do
click_link 'Delete'
end
expect(page).to_not have_content 'District 1'
end
end
end

View File

@@ -418,6 +418,64 @@ feature 'Budget Investments' do
end
end
context "Show Investment's price & cost explanation" do
let(:investment) { create(:budget_investment, :selected_with_price, heading: heading) }
context "When investment with price is selected" do
scenario "Price & explanation is shown when Budget is on published prices phase" do
Budget::PUBLISHED_PRICES_PHASES.each do |phase|
budget.update(phase: phase)
visit budget_investment_path(budget_id: budget.id, id: investment.id)
expect(page).to have_content(investment.formatted_price)
expect(page).to have_content(investment.price_explanation)
visit budget_investments_path(budget)
expect(page).to have_content(investment.formatted_price)
end
end
scenario "Price & explanation isn't shown when Budget is not on published prices phase" do
(Budget::PHASES - Budget::PUBLISHED_PRICES_PHASES).each do |phase|
budget.update(phase: phase)
visit budget_investment_path(budget_id: budget.id, id: investment.id)
expect(page).not_to have_content(investment.formatted_price)
expect(page).not_to have_content(investment.price_explanation)
visit budget_investments_path(budget)
expect(page).not_to have_content(investment.formatted_price)
end
end
end
context "When investment with price is unselected" do
background do
investment.update(selected: false)
end
scenario "Price & explanation isn't shown for any Budget's phase" do
Budget::PHASES.each do |phase|
budget.update(phase: phase)
visit budget_investment_path(budget_id: budget.id, id: investment.id)
expect(page).not_to have_content(investment.formatted_price)
expect(page).not_to have_content(investment.price_explanation)
visit budget_investments_path(budget)
expect(page).not_to have_content(investment.formatted_price)
end
end
end
end
scenario 'Can access the community' do
Setting['feature.community'] = true
@@ -477,13 +535,6 @@ feature 'Budget Investments' do
expect(page).not_to have_content(investment.price_explanation)
end
scenario "Budget in balloting phase" do
budget.update(phase: "balloting")
visit budget_investment_path(budget_id: budget.id, id: investment.id)
expect(page).to have_content("Price explanation")
expect(page).to have_content(investment.price_explanation)
end
end
scenario "Show (unfeasible budget investment)" do

View File

@@ -44,4 +44,16 @@ describe Budget::Heading do
end
end
describe "heading" do
it "can be deleted if no budget's investments associated" do
heading1 = create(:budget_heading, group: group, name: 'name')
heading2 = create(:budget_heading, group: group, name: 'name 2')
create(:budget_investment, heading: heading1)
expect(heading1.can_be_deleted?).to eq false
expect(heading2.can_be_deleted?).to eq true
end
end
end

View File

@@ -193,37 +193,73 @@ describe Budget::Investment do
end
end
describe "#should_show_price_info?" do
it "returns true for feasibles if phase is balloting or later and price_explanation is present" do
["balloting", "reviewing_ballots", "finished"].each do |phase|
budget = create(:budget, phase: phase)
investment = create(:budget_investment, :feasible, budget: budget, price_explanation: "price explanation")
describe "#should_show_price?" do
let(:budget) { create(:budget, :publishing_prices) }
let(:investment) do
create(:budget_investment, :selected, budget: budget)
end
expect(investment.should_show_price_info?).to eq(true)
it "returns true for selected investments which budget's phase is publishing_prices or later" do
Budget::PUBLISHED_PRICES_PHASES.each do |phase|
budget.update(phase: phase)
expect(investment.should_show_price?).to eq(true)
end
end
it "returns false in any other phase" do
(Budget::PHASES - ["balloting", "reviewing_ballots", "finished"]).each do |phase|
budget = create(:budget, phase: phase)
investment = create(:budget_investment, :feasible, budget: budget, price_explanation: "price explanation")
(Budget::PHASES - Budget::PUBLISHED_PRICES_PHASES).each do |phase|
budget.update(phase: phase)
expect(investment.should_show_price_info?).to eq(false)
expect(investment.should_show_price?).to eq(false)
end
end
it "returns false if investment is unfeasible" do
budget = create(:budget, phase: "balloting")
investment = create(:budget_investment, :unfeasible, budget: budget, price_explanation: "price explanation")
it "returns false if investment is not selected" do
investment.selected = false
expect(investment.should_show_price_info?).to eq(false)
expect(investment.should_show_price?).to eq(false)
end
it "returns false if price_explanation is blank" do
budget = create(:budget, phase: "balloting")
investment = create(:budget_investment, :unfeasible, budget: budget, price_explanation: "")
it "returns false if price is not present" do
investment.price = nil
expect(investment.should_show_price_info?).to eq(false)
expect(investment.should_show_price?).to eq(false)
end
end
describe "#should_show_price_explanation?" do
let(:budget) { create(:budget, :publishing_prices) }
let(:investment) do
create(:budget_investment, :selected, budget: budget, price_explanation: "because of reasons")
end
it "returns true for selected with price_explanation & budget in publishing_prices or later" do
Budget::PUBLISHED_PRICES_PHASES.each do |phase|
budget.update(phase: phase)
expect(investment.should_show_price_explanation?).to eq(true)
end
end
it "returns false in any other phase" do
(Budget::PHASES - Budget::PUBLISHED_PRICES_PHASES).each do |phase|
budget.update(phase: phase)
expect(investment.should_show_price_explanation?).to eq(false)
end
end
it "returns false if investment is not selected" do
investment.selected = false
expect(investment.should_show_price_explanation?).to eq(false)
end
it "returns false if price_explanation is not present" do
investment.price_explanation = ""
expect(investment.should_show_price_explanation?).to eq(false)
end
end

View File

@@ -55,6 +55,9 @@ describe Budget do
budget.phase = "valuating"
expect(budget).to be_valuating
budget.phase = "publishing_prices"
expect(budget).to be_publishing_prices
budget.phase = "balloting"
expect(budget).to be_balloting
@@ -81,6 +84,9 @@ describe Budget do
budget.phase = "valuating"
expect(budget).to be_on_hold
budget.phase = "publishing_prices"
expect(budget).to be_on_hold
budget.phase = "balloting"
expect(budget).not_to be_on_hold
@@ -107,6 +113,9 @@ describe Budget do
budget.phase = "valuating"
expect(budget).not_to be_balloting_or_later
budget.phase = "publishing_prices"
expect(budget).not_to be_balloting_or_later
budget.phase = "balloting"
expect(budget).to be_balloting_or_later
@@ -142,6 +151,8 @@ describe Budget do
expect(budget.investments_orders).to eq(['random'])
end
it "is random and price when ballotting and reviewing ballots" do
budget.phase = 'publishing_prices'
expect(budget.investments_orders).to eq(['random', 'price'])
budget.phase = 'balloting'
expect(budget.investments_orders).to eq(['random', 'price'])
budget.phase = 'reviewing_ballots'