diff --git a/CUSTOMIZE_ES.md b/CUSTOMIZE_ES.md index 09fdfe62c..33c91b268 100644 --- a/CUSTOMIZE_ES.md +++ b/CUSTOMIZE_ES.md @@ -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: * `app/assets/stylesheets/custom.css` +* `app/assets/stylesheets/_custom_settings.css` * `app/assets/javascripts/custom.js` * `Gemfile_custom` * `config/application.custom.rb` @@ -67,6 +68,11 @@ Si quieres cambiar algun selector CSS (de las hojas de estilo) puedes hacerlo en 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). diff --git a/app/assets/stylesheets/_custom_settings.scss b/app/assets/stylesheets/_custom_settings.scss new file mode 100644 index 000000000..92a304e6f --- /dev/null +++ b/app/assets/stylesheets/_custom_settings.scss @@ -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 +// diff --git a/app/assets/stylesheets/foundation_and_overrides.scss b/app/assets/stylesheets/foundation_and_overrides.scss index cd33ac92d..992b0cc81 100644 --- a/app/assets/stylesheets/foundation_and_overrides.scss +++ b/app/assets/stylesheets/foundation_and_overrides.scss @@ -1,6 +1,7 @@ @charset 'utf-8'; @import 'settings'; +@import 'custom_settings'; @import 'foundation'; @include foundation-global-styles; diff --git a/app/controllers/budgets/ballot/lines_controller.rb b/app/controllers/budgets/ballot/lines_controller.rb index 0f8209e5a..2feb83e5e 100644 --- a/app/controllers/budgets/ballot/lines_controller.rb +++ b/app/controllers/budgets/ballot/lines_controller.rb @@ -5,6 +5,8 @@ module Budgets #before_action :ensure_final_voting_allowed before_action :load_budget before_action :load_ballot + before_action :load_tag_cloud + before_action :load_categories before_action :load_investments @@ -63,6 +65,14 @@ module Budgets @heading = @investment.heading 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 diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 235163f2e..ebf14d94b 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -46,6 +46,7 @@ module Budgets @investment.author = current_user if @investment.save + Mailer.budget_investment_created(@investment).deliver_later redirect_to budget_investment_path(@budget, @investment), notice: t('flash.actions.create.budget_investment') else @@ -61,6 +62,10 @@ module Budgets def vote @investment.register_selection(current_user) load_investment_votes(@investment) + respond_to do |format| + format.html { redirect_to budget_investments_path(heading_id: @investment.heading.id) } + format.js + end end private diff --git a/app/controllers/management/budgets/investments_controller.rb b/app/controllers/management/budgets/investments_controller.rb index e790312d6..025b6301d 100644 --- a/app/controllers/management/budgets/investments_controller.rb +++ b/app/controllers/management/budgets/investments_controller.rb @@ -34,6 +34,10 @@ class Management::Budgets::InvestmentsController < Management::BaseController def vote @investment.register_selection(managed_user) 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 def print diff --git a/app/controllers/valuation/budget_investments_controller.rb b/app/controllers/valuation/budget_investments_controller.rb index 03facadb3..666fac74a 100644 --- a/app/controllers/valuation/budget_investments_controller.rb +++ b/app/controllers/valuation/budget_investments_controller.rb @@ -21,6 +21,11 @@ class Valuation::BudgetInvestmentsController < Valuation::BaseController def valuate 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') else render action: :edit diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index 3d30ce101..ebde2a954 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -1,13 +1,8 @@ module SearchHelper def official_level_search_options - options_for_select([ - [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)) + options_for_select((1..5).map{ |i| [setting["official_level_#{i}_name"], i] }, + params[:advanced_search].try(:[], :official_level)) end def date_range_options @@ -28,4 +23,4 @@ module SearchHelper params[:advanced_search].try(:[], :date_max).present? end -end \ No newline at end of file +end diff --git a/app/mailers/mailer.rb b/app/mailers/mailer.rb index 25c019857..188de029b 100644 --- a/app/mailers/mailer.rb +++ b/app/mailers/mailer.rb @@ -74,6 +74,23 @@ class Mailer < ApplicationMailer 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 def with_user(user, &block) diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 5389825e5..100433707 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -136,16 +136,26 @@ class Budget unfeasible? && valuation_finished? end + def unfeasible_email_pending? + unfeasible_email_sent_at.blank? && unfeasible? && valuation_finished? + end + def total_votes cached_votes_up + physical_votes end 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 def reason_for_not_being_selectable_by(user) return permission_problem(user) if permission_problem?(user) + return :different_heading_assigned unless valid_heading?(user) return :no_selecting_allowed unless budget.selecting? end @@ -173,6 +183,24 @@ class Budget reason_for_not_being_selectable_by(user).blank? 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) reason_for_not_being_ballotable_by(user).blank? end @@ -195,11 +223,17 @@ class Budget end def should_show_aside? - (budget.selecting? && !unfeasible?) || (budget.balloting? && feasible?) || budget.on_hold? + (budget.selecting? && !unfeasible?) || + (budget.balloting? && feasible?) || + (budget.valuating? && feasible?) end def should_show_votes? - budget.selecting? || budget.on_hold? + budget.selecting? + end + + def should_show_vote_count? + budget.valuating? end def should_show_ballots? diff --git a/app/models/user.rb b/app/models/user.rb index 82324da7e..a570b1477 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -104,6 +104,10 @@ class User < ActiveRecord::Base comment_flags.each_with_object({}){ |f, h| h[f.flaggable_id] = true } end + def voted_in_group?(group) + votes.for_budget_investments(Budget::Investment.where(group: group)).exists? + end + def administrator? administrator.present? end diff --git a/app/views/budgets/investments/_feasibility_link.html.erb b/app/views/budgets/investments/_feasibility_link.html.erb new file mode 100644 index 000000000..118a02e7f --- /dev/null +++ b/app/views/budgets/investments/_feasibility_link.html.erb @@ -0,0 +1,11 @@ + + +
+ +<% 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 %> \ No newline at end of file diff --git a/app/views/budgets/investments/_investment.html.erb b/app/views/budgets/investments/_investment.html.erb index c9c247784..c9391cbe5 100644 --- a/app/views/budgets/investments/_investment.html.erb +++ b/app/views/budgets/investments/_investment.html.erb @@ -46,7 +46,6 @@ <% unless investment.unfeasible? %> <% if investment.should_show_votes? %> -
<%= render partial: '/budgets/investments/votes', locals: { @@ -55,9 +54,17 @@ vote_url: namespaced_budget_investment_vote_path(investment, value: 'yes') } %>
- + <% elsif investment.should_show_vote_count? %> +
+
+ + <%= t("budgets.investments.investment.supports", + count: investment.total_votes) %> + +
+
<% elsif investment.should_show_ballots? %> -
<%= render partial: '/budgets/investments/ballot', locals: { @@ -66,7 +73,6 @@ ballot: ballot } %>
- <% end %> <% end %> diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index 12f23fe87..fad11d0f0 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -55,11 +55,10 @@ <% if investment.should_show_aside? %> diff --git a/app/views/budgets/investments/_sidebar.html.erb b/app/views/budgets/investments/_sidebar.html.erb index 9430120bc..4075bb29e 100644 --- a/app/views/budgets/investments/_sidebar.html.erb +++ b/app/views/budgets/investments/_sidebar.html.erb @@ -2,26 +2,29 @@ <% if can?(:create, Budget::Investment.new(budget: @budget)) %> <% 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 %>
<%= 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 %>
<% end %> <% end %> -<% if @budget.accepting? %> - <%= render "shared/tag_cloud", taggable: 'budget/investment' %> - <%= render 'categories' %> -<% end %> - +<%= render "shared/tag_cloud", taggable: 'budget/investment' %> +<%= render 'budgets/investments/categories' %> +<%= render 'budgets/investments/feasibility_link' %> <% if @heading && can?(:show, @ballot) %> - + + <% if @ballot.investments.by_heading(@heading.id).count > 0 %>

@@ -44,5 +47,7 @@ <% end %> -

<%= t("budgets.investments.index.sidebar.voted_info") %>

+

+ <%= t("budgets.investments.index.sidebar.voted_info") %> +

<% end %> diff --git a/app/views/budgets/investments/_votes.html.erb b/app/views/budgets/investments/_votes.html.erb index 6d62b9a02..c2870d76c 100644 --- a/app/views/budgets/investments/_votes.html.erb +++ b/app/views/budgets/investments/_votes.html.erb @@ -14,12 +14,12 @@ <%= t("budgets.investments.investment.already_supported") %> <% elsif investment.should_show_votes? %> - <%= link_to vote_url, class: "button button-support small expanded", title: t('budgets.investments.investment.support_title'), 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 %> <%= t("budgets.investments.investment.give_support") %> <% end %> diff --git a/app/views/budgets/show.html.erb b/app/views/budgets/show.html.erb index 499b7eb58..d68f2023c 100644 --- a/app/views/budgets/show.html.erb +++ b/app/views/budgets/show.html.erb @@ -14,7 +14,7 @@ <%= t("budgets.phase.#{@budget.phase}") %>

- <% if can?(:create, Budget::Investment.new(budget: @budget))%> + <% if @budget.accepting? %> <% if current_user %> <% 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" %> diff --git a/app/views/mailer/budget_investment_created.html.erb b/app/views/mailer/budget_investment_created.html.erb new file mode 100644 index 000000000..59af63dd1 --- /dev/null +++ b/app/views/mailer/budget_investment_created.html.erb @@ -0,0 +1,42 @@ + + +

+ <%= t("mailers.budget_investment_created.title") %> +

+ +

+ <%= t("mailers.budget_investment_created.intro_html", + author: @investment.author.name).html_safe %> +

+ +

+ <%= t("mailers.budget_investment_created.text_html", + investment: @investment.title, + budget: @investment.budget.name).html_safe %> +

+ +

+ <%= t("mailers.budget_investment_created.follow_html", + link: link_to(t("mailers.budget_investment_created.follow_link"), budgets_url)).html_safe %> +

+ + + + + + + +
+ <%= 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 %> +
+ +

+ <%= t("mailers.budget_investment_created.sincerely") %> +
+ + <%= t("mailers.budget_investment_created.signatory") %> + +

diff --git a/app/views/mailer/budget_investment_unfeasible.html.erb b/app/views/mailer/budget_investment_unfeasible.html.erb new file mode 100644 index 000000000..3bed46cec --- /dev/null +++ b/app/views/mailer/budget_investment_unfeasible.html.erb @@ -0,0 +1,35 @@ + + +

+ <%= t("mailers.budget_investment_unfeasible.hi") %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.unfeasible_html", + title: @investment.title) %> +

+ +

+ <%= @investment.unfeasibility_explanation %> +

+ +

+ <%= 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;")) %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.reconsider_html", code: @investment.code) %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.sorry") %> +

+ +

+ <%= t("mailers.budget_investment_unfeasible.sincerely") %>
+ + <%= t("mailers.budget_investment_unfeasible.signatory") %> +

+ \ No newline at end of file diff --git a/config/initializers/ckeditor.rb b/config/initializers/ckeditor.rb index 58e119048..b3ef16d2d 100644 --- a/config/initializers/ckeditor.rb +++ b/config/initializers/ckeditor.rb @@ -1,4 +1,4 @@ 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 = [] end diff --git a/config/locales/budgets.en.yml b/config/locales/budgets.en.yml index 3ce0bb3ee..9b57f6b22 100644 --- a/config/locales/budgets.en.yml +++ b/config/locales/budgets.en.yml @@ -64,6 +64,9 @@ en: not_logged_in: "To create a new budget investment you must %{sign_in} or %{sign_up}." sign_in: "sign in" sign_up: "sign up" + by_feasibility: By feasibility + feasible: Feasible projects + unfeasible: Unfeasible projects orders: random: random confidence_score: highest rated @@ -77,6 +80,8 @@ en: organization_name_html: 'Organization: %{name}' share: Share title: Investment project + supports: Supports + votes: Votes wrong_price_format: Only integer numbers investment: title: Investment project @@ -84,6 +89,7 @@ en: already_added: You have already added this investment project already_supported: You have already supported this. Share it! 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: one: 1 support other: "%{count} supports" diff --git a/config/locales/budgets.es.yml b/config/locales/budgets.es.yml index d558d5edd..93c7a15aa 100644 --- a/config/locales/budgets.es.yml +++ b/config/locales/budgets.es.yml @@ -64,6 +64,9 @@ es: not_logged_in: "Para crear una nueva propuesta de inversión debes %{sign_in} o %{sign_up}." sign_in: "iniciar sesión" sign_up: "registrarte" + by_feasibility: Por viabilidad + feasible: Ver los proyectos viables + unfeasible: Ver los proyectos inviables orders: random: Aleatorias confidence_score: Mejor valoradas @@ -77,6 +80,8 @@ es: organization_name_html: 'Organización: %{name}' share: Compartir title: Propuesta de inversión + supports: Apoyos + votes: Votos wrong_price_format: Solo puede incluir caracteres numéricos investment: title: Propuesta de inversión @@ -84,6 +89,7 @@ es: already_added: "Ya has añadido esta propuesta de inversión" already_supported: Ya has apoyado esta propuesta. ¡Compártelo! 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: one: 1 apoyo other: "%{count} apoyos" diff --git a/config/locales/en.yml b/config/locales/en.yml index d65c3b007..5fa5d6727 100755 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -522,11 +522,6 @@ en: advanced_search: author_type: 'By author 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_placeholder: 'DD/MM/YYYY' date_range_blank: 'Choose a date' @@ -708,6 +703,13 @@ en: organization: Organizations are not permitted to vote unfeasible: Unfeasible investment projects can not be supported 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: debates: description: For meeting, discussing and sharing the things that matter to us in our city. diff --git a/config/locales/es.yml b/config/locales/es.yml index 708a74ed2..2732af08f 100755 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -522,11 +522,6 @@ es: advanced_search: author_type: 'Por categoría de autor' 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_placeholder: 'DD/MM/AAAA' date_range_blank: 'Elige una fecha' @@ -708,6 +703,13 @@ es: organization: Las organizaciones no pueden votar. unfeasible: No se pueden votar propuestas inviables. 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: debates: description: Encontrarnos, debatir y compartir lo que nos parece importante en nuestra ciudad. diff --git a/config/locales/fr.yml b/config/locales/fr.yml index ef0f5a419..596531c0d 100644 --- a/config/locales/fr.yml +++ b/config/locales/fr.yml @@ -1361,11 +1361,6 @@ fr: shared: advanced_search: 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 date: Par date date_1: Dernières 24 heures diff --git a/config/locales/mailers.en.yml b/config/locales/mailers.en.yml index 3fa63f9ec..49143f354 100755 --- a/config/locales/mailers.en.yml +++ b/config/locales/mailers.en.yml @@ -31,6 +31,16 @@ en: 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 participatory budgets. We regret to inform you that your proposal '%{title}' 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 new proposal 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 participatory budgets. We regret to inform you that your proposal '%{title}' will be excluded from this participatory process for the following reason:" 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}." title: "Proposal notifications in %{org_name}" @@ -52,4 +62,24 @@ en: thanks: "Thank you very much." title: "Welcome to %{org}" button: Complete registration - subject: "Invitation to %{org_name}" \ No newline at end of file + 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 %{author}," + text_html: "Thank you for creating your investment %{investment} for Participatory Budgets %{budget}." + follow_html: "We will inform you about how the process progresses, which you can also follow on %{link}." + 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 new investment 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 participatory budgets. We regret to inform you that your investment '%{title}' will be excluded from this participatory process for the following reason:" \ No newline at end of file diff --git a/config/locales/mailers.es.yml b/config/locales/mailers.es.yml index 49e3e0796..82a03d8de 100644 --- a/config/locales/mailers.es.yml +++ b/config/locales/mailers.es.yml @@ -52,4 +52,24 @@ es: thanks: "Muchas gracias." title: "Bienvenido a %{org}" button: Completar registro - subject: "Invitación a %{org_name}" \ No newline at end of file + subject: "Invitación a %{org_name}" + budget_investment_created: + subject: "¡Gracias por crear un proyecto!" + title: "¡Gracias por crear un proyecto!" + intro_html: "Hola %{author}," + text_html: "Muchas gracias por crear tu proyecto %{investment} para los Presupuestos Participativos %{budget}." + follow_html: "Te informaremos de cómo avanza el proceso, que también puedes seguir en la página de %{link}." + 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 nuevo proyecto de gasto 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 Presupuestos Participativos. Lamentamos informarte de que tu proyecto '%{title}' quedará excluido de este proceso participativo por el siguiente motivo:" \ No newline at end of file diff --git a/config/locales/pt-BR.yml b/config/locales/pt-BR.yml index 2254e6e94..ace7406a7 100644 --- a/config/locales/pt-BR.yml +++ b/config/locales/pt-BR.yml @@ -1383,11 +1383,6 @@ pt-BR: shared: advanced_search: 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 date: Por data date_1: "Últimas 24 horas" diff --git a/db/dev_seeds.rb b/db/dev_seeds.rb index 33e239515..b70755b59 100644 --- a/db/dev_seeds.rb +++ b/db/dev_seeds.rb @@ -55,6 +55,7 @@ end admin = create_user('admin@consul.dev', 'admin') 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_moderator diff --git a/db/migrate/20170114154421_add_unfeasible_email_sent_at_to_budget_investments.rb b/db/migrate/20170114154421_add_unfeasible_email_sent_at_to_budget_investments.rb new file mode 100644 index 000000000..dbd1a203b --- /dev/null +++ b/db/migrate/20170114154421_add_unfeasible_email_sent_at_to_budget_investments.rb @@ -0,0 +1,5 @@ +class AddUnfeasibleEmailSentAtToBudgetInvestments < ActiveRecord::Migration + def change + add_column :budget_investments, :unfeasible_email_sent_at, :datetime + end +end diff --git a/db/schema.rb b/db/schema.rb index d5c2fa8f3..8118089ee 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -11,7 +11,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 20170106130838) do +ActiveRecord::Schema.define(version: 20170114154421) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -143,6 +143,7 @@ ActiveRecord::Schema.define(version: 20170106130838) do t.boolean "selected", default: false t.string "location" t.string "organization_name" + t.datetime "unfeasible_email_sent_at" end add_index "budget_investments", ["administrator_id"], name: "index_budget_investments_on_administrator_id", using: :btree diff --git a/spec/features/budgets/budgets_spec.rb b/spec/features/budgets/budgets_spec.rb index ccf94defd..4d4d603f3 100644 --- a/spec/features/budgets/budgets_spec.rb +++ b/spec/features/budgets/budgets_spec.rb @@ -17,4 +17,41 @@ feature 'Budgets' do budget.groups.each {|group| expect(page).to have_link(group.name)} 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 \ No newline at end of file diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb index 98540aa68..21238c554 100644 --- a/spec/features/budgets/investments_spec.rb +++ b/spec/features/budgets/investments_spec.rb @@ -23,6 +23,21 @@ feature 'Budget Investments' do 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 scenario 'Search by text' do @@ -288,6 +303,105 @@ feature 'Budget Investments' do 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 background do @@ -348,6 +462,15 @@ feature 'Budget Investments' do expect(page).to have_content "€10,000" 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 budget.update(phase: 'balloting') user = create(:user, :level_two) diff --git a/spec/features/budgets/votes_spec.rb b/spec/features/budgets/votes_spec.rb index c31545428..497046891 100644 --- a/spec/features/budgets/votes_spec.rb +++ b/spec/features/budgets/votes_spec.rb @@ -55,7 +55,7 @@ feature 'Votes' do feature 'Single spending proposal' do background do - @investment = create(:budget_investment, budget: budget) + @investment = create(:budget_investment, budget: budget, heading: heading) end scenario 'Show no votes' do @@ -94,15 +94,13 @@ feature 'Votes' do visit budget_investments_path(budget, heading_id: heading.id) within("#budget_investment_#{investment.id}") do - find("div.js-participation").hover - expect(page).to have_content 'No Selecting Allowed' + expect(page).to_not have_css("budget_investment_#{investment.id}_votes") end visit budget_investment_path(budget, investment) within("#budget_investment_#{investment.id}") do - find("div.js-participation").hover - expect(page).to have_content 'No Selecting Allowed' + expect(page).to_not have_css("budget_investment_#{investment.id}_votes") end end end diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index d959f4308..f16f416bf 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -426,7 +426,7 @@ feature 'Debates' do visit debates_path 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" expect(page).to have_content("There are 2 debates") @@ -449,7 +449,7 @@ feature 'Debates' do visit debates_path 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" expect(page).to have_content("There are 2 debates") @@ -472,7 +472,7 @@ feature 'Debates' do visit debates_path 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" expect(page).to have_content("There are 2 debates") @@ -495,7 +495,7 @@ feature 'Debates' do visit debates_path 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" expect(page).to have_content("There are 2 debates") @@ -518,7 +518,7 @@ feature 'Debates' do visit debates_path 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" expect(page).to have_content("There are 2 debates") @@ -652,7 +652,7 @@ feature 'Debates' do click_link "Advanced search" 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" click_button "Filter" @@ -668,14 +668,14 @@ feature 'Debates' do click_link "Advanced search" 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" click_button "Filter" within "#js-advanced-search" do 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') end end diff --git a/spec/features/emails_spec.rb b/spec/features/emails_spec.rb index fe6c18774..b3e52370d 100644 --- a/spec/features/emails_spec.rb +++ b/spec/features/emails_spec.rb @@ -261,4 +261,65 @@ feature 'Emails' do 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 diff --git a/spec/features/management/budget_investments_spec.rb b/spec/features/management/budget_investments_spec.rb index 02f4cf36f..5b3961306 100644 --- a/spec/features/management/budget_investments_spec.rb +++ b/spec/features/management/budget_investments_spec.rb @@ -140,7 +140,7 @@ feature 'Budget Investments' do context "Supporting" 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) login_managed_user(user) diff --git a/spec/features/proposals_spec.rb b/spec/features/proposals_spec.rb index 767f2d090..18864dc9b 100644 --- a/spec/features/proposals_spec.rb +++ b/spec/features/proposals_spec.rb @@ -766,7 +766,7 @@ feature 'Proposals' do visit proposals_path 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" expect(page).to have_content("There are 2 citizen proposals") @@ -789,7 +789,7 @@ feature 'Proposals' do visit proposals_path 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" expect(page).to have_content("There are 2 citizen proposals") @@ -812,7 +812,7 @@ feature 'Proposals' do visit proposals_path 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" expect(page).to have_content("There are 2 citizen proposals") @@ -835,7 +835,7 @@ feature 'Proposals' do visit proposals_path 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" expect(page).to have_content("There are 2 citizen proposals") @@ -858,7 +858,7 @@ feature 'Proposals' do visit proposals_path 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" expect(page).to have_content("There are 2 citizen proposals") @@ -992,7 +992,7 @@ feature 'Proposals' do click_link "Advanced search" 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" click_button "Filter" @@ -1009,7 +1009,7 @@ feature 'Proposals' do click_link "Advanced search" 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" click_button "Filter" @@ -1018,7 +1018,7 @@ feature 'Proposals' do within "#js-advanced-search" do 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') end end diff --git a/spec/features/tags/budget_investments_spec.rb b/spec/features/tags/budget_investments_spec.rb index f16e9a447..0b22297bf 100644 --- a/spec/features/tags/budget_investments_spec.rb +++ b/spec/features/tags/budget_investments_spec.rb @@ -164,72 +164,91 @@ feature 'Tags' 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 - earth = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - money = create(:budget_investment, heading: heading, tag_list: 'Economía') + 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) - within "#tag-cloud" do - expect(page).to have_content "Medio Ambiente" - expect(page).to have_content "Economía" + within "#tag-cloud" do + expect(page).to have_content "Medio Ambiente" + expect(page).to have_content "Economía" + end end end scenario "Filter by user tags" do - investment1 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - investment2 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - investment3 = create(:budget_investment, heading: heading, tag_list: 'Economía') + Budget::PHASES.each do |phase| + budget.update(phase: phase) - visit budget_investments_path(budget, heading_id: heading.id) + if budget.balloting? + [investment1, investment2, investment3].each do |investment| + investment.update(selected: true) + end + end - within "#tag-cloud" do - click_link "Medio Ambiente" + visit budget_investments_path(budget, heading_id: heading.id) + + within "#tag-cloud" do + click_link "Medio Ambiente" + end + + expect(page).to have_css ".budget-investment", count: 2 + expect(page).to have_content investment1.title + expect(page).to have_content investment2.title + expect(page).to_not have_content investment3.title end - - expect(page).to have_css ".budget-investment", count: 2 - expect(page).to have_content investment1.title - expect(page).to have_content investment2.title - expect(page).to_not have_content investment3.title end end context "Categories" do + let!(:tag1) { create(:tag, kind: 'category', name: 'Medio Ambiente') } + let!(:tag2) { create(:tag, kind: 'category', name: 'Economía') } + + 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 category tags' do - create(:tag, kind: 'category', name: 'Medio Ambiente') - create(:tag, kind: 'category', name: 'Economía') + Budget::PHASES.each do |phase| + budget.update(phase: phase) - earth = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - money = create(:budget_investment, heading: heading, tag_list: 'Economía') + visit budget_investments_path(budget, heading_id: heading.id) - visit budget_investments_path(budget, heading_id: heading.id) - - within "#categories" do - expect(page).to have_content "Medio Ambiente" - expect(page).to have_content "Economía" + within "#categories" do + expect(page).to have_content "Medio Ambiente" + expect(page).to have_content "Economía" + end end end scenario "Filter by category tags" do - create(:tag, kind: 'category', name: 'Medio Ambiente') - create(:tag, kind: 'category', name: 'Economía') + Budget::PHASES.each do |phase| + budget.update(phase: phase) - investment1 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - investment2 = create(:budget_investment, heading: heading, tag_list: 'Medio Ambiente') - 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, search: 'Economía') + visit budget_investments_path(budget, heading_id: heading.id, search: 'Economía') - within "#categories" do - click_link "Medio Ambiente" + within "#categories" do + click_link "Medio Ambiente" + end + + expect(page).to have_css ".budget-investment", count: 2 + expect(page).to have_content investment1.title + expect(page).to have_content investment2.title + expect(page).to_not have_content investment3.title end - - expect(page).to have_css ".budget-investment", count: 2 - expect(page).to have_content investment1.title - expect(page).to have_content investment2.title - expect(page).to_not have_content investment3.title end end diff --git a/spec/models/budget/investment_spec.rb b/spec/models/budget/investment_spec.rb index 0c6615a99..abbc8ad26 100644 --- a/spec/models/budget/investment_spec.rb +++ b/spec/models/budget/investment_spec.rb @@ -58,10 +58,47 @@ describe Budget::Investment do end describe "#code" do - it "returns the investment and budget id" do - investment = create(:budget_investment) - expect(investment.code).to include("#{investment.id}") - expect(investment.code).to include("#{investment.budget.id}") + let(:investment) { create(:budget_investment) } + + it "returns the proposal id" do + expect(investment.code).to include("#{investment.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 @@ -236,6 +273,18 @@ describe Budget::Investment do budget.phase = "selecting" expect(district_sp.reason_for_not_being_selectable_by(user)).to be_nil 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