diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb
index 0084e71db..969d3689d 100644
--- a/app/controllers/budgets/investments_controller.rb
+++ b/app/controllers/budgets/investments_controller.rb
@@ -13,6 +13,7 @@ module Budgets
before_action :load_ballot, only: [:index, :show]
before_action :load_heading, only: [:index, :show]
before_action :set_random_seed, only: :index
+ before_action :load_categories, only: [:index, :new, :create]
feature_flag :budgets
@@ -50,6 +51,7 @@ module Budgets
flash: { html_safe: true },
notice: t('flash.actions.create.budget_investment', activity: activity_link)
else
+
render :new
end
end
@@ -80,7 +82,7 @@ module Budgets
end
def investment_params
- params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :terms_of_service, :location)
+ params.require(:budget_investment).permit(:title, :description, :external_url, :heading_id, :terms_of_service, :location, :tag_list)
end
def load_ballot
@@ -95,6 +97,10 @@ module Budgets
end
end
+ def load_categories
+ @categories = ActsAsTaggableOn::Tag.where("kind = 'category'").order(:name)
+ end
+
end
end
diff --git a/app/models/budget/heading.rb b/app/models/budget/heading.rb
index 52da63c4f..1aad3316a 100644
--- a/app/models/budget/heading.rb
+++ b/app/models/budget/heading.rb
@@ -9,16 +9,10 @@ class Budget
validates :name, presence: true
validates :price, presence: true
+ delegate :budget, to: :group, allow_nil: true
+
scope :order_by_group_name, -> { includes(:group).order('budget_groups.name', 'budget_headings.name') }
- def budget
- group.budget
- end
-
- def budget=(resource)
- group.budget = resource
- end
-
def name_scoped_by_group
"#{group.name}: #{name}"
end
diff --git a/app/views/budgets/investments/_form.html.erb b/app/views/budgets/investments/_form.html.erb
index 8e7643285..724aae086 100644
--- a/app/views/budgets/investments/_form.html.erb
+++ b/app/views/budgets/investments/_form.html.erb
@@ -3,32 +3,46 @@
- <%= f.label :heading_id, t("budget.investments.form.heading") %>
- <%= f.select :heading_id, budget_heading_select_options(@budget), {include_blank: true, label: false} %>
+ <%= f.select :heading_id, budget_heading_select_options(@budget), include_blank: true %>
- <%= f.label :title, t("budget.investments.form.title") %>
- <%= f.text_field :title, maxlength: SpendingProposal.title_max_length, placeholder: t("budget.investments.form.title"), label: false %>
+ <%= f.text_field :title, maxlength: SpendingProposal.title_max_length %>
<%= f.invisible_captcha :subtitle %>
- <%= f.label :description, t("budget.investments.form.description") %>
- <%= f.cktext_area :description, maxlength: SpendingProposal.description_max_length, ckeditor: { language: I18n.locale }, label: false %>
+ <%= f.cktext_area :description, maxlength: SpendingProposal.description_max_length, ckeditor: { language: I18n.locale } %>
- <%= f.label :external_url, t("budget.investments.form.external_url") %>
- <%= f.text_field :external_url, placeholder: t("budget.investments.form.external_url"), label: false %>
+ <%= f.text_field :external_url %>
- <%= f.label :location, t("budget.investments.form.location") %>
- <%= f.text_field :location, placeholder: t("budget.investments.form.location"), label: false %>
+ <%= f.text_field :location %>
+
+ <%= f.label :tag_list, t("budget.investments.form.tags_label") %>
+
<%= t("budget.investments.form.tags_instructions") %>
+
+
+
+
+ <%= f.text_field :tag_list, value: @investment.tag_list.to_s,
+ label: false,
+ placeholder: t("budget.investments.form.tags_placeholder"),
+ class: 'js-tag-list' %>
+
+
+
<% unless current_user.manager? %>
@@ -45,7 +59,7 @@
<% end %>
- <%= f.submit(class: "button", value: t("budget.investments.form.submit_buttons.#{action_name}")) %>
+ <%= f.submit(nil, class: "button") %>
<% end %>
diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb
index 28659533d..c0816d534 100644
--- a/app/views/budgets/investments/_investment_show.html.erb
+++ b/app/views/budgets/investments/_investment_show.html.erb
@@ -35,6 +35,8 @@
<% end %>
+ <%= render 'shared/tags', taggable: @investment, url: budget_investments_path(@budget) %>
+
<%= safe_html_with_links investment.description.html_safe %>
<% if investment.external_url.present? %>
diff --git a/config/locales/activerecord.en.yml b/config/locales/activerecord.en.yml
index a9c4ba1bc..b2dd94e28 100644
--- a/config/locales/activerecord.en.yml
+++ b/config/locales/activerecord.en.yml
@@ -53,6 +53,11 @@ en:
phase: "Phase"
currency_symbol: "Currency"
budget/investment:
+ heading_id: "Sección de presupuesto"
+ title: "Title"
+ description: "Description"
+ external_url: "External url"
+ location: "Location"
administrator_id: "Administrator"
description: "Description"
external_url: "Link to additional documentation"
diff --git a/config/locales/budgets.es.yml b/config/locales/budgets.es.yml
index 1a9f9554b..e3b7269b1 100644
--- a/config/locales/budgets.es.yml
+++ b/config/locales/budgets.es.yml
@@ -24,13 +24,13 @@ es:
title: Selecciona una partida
budget:
phase:
- accepting: Aceptando propuestas
- reviewing: Revisando propuestas
- selecting: Fase de selección
+ accepting: Fase de propuestas
+ reviewing: Fase de revisión de propuestas
+ selecting: Fase de apoyos
valuating: Fase de evaluación de propuestas
balloting: Fase de votación
- reviewing_ballots: Contando resultados
- finished: Terminado
+ reviewing_ballots: Fase de revisión de resultados
+ finished: Resultados
groups:
index:
group_title: "Grupos"
diff --git a/spec/features/budgets/investments_spec.rb b/spec/features/budgets/investments_spec.rb
index 097f0bd8f..92b568373 100644
--- a/spec/features/budgets/investments_spec.rb
+++ b/spec/features/budgets/investments_spec.rb
@@ -404,4 +404,84 @@ feature 'Budget Investments' do
end
+ context 'Tagging' do
+ let(:author) { create(:user, :level_two) }
+ let(:budget) { create(:budget, :accepting) }
+ let(:group) { create(:budget_group, budget: budget) }
+ let!(:heading) { create(:budget_heading, group: group) }
+
+ background do
+ login_as(author)
+ end
+
+ scenario 'Category tags', :js do
+ education = create(:tag, name: 'Education', kind: 'category')
+ health = create(:tag, name: 'Health', kind: 'category')
+
+ visit new_budget_investment_path(budget, heading_id: heading.id)
+
+ select "#{heading.group.name}: #{heading.name}", from: 'budget_investment_heading_id'
+ fill_in 'budget_investment_title', with: 'Build gym near my street'
+ fill_in_ckeditor 'budget_investment_description', with: 'If I had a gym near my place I could go do Zumba'
+ check 'budget_investment_terms_of_service'
+
+ find('.js-add-tag-link', text: 'Education').click
+ click_button 'Create Investment'
+
+ expect(page).to have_content 'Budget Investment created successfully.'
+
+ within "#tags_budget_investment_#{Budget::Investment.last.id}" do
+ expect(page).to have_content 'Education'
+ expect(page).to_not have_content 'Health'
+ end
+ end
+
+ scenario 'Custom tags' do
+ visit new_proposal_path
+
+ fill_in 'proposal_title', with: 'Help refugees'
+ fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
+ fill_in 'proposal_summary', with: 'In summary, what we want is...'
+ fill_in 'proposal_description', with: 'This is very important because...'
+ fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
+ fill_in 'proposal_video_url', with: 'http://youtube.com'
+ fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
+ check 'proposal_terms_of_service'
+
+ fill_in 'proposal_tag_list', with: 'Refugees, Solidarity'
+ click_button 'Create proposal'
+
+ expect(page).to have_content 'Proposal created successfully.'
+ within "#tags_proposal_#{Proposal.last.id}" do
+ expect(page).to have_content 'Refugees'
+ expect(page).to have_content 'Solidarity'
+ end
+ end
+
+ scenario 'using dangerous strings' do
+ author = create(:user)
+ login_as(author)
+
+ visit new_proposal_path
+
+ fill_in 'proposal_title', with: 'A test of dangerous strings'
+ fill_in 'proposal_question', with: '¿Would you like to give assistance to war refugees?'
+ fill_in 'proposal_summary', with: 'In summary, what we want is...'
+ fill_in 'proposal_description', with: 'A description suitable for this test'
+ fill_in 'proposal_external_url', with: 'http://rescue.org/refugees'
+ fill_in 'proposal_responsible_name', with: 'Isabel Garcia'
+ check 'proposal_terms_of_service'
+
+ fill_in 'proposal_tag_list', with: 'user_id=1, &a=3, '
+
+ click_button 'Create proposal'
+
+ expect(page).to have_content 'Proposal created successfully.'
+ expect(page).to have_content 'user_id1'
+ expect(page).to have_content 'a3'
+ expect(page).to have_content 'scriptalert("hey");script'
+ expect(page.html).to_not include 'user_id=1, &a=3, '
+ end
+ end
+
end