From ac9eaec9d94ec5cb50b4f23dc0001b65809baa6e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Juanjo=20Baza=CC=81n?= Date: Fri, 4 Mar 2016 17:52:27 +0100 Subject: [PATCH] adds spending proposals index to valuation filters included: valuation_open, valuating, valuation_finished search by geozone & by valuator --- .../spending_proposals_controller.rb | 12 ++ app/helpers/valuation_helper.rb | 11 ++ app/views/valuation/_menu.html.erb | 17 +++ .../spending_proposals/index.html.erb | 63 ++++++++ config/locales/valuation.en.yml | 21 +++ config/locales/valuation.es.yml | 21 +++ .../valuation/spending_proposals_spec.rb | 143 ++++++++++++++++++ 7 files changed, 288 insertions(+) create mode 100644 app/controllers/valuation/spending_proposals_controller.rb create mode 100644 app/helpers/valuation_helper.rb create mode 100644 app/views/valuation/_menu.html.erb create mode 100644 app/views/valuation/spending_proposals/index.html.erb create mode 100644 config/locales/valuation.en.yml create mode 100644 config/locales/valuation.es.yml create mode 100644 spec/features/valuation/spending_proposals_spec.rb diff --git a/app/controllers/valuation/spending_proposals_controller.rb b/app/controllers/valuation/spending_proposals_controller.rb new file mode 100644 index 000000000..ac502334d --- /dev/null +++ b/app/controllers/valuation/spending_proposals_controller.rb @@ -0,0 +1,12 @@ +class Valuation::SpendingProposalsController < Valuation::BaseController + include FeatureFlags + feature_flag :spending_proposals + + has_filters %w{valuation_open valuating valuation_finished}, only: :index + + load_resource + + def index + @spending_proposals = SpendingProposal.search(params, @current_filter).order(created_at: :desc).page(params[:page]) + end +end diff --git a/app/helpers/valuation_helper.rb b/app/helpers/valuation_helper.rb new file mode 100644 index 000000000..becd29abb --- /dev/null +++ b/app/helpers/valuation_helper.rb @@ -0,0 +1,11 @@ +module ValuationHelper + + def valuator_select_options(valuator=nil) + if valuator.present? + Valuator.where.not(id: valuator.id).order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] }.prepend([valuator.name, valuator.id]) + else + Valuator.all.order('users.username asc').includes(:user).collect { |v| [ v.name, v.id ] } + end + end + +end \ No newline at end of file diff --git a/app/views/valuation/_menu.html.erb b/app/views/valuation/_menu.html.erb new file mode 100644 index 000000000..76f6ff434 --- /dev/null +++ b/app/views/valuation/_menu.html.erb @@ -0,0 +1,17 @@ + diff --git a/app/views/valuation/spending_proposals/index.html.erb b/app/views/valuation/spending_proposals/index.html.erb new file mode 100644 index 000000000..f7e8d4ba6 --- /dev/null +++ b/app/views/valuation/spending_proposals/index.html.erb @@ -0,0 +1,63 @@ +

<%= t("valuation.spending_proposals.index.title") %>

+ +
+ <%= form_tag valuation_spending_proposals_path, method: :get, enforce_utf8: false do %> +
+ <%= select_tag :geozone_id, + options_for_select(geozone_select_options.unshift([t("geozones.none"), "all"]), params[:geozone_id]), + { prompt: t("valuation.spending_proposals.index.geozone_filter_all"), + label: false, + class: "js-submit-on-change" } %> +
+
+ <%= select_tag :valuator_id, + options_for_select(valuator_select_options(current_user.valuator), params[:valuator_id]), + { prompt: t("valuation.spending_proposals.index.valuator_filter_all"), + label: false, + class: "js-submit-on-change" } %> +
+ <% end %> +
+ +<%= render 'shared/filter_subnav', i18n_namespace: "valuation.spending_proposals.index" %> + +

<%= page_entries_info @spending_proposals %>

+ + + <% @spending_proposals.each do |spending_proposal| %> + + + + + + + + <% end %> +
+ <%= spending_proposal.id %> + + <%= link_to spending_proposal.title, spending_proposal_path(spending_proposal) %> + + <% if spending_proposal.administrator.present? %> + <%= spending_proposal.administrator.name %> + <% else %> + <%= t("valuation.spending_proposals.index.no_admin_assigned") %> + <% end %> + + <% case spending_proposal.valuators.size %> + <% when 0 %> + <%= t("valuation.spending_proposals.index.no_valuators_assigned") %> + <% when 1 %> + + <%= spending_proposal.valuators.first.name %> + + <% else %> + + <%= t('valuation.spending_proposals.index.valuators_assigned', count: spending_proposal.valuators.size) %> + + <% end %> + + <%= geozone_name(spending_proposal) %> +
+ +<%= paginate @spending_proposals %> \ No newline at end of file diff --git a/config/locales/valuation.en.yml b/config/locales/valuation.en.yml new file mode 100644 index 000000000..8d5c0f3ed --- /dev/null +++ b/config/locales/valuation.en.yml @@ -0,0 +1,21 @@ +--- +en: + valuation: + menu: + title: Valuation + spending_proposals: Spending proposals + spending_proposals: + index: + geozone_filter_all: All zones + valuator_filter_all: All valuators + filters: + valuation_open: Open + valuating: Under valuation + valuation_finished: Valuation finished + title: Investment projects for participatory budgeting + admin_assigned: Assigned administrator + no_admin_assigned: No admin assigned + valuators_assigned: + one: Assigned valuator + other: "%{count} valuators assigned" + no_valuators_assigned: No valuators assigned \ No newline at end of file diff --git a/config/locales/valuation.es.yml b/config/locales/valuation.es.yml new file mode 100644 index 000000000..ca65fd82a --- /dev/null +++ b/config/locales/valuation.es.yml @@ -0,0 +1,21 @@ +--- +es: + valuation: + menu: + title: Evaluación + spending_proposals: Propuestas de inversión + spending_proposals: + index: + geozone_filter_all: Todos los ámbitos de actuación + valuator_filter_all: Todos los evaluadores + filters: + valuation_open: Abiertas + valuating: En evaluación + valuation_finished: Evaluación finalizada + title: Propuestas de inversión para presupuestos participativos + admin_assigned: Administrador asignado + no_admin_assigned: Sin admin asignado + valuators_assigned: + one: Evaluador asignado + other: "%{count} evaluadores asignados" + no_valuators_assigned: Sin evaluador \ No newline at end of file diff --git a/spec/features/valuation/spending_proposals_spec.rb b/spec/features/valuation/spending_proposals_spec.rb new file mode 100644 index 000000000..ae0c7df7a --- /dev/null +++ b/spec/features/valuation/spending_proposals_spec.rb @@ -0,0 +1,143 @@ +require 'rails_helper' + +feature 'Valuation spending proposals' do + + background do + valuator = create(:valuator) + login_as(valuator.user) + end + + scenario 'Disabled with a feature flag' do + Setting['feature.spending_proposals'] = nil + expect{ visit valuation_spending_proposals_path }.to raise_exception(FeatureFlags::FeatureDisabled) + end + + scenario 'Index shows spending proposals' do + spending_proposal = create(:spending_proposal) + visit valuation_spending_proposals_path + + expect(page).to have_content(spending_proposal.title) + end + + scenario 'Index shows assignments info' do + spending_proposal1 = create(:spending_proposal) + spending_proposal2 = create(:spending_proposal) + spending_proposal3 = create(:spending_proposal) + + valuator1 = create(:valuator, user: create(:user, username: 'Olga')) + valuator2 = create(:valuator, user: create(:user, username: 'Miriam')) + admin = create(:administrator, user: create(:user, username: 'Gema')) + + spending_proposal1.valuators << valuator1 + spending_proposal2.valuator_ids = [valuator1.id, valuator2.id] + spending_proposal3.update({administrator_id: admin.id}) + + visit valuation_spending_proposals_path + + within("#spending_proposal_#{spending_proposal1.id}") do + expect(page).to have_content("No admin assigned") + expect(page).to have_content("Olga") + end + + within("#spending_proposal_#{spending_proposal2.id}") do + expect(page).to have_content("No admin assigned") + expect(page).to have_content("2 valuators assigned") + end + + within("#spending_proposal_#{spending_proposal3.id}") do + expect(page).to have_content("Gema") + expect(page).to have_content("No valuators assigned") + end + end + + scenario "Index filtering by geozone", :js do + geozone = create(:geozone, name: "District 9") + create(:spending_proposal, title: "Realocate visitors", geozone: geozone) + create(:spending_proposal, title: "Destroy the city") + + visit valuation_spending_proposals_path + expect(page).to have_link("Realocate visitors") + expect(page).to have_link("Destroy the city") + + select "District 9", from: "geozone_id" + + expect(page).to have_link("Realocate visitors") + expect(page).to_not have_link("Destroy the city") + + select "All city", from: "geozone_id" + + expect(page).to have_link("Destroy the city") + expect(page).to_not have_link("Realocate visitors") + + select "All zones", from: "geozone_id" + expect(page).to have_link("Realocate visitors") + expect(page).to have_link("Destroy the city") + end + + scenario "Index filtering by valuator", :js do + user = create(:user, username: 'Karnak') + valuator = create(:valuator, user: user) + + spending = create(:spending_proposal, title: "Realocate visitors") + spending.valuators << valuator + create(:spending_proposal, title: "Destroy the city") + + visit valuation_spending_proposals_path + expect(page).to have_link("Realocate visitors") + expect(page).to have_link("Destroy the city") + + select "Karnak", from: "valuator_id" + + expect(page).to have_link("Realocate visitors") + expect(page).to_not have_link("Destroy the city") + + select "All valuators", from: "valuator_id" + + expect(page).to have_link("Destroy the city") + expect(page).to have_link("Realocate visitors") + end + + scenario "Current filter is properly highlighted" do + filters_links = {'valuation_open' => 'Open', + 'valuating' => 'Under valuation', + 'valuation_finished' => 'Valuation finished'} + + visit valuation_spending_proposals_path + + expect(page).to_not have_link(filters_links.values.first) + filters_links.keys.drop(1).each { |filter| expect(page).to have_link(filters_links[filter]) } + + filters_links.each_pair do |current_filter, link| + visit valuation_spending_proposals_path(filter: current_filter) + + expect(page).to_not have_link(link) + + (filters_links.keys - [current_filter]).each do |filter| + expect(page).to have_link(filters_links[filter]) + end + end + end + + scenario "Index filtering by valuation status" do + valuating = create(:spending_proposal, title: "Ongoing valuation") + valuated = create(:spending_proposal, title: "Old idea", valuation_finished: true) + valuating.valuators << create(:valuator) + valuated.valuators << create(:valuator) + + visit valuation_spending_proposals_path(filter: 'valuation_open') + + expect(page).to have_content("Ongoing valuation") + expect(page).to_not have_content("Old idea") + + visit valuation_spending_proposals_path(filter: 'valuating') + + expect(page).to have_content("Ongoing valuation") + expect(page).to_not have_content("Old idea") + + visit valuation_spending_proposals_path(filter: 'valuation_finished') + + expect(page).to_not have_content("Ongoing valuation") + expect(page).to have_content("Old idea") + end + +end