diff --git a/app/controllers/admin/budget_investments_controller.rb b/app/controllers/admin/budget_investments_controller.rb index dbaa91f99..8c45d7c9c 100644 --- a/app/controllers/admin/budget_investments_controller.rb +++ b/app/controllers/admin/budget_investments_controller.rb @@ -3,8 +3,8 @@ class Admin::BudgetInvestmentsController < Admin::BaseController include FeatureFlags feature_flag :budgets - has_filters(%w{valuation_open without_admin managed valuating valuation_finished - valuation_finished_feasible selected winners all}, + has_filters(%w{all without_admin without_valuator under_valuation + valuation_finished winners}, only: [:index, :toggle_selection]) before_action :load_budget @@ -15,6 +15,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController def index respond_to do |format| format.html + format.js { render layout: false } format.csv do send_data Budget::Investment.to_csv(@investments, headers: true), filename: 'budget_investments.csv' @@ -59,16 +60,16 @@ class Admin::BudgetInvestmentsController < Admin::BaseController def budget_investment_params params.require(:budget_investment) - .permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, :valuation_tag_list, :incompatible, - :selected, valuator_ids: []) + .permit(:title, :description, :external_url, :heading_id, :administrator_id, :tag_list, :valuation_tag_list, + :incompatible, :selected, valuator_ids: []) end def load_budget - @budget = Budget.includes(:groups).find params[:budget_id] + @budget = Budget.includes(:groups).find(params[:budget_id]) end def load_investment - @investment = Budget::Investment.where(budget_id: @budget.id).find params[:id] + @investment = Budget::Investment.where(budget_id: @budget.id).find(params[:id]) end def load_admins @@ -76,7 +77,7 @@ class Admin::BudgetInvestmentsController < Admin::BaseController end def load_valuators - @valuators = Valuator.includes(:user).all.order("description ASC").order("users.email ASC") + @valuators = Valuator.includes(:user).all.order(description: :asc).order("users.email ASC") end def load_tags @@ -92,4 +93,5 @@ class Admin::BudgetInvestmentsController < Admin::BaseController @investment.set_tag_list_on(:valuation, budget_investment_params[:valuation_tag_list]) params[:budget_investment] = params[:budget_investment].except(:valuation_tag_list) end + end diff --git a/app/models/budget/investment.rb b/app/models/budget/investment.rb index da99db004..5534c7d00 100644 --- a/app/models/budget/investment.rb +++ b/app/models/budget/investment.rb @@ -1,6 +1,7 @@ +require 'csv' + class Budget class Investment < ActiveRecord::Base - require 'csv' include Rails.application.routes.url_helpers include Measurable include Sanitizable @@ -52,8 +53,10 @@ class Budget scope :valuation_open, -> { where(valuation_finished: false) } scope :without_admin, -> { valuation_open.where(administrator_id: nil) } + scope :without_valuator, -> { valuation_open.where(valuator_assignments_count: 0) } + scope :under_valuation, -> { valuation_open.where("valuator_assignments_count > 0 AND administrator_id IS NOT ?", nil) } scope :managed, -> { valuation_open.where(valuator_assignments_count: 0).where("administrator_id IS NOT ?", nil) } - scope :valuating, -> { valuation_open.where("valuator_assignments_count > 0 AND valuation_finished = ?", false) } + scope :valuating, -> { valuation_open.where("valuator_assignments_count > 0") } scope :valuation_finished, -> { where(valuation_finished: true) } scope :valuation_finished_feasible, -> { where(valuation_finished: true, feasibility: "feasible") } scope :feasible, -> { where(feasibility: "feasible") } @@ -86,20 +89,42 @@ class Budget end def self.filter_params(params) - params.select{|x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include? x.to_s } + params.select{ |x, _| %w{heading_id group_id administrator_id tag_name valuator_id}.include?(x.to_s) } end def self.scoped_filter(params, current_filter) - results = Investment.where(budget_id: params[:budget_id]) + budget = Budget.find_by(slug: params[:budget_id]) || Budget.find_by(id: params[:budget_id]) + results = Investment.where(budget_id: budget.id) + + results = limit_results(budget, params, results) if params[:max_per_heading].present? results = results.where(group_id: params[:group_id]) if params[:group_id].present? - results = results.by_heading(params[:heading_id]) if params[:heading_id].present? - results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present? results = results.by_tag(params[:tag_name]) if params[:tag_name].present? + results = results.by_heading(params[:heading_id]) if params[:heading_id].present? results = results.by_valuator(params[:valuator_id]) if params[:valuator_id].present? + results = results.by_admin(params[:administrator_id]) if params[:administrator_id].present? + + # Advanced filters + results = results.valuation_finished_feasible if params[:second_filter] == 'feasible' + results = results.where(selected: true) if params[:second_filter] == 'selected' + results = results.undecided if params[:second_filter] == 'undecided' + results = results.unfeasible if params[:second_filter] == 'unfeasible' + results = results.send(current_filter) if current_filter.present? results.includes(:heading, :group, :budget, administrator: :user, valuators: :user) end + def self.limit_results(budget, params, results) + max_per_heading = params[:max_per_heading].to_i + return results if max_per_heading <= 0 + + ids = [] + budget.headings.pluck(:id).each do |hid| + ids += Investment.where(heading_id: hid).order(confidence_score: :desc).limit(max_per_heading).pluck(:id) + end + + results.where("budget_investments.id IN (?)", ids) + end + def searchable_values { title => 'A', author.username => 'B', diff --git a/app/views/admin/budget_investments/_advanced_filters.html.erb b/app/views/admin/budget_investments/_advanced_filters.html.erb new file mode 100644 index 000000000..e9b68efa8 --- /dev/null +++ b/app/views/admin/budget_investments/_advanced_filters.html.erb @@ -0,0 +1,27 @@ +
+ <%= form_tag(admin_budget_budget_investments_path(budget: @budget, + filter: params[:filter], + second_filter: params[:second_filter], + max_per_heading: params[:max_per_heading], + page: 1), method: :get, remote: true, enforce_utf8: false) do %> + + <%= check_box_tag :second_filter, "feasible" %> + <%= t("#{i18n_namespace}.filters.feasible") %> + + <%= check_box_tag :second_filter, "selected" %> + <%= t("#{i18n_namespace}.filters.selected") %> + + <%= check_box_tag :second_filter, "undecided" %> + <%= t("#{i18n_namespace}.filters.undecided") %> + + <%= check_box_tag :second_filter, "unfeasible" %> + <%= t("#{i18n_namespace}.filters.unfeasible") %> + +
+ <%= text_field_tag :max_per_heading %> + <%= t("#{i18n_namespace}.filters.max_per_heading") %> +
+ + <%= submit_tag t("#{i18n_namespace}.filters.button"), class: "button small float-right" %> + <% end %> +
diff --git a/app/views/admin/budget_investments/_filters_description.html.erb b/app/views/admin/budget_investments/_filters_description.html.erb new file mode 100644 index 000000000..43e48408f --- /dev/null +++ b/app/views/admin/budget_investments/_filters_description.html.erb @@ -0,0 +1,13 @@ +<% if params[:filter].present? && params[:second_filter].present? %> +

<%= t("#{i18n_namespace}.filters.two_filters_html", + filter: t("#{i18n_namespace}.filters.#{params[:filter]}"), + second_filter: t("#{i18n_namespace}.filters.#{params[:second_filter]}")) %>

+ +<% elsif params[:filter].present? %> +

<%= t("#{i18n_namespace}.filters.one_filter_html", + filter: t("#{i18n_namespace}.filters.#{params[:filter]}")) %>

+ +<% elsif params[:second_filter].present? %> +

<%= t("#{i18n_namespace}.filters.one_filter_html", + filter: t("#{i18n_namespace}.filters.#{params[:second_filter]}")) %>

+<% end %> diff --git a/app/views/admin/budget_investments/_investments.html.erb b/app/views/admin/budget_investments/_investments.html.erb index a60e2ac11..3456021db 100644 --- a/app/views/admin/budget_investments/_investments.html.erb +++ b/app/views/admin/budget_investments/_investments.html.erb @@ -3,7 +3,10 @@ class: "float-right small" %> <% if @investments.any? %> -

<%= page_entries_info @investments %>

+

<%= page_entries_info @investments %>


+ + <%= render "filters_description", i18n_namespace: "admin.budget_investments.index" %> + @@ -16,84 +19,89 @@ - <% if params[:filter] == 'selected' %> + <% if params[:filter] == "selected" %> <% end %> - <% @investments.each do |investment| %> - - - - - - - - - - - <% if params[:filter] == 'selected' %> - + <% @investments.each do |investment| %> + + - <% end %> - - <% end %> + + + + + + + + + <% if params[:filter] == "selected" %> + + <% end %> + + <% end %> +
<%= t("admin.budget_investments.index.table_feasibility") %> <%= t("admin.budget_investments.index.table_valuation_finished") %> <%= t("admin.budget_investments.index.table_selection") %><%= t("admin.budget_investments.index.table_incompatible") %>
- <%= investment.id %> - - <%= link_to investment.title, - admin_budget_budget_investment_path(budget_id: @budget.id, - id: investment.id, - params: Budget::Investment.filter_params(params)), - target: "_blank" %> - - <%= investment.total_votes %> - - <% if investment.administrator.present? %> - - <%= investment.administrator.name %> - - <% else %> - <%= t("admin.budget_investments.index.no_admin_assigned") %> - <% end %> - - <% if investment.valuators.size == 0 %> - <%= t("admin.budget_investments.index.no_valuators_assigned") %> - <% else %> - <%= investment.valuators.collect(&:description_or_name).join(', ') %> - <% end %> - - <%= investment.heading.name %> - - <%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}", - price: investment.formatted_price) - %> - - <%= investment.valuation_finished? ? t('shared.yes'): t('shared.no') %> - - <% if investment.selected? %> - <%= link_to_unless investment.budget.finished?, - t("admin.budget_investments.index.selected"), - toggle_selection_admin_budget_budget_investment_path(@budget, - investment, - filter: params[:filter], - page: params[:page]), - method: :patch, - remote: true, - class: "button small expanded" %> - <% elsif investment.feasible? && investment.valuation_finished? %> - <%= link_to_unless investment.budget.finished?, - t("admin.budget_investments.index.select"), - toggle_selection_admin_budget_budget_investment_path(@budget, - investment, - filter: params[:filter], - page: params[:page]), - method: :patch, - remote: true, - class: "button small hollow expanded" %> - <% end %> - - <%= investment.incompatible? ? t('shared.yes'): t('shared.no') %> +
+ <%= investment.id %>
+ <%= link_to investment.title, + admin_budget_budget_investment_path(budget_id: @budget.id, + id: investment.id, + params: Budget::Investment.filter_params(params)), + target: "_blank" %> + + <%= investment.total_votes %> + + <% if investment.administrator.present? %> + + <%= investment.administrator.name %> + + <% else %> + <%= t("admin.budget_investments.index.no_admin_assigned") %> + <% end %> + + <% if investment.valuators.size.zero? %> + <%= t("admin.budget_investments.index.no_valuators_assigned") %> + <% else %> + <%= investment.valuators.collect(&:description_or_name).join(", ") %> + <% end %> + + <%= investment.heading.name %> + + <%= t("admin.budget_investments.index.feasibility.#{investment.feasibility}", + price: investment.formatted_price) %> + + <%= investment.valuation_finished? ? t("shared.yes"): t("shared.no") %> + + <% if investment.selected? %> + <%= link_to_unless investment.budget.finished?, + t("admin.budget_investments.index.selected"), + toggle_selection_admin_budget_budget_investment_path(@budget, + investment, + filter: params[:filter], + second_filter: params[:second_filter], + max_per_heading: params[:max_per_heading], + page: params[:page]), + method: :patch, + remote: true, + class: "button small expanded" %> + <% elsif investment.feasible? && investment.valuation_finished? %> + <%= link_to_unless investment.budget.finished?, + t("admin.budget_investments.index.select"), + toggle_selection_admin_budget_budget_investment_path(@budget, + investment, + filter: params[:filter], + second_filter: params[:second_filter], + max_per_heading: params[:max_per_heading], + page: params[:page]), + method: :patch, + remote: true, + class: "button small hollow expanded" %> + <% end %> + + <%= investment.incompatible? ? t("shared.yes"): t("shared.no") %> +
<%= paginate @investments %> diff --git a/app/views/admin/budget_investments/index.html.erb b/app/views/admin/budget_investments/index.html.erb index e86402fd5..6deafed19 100644 --- a/app/views/admin/budget_investments/index.html.erb +++ b/app/views/admin/budget_investments/index.html.erb @@ -1,21 +1,21 @@

<%= @budget.name %> - <%= t("admin.budget_investments.index.title") %>

- <%= form_tag admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false do %> + <%= form_tag(admin_budget_budget_investments_path(budget: @budget), method: :get, enforce_utf8: false) do %>
<%= select_tag :administrator_id, - options_for_select(admin_select_options, params[:administrator_id]), - { prompt: t("admin.budget_investments.index.administrator_filter_all"), - label: false, - class: "js-submit-on-change" } %> + options_for_select(admin_select_options, params[:administrator_id]), + { prompt: t("admin.budget_investments.index.administrator_filter_all"), + label: false, + class: "js-submit-on-change" } %>
<%= select_tag :valuator_id, - options_for_select(valuator_select_options, params[:valuator_id]), - { prompt: t("admin.budget_investments.index.valuator_filter_all"), - label: false, - class: "js-submit-on-change" } %> + options_for_select(valuator_select_options, params[:valuator_id]), + { prompt: t("admin.budget_investments.index.valuator_filter_all"), + label: false, + class: "js-submit-on-change" } %>
@@ -36,8 +36,10 @@ <% end %>
-<%= render '/shared/filter_subnav', i18n_namespace: "admin.budget_investments.index" %> +<%= render "advanced_filters", i18n_namespace: "admin.budget_investments.index" %> + +<%= render "/shared/filter_subnav", i18n_namespace: "admin.budget_investments.index" %>
- <%= render '/admin/budget_investments/investments' %> + <%= render "investments" %>
diff --git a/app/views/admin/budget_investments/index.js.erb b/app/views/admin/budget_investments/index.js.erb new file mode 100644 index 000000000..dc3a8d67a --- /dev/null +++ b/app/views/admin/budget_investments/index.js.erb @@ -0,0 +1 @@ +$("#investments").html('<%= j render("admin/budget_investments/investments") %>'); diff --git a/config/locales/en/admin.yml b/config/locales/en/admin.yml index 16f599c8b..ea30543d9 100644 --- a/config/locales/en/admin.yml +++ b/config/locales/en/admin.yml @@ -138,15 +138,20 @@ en: valuator_filter_all: All valuators tags_filter_all: All tags filters: - valuation_open: Open - without_admin: Without assigned admin - managed: Managed - valuating: Under valuation - valuation_finished: Valuation finished - valuation_finished_feasible: Val. fin. Feasible - selected: Selected - winners: Winners all: All + without_admin: Without assigned admin + without_valuator: Without assigned valuator + under_valuation: Under valuation + valuation_finished: Valuation finished + feasible: Feasible + selected: Selected + undecided: Undecided + unfeasible: Unfeasible + max_per_heading: Max. supports per heading + winners: Winners + button: Filter + one_filter_html: "Current applied filter: %{filter}" + two_filters_html: "Current applied filters: %{filter}, %{second_filter}" download_current_selection: "Download current selection" no_budget_investments: "There are no investment projects." title: Investment projects @@ -168,7 +173,7 @@ en: table_geozone: "Scope of operation" table_feasibility: "Feasibility" table_valuation_finished: "Val. Fin." - table_selection: "Selection" + table_selection: "Selected" table_incompatible: "Incompatible" show: assigned_admin: Assigned administrator diff --git a/config/locales/es/admin.yml b/config/locales/es/admin.yml index 07fe9340a..36dfb6be6 100644 --- a/config/locales/es/admin.yml +++ b/config/locales/es/admin.yml @@ -138,15 +138,20 @@ es: valuator_filter_all: Todos los evaluadores tags_filter_all: Todas las etiquetas filters: - valuation_open: Abiertas + all: Todos without_admin: Sin administrador - managed: Gestionando - valuating: En evaluación + without_valuator: Sin evaluador + under_valuation: En evaluación valuation_finished: Evaluación finalizada - valuation_finished_feasible: Viables - selected: Seleccionadas - winners: Ganadoras - all: Todas + feasible: Viables + selected: Seleccionados + undecided: Sin decidir + unfeasible: Inviables + max_per_heading: Corte por partida + winners: Ganadores + button: Filtrar + one_filter_html: "Filtro en uso: %{filter}" + two_filters_html: "Filtros en uso: %{filter}, %{second_filter}" download_current_selection: "Descargar selección actual" no_budget_investments: "No hay proyectos de gasto." title: Proyectos de gasto @@ -167,7 +172,7 @@ es: table_geozone: "Ámbito de actuación" table_feasibility: "Viabilidad" table_valuation_finished: "Ev. Fin." - table_selection: "Selección" + table_selection: "Seleccionado" table_incompatible: "Incompatible" show: assigned_admin: Administrador asignado diff --git a/spec/features/admin/budget_investments_spec.rb b/spec/features/admin/budget_investments_spec.rb index 627824045..05e3f905d 100644 --- a/spec/features/admin/budget_investments_spec.rb +++ b/spec/features/admin/budget_investments_spec.rb @@ -187,12 +187,11 @@ feature 'Admin budget investments' do end scenario "Current filter is properly highlighted" do - filters_links = {'valuation_open' => 'Open', - 'without_admin' => 'Without assigned admin', - 'managed' => 'Managed', - 'valuating' => 'Under valuation', - 'valuation_finished' => 'Valuation finished', - 'all' => 'All'} + filters_links = { 'all' => 'All', + 'without_admin' => 'Without assigned admin', + 'without_valuator' => 'Without assigned valuator', + 'under_valuation' => 'Under valuation', + 'valuation_finished' => 'Valuation finished' } visit admin_budget_budget_investments_path(budget_id: @budget.id) @@ -213,36 +212,26 @@ feature 'Admin budget investments' do scenario "Filtering by assignment status" do assigned = create(:budget_investment, title: "Assigned idea", budget: @budget, administrator: create(:administrator)) valuating = create(:budget_investment, title: "Evaluating...", budget: @budget) - valuating.valuators << create(:valuator) - - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_open') - - expect(page).to have_content("Assigned idea") - expect(page).to have_content("Evaluating...") + valuating.valuators.push(create(:valuator)) visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_admin') expect(page).to have_content("Evaluating...") expect(page).not_to have_content("Assigned idea") - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'managed') + visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'without_valuator') expect(page).to have_content("Assigned idea") expect(page).not_to have_content("Evaluating...") end scenario "Filtering by valuation status" do - valuating = create(:budget_investment, budget: @budget, title: "Ongoing valuation") + valuating = create(:budget_investment, budget: @budget, title: "Ongoing valuation", administrator: create(:administrator)) valuated = create(:budget_investment, budget: @budget, title: "Old idea", valuation_finished: true) - valuating.valuators << create(:valuator) - valuated.valuators << create(:valuator) + valuating.valuators.push(create(:valuator)) + valuated.valuators.push(create(:valuator)) - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuation_open') - - expect(page).to have_content("Ongoing valuation") - expect(page).not_to have_content("Old idea") - - visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'valuating') + visit admin_budget_budget_investments_path(budget_id: @budget.id, filter: 'under_valuation') expect(page).to have_content("Ongoing valuation") expect(page).not_to have_content("Old idea") @@ -292,6 +281,60 @@ feature 'Admin budget investments' do expect(page).to have_select("tag_name", options: ["All tags", "Hospitals", "Teachers"]) end + scenario "Limiting by max number of investments per heading", :js do + group_1 = create(:budget_group, budget: @budget) + group_2 = create(:budget_group, budget: @budget) + parks = create(:budget_heading, group: group_1) + roads = create(:budget_heading, group: group_2) + streets = create(:budget_heading, group: group_2) + + [2, 4, 90, 100, 200, 300].each do |n| + create(:budget_investment, heading: parks, cached_votes_up: n, title: "Park with #{n} supports") + end + + [21, 31, 51, 81, 91, 101].each do |n| + create(:budget_investment, heading: roads, cached_votes_up: n, title: "Road with #{n} supports") + end + + [3, 10, 30, 33, 44, 55].each do |n| + create(:budget_investment, heading: streets, cached_votes_up: n, title: "Street with #{n} supports") + end + + visit admin_budget_budget_investments_path(@budget) + + [2, 4, 90, 100, 200, 300].each do |n| + expect(page).to have_link("Park with #{n} supports") + end + + [21, 31, 51, 81, 91, 101].each do |n| + expect(page).to have_link("Road with #{n} supports") + end + + [3, 10, 30, 33, 44, 55].each do |n| + expect(page).to have_link("Street with #{n} supports") + end + + fill_in "max_per_heading", with: 5 + click_button 'Filter' + + expect(page).to have_content('There are 15 investments') + expect(page).not_to have_link("Park with 2 supports") + expect(page).not_to have_link("Road with 21 supports") + expect(page).not_to have_link("Street with 3 supports") + + [4, 90, 100, 200, 300].each do |n| + expect(page).to have_link("Park with #{n} supports") + end + + [31, 51, 81, 91, 101].each do |n| + expect(page).to have_link("Road with #{n} supports") + end + + [10, 30, 33, 44, 55].each do |n| + expect(page).to have_link("Street with #{n} supports") + end + end + end context 'Show' do @@ -575,7 +618,7 @@ feature 'Admin budget investments' do let!(:selected_bi) { create(:budget_investment, :selected, budget: @budget, title: "Selected project") } let!(:winner_bi) { create(:budget_investment, :winner, budget: @budget, title: "Winner project") } - scenario "Filtering by valuation and selection" do + scenario "Filtering by valuation and selection", :js do visit admin_budget_budget_investments_path(@budget) within('#filter-subnav') { click_link 'Valuation finished' } @@ -585,14 +628,18 @@ feature 'Admin budget investments' do expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) - within('#filter-subnav') { click_link 'Val. fin. Feasible' } + within('#advanced-filters') { find(:css, "#second_filter[value='feasible']").set(true) } + click_button 'Filter' + expect(page).not_to have_content(unfeasible_bi.title) expect(page).not_to have_content(feasible_bi.title) expect(page).to have_content(feasible_vf_bi.title) expect(page).to have_content(selected_bi.title) expect(page).to have_content(winner_bi.title) - within('#filter-subnav') { click_link 'Selected' } + within('#advanced-filters') { find(:css, "#second_filter[value='selected']").set(true) } + click_button 'Filter' + expect(page).not_to have_content(unfeasible_bi.title) expect(page).not_to have_content(feasible_bi.title) expect(page).not_to have_content(feasible_vf_bi.title) @@ -609,7 +656,6 @@ feature 'Admin budget investments' do scenario "Showing the selection buttons", :js do visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'All' } within("#budget_investment_#{unfeasible_bi.id}") do expect(page).not_to have_link('Select') @@ -634,14 +680,14 @@ feature 'Admin budget investments' do scenario "Selecting an investment", :js do visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'All' } within("#budget_investment_#{feasible_vf_bi.id}") do click_link('Select') expect(page).to have_link('Selected') end - within('#filter-subnav') { click_link 'Selected' } + within('#advanced-filters') { find(:css, "#second_filter[value='selected']").set(true) } + click_button 'Filter' within("#budget_investment_#{feasible_vf_bi.id}") do expect(page).not_to have_link('Select') @@ -651,7 +697,8 @@ feature 'Admin budget investments' do scenario "Unselecting an investment", :js do visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'Selected' } + within('#advanced-filters') { find(:css, "#second_filter[value='selected']").set(true) } + click_button 'Filter' expect(page).to have_content('There are 2 investments') @@ -662,7 +709,7 @@ feature 'Admin budget investments' do expect(page).not_to have_content(selected_bi.title) expect(page).to have_content('There is 1 investment') - within('#filter-subnav') { click_link 'All' } + visit admin_budget_budget_investments_path(@budget) within("#budget_investment_#{selected_bi.id}") do expect(page).to have_link('Select') @@ -678,13 +725,12 @@ feature 'Admin budget investments' do price: 100) valuator = create(:valuator, user: create(:user, username: 'Rachel', email: 'rachel@val.org')) - investment.valuators << valuator + investment.valuators.push(valuator) admin = create(:administrator, user: create(:user, username: 'Gema')) investment.update(administrator_id: admin.id) visit admin_budget_budget_investments_path(@budget) - within('#filter-subnav') { click_link 'All' } click_link "Download current selection"