diff --git a/app/controllers/debates_controller.rb b/app/controllers/debates_controller.rb index cf6d14f65..c0b23577d 100644 --- a/app/controllers/debates_controller.rb +++ b/app/controllers/debates_controller.rb @@ -1,11 +1,12 @@ class DebatesController < ApplicationController + before_action :parse_filter, only: :index before_action :authenticate_user!, except: [:index, :show] load_and_authorize_resource respond_to :html, :js def index - @debates = Debate.search(params).page(params[:page]).for_render + @debates = Debate.search(params).page(params[:page]).for_render.sort_by(@filter) set_debate_votes(@debates) end @@ -71,4 +72,9 @@ class DebatesController < ApplicationController @featured_tags = ActsAsTaggableOn::Tag.where(featured: true) end + def parse_filter + @valid_filters = ['votes', 'news', 'rated'] + @filter = @valid_filters.include?(params[:filter]) ? params[:filter] : 'news' + end + end diff --git a/app/models/debate.rb b/app/models/debate.rb index 15590fc60..194d6537b 100644 --- a/app/models/debate.rb +++ b/app/models/debate.rb @@ -40,6 +40,17 @@ class Debate < ActiveRecord::Base end end + def self.sort_by(filter) + case filter + when 'votes' + reorder(cached_votes_total: :desc) + when 'news' + reorder(created_at: :desc) + when 'rated' + reorder(cached_votes_up: :desc) + end + end + def likes cached_votes_up end diff --git a/app/views/debates/_filter_selector.erb b/app/views/debates/_filter_selector.erb new file mode 100644 index 000000000..fa26347f1 --- /dev/null +++ b/app/views/debates/_filter_selector.erb @@ -0,0 +1,7 @@ +<% options = @valid_filters.map { |f| [t("debates.index.filter_#{f}"), f] } %> + +<%= form_tag('/debates', method: 'get', class: 'inline-block') do %> + + <%= select_tag 'filter', options_for_select(options, @filter), onchange: "this.form.submit()" %> + +<% end %> diff --git a/app/views/debates/index.html.erb b/app/views/debates/index.html.erb index 59d11f37c..cf4205af6 100644 --- a/app/views/debates/index.html.erb +++ b/app/views/debates/index.html.erb @@ -4,18 +4,7 @@

<%= t("debates.index.showing") %>

- - + <%= render 'filter_selector' %>
diff --git a/spec/features/debates_spec.rb b/spec/features/debates_spec.rb index 22b689308..748b36c73 100644 --- a/spec/features/debates_spec.rb +++ b/spec/features/debates_spec.rb @@ -350,4 +350,61 @@ feature 'Debates' do expect(InappropiateFlag.flagged?(user, debate)).to_not be end + feature 'Debate index order filters', :js do + + before do + @debates = [create(:debate), create(:debate), create(:debate)] + create_list(:vote, 2, votable: @debates[1]) + create_list(:vote, 2, votable: @debates[0], vote_flag: false) + create(:vote, votable: @debates[0]) + end + + def expect_debate_order(order) + debate_divs = page.all("#debates .debate") + (0..2).each do |n| + expect(debate_divs[n]).to have_content(@debates[order[n]].title) + end + end + + scenario 'Default filter is newest' do + visit debates_path + + expect(page).to have_select('filter', selected: 'the newest') + expect_debate_order([2, 1, 0]) + end + + scenario 'Debates are ordered by most voted' do + visit debates_path + + select 'the most voted', from: 'filter' + expect(page).to have_select('filter', selected: 'the most voted') + + expect(find("#debates .debate", match: :first)).to have_content(@debates[0].title) # Necessary to force capybara to wait for redirect + expect(current_url).to include('filter=votes') + expect_debate_order([0, 1, 2]) + end + + scenario 'Debates are ordered by best rated' do + visit debates_path + + select 'the best rated', from: 'filter' + expect(find("#debates .debate", match: :first)).to have_content(@debates[1].title) + + expect(current_url).to include('filter=rated') + expect_debate_order([1, 0, 2]) + end + + scenario 'Debates are ordered by newest' do + visit debates_path + + select 'the most voted', from: 'filter' + expect(find("#debates .debate", match: :first)).to have_content(@debates[0].title) + + select 'the newest', from: 'filter' + expect(find("#debates .debate", match: :first)).to have_content(@debates[2].title) + + expect(current_url).to include('filter=news') + expect_debate_order([2, 1, 0]) + end + end end