Merge pull request #822 from consul/advanced-search

Advanced search
This commit is contained in:
Juanjo Bazán
2016-01-18 15:17:17 +01:00
21 changed files with 1084 additions and 178 deletions

View File

@@ -0,0 +1,29 @@
App.AdvancedSearch =
advanced_search_terms: ->
$('#js-advanced-search').data('advanced-search-terms')
toggle_form: (event) ->
event.preventDefault();
$('#js-advanced-search').slideToggle()
toggle_date_options: ->
if $('#js-advanced-search-date-min').val() == 'custom'
$('#js-custom-date').show()
$('#js-custom-date input').prop 'disabled', false
else
$('#js-custom-date').hide()
$('#js-custom-date input').prop 'disabled', true
initialize: ->
if App.AdvancedSearch.advanced_search_terms()
$('#js-advanced-search').show()
App.AdvancedSearch.toggle_date_options()
$('#js-advanced-search-title').on
click: (event) ->
App.AdvancedSearch.toggle_form(event)
$('#js-advanced-search-date-min').on
change: ->
App.AdvancedSearch.toggle_date_options()

View File

@@ -35,6 +35,7 @@
//= require users //= require users
//= require votes //= require votes
//= require annotatable //= require annotatable
//= require advanced_search
var initialize_modules = function() { var initialize_modules = function() {
@@ -48,6 +49,7 @@ var initialize_modules = function() {
App.PreventDoubleSubmission.initialize(); App.PreventDoubleSubmission.initialize();
App.IeAlert.initialize(); App.IeAlert.initialize();
App.Annotatable.initialize(); App.Annotatable.initialize();
App.AdvancedSearch.initialize();
}; };
$(function(){ $(function(){

View File

@@ -230,6 +230,10 @@ a {
} }
} }
.small {
font-size: $small-font-size;
}
// 02. Header // 02. Header
// - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - -
@@ -515,7 +519,7 @@ header {
background: white; background: white;
border-bottom: 1px solid $border; border-bottom: 1px solid $border;
clear: both; clear: both;
margin: $line-height 0 $line-height/2; margin-bottom: $line-height/2;
a { a {
color: $text; color: $text;
@@ -1033,6 +1037,42 @@ img.avatar, img.admin-avatar, img.moderator-avatar, img.initialjs-avatar {
} }
} }
.search-results {
h2 {
margin-bottom: 0;
}
}
.advanced-search {
float: left;
margin: $line-height 0;
@media (min-width: $small-breakpoint) {
float: right;
margin-bottom: 0;
margin-top: rem-calc(28);
position: absolute;
right: 15px;
z-index: 2;
}
}
.advanced-search-form {
margin-top: $line-height;
select {
height: $line-height*2;
}
@media (max-width: $medium-breakpoint) {
.column {
padding: 0;
}
}
}
// 10. Officials levels // 10. Officials levels
// - - - - - - - - - - - - - - - - - - - - - - - - - // - - - - - - - - - - - - - - - - - - - - - - - - -

View File

@@ -4,11 +4,13 @@ module CommentableActions
def index def index
@resources = @search_terms.present? ? resource_model.search(@search_terms) : resource_model.all @resources = @search_terms.present? ? resource_model.search(@search_terms) : resource_model.all
@resources = @advanced_search_terms.present? ? @resources.filter(@advanced_search_terms) : @resources
@resources = @resources.tagged_with(@tag_filter) if @tag_filter @resources = @resources.tagged_with(@tag_filter) if @tag_filter
@resources = @resources.page(params[:page]).for_render.send("sort_by_#{@current_order}") @resources = @resources.page(params[:page]).for_render.send("sort_by_#{@current_order}")
index_customization if index_customization.present? index_customization if index_customization.present?
@tag_cloud = tag_cloud
@tag_cloud = tag_cloud
set_resource_votes(@resources) set_resource_votes(@resources)
set_resources_instance set_resources_instance
end end
@@ -81,6 +83,47 @@ module CommentableActions
@search_terms = params[:search] if params[:search].present? @search_terms = params[:search] if params[:search].present?
end end
def parse_advanced_search_terms
@advanced_search_terms = params[:advanced_search] if params[:advanced_search].present?
parse_search_date
end
def parse_search_date
return unless search_by_date?
params[:advanced_search][:date_range] = search_date_range
end
def search_by_date?
params[:advanced_search] && params[:advanced_search][:date_min].present?
end
def search_start_date
case params[:advanced_search][:date_min]
when '1'
24.hours.ago
when '2'
1.week.ago
when '3'
1.month.ago
when '4'
1.year.ago
else
Date.parse(params[:advanced_search][:date_min]) rescue nil
end
end
def method_name
end
def search_finish_date
params[:advanced_search][:date_max].try(:to_date) || Date.today
end
def search_date_range
search_start_date.beginning_of_day..search_finish_date.end_of_day
end
def set_search_order def set_search_order
if params[:search].present? && params[:order].blank? if params[:search].present? && params[:order].blank?
params[:order] = 'relevance' params[:order] = 'relevance'

View File

@@ -3,6 +3,7 @@ class DebatesController < ApplicationController
include FlagActions include FlagActions
before_action :parse_search_terms, only: :index before_action :parse_search_terms, only: :index
before_action :parse_advanced_search_terms, only: :index
before_action :parse_tag_filter, only: :index before_action :parse_tag_filter, only: :index
before_action :set_search_order, only: :index before_action :set_search_order, only: :index
before_action :authenticate_user!, except: [:index, :show] before_action :authenticate_user!, except: [:index, :show]

View File

@@ -3,6 +3,7 @@ class ProposalsController < ApplicationController
include FlagActions include FlagActions
before_action :parse_search_terms, only: :index before_action :parse_search_terms, only: :index
before_action :parse_advanced_search_terms, only: :index
before_action :parse_tag_filter, only: :index before_action :parse_tag_filter, only: :index
before_action :set_search_order, only: :index before_action :set_search_order, only: :index
before_action :authenticate_user!, except: [:index, :show] before_action :authenticate_user!, except: [:index, :show]
@@ -14,7 +15,7 @@ class ProposalsController < ApplicationController
respond_to :html, :js respond_to :html, :js
def index_customization def index_customization
@featured_proposals = Proposal.all.sort_by_confidence_score.limit(3) if (@search_terms.blank? && @tag_filter.blank?) @featured_proposals = Proposal.all.sort_by_confidence_score.limit(3) if (!@advanced_search_terms && @search_terms.blank? && @tag_filter.blank?)
if @featured_proposals.present? if @featured_proposals.present?
set_featured_proposal_votes(@featured_proposals) set_featured_proposal_votes(@featured_proposals)
@resources = @resources.where('proposals.id NOT IN (?)', @featured_proposals.map(&:id)) @resources = @resources.where('proposals.id NOT IN (?)', @featured_proposals.map(&:id))
@@ -44,4 +45,5 @@ class ProposalsController < ApplicationController
def set_featured_proposal_votes(proposals) def set_featured_proposal_votes(proposals)
@featured_proposals_votes = current_user ? current_user.proposal_votes(proposals) : {} @featured_proposals_votes = current_user ? current_user.proposal_votes(proposals) : {}
end end
end end

View File

@@ -0,0 +1,31 @@
module SearchHelper
def official_level_search_options
options_for_select([
[t("shared.advanced_search.author_type_1"), 1],
[t("shared.advanced_search.author_type_2"), 2],
[t("shared.advanced_search.author_type_3"), 3],
[t("shared.advanced_search.author_type_4"), 4],
[t("shared.advanced_search.author_type_5"), 5]],
params[:advanced_search].try(:[], :official_level))
end
def date_range_options
options_for_select([
[t("shared.advanced_search.date_1"), 1],
[t("shared.advanced_search.date_2"), 2],
[t("shared.advanced_search.date_3"), 3],
[t("shared.advanced_search.date_4"), 4],
[t("shared.advanced_search.date_5"), 'custom']],
selected_date_range)
end
def selected_date_range
custom_date_range? ? 'custom' : params[:advanced_search].try(:[], :date_min)
end
def custom_date_range?
params[:advanced_search].try(:[], :date_max).present?
end
end

View File

@@ -0,0 +1,28 @@
module Filterable
extend ActiveSupport::Concern
included do
scope :by_official_level, -> (official_level) { where(users: { official_level: official_level }).joins(:author) }
scope :by_date_range, -> (date_range) { where(created_at: date_range) }
end
class_methods do
def filter(params)
resources = self.all
params.each do |filter, value|
if allowed_filter?(filter, value)
resources = resources.send("by_#{filter}", value)
end
end
resources
end
def allowed_filter?(filter, value)
return if value.blank?
['official_level', 'date_range'].include?(filter)
end
end
end

View File

@@ -6,6 +6,7 @@ class Debate < ActiveRecord::Base
include Measurable include Measurable
include Sanitizable include Sanitizable
include PgSearch include PgSearch
include Filterable
apply_simple_captcha apply_simple_captcha
acts_as_votable acts_as_votable

View File

@@ -6,6 +6,7 @@ class Proposal < ActiveRecord::Base
include Sanitizable include Sanitizable
include PgSearch include PgSearch
include SearchCache include SearchCache
include Filterable
apply_simple_captcha apply_simple_captcha
acts_as_votable acts_as_votable
@@ -68,9 +69,14 @@ class Proposal < ActiveRecord::Base
description => 'D' description => 'D'
} }
tag_list.each{ |tag| values[tag] = 'D' } tag_list.each{ |tag| values[tag] = 'D' }
values[author.username] = 'D'
values values
end end
def self.search(terms)
self.pg_search(terms)
end
def description def description
super.try :html_safe super.try :html_safe
end end
@@ -124,10 +130,6 @@ class Proposal < ActiveRecord::Base
self.tags.each{ |t| t.increment_custom_counter_for('Proposal') } self.tags.each{ |t| t.increment_custom_counter_for('Proposal') }
end end
def self.search(terms)
self.pg_search(terms)
end
def self.votes_needed_for_success def self.votes_needed_for_success
Setting['votes_for_proposal_success'].to_i Setting['votes_for_proposal_success'].to_i
end end

View File

@@ -1,6 +1,6 @@
<% provide :title do %><%= t('debates.index.title') %><% end %> <% provide :title do %><%= t('debates.index.title') %><% end %>
<% content_for :header_addon do %> <% content_for :header_addon do %>
<%= render "shared/search_form_header", <%= render "shared/search_form",
search_path: debates_path(page: 1), search_path: debates_path(page: 1),
i18n_namespace: "debates.index.search_form" %> i18n_namespace: "debates.index.search_form" %>
<% end %> <% end %>
@@ -9,14 +9,16 @@
<div class="wrap row"> <div class="wrap row">
<div id="debates" class="debates-list small-12 medium-9 column"> <div id="debates" class="debates-list small-12 medium-9 column">
<div class="small-12 medium-7 left"> <div class="small-12 margin-top search-results">
<% if @search_terms %> <% if @search_terms || @advanced_search_terms %>
<h2 class="margin-top"> <h2>
<%= page_entries_info @debates %> <%= page_entries_info @debates %>
<% if !@advanced_search_terms %>
<%= t("debates.index.search_results", count: @debates.size, search_term: @search_terms) %> <%= t("debates.index.search_results", count: @debates.size, search_term: @search_terms) %>
<% end %>
</h2> </h2>
<% elsif @tag_filter %> <% elsif @tag_filter %>
<h2 class="margin-top"> <h2>
<%= page_entries_info @debates %> <%= page_entries_info @debates %>
<%= t("debates.index.filter_topic", count: @debates.size, topic: @tag_filter) %> <%= t("debates.index.filter_topic", count: @debates.size, topic: @tag_filter) %>
</h2> </h2>
@@ -27,6 +29,8 @@
<%= render "featured_debates_static" %> <%= render "featured_debates_static" %>
<% end %> <% end %>
<%= render "shared/advanced_search", search_path: debates_path(page: 1) %>
<%= render 'shared/order_links', i18n_namespace: "debates.index" %> <%= render 'shared/order_links', i18n_namespace: "debates.index" %>
<div class="show-for-small-only"> <div class="show-for-small-only">

View File

@@ -1,6 +1,6 @@
<% provide :title do %><%= t('proposals.index.title') %><% end %> <% provide :title do %><%= t('proposals.index.title') %><% end %>
<% content_for :header_addon do %> <% content_for :header_addon do %>
<%= render "shared/search_form_header", <%= render "shared/search_form",
search_path: proposals_path(page: 1), search_path: proposals_path(page: 1),
i18n_namespace: "proposals.index.search_form" %> i18n_namespace: "proposals.index.search_form" %>
<% end %> <% end %>
@@ -9,14 +9,16 @@
<div class="wrap row"> <div class="wrap row">
<div id="proposals" class="proposals-list small-12 medium-9 column"> <div id="proposals" class="proposals-list small-12 medium-9 column">
<div class="small-12 medium-7 left"> <div class="small-12 margin-top search-results">
<% if @search_terms %> <% if @search_terms || @advanced_search_terms %>
<h2 class="margin-top"> <h2>
<%= page_entries_info @proposals %> <%= page_entries_info @proposals %>
<% if !@advanced_search_terms %>
<%= t("proposals.index.search_results", count: @proposals.size, search_term: @search_terms) %> <%= t("proposals.index.search_results", count: @proposals.size, search_term: @search_terms) %>
<% end %>
</h2> </h2>
<% elsif @tag_filter %> <% elsif @tag_filter %>
<h2 class="margin-top"> <h2>
<%= page_entries_info @proposals %> <%= page_entries_info @proposals %>
<%= t("proposals.index.filter_topic", count: @proposals.size, topic: @tag_filter) %> <%= t("proposals.index.filter_topic", count: @proposals.size, topic: @tag_filter) %>
</h2> </h2>
@@ -36,6 +38,8 @@
</div> </div>
<% end %> <% end %>
<%= render "shared/advanced_search", search_path: proposals_path(page: 1)%>
<%= render 'shared/order_links', i18n_namespace: "proposals.index" %> <%= render 'shared/order_links', i18n_namespace: "proposals.index" %>
<div class="show-for-small-only"> <div class="show-for-small-only">

View File

@@ -0,0 +1,47 @@
<%= link_to t("shared.advanced_search.title"), "#", id: 'js-advanced-search-title', class: "advanced-search small" %>
<div class="advanced-search-form clear">
<%= form_tag search_path, method: :get do %>
<div id='js-advanced-search' data-advanced-search-terms=<%= @advanced_search_terms.present? %> style="display: none">
<div class="small-12">
<label><%= t("shared.advanced_search.general") %></label>
<%= text_field_tag "search", params[:search],
placeholder: t("shared.advanced_search.general_placeholder") %>
</div>
<div class="small-12 large-3 left">
<label><%= t("shared.advanced_search.author_type") %></label>
<%= select_tag('advanced_search[official_level]', official_level_search_options,
include_blank: t("shared.advanced_search.author_type_blank")) %>
</div>
<div class="small-12 large-9 column">
<div class="small-12 large-4 left">
<label><%= t("shared.advanced_search.date") %></label>
<%= select_tag('advanced_search[date_min]', date_range_options,
include_blank: t("shared.advanced_search.date_range_blank"),
id: 'js-advanced-search-date-min') %>
</div>
<div id='js-custom-date' class='small-12 large-8 column' style="display: none">
<div class='small-12 large-6 column'>
<label><%= t("shared.advanced_search.from") %></label>
<%= date_field 'advanced_search', 'date_min', max: Date.today,
value: params[:advanced_search].try(:[], :date_min) %>
</div>
<div class='small-12 large-6 column'>
<label><%= t("shared.advanced_search.to") %></label>
<%= date_field 'advanced_search', 'date_max', max: Date.today,
value: params[:advanced_search].try(:[], :date_max) %>
</div>
</div>
</div>
<div class="small-12 medium-3">
<%= submit_tag t("shared.advanced_search.search"), class: 'button radius expand' %>
</div>
</div>
<% end %>
</div>

View File

@@ -1,27 +1,22 @@
<% # Params: <div id="search_form" class="search-form">
#
# search_path: for example debates_path
# i18n_namespace: for example "debates.index.search_form"
%>
<div class="search-form">
<div class="sidebar-divider"></div>
<h3><%= t("#{i18n_namespace}.title") %></h3>
<br>
<div class="row"> <div class="row">
<%= form_tag search_path, method: :get do %> <%= form_tag search_path, method: :get do %>
<div class="small-12 columns"> <div class="small-12 column">
<div class="row collapse"> <div class="row collapse">
<div class="small-10 column">
<div class="small-9 medium-12 large-9 columns"> <label class="sr-only"><%= t("#{i18n_namespace}.title") %></label>
<input type="text" name="search" placeholder="<%= t("#{i18n_namespace}.placeholder") %>" class="search-form"> <input type="text" name="search" placeholder="<%= t("#{i18n_namespace}.placeholder") %>" class="search-form" value="<%= params[:search] %>">
</div> </div>
<div class="small-3 medium-12 large-3 columns"> <div class="small-2 column">
<input type="submit" class="button secondary postfix" value="<%= t("#{i18n_namespace}.button") %>"> <button type="submit" class="button postfix" title="<%= t("#{i18n_namespace}.button") %>">
<span class="sr-only"><%= t("#{i18n_namespace}.button") %></span>
<i class="icon-search"></i>
</button>
</div> </div>
</div> </div>
</div> </div>
<% end %> <% end %>
</div> </div>
</div> </div>

View File

@@ -1,28 +0,0 @@
<% # Params:
#
# i18n_namespace: for example "debates.index.search_form"
# search_path: for example debates_path
%>
<div class="search-form">
<div class="row">
<%= form_tag search_path, method: :get do %>
<div class="small-12 column">
<div class="row collapse">
<div class="small-10 column">
<label for="search-form-header" class="sr-only"><%= t("debates.index.search_form.title") %></label>
<input type="text" id="search-form-header" name="search" placeholder="<%= t("#{i18n_namespace}.placeholder") %>" class="search-form">
</div>
<div class="small-2 column">
<button type="submit" class="button postfix" title="<%= t("#{i18n_namespace}.button") %>">
<span class="sr-only"><%= t("debates.index.search_form.button") %></span>
<i class="icon-search"></i>
</button>
</div>
</div>
</div>
<% end %>
</div>
</div>

View File

@@ -327,6 +327,27 @@ en:
form: form:
submit_button: Save changes submit_button: Save changes
shared: shared:
advanced_search:
author_type: 'By author category'
author_type_blank: 'Select a category'
author_type_1: 'Public employee'
author_type_2: 'Municipal Organization'
author_type_3: 'General director'
author_type_4: 'City councillor'
author_type_5: 'Mayoress'
date: 'By date'
date_range_blank: 'Choose a date'
date_1: 'Last 24 hours'
date_2: 'Last week'
date_3: 'Last month'
date_4: 'Last year'
date_5: 'Customized'
from: 'From'
general: 'With the text'
general_placeholder: 'Write the text'
search: 'Filter'
title: 'Advanced search'
to: 'To'
author_info: author_info:
author_deleted: User deleted author_deleted: User deleted
check: Select check: Select

View File

@@ -327,6 +327,27 @@ es:
form: form:
submit_button: Guardar cambios submit_button: Guardar cambios
shared: shared:
advanced_search:
author_type: 'Por categoría de autor'
author_type_blank: 'Elige una categoría'
author_type_1: 'Empleado público'
author_type_2: 'Organización Municipal'
author_type_3: 'Director general'
author_type_4: 'Concejal'
author_type_5: 'Alcaldesa'
date: 'Por fecha'
date_range_blank: 'Elige una fecha'
date_1: 'Últimas 24 horas'
date_2: 'Última semana'
date_3: 'Último mes'
date_4: 'Último año'
date_5: 'Personalizada'
from: 'Desde'
general: 'Con el texto'
general_placeholder: 'Escribe el texto'
search: 'Filtrar'
title: 'Búsqueda avanzada'
to: 'Hasta'
author_info: author_info:
author_deleted: Usuario eliminado author_deleted: Usuario eliminado
check: Seleccionar check: Seleccionar

View File

@@ -453,31 +453,352 @@ feature 'Debates' do
end end
end end
scenario 'Debate index search' do context "Search" do
debate1 = create(:debate, title: "Show me what you got")
debate2 = create(:debate, title: "Get Schwifty") context "Basic search" do
debate3 = create(:debate)
debate4 = create(:debate, description: "Schwifty in here") scenario 'Search by text' do
debate5 = create(:debate, tag_list: 'schwifty') debate1 = create(:debate, title: "Get Schwifty")
debate6 = create(:debate, tag_list: ['awesome foreign schwifty', 'major']) debate2 = create(:debate, title: "Schwifty Hello")
debate3 = create(:debate, title: "Do not show me")
visit debates_path visit debates_path
within "#search_form" do
fill_in "search", with: "Schwifty" fill_in "search", with: "Schwifty"
click_button "Search" click_button "Search"
end
within("#debates") do within("#debates") do
expect(page).to have_css('.debate', count: 4) expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title) expect(page).to have_content(debate2.title)
expect(page).to have_content(debate4.title)
expect(page).to have_content(debate5.title)
expect(page).to have_content(debate6.title)
expect(page).to_not have_content(debate1.title)
expect(page).to_not have_content(debate3.title) expect(page).to_not have_content(debate3.title)
end end
end end
scenario "Maintain search criteria" do
visit debates_path
within "#search_form" do
fill_in "search", with: "Schwifty"
click_button "Search"
end
expect(page).to have_selector("input[name='search'][value='Schwifty']")
end
end
context "Advanced search" do
scenario "Search by text", :js do
debate1 = create(:debate, title: "Get Schwifty")
debate2 = create(:debate, title: "Schwifty Hello")
debate3 = create(:debate, title: "Do not show me")
visit debates_path
click_link "Advanced search"
fill_in "Write the text", with: "Schwifty"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
context "Search by author type" do
scenario "Public employee", :js do
ana = create :user, official_level: 1
john = create :user, official_level: 2
debate1 = create(:debate, author: ana)
debate2 = create(:debate, author: ana)
debate3 = create(:debate, author: john)
visit debates_path
click_link "Advanced search"
select "Public employee", from: "advanced_search_official_level"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "Municipal Organization", :js do
ana = create :user, official_level: 2
john = create :user, official_level: 3
debate1 = create(:debate, author: ana)
debate2 = create(:debate, author: ana)
debate3 = create(:debate, author: john)
visit debates_path
click_link "Advanced search"
select "Municipal Organization", from: "advanced_search_official_level"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "General director", :js do
ana = create :user, official_level: 3
john = create :user, official_level: 4
debate1 = create(:debate, author: ana)
debate2 = create(:debate, author: ana)
debate3 = create(:debate, author: john)
visit debates_path
click_link "Advanced search"
select "General director", from: "advanced_search_official_level"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "City councillor", :js do
ana = create :user, official_level: 4
john = create :user, official_level: 5
debate1 = create(:debate, author: ana)
debate2 = create(:debate, author: ana)
debate3 = create(:debate, author: john)
visit debates_path
click_link "Advanced search"
select "City councillor", from: "advanced_search_official_level"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "Mayoress", :js do
ana = create :user, official_level: 5
john = create :user, official_level: 4
debate1 = create(:debate, author: ana)
debate2 = create(:debate, author: ana)
debate3 = create(:debate, author: john)
visit debates_path
click_link "Advanced search"
select "Mayoress", from: "advanced_search_official_level"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
end
context "Search by date" do
context "Predefined date ranges" do
scenario "Last day", :js do
debate1 = create(:debate, created_at: 1.minute.ago)
debate2 = create(:debate, created_at: 1.hour.ago)
debate3 = create(:debate, created_at: 2.days.ago)
visit debates_path
click_link "Advanced search"
select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "Last week", :js do
debate1 = create(:debate, created_at: 1.day.ago)
debate2 = create(:debate, created_at: 5.days.ago)
debate3 = create(:debate, created_at: 8.days.ago)
visit debates_path
click_link "Advanced search"
select "Last week", from: "js-advanced-search-date-min"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "Last month", :js do
debate1 = create(:debate, created_at: 10.days.ago)
debate2 = create(:debate, created_at: 20.days.ago)
debate3 = create(:debate, created_at: 33.days.ago)
visit debates_path
click_link "Advanced search"
select "Last month", from: "js-advanced-search-date-min"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "Last year", :js do
debate1 = create(:debate, created_at: 300.days.ago)
debate2 = create(:debate, created_at: 350.days.ago)
debate3 = create(:debate, created_at: 370.days.ago)
visit debates_path
click_link "Advanced search"
select "Last year", from: "js-advanced-search-date-min"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
end
scenario "Search by custom date range", :js do
debate1 = create(:debate, created_at: 2.days.ago)
debate2 = create(:debate, created_at: 3.days.ago)
debate3 = create(:debate, created_at: 9.days.ago)
visit debates_path
click_link "Advanced search"
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.days.ago
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 2)
expect(page).to have_content(debate1.title)
expect(page).to have_content(debate2.title)
expect(page).to_not have_content(debate3.title)
end
end
scenario "Search by multiple filters", :js do
ana = create :user, official_level: 1
john = create :user, official_level: 1
debate1 = create(:debate, title: "Get Schwifty", author: ana, created_at: 1.minute.ago)
debate2 = create(:debate, title: "Hello Schwifty", author: john, created_at: 2.days.ago)
debate3 = create(:debate, title: "Save the forest")
visit debates_path
click_link "Advanced search"
fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter"
within("#debates") do
expect(page).to have_css('.debate', count: 1)
expect(page).to have_content(debate1.title)
end
end
scenario "Maintain advanced search criteria", :js do
visit debates_path
click_link "Advanced search"
fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter"
within "#js-advanced-search" do
expect(page).to have_selector("input[name='search'][value='Schwifty']")
expect(page).to have_select('advanced_search[official_level]', selected: 'Public employee')
expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours')
end
end
scenario "Maintain custom date search criteria", :js do
visit debates_path
click_link "Advanced search"
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.days.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
pending "Order by relevance by default", :js do pending "Order by relevance by default", :js do
debate1 = create(:debate, title: "Show you got", cached_votes_up: 10) debate1 = create(:debate, title: "Show you got", cached_votes_up: 10)
debate2 = create(:debate, title: "Show what you got", cached_votes_up: 1) debate2 = create(:debate, title: "Show what you got", cached_votes_up: 1)
@@ -487,7 +808,7 @@ feature 'Debates' do
fill_in "search", with: "Show what you got" fill_in "search", with: "Show what you got"
click_button "Search" click_button "Search"
expect(page).to have_selector('a.active', text: "relevance") expect(page).to have_selector("a.active", text: "relevance")
within("#debates") do within("#debates") do
expect(all(".debate")[0].text).to match "Show what you got" expect(all(".debate")[0].text).to match "Show what you got"
@@ -505,9 +826,8 @@ feature 'Debates' do
visit debates_path visit debates_path
fill_in "search", with: "Show what you got" fill_in "search", with: "Show what you got"
click_button "Search" click_button "Search"
click_link 'newest'
click_link "newest" expect(page).to have_selector("a.active", text: "newest")
expect(page).to have_selector('a.active', text: "Newest")
within("#debates") do within("#debates") do
expect(all(".debate")[0].text).to match "Show you got" expect(all(".debate")[0].text).to match "Show you got"
@@ -517,18 +837,22 @@ feature 'Debates' do
end end
end end
scenario 'Index search does not show featured debates' do scenario 'After a search do not show featured debates' do
featured_debates = create_featured_debates featured_debates = create_featured_debates
debate = create(:debate, title: "Abcdefghi") debate = create(:debate, title: "Abcdefghi")
visit debates_path visit debates_path
within "#search_form" do
fill_in "search", with: debate.title fill_in "search", with: debate.title
click_button "Search" click_button "Search"
end
expect(page).to_not have_selector('#debates .debate-featured') expect(page).to_not have_selector('#debates .debate-featured')
expect(page).to_not have_selector('#featured-debates') expect(page).to_not have_selector('#featured-debates')
end end
end
scenario 'Index tag does not show featured debates' do scenario 'Index tag does not show featured debates' do
featured_debates = create_featured_debates featured_debates = create_featured_debates
debates = create(:debate, tag_list: "123") debates = create(:debate, tag_list: "123")

View File

@@ -516,31 +516,352 @@ feature 'Proposals' do
end end
end end
scenario 'Proposal index search' do context "Search" do
proposal1 = create(:proposal, title: "Show me what you got")
proposal2 = create(:proposal, title: "Get Schwifty") context "Basic search" do
proposal3 = create(:proposal)
proposal4 = create(:proposal, description: "Schwifty in here") scenario 'Search by text' do
proposal5 = create(:proposal, question: "Schwifty in here") proposal1 = create(:proposal, title: "Get Schwifty")
proposal2 = create(:proposal, title: "Schwifty Hello")
proposal3 = create(:proposal, title: "Do not show me")
visit proposals_path visit proposals_path
within "#search_form" do
fill_in "search", with: "Schwifty" fill_in "search", with: "Schwifty"
click_button "Search" click_button "Search"
end
expect(current_path).to eq(proposals_path)
within("#proposals") do within("#proposals") do
expect(page).to have_css('.proposal', count: 3) expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title) expect(page).to have_content(proposal2.title)
expect(page).to have_content(proposal4.title)
expect(page).to have_content(proposal5.title)
expect(page).to_not have_content(proposal1.title)
expect(page).to_not have_content(proposal3.title) expect(page).to_not have_content(proposal3.title)
end end
end end
scenario "Maintain search criteria" do
visit proposals_path
within "#search_form" do
fill_in "search", with: "Schwifty"
click_button "Search"
end
expect(page).to have_selector("input[name='search'][value='Schwifty']")
end
end
context "Advanced search" do
scenario "Search by text", :js do
proposal1 = create(:proposal, title: "Get Schwifty")
proposal2 = create(:proposal, title: "Schwifty Hello")
proposal3 = create(:proposal, title: "Do not show me")
visit proposals_path
click_link "Advanced search"
fill_in "Write the text", with: "Schwifty"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
context "Search by author type" do
scenario "Public employee", :js do
ana = create :user, official_level: 1
john = create :user, official_level: 2
proposal1 = create(:proposal, author: ana)
proposal2 = create(:proposal, author: ana)
proposal3 = create(:proposal, author: john)
visit proposals_path
click_link "Advanced search"
select "Public employee", from: "advanced_search_official_level"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "Municipal Organization", :js do
ana = create :user, official_level: 2
john = create :user, official_level: 3
proposal1 = create(:proposal, author: ana)
proposal2 = create(:proposal, author: ana)
proposal3 = create(:proposal, author: john)
visit proposals_path
click_link "Advanced search"
select "Municipal Organization", from: "advanced_search_official_level"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "General director", :js do
ana = create :user, official_level: 3
john = create :user, official_level: 4
proposal1 = create(:proposal, author: ana)
proposal2 = create(:proposal, author: ana)
proposal3 = create(:proposal, author: john)
visit proposals_path
click_link "Advanced search"
select "General director", from: "advanced_search_official_level"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "City councillor", :js do
ana = create :user, official_level: 4
john = create :user, official_level: 5
proposal1 = create(:proposal, author: ana)
proposal2 = create(:proposal, author: ana)
proposal3 = create(:proposal, author: john)
visit proposals_path
click_link "Advanced search"
select "City councillor", from: "advanced_search_official_level"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "Mayoress", :js do
ana = create :user, official_level: 5
john = create :user, official_level: 4
proposal1 = create(:proposal, author: ana)
proposal2 = create(:proposal, author: ana)
proposal3 = create(:proposal, author: john)
visit proposals_path
click_link "Advanced search"
select "Mayoress", from: "advanced_search_official_level"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
end
context "Search by date" do
context "Predefined date ranges" do
scenario "Last day", :js do
proposal1 = create(:proposal, created_at: 1.minute.ago)
proposal2 = create(:proposal, created_at: 1.hour.ago)
proposal3 = create(:proposal, created_at: 2.days.ago)
visit proposals_path
click_link "Advanced search"
select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "Last week", :js do
proposal1 = create(:proposal, created_at: 1.day.ago)
proposal2 = create(:proposal, created_at: 5.days.ago)
proposal3 = create(:proposal, created_at: 8.days.ago)
visit proposals_path
click_link "Advanced search"
select "Last week", from: "js-advanced-search-date-min"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "Last month", :js do
proposal1 = create(:proposal, created_at: 10.days.ago)
proposal2 = create(:proposal, created_at: 20.days.ago)
proposal3 = create(:proposal, created_at: 33.days.ago)
visit proposals_path
click_link "Advanced search"
select "Last month", from: "js-advanced-search-date-min"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "Last year", :js do
proposal1 = create(:proposal, created_at: 300.days.ago)
proposal2 = create(:proposal, created_at: 350.days.ago)
proposal3 = create(:proposal, created_at: 370.days.ago)
visit proposals_path
click_link "Advanced search"
select "Last year", from: "js-advanced-search-date-min"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
end
scenario "Search by custom date range", :js do
proposal1 = create(:proposal, created_at: 2.days.ago)
proposal2 = create(:proposal, created_at: 3.days.ago)
proposal3 = create(:proposal, created_at: 9.days.ago)
visit proposals_path
click_link "Advanced search"
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.days.ago
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 2)
expect(page).to have_content(proposal1.title)
expect(page).to have_content(proposal2.title)
expect(page).to_not have_content(proposal3.title)
end
end
scenario "Search by multiple filters", :js do
ana = create :user, official_level: 1
john = create :user, official_level: 1
proposal1 = create(:proposal, title: "Get Schwifty", author: ana, created_at: 1.minute.ago)
proposal2 = create(:proposal, title: "Hello Schwifty", author: john, created_at: 2.days.ago)
proposal3 = create(:proposal, title: "Save the forest")
visit proposals_path
click_link "Advanced search"
fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter"
within("#proposals") do
expect(page).to have_css('.proposal', count: 1)
expect(page).to have_content(proposal1.title)
end
end
scenario "Maintain advanced search criteria", :js do
visit proposals_path
click_link "Advanced search"
fill_in "Write the text", with: "Schwifty"
select "Public employee", from: "advanced_search_official_level"
select "Last 24 hours", from: "js-advanced-search-date-min"
click_button "Filter"
within "#js-advanced-search" do
expect(page).to have_selector("input[name='search'][value='Schwifty']")
expect(page).to have_select('advanced_search[official_level]', selected: 'Public employee')
expect(page).to have_select('advanced_search[date_min]', selected: 'Last 24 hours')
end
end
scenario "Maintain custom date search criteria", :js do
visit proposals_path
click_link "Advanced search"
select "Customized", from: "js-advanced-search-date-min"
fill_in "advanced_search_date_min", with: 7.days.ago.to_date
fill_in "advanced_search_date_max", with: 1.days.ago.to_date
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
scenario "Order by relevance by default", :js do scenario "Order by relevance by default", :js do
proposal1 = create(:proposal, title: "Show you got", cached_votes_up: 10) proposal1 = create(:proposal, title: "Show you got", cached_votes_up: 10)
proposal2 = create(:proposal, title: "Show what you got", cached_votes_up: 1) proposal2 = create(:proposal, title: "Show what you got", cached_votes_up: 1)
@@ -579,18 +900,22 @@ feature 'Proposals' do
end end
end end
scenario 'Index search does not show featured proposals' do scenario 'After a search do not show featured proposals' do
featured_proposals = create_featured_proposals featured_proposals = create_featured_proposals
proposal = create(:proposal, title: "Abcdefghi") proposal = create(:proposal, title: "Abcdefghi")
visit proposals_path visit proposals_path
within "#search_form" do
fill_in "search", with: proposal.title fill_in "search", with: proposal.title
click_button "Search" click_button "Search"
end
expect(page).to_not have_selector('#proposals .proposal-featured') expect(page).to_not have_selector('#proposals .proposal-featured')
expect(page).to_not have_selector('#featured-proposals') expect(page).to_not have_selector('#featured-proposals')
end end
end
scenario 'Index tag does not show featured proposals' do scenario 'Index tag does not show featured proposals' do
featured_proposals = create_featured_proposals featured_proposals = create_featured_proposals
proposal = create(:proposal, tag_list: "123") proposal = create(:proposal, tag_list: "123")

View File

@@ -445,6 +445,13 @@ describe Debate do
expect(results).to eq([debate]) expect(results).to eq([debate])
end end
xit "searches by author name" do
author = create(:user, username: 'Danny Trejo')
debate = create(:debate, author: author)
results = Debate.search('Danny')
expect(results).to eq([debate])
end
end end
context "stemming" do context "stemming" do

View File

@@ -395,6 +395,13 @@ describe Proposal do
expect(results).to eq([proposal]) expect(results).to eq([proposal])
end end
it "searches by author name" do
author = create(:user, username: 'Danny Trejo')
proposal = create(:proposal, author: author)
results = Proposal.search('Danny')
expect(results).to eq([proposal])
end
end end
context "stemming" do context "stemming" do