From 5ac2d9ccc9b2c5d9259ae91ed24d373544534aa9 Mon Sep 17 00:00:00 2001 From: kikito Date: Tue, 3 Jan 2017 17:13:28 +0100 Subject: [PATCH 1/6] started working on tags for budget investments. Error in investments/show because paths are hard --- .../budgets/investments_controller.rb | 8 +- app/models/budget/heading.rb | 10 +-- app/views/budgets/investments/_form.html.erb | 36 ++++++--- .../investments/_investment_show.html.erb | 2 + config/locales/activerecord.en.yml | 5 ++ config/locales/budgets.es.yml | 10 +-- spec/features/budgets/investments_spec.rb | 80 +++++++++++++++++++ 7 files changed, 126 insertions(+), 25 deletions(-) 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.label :category_tag_list, t("budget.investments.form.tag_category_label") %> + <% @categories.each do |tag| %> + <%= tag.name %> + <% end %> +
+ +
+ <%= 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 From fd28f6c2b3169e68e90b28f0516183a6c3ab050b Mon Sep 17 00:00:00 2001 From: rgarcia Date: Sun, 8 Jan 2017 11:37:02 +0100 Subject: [PATCH 2/6] adds tags to investment --- .../budgets/investments_controller.rb | 4 + app/helpers/tags_helper.rb | 2 + app/models/budget/investment.rb | 2 + app/models/tag_cloud.rb | 2 +- .../budgets/investments/_categories.html.erb | 11 + .../budgets/investments/_investment.html.erb | 1 + .../investments/_investment_show.html.erb | 2 +- .../budgets/investments/_sidebar.html.erb | 2 + app/views/shared/_tags.html.erb | 5 +- config/locales/activerecord.en.yml | 4 + config/locales/budgets.en.yml | 4 + config/locales/budgets.es.yml | 4 + config/locales/en.yml | 1 + config/locales/es.yml | 1 + spec/features/budgets/ballots_spec.rb | 6 +- spec/features/budgets/investments_spec.rb | 86 +---- spec/features/debates_spec.rb | 119 ------- spec/features/proposals_spec.rb | 142 +-------- spec/features/tags/budget_investments_spec.rb | 235 ++++++++++++++ spec/features/tags/debates_spec.rb | 218 +++++++++++++ spec/features/tags/proposals_spec.rb | 294 ++++++++++++++++++ spec/models/budget/investment_spec.rb | 17 + spec/models/tag_cloud_spec.rb | 9 + 23 files changed, 823 insertions(+), 348 deletions(-) create mode 100644 app/views/budgets/investments/_categories.html.erb create mode 100644 spec/features/tags/budget_investments_spec.rb create mode 100644 spec/features/tags/debates_spec.rb create mode 100644 spec/features/tags/proposals_spec.rb diff --git a/app/controllers/budgets/investments_controller.rb b/app/controllers/budgets/investments_controller.rb index 969d3689d..bf8fd7574 100644 --- a/app/controllers/budgets/investments_controller.rb +++ b/app/controllers/budgets/investments_controller.rb @@ -28,6 +28,7 @@ module Budgets @investments = @investments.apply_filters_and_search(@budget, params).send("sort_by_#{@current_order}").page(params[:page]).per(10).for_render @investment_ids = @investments.pluck(:id) load_investment_votes(@investments) + @tag_cloud = tag_cloud end def new @@ -101,6 +102,9 @@ module Budgets @categories = ActsAsTaggableOn::Tag.where("kind = 'category'").order(:name) end + def tag_cloud + TagCloud.new(Budget::Investment, params[:search]) + end end end diff --git a/app/helpers/tags_helper.rb b/app/helpers/tags_helper.rb index da7824622..36ba8d048 100644 --- a/app/helpers/tags_helper.rb +++ b/app/helpers/tags_helper.rb @@ -6,6 +6,8 @@ module TagsHelper debates_path(search: tag_name) when 'proposal' proposals_path(search: tag_name) + when 'budget/investment' + budget_investments_path(@budget, search: tag_name) else '#' end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index 9575e7ae7..5389825e5 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -46,6 +46,7 @@ class Budget scope :undecided, -> { where(feasibility: "undecided") } scope :with_supports, -> { where('cached_votes_up > 0') } scope :selected, -> { where(selected: true) } + scope :last_week, -> { where("created_at >= ?", 7.days.ago)} scope :by_group, -> (group_id) { where(group_id: group_id) } scope :by_heading, -> (heading_id) { where(heading_id: heading_id) } @@ -106,6 +107,7 @@ class Budget { title => 'A', author.username => 'B', heading.try(:name) => 'B', + tag_list.join(' ') => 'B', description => 'C' } end diff --git a/app/models/tag_cloud.rb b/app/models/tag_cloud.rb index f3ea655f0..107ecbf1a 100644 --- a/app/models/tag_cloud.rb +++ b/app/models/tag_cloud.rb @@ -32,7 +32,7 @@ class TagCloud end def table_name - resource_model.to_s.downcase.pluralize + resource_model.to_s.downcase.pluralize.gsub("::", "/") end end \ No newline at end of file diff --git a/app/views/budgets/investments/_categories.html.erb b/app/views/budgets/investments/_categories.html.erb new file mode 100644 index 000000000..ad628b1b1 --- /dev/null +++ b/app/views/budgets/investments/_categories.html.erb @@ -0,0 +1,11 @@ + + +
+ +
    + <% @categories.each do |category| %> +
  • + <%= link_to category.name, + budget_investments_path(@budget, search: category.name) %>
  • + <% 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 87c2f663e..e90801f17 100644 --- a/app/views/budgets/investments/_investment.html.erb +++ b/app/views/budgets/investments/_investment.html.erb @@ -38,6 +38,7 @@

<%= link_to investment.description, namespaced_budget_investment_path(investment) %>

+ <%= render "shared/tags", taggable: investment, limit: 5 %> <% end %> diff --git a/app/views/budgets/investments/_investment_show.html.erb b/app/views/budgets/investments/_investment_show.html.erb index c0816d534..7917889c4 100644 --- a/app/views/budgets/investments/_investment_show.html.erb +++ b/app/views/budgets/investments/_investment_show.html.erb @@ -35,7 +35,7 @@

<% end %> - <%= render 'shared/tags', taggable: @investment, url: budget_investments_path(@budget) %> + <%= render 'shared/tags', taggable: @investment %> <%= safe_html_with_links investment.description.html_safe %> diff --git a/app/views/budgets/investments/_sidebar.html.erb b/app/views/budgets/investments/_sidebar.html.erb index 173132257..639106934 100644 --- a/app/views/budgets/investments/_sidebar.html.erb +++ b/app/views/budgets/investments/_sidebar.html.erb @@ -9,6 +9,8 @@ verify: link_to(t("budget.investments.index.sidebar.verify_account"), verification_path)).html_safe %> <% end %> + <%= render "shared/tag_cloud", taggable: 'budget/investment' %> + <%= render 'categories' %> <% end %> diff --git a/app/views/shared/_tags.html.erb b/app/views/shared/_tags.html.erb index ddb6fc7f2..950b074b1 100644 --- a/app/views/shared/_tags.html.erb +++ b/app/views/shared/_tags.html.erb @@ -3,7 +3,10 @@ <% if taggable.tags.any? %>