Merge branch 'master' into legislation-module-stable

This commit is contained in:
Amaia Castro
2017-01-17 10:46:33 +01:00
40 changed files with 687 additions and 127 deletions

View File

@@ -17,6 +17,7 @@ Para adaptarlo puedes hacerlo a través de los directorios que están en custom
Aparte de estos directorios también cuentas con ciertos ficheros para: Aparte de estos directorios también cuentas con ciertos ficheros para:
* `app/assets/stylesheets/custom.css` * `app/assets/stylesheets/custom.css`
* `app/assets/stylesheets/_custom_settings.css`
* `app/assets/javascripts/custom.js` * `app/assets/javascripts/custom.js`
* `Gemfile_custom` * `Gemfile_custom`
* `config/application.custom.rb` * `config/application.custom.rb`
@@ -67,6 +68,11 @@ Si quieres cambiar algun selector CSS (de las hojas de estilo) puedes hacerlo en
background: red; background: red;
} }
``` ```
Si quieres cambiar alguna variable de foundation puedes hacerlo en el fichero `app/assets/stylesheets/_custom_settings.scss`. Por ejemplo para cambiar el color general de la aplicación puedes hacerlo agregando:
```css
$brand: #446336;
```
Usamos un preprocesador de CSS, [SASS, con la sintaxis SCSS](http://sass-lang.com/guide). Usamos un preprocesador de CSS, [SASS, con la sintaxis SCSS](http://sass-lang.com/guide).

View File

@@ -0,0 +1,5 @@
// Overrides and adds customized foundation settings in this file
// Read more on documentation:
// * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#css
// * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#css
//

View File

@@ -1,6 +1,7 @@
@charset 'utf-8'; @charset 'utf-8';
@import 'settings'; @import 'settings';
@import 'custom_settings';
@import 'foundation'; @import 'foundation';
@include foundation-global-styles; @include foundation-global-styles;

View File

@@ -5,6 +5,8 @@ module Budgets
#before_action :ensure_final_voting_allowed #before_action :ensure_final_voting_allowed
before_action :load_budget before_action :load_budget
before_action :load_ballot before_action :load_ballot
before_action :load_tag_cloud
before_action :load_categories
before_action :load_investments before_action :load_investments
@@ -63,6 +65,14 @@ module Budgets
@heading = @investment.heading @heading = @investment.heading
end end
def load_tag_cloud
@tag_cloud = TagCloud.new(Budget::Investment, params[:search])
end
def load_categories
@categories = ActsAsTaggableOn::Tag.where("kind = 'category'").order(:name)
end
end end
end end
end end

View File

@@ -46,6 +46,7 @@ module Budgets
@investment.author = current_user @investment.author = current_user
if @investment.save if @investment.save
Mailer.budget_investment_created(@investment).deliver_later
redirect_to budget_investment_path(@budget, @investment), redirect_to budget_investment_path(@budget, @investment),
notice: t('flash.actions.create.budget_investment') notice: t('flash.actions.create.budget_investment')
else else
@@ -61,6 +62,10 @@ module Budgets
def vote def vote
@investment.register_selection(current_user) @investment.register_selection(current_user)
load_investment_votes(@investment) load_investment_votes(@investment)
respond_to do |format|
format.html { redirect_to budget_investments_path(heading_id: @investment.heading.id) }
format.js
end
end end
private private

View File

@@ -34,6 +34,10 @@ class Management::Budgets::InvestmentsController < Management::BaseController
def vote def vote
@investment.register_selection(managed_user) @investment.register_selection(managed_user)
load_investment_votes(@investment) load_investment_votes(@investment)
respond_to do |format|
format.html { redirect_to management_budget_investments_path(heading_id: @investment.heading.id) }
format.js
end
end end
def print def print

View File

@@ -21,6 +21,11 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController
def valuate def valuate
if valid_price_params? && @investment.update(valuation_params) if valid_price_params? && @investment.update(valuation_params)
if @investment.unfeasible_email_pending?
@investment.send_unfeasible_email
end
redirect_to valuation_budget_budget_investment_path(@budget, @investment), notice: t('valuation.budget_investments.notice.valuate') redirect_to valuation_budget_budget_investment_path(@budget, @investment), notice: t('valuation.budget_investments.notice.valuate')
else else
render action: :edit render action: :edit

View File

@@ -1,12 +1,7 @@
module SearchHelper module SearchHelper
def official_level_search_options def official_level_search_options
options_for_select([ options_for_select((1..5).map{ |i| [setting["official_level_#{i}_name"], i] },
[t("shared.advanced_search.author_type_1"), 1],
[t("shared.advanced_search.author_type_2"), 2],
[t("shared.advanced_search.author_type_3"), 3],
[t("shared.advanced_search.author_type_4"), 4],
[t("shared.advanced_search.author_type_5"), 5]],
params[:advanced_search].try(:[], :official_level)) params[:advanced_search].try(:[], :official_level))
end end

View File

@@ -74,6 +74,23 @@ class Mailer < ApplicationMailer
end end
end end
def budget_investment_created(investment)
@investment = investment
with_user(@investment.author) do
mail(to: @investment.author.email, subject: t('mailers.budget_investment_created.subject'))
end
end
def budget_investment_unfeasible(investment)
@investment = investment
@author = investment.author
with_user(@author) do
mail(to: @author.email, subject: t('mailers.budget_investment_unfeasible.subject', code: @investment.code))
end
end
private private
def with_user(user, &block) def with_user(user, &block)

View File

@@ -136,16 +136,26 @@ class Budget
unfeasible? && valuation_finished? unfeasible? && valuation_finished?
end end
def unfeasible_email_pending?
unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished?
end
def total_votes def total_votes
cached_votes_up + physical_votes cached_votes_up + physical_votes
end end
def code def code
"B#{budget.id}I#{id}" "#{created_at.strftime('%Y')}-#{id}" + (administrator.present? ? "-A#{administrator.id}" : "")
end
def send_unfeasible_email
Mailer.budget_investment_unfeasible(self).deliver_later
update(unfeasible_email_sent_at: Time.current)
end end
def reason_for_not_being_selectable_by(user) def reason_for_not_being_selectable_by(user)
return permission_problem(user) if permission_problem?(user) return permission_problem(user) if permission_problem?(user)
return :different_heading_assigned unless valid_heading?(user)
return :no_selecting_allowed unless budget.selecting? return :no_selecting_allowed unless budget.selecting?
end end
@@ -173,6 +183,24 @@ class Budget
reason_for_not_being_selectable_by(user).blank? reason_for_not_being_selectable_by(user).blank?
end end
def valid_heading?(user)
!different_heading_assigned?(user)
end
def different_heading_assigned?(user)
other_heading_ids = group.heading_ids - [heading.id]
voted_in?(other_heading_ids, user)
end
def voted_in?(heading_ids, user)
heading_ids.include? heading_voted_by_user?(user)
end
def heading_voted_by_user?(user)
user.votes.for_budget_investments(budget.investments.where(group: group)).
votables.map(&:heading_id).first
end
def ballotable_by?(user) def ballotable_by?(user)
reason_for_not_being_ballotable_by(user).blank? reason_for_not_being_ballotable_by(user).blank?
end end
@@ -195,11 +223,17 @@ class Budget
end end
def should_show_aside? def should_show_aside?
(budget.selecting? && !unfeasible?) || (budget.balloting? && feasible?) || budget.on_hold? (budget.selecting? && !unfeasible?) ||
(budget.balloting? && feasible?) ||
(budget.valuating? && feasible?)
end end
def should_show_votes? def should_show_votes?
budget.selecting? || budget.on_hold? budget.selecting?
end
def should_show_vote_count?
budget.valuating?
end end
def should_show_ballots? def should_show_ballots?

View File

@@ -104,6 +104,10 @@ class User < ActiveRecord::Base
comment_flags.each_with_object({}){ |f, h| h[f.flaggable_id] = true } comment_flags.each_with_object({}){ |f, h| h[f.flaggable_id] = true }
end end
def voted_in_group?(group)
votes.for_budget_investments(Budget::Investment.where(group: group)).exists?
end
def administrator? def administrator?
administrator.present? administrator.present?
end end

View File

@@ -0,0 +1,11 @@
<div class="sidebar-divider"></div>
<h2 class="sidebar-title"><%= t("budgets.investments.index.sidebar.by_feasibility") %></h2>
<br>
<% if params[:unfeasible].present? %>
<%= link_to t("budgets.investments.index.sidebar.feasible"),
budget_investments_path(@budget, heading_id: @heading, unfeasible: nil) %>
<% else %>
<%= link_to t("budgets.investments.index.sidebar.unfeasible"),
budget_investments_path(@budget, heading_id: @heading, unfeasible: 1) %>
<% end %>

View File

@@ -46,7 +46,6 @@
<% unless investment.unfeasible? %> <% unless investment.unfeasible? %>
<% if investment.should_show_votes? %> <% if investment.should_show_votes? %>
<div id="<%= dom_id(investment) %>_votes" <div id="<%= dom_id(investment) %>_votes"
class="small-12 medium-3 column text-center"> class="small-12 medium-3 column text-center">
<%= render partial: '/budgets/investments/votes', locals: { <%= render partial: '/budgets/investments/votes', locals: {
@@ -55,9 +54,17 @@
vote_url: namespaced_budget_investment_vote_path(investment, value: 'yes') vote_url: namespaced_budget_investment_vote_path(investment, value: 'yes')
} %> } %>
</div> </div>
<% elsif investment.should_show_vote_count? %>
<div id="<%= dom_id(investment) %>_votes"
class="small-12 medium-3 column text-center">
<div class="supports js-participation">
<span class="total-supports no-button">
<%= t("budgets.investments.investment.supports",
count: investment.total_votes) %>
</span>
</div>
</div>
<% elsif investment.should_show_ballots? %> <% elsif investment.should_show_ballots? %>
<div id="<%= dom_id(investment) %>_ballot" <div id="<%= dom_id(investment) %>_ballot"
class="small-12 medium-3 column text-center"> class="small-12 medium-3 column text-center">
<%= render partial: '/budgets/investments/ballot', locals: { <%= render partial: '/budgets/investments/ballot', locals: {
@@ -66,7 +73,6 @@
ballot: ballot ballot: ballot
} %> } %>
</div> </div>
<% end %> <% end %>
<% end %> <% end %>

View File

@@ -55,11 +55,10 @@
<% if investment.should_show_aside? %> <% if investment.should_show_aside? %>
<aside class="small-12 medium-3 column"> <aside class="small-12 medium-3 column">
<div class="sidebar-divider"></div>
<h2><%= t("votes.supports") %></h2>
<div class="text-center">
<% if investment.should_show_votes? %> <% if investment.should_show_votes? %>
<div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.supports") %></h2>
<div class="text-center">
<div id="<%= dom_id(investment) %>_votes"> <div id="<%= dom_id(investment) %>_votes">
<%= render partial: '/budgets/investments/votes', locals: { <%= render partial: '/budgets/investments/votes', locals: {
investment: investment, investment: investment,
@@ -67,7 +66,20 @@
vote_url: vote_budget_investment_path(investment.budget, investment, value: 'yes') vote_url: vote_budget_investment_path(investment.budget, investment, value: 'yes')
} %> } %>
</div> </div>
</div>
<% elsif investment.should_show_vote_count? %>
<div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.supports") %></h2>
<div class="text-center">
<span class="total-supports">
<%= t("budgets.investments.investment.supports",
count: investment.total_votes) %>
</span>
</div>
<% elsif investment.should_show_ballots? %> <% elsif investment.should_show_ballots? %>
<div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.votes") %></h2>
<div class="text-center">
<div id="<%= dom_id(investment) %>_ballot"> <div id="<%= dom_id(investment) %>_ballot">
<%= render partial: 'ballot', locals: { <%= render partial: 'ballot', locals: {
investment: investment, investment: investment,
@@ -75,11 +87,33 @@
ballot: ballot, ballot: ballot,
} %> } %>
</div> </div>
<% end %>
</div> </div>
<% end %>
<div class="sidebar-divider"></div> <div class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.share") %></h2> <h2><%= t("budgets.investments.show.share") %></h2>
<div class="social-share-full">
<%= social_share_button_tag("#{investment.title} #{setting['twitter_hashtag']}") %>
<% if browser.device.mobile? %>
<a href="whatsapp://send?text=<%= investment.title %> <%= budget_investment_url(budget_id: investment.budget_id, id: investment.id) %>"
data-action="share/whatsapp/share">
<span class="icon-whatsapp whatsapp"></span>
</a>
<% end %>
</div>
</aside>
<% else %>
<div class="small-12 medium-3 column">
<div class="float-right">
<span class="label-budget-investment float-left">
<%= t("budgets.investments.show.title") %>
</span>
<span class="icon-budget"></span>
</div>
<br>
<% end %>
<div id="social-share" class="sidebar-divider"></div>
<h2><%= t("budgets.investments.show.share") %></h2>
<div class="social-share-full"> <div class="social-share-full">
<%= social_share_button_tag("#{investment.title} #{setting['twitter_hashtag']}") %> <%= social_share_button_tag("#{investment.title} #{setting['twitter_hashtag']}") %>
<% if browser.device.mobile? %> <% if browser.device.mobile? %>
@@ -89,14 +123,5 @@
<% end %> <% end %>
</div> </div>
</aside> </aside>
<% else %>
<div class="small-12 medium-3 column">
<div class="float-right">
<span class="label-budget-investment float-left"><%= t("budgets.investments.show.title") %></span>
<span class="icon-budget"></span>
</div>
</div>
<% end %>
</div> </div>
</section> </section>

View File

@@ -2,26 +2,29 @@
<% if can?(:create, Budget::Investment.new(budget: @budget)) %> <% if can?(:create, Budget::Investment.new(budget: @budget)) %>
<% if current_user && current_user.level_two_or_three_verified? %> <% if current_user && current_user.level_two_or_three_verified? %>
<%= link_to t("budgets.investments.index.sidebar.create"), new_budget_investment_path, class: "button budget expanded" %> <%= link_to t("budgets.investments.index.sidebar.create"),
new_budget_investment_path, class: "button budget expanded" %>
<% else %> <% else %>
<div class="callout warning"> <div class="callout warning">
<%= t("budgets.investments.index.sidebar.verified_only", <%= t("budgets.investments.index.sidebar.verified_only",
verify: link_to(t("budgets.investments.index.sidebar.verify_account"), verification_path)).html_safe %> verify: link_to(t("budgets.investments.index.sidebar.verify_account"),
verification_path)).html_safe %>
</div> </div>
<% end %> <% end %>
<% end %> <% end %>
<% if @budget.accepting? %>
<%= render "shared/tag_cloud", taggable: 'budget/investment' %> <%= render "shared/tag_cloud", taggable: 'budget/investment' %>
<%= render 'categories' %> <%= render 'budgets/investments/categories' %>
<% end %> <%= render 'budgets/investments/feasibility_link' %>
<% if @heading && can?(:show, @ballot) %> <% if @heading && can?(:show, @ballot) %>
<div class="sidebar-divider"></div> <div class="sidebar-divider"></div>
<h2 class="sidebar-title"><%= t("budgets.investments.index.sidebar.my_ballot") %></h2> <h2 class="sidebar-title">
<%= t("budgets.investments.index.sidebar.my_ballot") %>
</h2>
<% if @ballot.investments.by_heading(@heading.id).count > 0 %> <% if @ballot.investments.by_heading(@heading.id).count > 0 %>
<p> <p>
<em> <em>
@@ -44,5 +47,7 @@
<% end %> <% end %>
</ul> </ul>
<p class="callout primary"><%= t("budgets.investments.index.sidebar.voted_info") %></p> <p class="callout primary">
<%= t("budgets.investments.index.sidebar.voted_info") %>
</p>
<% end %> <% end %>

View File

@@ -14,12 +14,12 @@
<%= t("budgets.investments.investment.already_supported") %> <%= t("budgets.investments.investment.already_supported") %>
</div> </div>
<% elsif investment.should_show_votes? %> <% elsif investment.should_show_votes? %>
<%= link_to vote_url, <%= link_to vote_url,
class: "button button-support small expanded", class: "button button-support small expanded",
title: t('budgets.investments.investment.support_title'), title: t('budgets.investments.investment.support_title'),
method: "post", method: "post",
remote: true, remote: (current_user && current_user.voted_in_group?(investment.group) ? true : false),
data: (current_user && current_user.voted_in_group?(investment.group) ? nil : { confirm: t('budgets.investments.investment.confirm_group')} ),
"aria-hidden" => css_for_aria_hidden(reason) do %> "aria-hidden" => css_for_aria_hidden(reason) do %>
<%= t("budgets.investments.investment.give_support") %> <%= t("budgets.investments.investment.give_support") %>
<% end %> <% end %>

View File

@@ -14,7 +14,7 @@
<%= t("budgets.phase.#{@budget.phase}") %> <%= t("budgets.phase.#{@budget.phase}") %>
</p> </p>
<% if can?(:create, Budget::Investment.new(budget: @budget))%> <% if @budget.accepting? %>
<% if current_user %> <% if current_user %>
<% if current_user.level_two_or_three_verified? %> <% if current_user.level_two_or_three_verified? %>
<%= link_to t("budgets.investments.index.sidebar.create"), new_budget_investment_path(@budget), class: "button margin-top expanded" %> <%= link_to t("budgets.investments.index.sidebar.create"), new_budget_investment_path(@budget), class: "button margin-top expanded" %>

View File

@@ -0,0 +1,42 @@
<td style="padding-bottom: 20px; padding-left: 10px;">
<h1 style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;">
<%= t("mailers.budget_investment_created.title") %>
</h1>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_created.intro_html",
author: @investment.author.name).html_safe %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_created.text_html",
investment: @investment.title,
budget: @investment.budget.name).html_safe %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_created.follow_html",
link: link_to(t("mailers.budget_investment_created.follow_link"), budgets_url)).html_safe %>
</p>
<table style="width: 100%;">
<tbody>
<tr>
<td style="padding-bottom: 12px; text-align: center;">
<%= link_to budget_investment_url(@investment.budget, @investment, anchor: "social-share"), style: "font-family: 'Open Sans','Helvetica Neue',arial,sans-serif; background: #f7f5f2; border-radius: 6px; color: #3d3d66!important; font-weight: bold; margin: 0px; padding: 10px 15px; text-align: center; text-decoration: none; min-width: 160px; display: inline-block;" do %>
<%= image_tag('icon_mailer_share.png', style: "border: 0; display: inline-block; width: 100%; max-width: 16px", alt: "") %>
<%= t('mailers.budget_investment_created.share') %>
<% end %>
</td>
</tr>
</tbody>
</table>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_created.sincerely") %>
<br>
<span style="color: #ccc; font-size: 12px;">
<%= t("mailers.budget_investment_created.signatory") %>
</span>
</p>

View File

@@ -0,0 +1,35 @@
<td style="padding-bottom: 20px; padding-left: 10px;">
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_unfeasible.hi") %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_unfeasible.unfeasible_html",
title: @investment.title) %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px; padding-left: 12px; border-left: 2px solid #ccc;">
<%= @investment.unfeasibility_explanation %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_unfeasible.new_html",
url: link_to(t("mailers.budget_investment_unfeasible.new_href"),
new_budget_investment_url(@investment.budget), style: "color: #2895F1; text-decoration: underline;")) %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_unfeasible.reconsider_html", code: @investment.code) %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_unfeasible.sorry") %>
</p>
<p style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 14px;font-weight: normal;line-height: 24px;">
<%= t("mailers.budget_investment_unfeasible.sincerely") %><br>
<span style="font-family: 'Open Sans','Helvetica Neue',arial,sans-serif;font-size: 12px;font-weight: normal;line-height: 24px; color: #ccc;">
<%= t("mailers.budget_investment_unfeasible.signatory") %></span>
</p>
</td>

View File

@@ -1,4 +1,4 @@
Ckeditor.setup do |config| Ckeditor.setup do |config|
config.assets_languages = I18n.available_locales.map(&:to_s) config.assets_languages = Rails.application.config.i18n.available_locales.map{|l| l.to_s.downcase}
config.assets_plugins = [] config.assets_plugins = []
end end

View File

@@ -64,6 +64,9 @@ en:
not_logged_in: "To create a new budget investment you must %{sign_in} or %{sign_up}." not_logged_in: "To create a new budget investment you must %{sign_in} or %{sign_up}."
sign_in: "sign in" sign_in: "sign in"
sign_up: "sign up" sign_up: "sign up"
by_feasibility: By feasibility
feasible: Feasible projects
unfeasible: Unfeasible projects
orders: orders:
random: random random: random
confidence_score: highest rated confidence_score: highest rated
@@ -77,6 +80,8 @@ en:
organization_name_html: 'Organization: <strong>%{name}</strong>' organization_name_html: 'Organization: <strong>%{name}</strong>'
share: Share share: Share
title: Investment project title: Investment project
supports: Supports
votes: Votes
wrong_price_format: Only integer numbers wrong_price_format: Only integer numbers
investment: investment:
title: Investment project title: Investment project
@@ -84,6 +89,7 @@ en:
already_added: You have already added this investment project already_added: You have already added this investment project
already_supported: You have already supported this. Share it! already_supported: You have already supported this. Share it!
support_title: Support this project support_title: Support this project
confirm_group: "You can only support investments in one district. If you continue you cannot change your decision. Are you sure?"
supports: supports:
one: 1 support one: 1 support
other: "%{count} supports" other: "%{count} supports"

View File

@@ -64,6 +64,9 @@ es:
not_logged_in: "Para crear una nueva propuesta de inversión debes %{sign_in} o %{sign_up}." not_logged_in: "Para crear una nueva propuesta de inversión debes %{sign_in} o %{sign_up}."
sign_in: "iniciar sesión" sign_in: "iniciar sesión"
sign_up: "registrarte" sign_up: "registrarte"
by_feasibility: Por viabilidad
feasible: Ver los proyectos viables
unfeasible: Ver los proyectos inviables
orders: orders:
random: Aleatorias random: Aleatorias
confidence_score: Mejor valoradas confidence_score: Mejor valoradas
@@ -77,6 +80,8 @@ es:
organization_name_html: 'Organización: <strong>%{name}</strong>' organization_name_html: 'Organización: <strong>%{name}</strong>'
share: Compartir share: Compartir
title: Propuesta de inversión title: Propuesta de inversión
supports: Apoyos
votes: Votos
wrong_price_format: Solo puede incluir caracteres numéricos wrong_price_format: Solo puede incluir caracteres numéricos
investment: investment:
title: Propuesta de inversión title: Propuesta de inversión
@@ -84,6 +89,7 @@ es:
already_added: "Ya has añadido esta propuesta de inversión" already_added: "Ya has añadido esta propuesta de inversión"
already_supported: Ya has apoyado esta propuesta. ¡Compártelo! already_supported: Ya has apoyado esta propuesta. ¡Compártelo!
support_title: Apoyar esta propuesta support_title: Apoyar esta propuesta
confirm_group: "Sólo puedes apoyar propuestas en un distrito. Si sigues adelante no podrás cambiar esta decisión. ¿Estás seguro?"
supports: supports:
one: 1 apoyo one: 1 apoyo
other: "%{count} apoyos" other: "%{count} apoyos"

View File

@@ -522,11 +522,6 @@ en:
advanced_search: advanced_search:
author_type: 'By author category' author_type: 'By author category'
author_type_blank: 'Select a category' author_type_blank: 'Select a category'
author_type_1: 'Public employee'
author_type_2: 'Municipal Organization'
author_type_3: 'General director'
author_type_4: 'City councillor'
author_type_5: 'Mayoress'
date: 'By date' date: 'By date'
date_placeholder: 'DD/MM/YYYY' date_placeholder: 'DD/MM/YYYY'
date_range_blank: 'Choose a date' date_range_blank: 'Choose a date'
@@ -708,6 +703,13 @@ en:
organization: Organizations are not permitted to vote organization: Organizations are not permitted to vote
unfeasible: Unfeasible investment projects can not be supported unfeasible: Unfeasible investment projects can not be supported
not_voting_allowed: Voting phase is closed not_voting_allowed: Voting phase is closed
budget_investments:
not_logged_in: You must %{signin} or %{signup} to continue.
not_verified: Only verified users can vote on proposals; %{verify_account}.
organization: Organizations are not permitted to vote
unfeasible: Unfeasible investment projects can not be supported
not_voting_allowed: Voting phase is closed
different_heading_assigned: You can only support proposals in one district
welcome: welcome:
debates: debates:
description: For meeting, discussing and sharing the things that matter to us in our city. description: For meeting, discussing and sharing the things that matter to us in our city.

View File

@@ -522,11 +522,6 @@ es:
advanced_search: advanced_search:
author_type: 'Por categoría de autor' author_type: 'Por categoría de autor'
author_type_blank: 'Elige una categoría' author_type_blank: 'Elige una categoría'
author_type_1: 'Empleado público'
author_type_2: 'Organización Municipal'
author_type_3: 'Director general'
author_type_4: 'Concejal'
author_type_5: 'Alcaldesa'
date: 'Por fecha' date: 'Por fecha'
date_placeholder: 'DD/MM/AAAA' date_placeholder: 'DD/MM/AAAA'
date_range_blank: 'Elige una fecha' date_range_blank: 'Elige una fecha'
@@ -708,6 +703,13 @@ es:
organization: Las organizaciones no pueden votar. organization: Las organizaciones no pueden votar.
unfeasible: No se pueden votar propuestas inviables. unfeasible: No se pueden votar propuestas inviables.
not_voting_allowed: El periodo de votación está cerrado. not_voting_allowed: El periodo de votación está cerrado.
budget_investments:
not_logged_in: Necesitas %{signin} o %{signup} para continuar.
not_verified: Las propuestas de inversión sólo pueden ser apoyadas por usuarios verificados, %{verify_account}.
organization: Las organizaciones no pueden votar.
unfeasible: No se pueden votar propuestas inviables.
not_voting_allowed: El periodo de votación está cerrado.
different_heading_assigned: Sólo puedes apoyar propuestas en un distrito
welcome: welcome:
debates: debates:
description: Encontrarnos, debatir y compartir lo que nos parece importante en nuestra ciudad. description: Encontrarnos, debatir y compartir lo que nos parece importante en nuestra ciudad.

View File

@@ -1361,11 +1361,6 @@ fr:
shared: shared:
advanced_search: advanced_search:
author_type: Par catégorie d'auteur author_type: Par catégorie d'auteur
author_type_1: Fonctionnaire
author_type_2: Organisation municipale
author_type_3: Directeur général
author_type_4: Conseiller municipal
author_type_5: Maire
author_type_blank: Sélectionner une catégorie author_type_blank: Sélectionner une catégorie
date: Par date date: Par date
date_1: Dernières 24 heures date_1: Dernières 24 heures

View File

@@ -31,6 +31,16 @@ en:
sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation." sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation."
subject: "Your investment project '%{code}' has been marked as unfeasible" subject: "Your investment project '%{code}' has been marked as unfeasible"
unfeasible_html: "From the City Council we want to thank you for your participation in the <strong>participatory budgets</strong>. We regret to inform you that your proposal <strong>'%{title}'</strong> will be excluded from this participatory process for the following reason:" unfeasible_html: "From the City Council we want to thank you for your participation in the <strong>participatory budgets</strong>. We regret to inform you that your proposal <strong>'%{title}'</strong> will be excluded from this participatory process for the following reason:"
budget_investment_unfeasible:
hi: "Dear user,"
new_html: "For all these, we invite you to elaborate a <strong>new proposal</strong> that ajusts to the conditions of this process. You can do it following this link: %{url}."
new_href: "new investment project"
reconsider_html: "If you believe that the rejected proposal meets the requirements to be an investment proposal, you can communicate this, within 48 hours, responding to the email address examples@consul.es. Including the code %{code} in the subject of the email."
sincerely: "Sincerely"
signatory: "DEPARTMENT OF PUBLIC PARTICIPATION"
sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation."
subject: "Your investment project '%{code}' has been marked as unfeasible"
unfeasible_html: "From the City Council we want to thank you for your participation in the <strong>participatory budgets</strong>. We regret to inform you that your proposal <strong>'%{title}'</strong> will be excluded from this participatory process for the following reason:"
proposal_notification_digest: proposal_notification_digest:
info: "Here are the new notifications that have been published by authors of the proposals that you have supported in %{org_name}." info: "Here are the new notifications that have been published by authors of the proposals that you have supported in %{org_name}."
title: "Proposal notifications in %{org_name}" title: "Proposal notifications in %{org_name}"
@@ -53,3 +63,23 @@ en:
title: "Welcome to %{org}" title: "Welcome to %{org}"
button: Complete registration button: Complete registration
subject: "Invitation to %{org_name}" subject: "Invitation to %{org_name}"
budget_investment_created:
subject: "Thank you for creating an investment!"
title: "Thank you for creating an investment!"
intro_html: "Hi <strong>%{author}</strong>,"
text_html: "Thank you for creating your investment <strong>%{investment}</strong> for Participatory Budgets <strong>%{budget}</strong>."
follow_html: "We will inform you about how the process progresses, which you can also follow on <strong>%{link}</strong>."
follow_link: "Participatory Budgets"
sincerely: "Sincerely,"
signatory: "DEPARTMENT OF PUBLIC PARTICIPATION"
share: "Comparte tu proyecto"
budget_investment_unfeasible:
hi: "Dear user,"
new_html: "For all these, we invite you to elaborate a <strong>new investment</strong> that ajusts to the conditions of this process. You can do it following this link: %{url}."
new_href: "new investment project"
reconsider_html: "If you believe that the rejected investment meets the requirements to be an investment project, you can communicate this, within 48 hours, responding to the email address examples@consul.es. Including the code %{code} in the subject of the email."
sincerely: "Sincerely"
signatory: "DEPARTMENT OF PUBLIC PARTICIPATION"
sorry: "Sorry for the inconvenience and we again thank you for your invaluable participation."
subject: "Your investment project '%{code}' has been marked as unfeasible"
unfeasible_html: "From the City Council we want to thank you for your participation in the <strong>participatory budgets</strong>. We regret to inform you that your investment <strong>'%{title}'</strong> will be excluded from this participatory process for the following reason:"

View File

@@ -53,3 +53,23 @@ es:
title: "Bienvenido a %{org}" title: "Bienvenido a %{org}"
button: Completar registro button: Completar registro
subject: "Invitación a %{org_name}" subject: "Invitación a %{org_name}"
budget_investment_created:
subject: "¡Gracias por crear un proyecto!"
title: "¡Gracias por crear un proyecto!"
intro_html: "Hola <strong>%{author}</strong>,"
text_html: "Muchas gracias por crear tu proyecto <strong>%{investment}</strong> para los Presupuestos Participativos <strong>%{budget}</strong>."
follow_html: "Te informaremos de cómo avanza el proceso, que también puedes seguir en la página de <strong>%{link}</strong>."
follow_link: "Presupuestos participativos"
sincerely: "Atentamente,"
signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA"
share: "Comparte tu proyecto"
budget_investment_unfeasible:
hi: "Estimado usuario,"
new_html: "Por todo ello, te invitamos a que elabores un <strong>nuevo proyecto de gasto</strong> que se ajuste a las condiciones de este proceso. Esto lo puedes hacer en este enlace: %{url}."
new_href: "nueva propuesta de inversión"
reconsider_html: "Si consideras que el proyecto rechazado cumple los requisitos para mantenerlo como proyecto de gasto, podrás comunicarlo, en el plazo de 48 horas, al correo example@consul.es, indicando necesariamente para su tramitación el código %{code} como asunto del correo, correspondiente a tu proyecto."
sincerely: "Atentamente"
signatory: "DIRECCIÓN GENERAL DE PARTICIPACIÓN CIUDADANA"
sorry: "Sentimos las molestias ocasionadas y volvemos a darte las gracias por tu inestimable participación."
subject: "Tu propuesta de inversión '%{code}' ha sido marcada como inviable"
unfeasible_html: "Desde el Ayuntamiento queremos agradecer tu participación en los <strong>Presupuestos Participativos</strong>. Lamentamos informarte de que tu proyecto <strong>'%{title}'</strong> quedará excluido de este proceso participativo por el siguiente motivo:"

View File

@@ -1383,11 +1383,6 @@ pt-BR:
shared: shared:
advanced_search: advanced_search:
author_type: Por categoria de autor author_type: Por categoria de autor
author_type_1: Servidor público
author_type_2: Organização municipal
author_type_3: Diretor geral
author_type_4: Conselheiro municipal
author_type_5: Prefeita
author_type_blank: Selecione um categoria author_type_blank: Selecione um categoria
date: Por data date: Por data
date_1: "Últimas 24 horas" date_1: "Últimas 24 horas"

View File

@@ -55,6 +55,7 @@ end
admin = create_user('admin@consul.dev', 'admin') admin = create_user('admin@consul.dev', 'admin')
admin.create_administrator admin.create_administrator
admin.update(residence_verified_at: Time.current, confirmed_phone: Faker::PhoneNumber.phone_number, document_type: "1", verified_at: Time.current, document_number: "1111111111")
moderator = create_user('mod@consul.dev', 'mod') moderator = create_user('mod@consul.dev', 'mod')
moderator.create_moderator moderator.create_moderator

View File

@@ -0,0 +1,5 @@
class AddUnfeasibleEmailSentAtToBudgetInvestments < ActiveRecord::Migration
def change
add_column :budget_investments, :unfeasible_email_sent_at, :datetime
end
end

View File

@@ -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: 20170106130838) do ActiveRecord::Schema.define(version: 20170114154421) 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"
@@ -143,6 +143,7 @@ ActiveRecord::Schema.define(version: 20170106130838) do
t.boolean "selected", default: false t.boolean "selected", default: false
t.string "location" t.string "location"
t.string "organization_name" t.string "organization_name"
t.datetime "unfeasible_email_sent_at"
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

View File

@@ -17,4 +17,41 @@ feature 'Budgets' do
budget.groups.each {|group| expect(page).to have_link(group.name)} budget.groups.each {|group| expect(page).to have_link(group.name)}
end end
context 'Accepting' do
let(:budget) { create(:budget) }
background do
budget.update(phase: 'accepting')
end
context "Permissions" do
scenario "Verified user" do
user = create(:user, :level_two)
login_as(user)
visit budget_path(budget)
expect(page).to have_link "Create budget investment"
end
scenario "Unverified user" do
user = create(:user)
login_as(user)
visit budget_path(budget)
expect(page).to have_content "To create a new budget investment verify your account."
end
scenario "user not logged in" do
visit budget_path(budget)
expect(page).to have_content "To create a new budget investment you must sign in or sign up."
end
end
end
end end

View File

@@ -23,6 +23,21 @@ feature 'Budget Investments' do
end end
end end
scenario 'Feasibility links' do
visit budget_investments_path(budget, heading_id: heading.id)
expect(page).to_not have_content('Feasible projects')
within('#sidebar') do
click_link 'Unfeasible projects'
end
expect(page).to have_current_path(budget_investments_path(budget, heading_id: heading.id, unfeasible: 1))
within('#sidebar') do
click_link 'Feasible projects'
end
expect(page).to have_current_path(budget_investments_path(budget, heading_id: heading.id, unfeasible: nil))
end
context("Search") do context("Search") do
scenario 'Search by text' do scenario 'Search by text' do
@@ -288,6 +303,105 @@ feature 'Budget Investments' do
end end
context "Selecting Phase" do
background do
budget.update(phase: "selecting")
end
context "Popup alert to vote only in one heading per group" do
scenario "When supporting in the first heading group", :js do
carabanchel = create(:budget_heading, group: group)
salamanca = create(:budget_heading, group: group)
carabanchel_investment = create(:budget_investment, :selected, heading: carabanchel)
salamanca_investment = create(:budget_investment, :selected, heading: salamanca)
visit budget_investments_path(budget, heading_id: carabanchel.id)
within("#budget_investment_#{carabanchel_investment.id}") do
expect(page).to have_css(".in-favor a[data-confirm]")
end
end
scenario "When already supported in the group", :js do
carabanchel = create(:budget_heading, group: group)
salamanca = create(:budget_heading, group: group)
carabanchel_investment = create(:budget_investment, heading: carabanchel)
salamanca_investment = create(:budget_investment, heading: salamanca)
create(:vote, votable: carabanchel_investment, voter: author)
login_as(author)
visit budget_investments_path(budget, heading_id: carabanchel.id)
within("#budget_investment_#{carabanchel_investment.id}") do
expect(page).to_not have_css(".in-favor a[data-confirm]")
end
end
scenario "When supporting in another group", :js do
carabanchel = create(:budget_heading, group: group)
another_heading = create(:budget_heading, group: create(:budget_group, budget: budget))
carabanchel_investment = create(:budget_investment, heading: carabanchel)
another_group_investment = create(:budget_investment, heading: another_heading)
create(:vote, votable: carabanchel_investment, voter: author)
login_as(author)
visit budget_investments_path(budget, heading_id: another_heading.id)
within("#budget_investment_#{another_group_investment.id}") do
expect(page).to have_css(".in-favor a[data-confirm]")
end
end
end
scenario "Sidebar in show should display support text" do
investment = create(:budget_investment, budget: budget)
visit budget_investment_path(budget, investment)
within("aside") do
expect(page).to have_content "Supports"
end
end
end
context "Evaluating Phase" do
background do
budget.update(phase: "valuating")
end
scenario "Sidebar in show should display supports text and supports" do
investment = create(:budget_investment, :selected, budget: budget)
create(:vote, votable: investment)
visit budget_investment_path(budget, investment)
within("aside") do
expect(page).to have_content "Supports"
expect(page).to have_content "1 support"
end
end
scenario "Index should display supports" do
investment = create(:budget_investment, :selected, budget: budget, heading: heading)
create(:vote, votable: investment)
visit budget_investments_path(budget, heading_id: heading.id)
within("#budget_investment_#{investment.id}") do
expect(page).to have_content "1 support"
end
end
end
context "Balloting Phase" do context "Balloting Phase" do
background do background do
@@ -348,6 +462,15 @@ feature 'Budget Investments' do
expect(page).to have_content "€10,000" expect(page).to have_content "€10,000"
end end
scenario "Sidebar in show should display vote text" do
investment = create(:budget_investment, :selected, budget: budget)
visit budget_investment_path(budget, investment)
within("aside") do
expect(page).to have_content "Votes"
end
end
scenario "Confirm", :js do scenario "Confirm", :js do
budget.update(phase: 'balloting') budget.update(phase: 'balloting')
user = create(:user, :level_two) user = create(:user, :level_two)

View File

@@ -55,7 +55,7 @@ feature 'Votes' do
feature 'Single spending proposal' do feature 'Single spending proposal' do
background do background do
@investment = create(:budget_investment, budget: budget) @investment = create(:budget_investment, budget: budget, heading: heading)
end end
scenario 'Show no votes' do scenario 'Show no votes' do
@@ -94,15 +94,13 @@ feature 'Votes' do
visit budget_investments_path(budget, heading_id: heading.id) visit budget_investments_path(budget, heading_id: heading.id)
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
find("div.js-participation").hover expect(page).to_not have_css("budget_investment_#{investment.id}_votes")
expect(page).to have_content 'No Selecting Allowed'
end end
visit budget_investment_path(budget, investment) visit budget_investment_path(budget, investment)
within("#budget_investment_#{investment.id}") do within("#budget_investment_#{investment.id}") do
find("div.js-participation").hover expect(page).to_not have_css("budget_investment_#{investment.id}_votes")
expect(page).to have_content 'No Selecting Allowed'
end end
end end
end end

View File

@@ -426,7 +426,7 @@ feature 'Debates' do
visit debates_path visit debates_path
click_link "Advanced search" click_link "Advanced search"
select "Public employee", from: "advanced_search_official_level" select Setting['official_level_1_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 debates") expect(page).to have_content("There are 2 debates")
@@ -449,7 +449,7 @@ feature 'Debates' do
visit debates_path visit debates_path
click_link "Advanced search" click_link "Advanced search"
select "Municipal Organization", from: "advanced_search_official_level" select Setting['official_level_2_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 debates") expect(page).to have_content("There are 2 debates")
@@ -472,7 +472,7 @@ feature 'Debates' do
visit debates_path visit debates_path
click_link "Advanced search" click_link "Advanced search"
select "General director", from: "advanced_search_official_level" select Setting['official_level_3_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 debates") expect(page).to have_content("There are 2 debates")
@@ -495,7 +495,7 @@ feature 'Debates' do
visit debates_path visit debates_path
click_link "Advanced search" click_link "Advanced search"
select "City councillor", from: "advanced_search_official_level" select Setting['official_level_4_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 debates") expect(page).to have_content("There are 2 debates")
@@ -518,7 +518,7 @@ feature 'Debates' do
visit debates_path visit debates_path
click_link "Advanced search" click_link "Advanced search"
select "Mayoress", from: "advanced_search_official_level" select Setting['official_level_5_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 debates") expect(page).to have_content("There are 2 debates")
@@ -652,7 +652,7 @@ feature 'Debates' do
click_link "Advanced search" click_link "Advanced search"
fill_in "Write the text", with: "Schwifty" fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level" select Setting['official_level_1_name'], from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min" select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter" click_button "Filter"
@@ -668,14 +668,14 @@ feature 'Debates' do
click_link "Advanced search" click_link "Advanced search"
fill_in "Write the text", with: "Schwifty" fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level" select Setting['official_level_1_name'], from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min" select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter" click_button "Filter"
within "#js-advanced-search" do within "#js-advanced-search" do
expect(page).to have_selector("input[name='search'][value='Schwifty']") expect(page).to have_selector("input[name='search'][value='Schwifty']")
expect(page).to have_select('advanced_search[official_level]', selected: 'Public employee') expect(page).to have_select('advanced_search[official_level]', selected: Setting['official_level_1_name'])
expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours') expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours')
end end
end end

View File

@@ -261,4 +261,65 @@ feature 'Emails' do
end end
context "Budgets" do
background do
Setting["feature.budgets"] = true
end
let(:author) { create(:user, :level_two) }
let(:budget) { create(:budget) }
let(:group) { create(:budget_group, name: "Health", budget: budget) }
let!(:heading) { create(:budget_heading, name: "More hospitals", group: group) }
scenario "Investment created" do
login_as(author)
visit new_budget_investment_path(budget_id: budget.id)
select 'Health: More hospitals', from: 'budget_investment_heading_id'
fill_in 'budget_investment_title', with: 'Build a hospital'
fill_in 'budget_investment_description', with: 'We have lots of people that require medical attention'
fill_in 'budget_investment_external_url', with: 'http://http://hospitalsforallthepeople.com/'
check 'budget_investment_terms_of_service'
click_button 'Create Investment'
expect(page).to have_content 'Investment created successfully'
email = open_last_email
investment = Budget::Investment.last
expect(email).to have_subject("Thank you for creating an investment!")
expect(email).to deliver_to(investment.author.email)
expect(email).to have_body_text(author.name)
expect(email).to have_body_text(investment.title)
expect(email).to have_body_text(investment.budget.name)
expect(email).to have_body_text(budget_path(budget))
end
scenario "Unfeasible investment" do
investment = create(:budget_investment, author: author, budget: budget)
valuator = create(:valuator)
investment.valuators << valuator
login_as(valuator.user)
visit edit_valuation_budget_budget_investment_path(budget, investment)
choose 'budget_investment_feasibility_unfeasible'
fill_in 'budget_investment_unfeasibility_explanation', with: 'This is not legal as stated in Article 34.9'
check 'budget_investment_valuation_finished'
click_button 'Save changes'
expect(page).to have_content "Dossier updated"
investment.reload
email = open_last_email
expect(email).to have_subject("Your investment project '#{investment.code}' has been marked as unfeasible")
expect(email).to deliver_to(investment.author.email)
expect(email).to have_body_text(investment.title)
expect(email).to have_body_text(investment.code)
expect(email).to have_body_text(investment.unfeasibility_explanation)
end
end
end end

View File

@@ -140,7 +140,7 @@ feature 'Budget Investments' do
context "Supporting" do context "Supporting" do
scenario 'Supporting budget investments on behalf of someone in index view', :js do scenario 'Supporting budget investments on behalf of someone in index view', :js do
budget_investment = create(:budget_investment, budget: @budget) budget_investment = create(:budget_investment, budget: @budget, heading: @heading)
user = create(:user, :level_two) user = create(:user, :level_two)
login_managed_user(user) login_managed_user(user)

View File

@@ -766,7 +766,7 @@ feature 'Proposals' do
visit proposals_path visit proposals_path
click_link "Advanced search" click_link "Advanced search"
select "Public employee", from: "advanced_search_official_level" select Setting['official_level_1_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 citizen proposals") expect(page).to have_content("There are 2 citizen proposals")
@@ -789,7 +789,7 @@ feature 'Proposals' do
visit proposals_path visit proposals_path
click_link "Advanced search" click_link "Advanced search"
select "Municipal Organization", from: "advanced_search_official_level" select Setting['official_level_2_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 citizen proposals") expect(page).to have_content("There are 2 citizen proposals")
@@ -812,7 +812,7 @@ feature 'Proposals' do
visit proposals_path visit proposals_path
click_link "Advanced search" click_link "Advanced search"
select "General director", from: "advanced_search_official_level" select Setting['official_level_3_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 citizen proposals") expect(page).to have_content("There are 2 citizen proposals")
@@ -835,7 +835,7 @@ feature 'Proposals' do
visit proposals_path visit proposals_path
click_link "Advanced search" click_link "Advanced search"
select "City councillor", from: "advanced_search_official_level" select Setting['official_level_4_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 citizen proposals") expect(page).to have_content("There are 2 citizen proposals")
@@ -858,7 +858,7 @@ feature 'Proposals' do
visit proposals_path visit proposals_path
click_link "Advanced search" click_link "Advanced search"
select "Mayoress", from: "advanced_search_official_level" select Setting['official_level_5_name'], from: "advanced_search_official_level"
click_button "Filter" click_button "Filter"
expect(page).to have_content("There are 2 citizen proposals") expect(page).to have_content("There are 2 citizen proposals")
@@ -992,7 +992,7 @@ feature 'Proposals' do
click_link "Advanced search" click_link "Advanced search"
fill_in "Write the text", with: "Schwifty" fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level" select Setting['official_level_1_name'], from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min" select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter" click_button "Filter"
@@ -1009,7 +1009,7 @@ feature 'Proposals' do
click_link "Advanced search" click_link "Advanced search"
fill_in "Write the text", with: "Schwifty" fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level" select Setting['official_level_1_name'], from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min" select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter" click_button "Filter"
@@ -1018,7 +1018,7 @@ feature 'Proposals' do
within "#js-advanced-search" do within "#js-advanced-search" do
expect(page).to have_selector("input[name='search'][value='Schwifty']") expect(page).to have_selector("input[name='search'][value='Schwifty']")
expect(page).to have_select('advanced_search[official_level]', selected: 'Public employee') expect(page).to have_select('advanced_search[official_level]', selected: Setting['official_level_1_name'])
expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours') expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours')
end end
end end

View File

@@ -164,9 +164,13 @@ feature 'Tags' do
context 'Tag cloud' do context 'Tag cloud' do
let!(:investment1) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') }
let!(:investment2) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') }
let!(:investment3) { create(:budget_investment, heading: heading, tag_list: 'Economía') }
scenario 'Display user tags' do scenario 'Display user tags' do
earth = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') Budget::PHASES.each do |phase|
money = create(:budget_investment, heading: heading, tag_list: 'Economía') budget.update(phase: phase)
visit budget_investments_path(budget, heading_id: heading.id) visit budget_investments_path(budget, heading_id: heading.id)
@@ -175,11 +179,17 @@ feature 'Tags' do
expect(page).to have_content "Economía" expect(page).to have_content "Economía"
end end
end end
end
scenario "Filter by user tags" do scenario "Filter by user tags" do
investment1 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') Budget::PHASES.each do |phase|
investment2 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') budget.update(phase: phase)
investment3 = create(:budget_investment, heading: heading, tag_list: 'Economía')
if budget.balloting?
[investment1, investment2, investment3].each do |investment|
investment.update(selected: true)
end
end
visit budget_investments_path(budget, heading_id: heading.id) visit budget_investments_path(budget, heading_id: heading.id)
@@ -192,17 +202,22 @@ feature 'Tags' do
expect(page).to have_content investment2.title expect(page).to have_content investment2.title
expect(page).to_not have_content investment3.title expect(page).to_not have_content investment3.title
end end
end
end end
context "Categories" do context "Categories" do
scenario 'Display category tags' do let!(:tag1) { create(:tag, kind: 'category', name: 'Medio Ambiente') }
create(:tag, kind: 'category', name: 'Medio Ambiente') let!(:tag2) { create(:tag, kind: 'category', name: 'Economía') }
create(:tag, kind: 'category', name: 'Economía')
earth = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') let!(:investment1) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') }
money = create(:budget_investment, heading: heading, tag_list: 'Economía') let!(:investment2) { create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') }
let!(:investment3) { create(:budget_investment, heading: heading, tag_list: 'Economía') }
scenario 'Display category tags' do
Budget::PHASES.each do |phase|
budget.update(phase: phase)
visit budget_investments_path(budget, heading_id: heading.id) visit budget_investments_path(budget, heading_id: heading.id)
@@ -211,14 +226,17 @@ feature 'Tags' do
expect(page).to have_content "Economía" expect(page).to have_content "Economía"
end end
end end
end
scenario "Filter by category tags" do scenario "Filter by category tags" do
create(:tag, kind: 'category', name: 'Medio Ambiente') Budget::PHASES.each do |phase|
create(:tag, kind: 'category', name: 'Economía') budget.update(phase: phase)
investment1 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') if budget.balloting?
investment2 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') [investment1, investment2, investment3].each do |investment|
investment3 = create(:budget_investment, heading: heading, tag_list: 'Economía') investment.update(selected: true)
end
end
visit budget_investments_path(budget, heading_id: heading.id, search: 'Economía') visit budget_investments_path(budget, heading_id: heading.id, search: 'Economía')
@@ -232,6 +250,7 @@ feature 'Tags' do
expect(page).to_not have_content investment3.title expect(page).to_not have_content investment3.title
end end
end end
end
context "Valuation" do context "Valuation" do

View File

@@ -58,10 +58,47 @@ describe Budget::Investment do
end end
describe "#code" do describe "#code" do
it "returns the investment and budget id" do let(:investment) { create(:budget_investment) }
investment = create(:budget_investment)
it "returns the proposal id" do
expect(investment.code).to include("#{investment.id}") expect(investment.code).to include("#{investment.id}")
expect(investment.code).to include("#{investment.budget.id}") end
it "returns the administrator id when assigned" do
investment.administrator = create(:administrator)
expect(investment.code).to include("#{investment.id}-A#{investment.administrator.id}")
end
end
describe "#send_unfeasible_email" do
let(:investment) { create(:budget_investment) }
it "sets the time when the unfeasible email was sent" do
expect(investment.unfeasible_email_sent_at).to_not be
investment.send_unfeasible_email
expect(investment.unfeasible_email_sent_at).to be
end
it "send an email" do
expect {investment.send_unfeasible_email}.to change { ActionMailer::Base.deliveries.count }.by(1)
end
end
describe "#should_show_votes?" do
it "returns true in selecting phase" do
budget = create(:budget, phase: "selecting")
investment = create(:budget_investment, budget: budget)
expect(investment.should_show_votes?).to eq(true)
end
it "returns false in any other phase" do
Budget::PHASES.reject {|phase| phase == "selecting"}.each do |phase|
budget = create(:budget, phase: phase)
investment = create(:budget_investment, budget: budget)
expect(investment.should_show_votes?).to eq(false)
end
end end
end end
@@ -236,6 +273,18 @@ describe Budget::Investment do
budget.phase = "selecting" budget.phase = "selecting"
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
it "rejects votes in two headings of the same group" do
carabanchel = create(:budget_heading, group: group)
salamanca = create(:budget_heading, group: group)
carabanchel_investment = create(:budget_investment, heading: carabanchel)
salamanca_investment = create(:budget_investment, heading: salamanca)
create(:vote, votable: carabanchel_investment, voter: user)
expect(salamanca_investment.valid_heading?(user)).to eq(false)
end
end end
end end