diff --git a/Gemfile_custom b/Gemfile_custom index 9d91e0680..076c8490f 100644 --- a/Gemfile_custom +++ b/Gemfile_custom @@ -1,5 +1,4 @@ # Overrides and adds customized gems in this file -# Read more on documentation: +# Read more on documentation: # * English: https://github.com/consul/consul/blob/master/CUSTOMIZE_EN.md#gemfile -# * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#gemfile -# +# * Spanish: https://github.com/consul/consul/blob/master/CUSTOMIZE_ES.md#gemfile \ No newline at end of file diff --git a/app/controllers/budgets_controller.rb b/app/controllers/budgets_controller.rb index 52b735188..c77092a3e 100644 --- a/app/controllers/budgets_controller.rb +++ b/app/controllers/budgets_controller.rb @@ -1,6 +1,7 @@ class BudgetsController < ApplicationController include FeatureFlags include BudgetsHelper + include Search feature_flag :budgets load_and_authorize_resource diff --git a/app/helpers/search_helper.rb b/app/helpers/search_helper.rb index ebde2a954..83aff998f 100644 --- a/app/helpers/search_helper.rb +++ b/app/helpers/search_helper.rb @@ -5,6 +5,19 @@ module SearchHelper params[:advanced_search].try(:[], :official_level)) end + def budget_phases_search_options + selected = params[:advanced_search].nil? ? '' : params[:advanced_search][:budget_phase] + options_for_select([ + [t("budgets.phase.accepting"), 'accepting'], + [t("budgets.phase.reviewing"), 'reviewing'], + [t("budgets.phase.selecting"), 'selecting'], + [t("budgets.phase.valuating"), 'valuating'], + [t("budgets.phase.balloting"), 'balloting'], + [t("budgets.phase.reviewing_ballots"), 'reviewing_ballots'], + [t("budgets.phase.finished"), 'finished']], + selected) + end + def date_range_options options_for_select([ [t("shared.advanced_search.date_1"), 1], diff --git a/app/models/budget.rb b/app/models/budget.rb index 8457ba1ac..570ed100c 100644 --- a/app/models/budget.rb +++ b/app/models/budget.rb @@ -44,6 +44,24 @@ class Budget < ActiveRecord::Base phases.published.order(:id) end + scope :by_date_range, ->(date_range) { where(created_at: date_range) } + + def self.search(terms) + if terms.values.delete_if(&:blank?).empty? + Budget.none + else + Budget.search_by_phase(terms[:phase]).by_date_range(terms[:date_range]).all + end + end + + def self.search_by_phase(phase) + if phase.empty? + Budget + else + Budget.send(phase) + end + end + def description description_for_phase(phase) end diff --git a/app/views/budgets/_advanced_search.html.erb b/app/views/budgets/_advanced_search.html.erb new file mode 100644 index 000000000..5c05e307e --- /dev/null +++ b/app/views/budgets/_advanced_search.html.erb @@ -0,0 +1,51 @@ +
+ <%= link_to t("shared.advanced_search.title"), "#advanced_search_form", id: 'js-advanced-search-title', class: "advanced-search small" %> +
+ +
+ <%= form_tag search_path, id: "advanced_search_form", method: :get do %> + + <% end %> +
diff --git a/spec/features/budgets/budgets_spec.rb b/spec/features/budgets/budgets_spec.rb index 71e0b9a4a..66f94da1b 100644 --- a/spec/features/budgets/budgets_spec.rb +++ b/spec/features/budgets/budgets_spec.rb @@ -110,21 +110,176 @@ feature 'Budgets' do expect(page).to have_css(".phase.active", count: 1) end + context "Advanced search" do + + context "Search by phase type" do + + scenario "Accepting Budget", :js do + budget = create(:budget, :accepting) + budget2 = create(:budget, :reviewing) + visit budgets_path + click_link "js-advanced-search-title" + select('Accepting projects', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Reviewing Budget", :js do + budget = create(:budget, :reviewing) + budget2 = create(:budget, :accepting) + visit budgets_path + click_link "js-advanced-search-title" + select('Reviewing projects', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Selecting Budget", :js do + budget = create(:budget, :selecting) + budget2 = create(:budget, :reviewing) + visit budgets_path + click_link "js-advanced-search-title" + select('Selecting projects', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Valuating Budget", :js do + budget = create(:budget, :valuating) + budget2 = create(:budget, :reviewing) + visit budgets_path + click_link "js-advanced-search-title" + select('Valuating projects', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Balloting Budget", :js do + budget = create(:budget, :balloting) + budget2 = create(:budget, :reviewing) + visit budgets_path + click_link "js-advanced-search-title" + select('Balloting projects', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Reviewing Ballots", :js do + budget = create(:budget, :reviewing_ballots) + budget2 = create(:budget, :reviewing) + visit budgets_path + click_link "js-advanced-search-title" + select('Reviewing Ballots', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Finished Ballots", :js do + budget = create(:budget, :finished) + budget2 = create(:budget, :reviewing) + visit budgets_path + click_link "js-advanced-search-title" + select('Finished budget', from: 'advanced_search_budget_phase') + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + end + end + + context "Search by date" do + + context "Predefined date ranges" do + + scenario "Last day", :js do + budget = create(:budget, :accepting, created_at: 1.day.ago) + budget2 = create(:budget, :reviewing, created_at: 2.days.ago) + visit budgets_path + click_link "js-advanced-search-title" + select "Last 24 hours", from: "js-advanced-search-date-min" + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Search by multiple filters", :js do + budget = create(:budget, :accepting, created_at: 1.day.ago) + budget2 = create(:budget, :selecting, created_at: 2.days.ago) + visit budgets_path + click_link "js-advanced-search-title" + select('Accepting projects', from: 'advanced_search_budget_phase') + select "Last 24 hours", from: "js-advanced-search-date-min" + click_button "Filter" + within "#budgets" do + expect(page).to have_content(budget.translated_phase) + expect(page).to_not have_content(budget2.translated_phase) + end + end + + scenario "Maintain advanced search criteria", :js do + visit budgets_path + click_link "js-advanced-search-title" + select('Accepting projects', from: 'advanced_search_budget_phase') + select "Last 24 hours", from: "js-advanced-search-date-min" + click_button "Filter" + within "#js-advanced-search" do + expect(page).to have_select('advanced_search[budget_phase]', selected: 'Accepting projects') + expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours') + end + end + + scenario "Maintain custom date search criteria", :js do + visit budgets_path + click_link "js-advanced-search-title" + select "Customized", from: "js-advanced-search-date-min" + fill_in "advanced_search_date_min", with: 7.days.ago + fill_in "advanced_search_date_max", with: 1.day.ago + click_button "Filter" + within "#js-advanced-search" do + expect(page).to have_select('advanced_search[date_min]', selected: 'Customized') + expect(page).to have_selector("input[name='advanced_search[date_min]'][value*='#{7.days.ago.strftime('%Y-%m-%d')}']") + expect(page).to have_selector("input[name='advanced_search[date_max]'][value*='#{1.day.ago.strftime('%Y-%m-%d')}']") + end + end + + end + end + + context 'Show' do scenario "List all groups" do group1 = create(:budget_group, budget: budget) group2 = create(:budget_group, budget: budget) - visit budget_path(budget) - budget.groups.each {|group| expect(page).to have_link(group.name)} end scenario "Links to unfeasible and selected if balloting or later" do budget = create(:budget, :selecting) group = create(:budget_group, budget: budget) - visit budget_path(budget) expect(page).not_to have_link "See unfeasible investments" @@ -136,26 +291,17 @@ feature 'Budgets' do expect(page).not_to have_link "See investments not selected for balloting phase" budget.update(phase: :balloting) - visit budget_path(budget) - expect(page).to have_link "See unfeasible investments" expect(page).to have_link "See investments not selected for balloting phase" - click_link group.name - expect(page).to have_link "See unfeasible investments" expect(page).to have_link "See investments not selected for balloting phase" - budget.update(phase: :finished) - visit budget_path(budget) - expect(page).to have_link "See unfeasible investments" expect(page).to have_link "See investments not selected for balloting phase" - click_link group.name - expect(page).to have_link "See unfeasible investments" expect(page).to have_link "See investments not selected for balloting phase" end @@ -227,25 +373,21 @@ feature 'Budgets' do login_as(level_two_user) visit budget_path(budget) - expect(page).to have_link "Create a 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