Merge pull request #353 from AyuntamientoMadrid/hot-score-347
Hot score 347
This commit is contained in:
@@ -5,8 +5,7 @@ module HasFilters
|
||||
def has_filters(valid_filters, *args)
|
||||
before_action(*args) do
|
||||
@valid_filters = valid_filters
|
||||
@current_filter = params[:filter]
|
||||
@current_filter = @valid_filters.first unless @valid_filters.include?(@current_filter)
|
||||
@current_filter = @valid_filters.include?(params[:filter]) ? params[:filter] : @valid_filters.first
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@@ -82,8 +82,8 @@ class DebatesController < ApplicationController
|
||||
end
|
||||
|
||||
def parse_order
|
||||
@valid_orders = ['created_at', 'score', 'most_commented', 'random']
|
||||
@order = @valid_orders.include?(params[:order]) ? params[:order] : 'created_at'
|
||||
@valid_orders = ['hot_score', 'created_at', 'score', 'most_commented', 'random']
|
||||
@order = @valid_orders.include?(params[:order]) ? params[:order] : @valid_orders.first
|
||||
end
|
||||
|
||||
def parse_tag_filter
|
||||
|
||||
@@ -27,7 +27,7 @@ class Moderation::CommentsController < Moderation::BaseController
|
||||
private
|
||||
|
||||
def load_comments
|
||||
@comments = Comment.accessible_by(current_ability, :hide).flagged.sorted_for_moderation.includes(:commentable)
|
||||
@comments = Comment.accessible_by(current_ability, :hide).flagged.sort_for_moderation.includes(:commentable)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -26,7 +26,7 @@ class Moderation::DebatesController < Moderation::BaseController
|
||||
private
|
||||
|
||||
def load_debates
|
||||
@debates = Debate.accessible_by(current_ability, :hide).flagged.sorted_for_moderation
|
||||
@debates = Debate.accessible_by(current_ability, :hide).flagged.sort_for_moderation
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -2,8 +2,8 @@ class WelcomeController < ApplicationController
|
||||
skip_authorization_check
|
||||
|
||||
def index
|
||||
@featured_debates = Debate.includes(:tags).limit(3)
|
||||
@featured_debates = Debate.sort_by_hot_score.limit(3).for_render
|
||||
set_debate_votes(@featured_debates)
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -17,13 +17,15 @@ class Comment < ActiveRecord::Base
|
||||
|
||||
scope :recent, -> { order(id: :desc) }
|
||||
|
||||
scope :sorted_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :sort_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
|
||||
scope :with_ignored_flag, -> { where("ignored_flag_at IS NOT NULL AND hidden_at IS NULL") }
|
||||
scope :flagged, -> { where("flags_count > 0") }
|
||||
|
||||
scope :for_render, -> { with_hidden.includes(user: :organization) }
|
||||
|
||||
after_create :call_after_commented
|
||||
|
||||
def self.build(commentable, user, body, p_id=nil)
|
||||
new commentable: commentable,
|
||||
user_id: user.id,
|
||||
@@ -87,4 +89,8 @@ class Comment < ActiveRecord::Base
|
||||
!root?
|
||||
end
|
||||
|
||||
def call_after_commented
|
||||
self.commentable.try(:after_commented)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
require 'numeric'
|
||||
class Debate < ActiveRecord::Base
|
||||
default_scope { order(created_at: :desc) }
|
||||
|
||||
apply_simple_captcha
|
||||
TITLE_LENGTH = Debate.columns.find { |c| c.name == 'title' }.limit
|
||||
|
||||
@@ -23,15 +21,18 @@ class Debate < ActiveRecord::Base
|
||||
before_validation :sanitize_description
|
||||
before_validation :sanitize_tag_list
|
||||
|
||||
scope :sorted_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
before_save :calculate_hot_score
|
||||
|
||||
scope :sort_for_moderation, -> { order(flags_count: :desc, updated_at: :desc) }
|
||||
scope :pending_flag_review, -> { where(ignored_flag_at: nil, hidden_at: nil) }
|
||||
scope :with_ignored_flag, -> { where("ignored_flag_at IS NOT NULL AND hidden_at IS NULL") }
|
||||
scope :flagged, -> { where("flags_count > 0") }
|
||||
scope :for_render, -> { includes(:tags) }
|
||||
scope :sort_by_score , -> { reorder(cached_votes_score: :desc) }
|
||||
scope :sort_by_created_at, -> { reorder(created_at: :desc) }
|
||||
scope :sort_by_most_commented, -> { reorder(comments_count: :desc) }
|
||||
scope :sort_by_random, -> { reorder("RANDOM()") }
|
||||
scope :sort_by_hot_score , -> { order(hot_score: :desc) }
|
||||
scope :sort_by_score , -> { order(cached_votes_score: :desc) }
|
||||
scope :sort_by_created_at, -> { order(created_at: :desc) }
|
||||
scope :sort_by_most_commented, -> { order(comments_count: :desc) }
|
||||
scope :sort_by_random, -> { order("RANDOM()") }
|
||||
|
||||
# Ahoy setup
|
||||
visitable # Ahoy will automatically assign visit_id on create
|
||||
@@ -103,6 +104,30 @@ class Debate < ActiveRecord::Base
|
||||
update(ignored_flag_at: Time.now)
|
||||
end
|
||||
|
||||
def after_commented
|
||||
save # updates teh hot_score because there is a before_save
|
||||
end
|
||||
|
||||
def calculate_hot_score
|
||||
z = 1.96 # Normal distribution with a confidence of 0.95
|
||||
time_unit = 1.0 * 12.hours
|
||||
start = Time.new(2015, 6, 15)
|
||||
comments_weight = 1.0/3 # 3 comments == 1 positive vote
|
||||
|
||||
weighted_score = 0
|
||||
|
||||
n = cached_votes_total + comments_weight * comments_count
|
||||
if n > 0 then
|
||||
pos = cached_votes_up + comments_weight * comments_count
|
||||
phat = 1.0 * pos / n
|
||||
weighted_score = (phat + z*z/(2*n) - z * Math.sqrt((phat*(1-phat)+z*z/(4*n))/n))/(1+z*z/n)
|
||||
end
|
||||
|
||||
age_in_units = 1.0 * ((created_at || Time.now) - start) / time_unit
|
||||
|
||||
self.hot_score = (age_in_units**3 + weighted_score * 1000).round
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def sanitize_description
|
||||
@@ -112,5 +137,4 @@ class Debate < ActiveRecord::Base
|
||||
def sanitize_tag_list
|
||||
self.tag_list = TagSanitizer.new.sanitize_tag_list(self.tag_list)
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
|
||||
<table>
|
||||
<% @organizations.each do |organization| %>
|
||||
<tr>
|
||||
<tr id="<%= dom_id(organization) %>">
|
||||
<td><%= organization.name %></td>
|
||||
<td><%= organization.email %></td>
|
||||
<td><%= organization.phone_number %></td>
|
||||
|
||||
@@ -11,6 +11,8 @@
|
||||
<p class="debate-info">
|
||||
<i class="icon-comments"></i>
|
||||
<%= link_to t("debates.debate.comments", count: debate.comments_count), debate_path(debate, anchor: "comments") %>
|
||||
<span class="bullet"> • </span>
|
||||
<%= l debate.created_at.to_date %>
|
||||
</p>
|
||||
<div class="debate-description">
|
||||
<%= link_to debate.description, debate %>
|
||||
|
||||
@@ -69,6 +69,7 @@ en:
|
||||
select_order: Order by
|
||||
select_order_long: Order debates by
|
||||
orders:
|
||||
hot_score: most active
|
||||
created_at: newest
|
||||
score: best rated
|
||||
most_commented: most commented
|
||||
|
||||
@@ -69,6 +69,7 @@ es:
|
||||
select_order: Ordenar por
|
||||
select_order_long: Estás viendo los debates
|
||||
orders:
|
||||
hot_score: "más activos"
|
||||
created_at: "más nuevos"
|
||||
score: "mejor valorados"
|
||||
most_commented: "más comentados"
|
||||
|
||||
@@ -59,6 +59,7 @@ tags = Faker::Lorem.words(25)
|
||||
description = "<p>#{Faker::Lorem.paragraphs.join('</p></p>')}</p>"
|
||||
debate = Debate.create!(author: author,
|
||||
title: Faker::Lorem.sentence(3),
|
||||
created_at: rand((Time.now - 1.week) .. Time.now),
|
||||
description: description,
|
||||
tag_list: tags.sample(3).join(','),
|
||||
terms_of_service: "1")
|
||||
@@ -72,6 +73,7 @@ puts "Commenting Debates"
|
||||
author = User.reorder("RANDOM()").first
|
||||
debate = Debate.reorder("RANDOM()").first
|
||||
Comment.create!(user: author,
|
||||
created_at: rand(debate.created_at .. Time.now),
|
||||
commentable: debate,
|
||||
body: Faker::Lorem.sentence)
|
||||
end
|
||||
@@ -82,7 +84,8 @@ puts "Commenting Comments"
|
||||
(1..100).each do |i|
|
||||
author = User.reorder("RANDOM()").first
|
||||
parent = Comment.reorder("RANDOM()").first
|
||||
comment = Comment.create!(user: author,
|
||||
Comment.create!(user: author,
|
||||
created_at: rand(parent.created_at .. Time.now),
|
||||
commentable_id: parent.commentable_id,
|
||||
commentable_type: parent.commentable_type,
|
||||
body: Faker::Lorem.sentence,
|
||||
|
||||
5
db/migrate/20150903171309_add_hot_score_to_debates.rb
Normal file
5
db/migrate/20150903171309_add_hot_score_to_debates.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddHotScoreToDebates < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :debates, :hot_score, :bigint, default: 0
|
||||
end
|
||||
end
|
||||
@@ -101,6 +101,7 @@ ActiveRecord::Schema.define(version: 20150903200440) do
|
||||
t.datetime "confirmed_hide_at"
|
||||
t.integer "cached_anonymous_votes_total", default: 0
|
||||
t.integer "cached_votes_score", default: 0
|
||||
t.integer "hot_score", limit: 8, default: 0
|
||||
end
|
||||
|
||||
add_index "debates", ["cached_votes_down"], name: "index_debates_on_cached_votes_down", using: :btree
|
||||
|
||||
9
lib/tasks/debates.rake
Normal file
9
lib/tasks/debates.rake
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace :debates do
|
||||
desc "Updates all debates by recalculating their hot_score"
|
||||
task hot_score: :environment do
|
||||
Debate.find_in_batches do |debates|
|
||||
debates.each(&:save)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
@@ -71,6 +71,10 @@ FactoryGirl.define do
|
||||
Flag.flag(FactoryGirl.create(:user), debate)
|
||||
end
|
||||
end
|
||||
|
||||
trait :with_hot_score do
|
||||
before(:save) { |d| d.calculate_hot_score }
|
||||
end
|
||||
end
|
||||
|
||||
factory :vote do
|
||||
|
||||
@@ -13,7 +13,7 @@ feature 'Admin::Organizations' do
|
||||
|
||||
background do
|
||||
@user = create(:user, email: "marley@humanrights.com", phone_number: "6764440002")
|
||||
organization = create(:organization, user: @user, name: "Get up, Stand up")
|
||||
create(:organization, user: @user, name: "Get up, Stand up")
|
||||
end
|
||||
|
||||
scenario "returns no results if search term is empty" do
|
||||
@@ -70,11 +70,13 @@ feature 'Admin::Organizations' do
|
||||
organization = create(:organization)
|
||||
|
||||
visit admin_organizations_path
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_link('Verify')
|
||||
expect(page).to have_link('Reject')
|
||||
within("#organization_#{organization.id}") do
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_link('Verify')
|
||||
expect(page).to have_link('Reject')
|
||||
|
||||
click_on 'Verify'
|
||||
click_on 'Verify'
|
||||
end
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_content ('Verified')
|
||||
|
||||
@@ -86,11 +88,13 @@ feature 'Admin::Organizations' do
|
||||
|
||||
visit admin_organizations_path
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_content ('Verified')
|
||||
expect(page).to_not have_link('Verify')
|
||||
expect(page).to have_link('Reject')
|
||||
within("#organization_#{organization.id}") do
|
||||
expect(page).to have_content ('Verified')
|
||||
expect(page).to_not have_link('Verify')
|
||||
expect(page).to have_link('Reject')
|
||||
|
||||
click_on 'Reject'
|
||||
click_on 'Reject'
|
||||
end
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_content ('Rejected')
|
||||
|
||||
@@ -102,10 +106,12 @@ feature 'Admin::Organizations' do
|
||||
|
||||
visit admin_organizations_path
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_link('Verify')
|
||||
expect(page).to_not have_link('Reject', exact: true)
|
||||
within("#organization_#{organization.id}") do
|
||||
expect(page).to have_link('Verify')
|
||||
expect(page).to_not have_link('Reject', exact: true)
|
||||
|
||||
click_on 'Verify'
|
||||
click_on 'Verify'
|
||||
end
|
||||
expect(current_path).to eq(admin_organizations_path)
|
||||
expect(page).to have_content ('Verified')
|
||||
|
||||
|
||||
@@ -364,80 +364,87 @@ feature 'Debates' do
|
||||
expect(Flag.flagged?(user, debate)).to_not be
|
||||
end
|
||||
|
||||
feature 'Debate index order filters', :js do
|
||||
feature 'Debate index order filters' do
|
||||
|
||||
before do
|
||||
@most_commented_debate = create(:debate)
|
||||
@most_score_debate = create(:debate)
|
||||
@most_recent_debate = create(:debate)
|
||||
create_list(:comment, 2, commentable: @most_commented_debate)
|
||||
create_list(:vote, 2, votable: @most_score_debate)
|
||||
create_list(:vote, 2, votable: @most_recent_debate, vote_flag: false)
|
||||
create(:vote, votable: @most_recent_debate)
|
||||
create(:comment, commentable: @most_recent_debate)
|
||||
end
|
||||
scenario 'Default order is hot_score', :js do
|
||||
create(:debate, title: 'best').update_column(:hot_score, 10)
|
||||
create(:debate, title: 'worst').update_column(:hot_score, 2)
|
||||
create(:debate, title: 'medium').update_column(:hot_score, 5)
|
||||
|
||||
scenario 'Default order is created_at' do
|
||||
visit debates_path
|
||||
|
||||
expect(page).to have_select('order-selector', selected: 'newest')
|
||||
expect(@most_recent_debate.title).to appear_before(@most_score_debate.title)
|
||||
expect(@most_score_debate.title).to appear_before(@most_commented_debate.title)
|
||||
expect(page).to have_select('order-selector', selected: 'most active')
|
||||
expect('best').to appear_before('medium')
|
||||
expect('medium').to appear_before('worst')
|
||||
end
|
||||
|
||||
scenario 'Debates are ordered by best rated' do
|
||||
visit debates_path
|
||||
scenario 'Debates are ordered by best rated', :js do
|
||||
create(:debate, title: 'best', cached_votes_score: 10)
|
||||
create(:debate, title: 'medium', cached_votes_score: 5)
|
||||
create(:debate, title: 'worst', cached_votes_score: 2)
|
||||
|
||||
visit debates_path
|
||||
select 'best rated', from: 'order-selector'
|
||||
expect(page).to have_select('order-selector', selected: 'best rated')
|
||||
expect(find("#debates .debate", match: :first)).to have_content(@most_score_debate.title)
|
||||
|
||||
within '#debates' do
|
||||
expect('best').to appear_before('medium')
|
||||
expect('medium').to appear_before('worst')
|
||||
end
|
||||
|
||||
expect(current_url).to include('order=score')
|
||||
expect(@most_score_debate.title).to appear_before(@most_commented_debate.title)
|
||||
expect(@most_commented_debate.title).to appear_before(@most_recent_debate.title)
|
||||
end
|
||||
|
||||
scenario 'Debates are ordered by most commented' do
|
||||
visit debates_path
|
||||
scenario 'Debates are ordered by most commented', :js do
|
||||
create(:debate, title: 'best', comments_count: 10)
|
||||
create(:debate, title: 'medium', comments_count: 5)
|
||||
create(:debate, title: 'worst', comments_count: 2)
|
||||
|
||||
visit debates_path
|
||||
select 'most commented', from: 'order-selector'
|
||||
expect(page).to have_select('order-selector', selected: 'most commented')
|
||||
expect(find("#debates .debate", match: :first)).to have_content(@most_commented_debate.title)
|
||||
|
||||
within '#debates' do
|
||||
expect('best').to appear_before('medium')
|
||||
expect('medium').to appear_before('worst')
|
||||
end
|
||||
|
||||
expect(current_url).to include('order=most_commented')
|
||||
expect(@most_commented_debate.title).to appear_before(@most_recent_debate.title)
|
||||
expect(@most_recent_debate.title).to appear_before(@most_score_debate.title)
|
||||
end
|
||||
|
||||
scenario 'Debates are ordered by newest' do
|
||||
scenario 'Debates are ordered by newest', :js do
|
||||
create(:debate, title: 'best', created_at: Time.now)
|
||||
create(:debate, title: 'medium', created_at: Time.now - 1.hour)
|
||||
create(:debate, title: 'worst', created_at: Time.now - 1.day)
|
||||
|
||||
visit debates_path
|
||||
|
||||
select 'best rated', from: 'order-selector'
|
||||
expect(find("#debates .debate", match: :first)).to have_content(@most_score_debate.title)
|
||||
|
||||
select 'newest', from: 'order-selector'
|
||||
expect(page).to have_select('order-selector', selected: 'newest')
|
||||
expect(find("#debates .debate", match: :first)).to have_content(@most_recent_debate.title)
|
||||
|
||||
within '#debates' do
|
||||
expect('best').to appear_before('medium')
|
||||
expect('medium').to appear_before('worst')
|
||||
end
|
||||
|
||||
expect(current_url).to include('order=created_at')
|
||||
expect(@most_recent_debate.title).to appear_before(@most_score_debate.title)
|
||||
expect(@most_score_debate.title).to appear_before(@most_commented_debate.title)
|
||||
end
|
||||
|
||||
scenario 'Debates are ordered randomly' do
|
||||
scenario 'Debates are ordered randomly', :js do
|
||||
create_list(:debate, 12)
|
||||
visit debates_path
|
||||
|
||||
select 'random', from: 'order-selector'
|
||||
expect(page).to have_select('order-selector', selected: 'random')
|
||||
expect(page).to have_selector('#debates')
|
||||
debates_first_time = find("#debates").text
|
||||
|
||||
select 'most commented', from: 'order-selector'
|
||||
expect(page).to have_select('order-selector', selected: 'most commented')
|
||||
expect(find("#debates .debate", match: :first)).to have_content(@most_commented_debate.title)
|
||||
expect(page).to have_selector('#debates')
|
||||
|
||||
select 'random', from: 'order-selector'
|
||||
expect(page).to have_select('order-selector', selected: 'random')
|
||||
expect(page).to have_selector('#debates')
|
||||
debates_second_time = find("#debates").text
|
||||
|
||||
expect(debates_first_time).to_not eq(debates_second_time)
|
||||
|
||||
@@ -2,17 +2,14 @@ require 'rails_helper'
|
||||
|
||||
feature 'Votes' do
|
||||
|
||||
background do
|
||||
@manuela = create(:user, verified_at: Time.now)
|
||||
@pablo = create(:user)
|
||||
|
||||
login_as(@manuela)
|
||||
end
|
||||
|
||||
feature 'Debates' do
|
||||
|
||||
background do
|
||||
@manuela = create(:user, verified_at: Time.now)
|
||||
@pablo = create(:user)
|
||||
@debate = create(:debate)
|
||||
|
||||
login_as(@manuela)
|
||||
visit debate_path(@debate)
|
||||
end
|
||||
|
||||
scenario "Home shows user votes on featured debates" do
|
||||
debate1 = create(:debate)
|
||||
debate2 = create(:debate)
|
||||
@@ -109,84 +106,86 @@ feature 'Votes' do
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Show no votes' do
|
||||
visit debate_path(@debate)
|
||||
|
||||
expect(page).to have_content "No votes"
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to_not have_css("a.voted")
|
||||
expect(page).to_not have_css("a.no-voted")
|
||||
feature 'Single debate' do
|
||||
background do
|
||||
@debate = create(:debate)
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to_not have_css("a.voted")
|
||||
expect(page).to_not have_css("a.no-voted")
|
||||
end
|
||||
end
|
||||
scenario 'Show no votes' do
|
||||
visit debate_path(@debate)
|
||||
|
||||
scenario 'Show' do
|
||||
create(:vote, voter: @manuela, votable: @debate, vote_flag: true)
|
||||
create(:vote, voter: @pablo, votable: @debate, vote_flag: false)
|
||||
|
||||
visit debate_path(@debate)
|
||||
|
||||
expect(page).to have_content "2 votes"
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "50%"
|
||||
expect(page).to have_css("a.voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "50%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Create from debate show', :js do
|
||||
find('.in-favor a').click
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_css("a.voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
|
||||
scenario 'Create from debate featured', :js do
|
||||
visit root_path
|
||||
|
||||
within("#featured-debates") do
|
||||
find('.in-favor a').click
|
||||
expect(page).to have_content "No votes"
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_css("a.voted")
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to_not have_css("a.voted")
|
||||
expect(page).to_not have_css("a.no-voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to_not have_css("a.voted")
|
||||
expect(page).to_not have_css("a.no-voted")
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Update', :js do
|
||||
visit debate_path(@debate)
|
||||
|
||||
find('.in-favor a').click
|
||||
find('.against a').click
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_css("a.voted")
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
expect(URI.parse(current_url).path).to eq(root_path)
|
||||
end
|
||||
|
||||
scenario 'Create from debate index', :js do
|
||||
visit debates_path
|
||||
scenario 'Trying to vote multiple times', :js do
|
||||
visit debate_path(@debate)
|
||||
|
||||
within("#debates") do
|
||||
find('.in-favor a').click
|
||||
find('.in-favor a').click
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "100%"
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
|
||||
scenario 'Show' do
|
||||
create(:vote, voter: @manuela, votable: @debate, vote_flag: true)
|
||||
create(:vote, voter: @pablo, votable: @debate, vote_flag: false)
|
||||
|
||||
visit debate_path(@debate)
|
||||
|
||||
expect(page).to have_content "2 votes"
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "50%"
|
||||
expect(page).to have_css("a.voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "50%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
end
|
||||
end
|
||||
|
||||
scenario 'Create from debate show', :js do
|
||||
visit debate_path(@debate)
|
||||
|
||||
find('.in-favor a').click
|
||||
|
||||
@@ -202,51 +201,56 @@ feature 'Votes' do
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
expect(URI.parse(current_url).path).to eq(debates_path)
|
||||
end
|
||||
|
||||
scenario 'Update', :js do
|
||||
find('.in-favor a').click
|
||||
find('.against a').click
|
||||
scenario 'Create in featured', :js do
|
||||
visit root_path
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
within("#featured-debates") do
|
||||
find('.in-favor a').click
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_css("a.voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
expect(URI.parse(current_url).path).to eq(root_path)
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_css("a.voted")
|
||||
scenario 'Create in index', :js do
|
||||
visit debates_path
|
||||
|
||||
within("#debates") do
|
||||
|
||||
find('.in-favor a').click
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "100%"
|
||||
expect(page).to have_css("a.voted")
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
expect(page).to have_css("a.no-voted")
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
expect(URI.parse(current_url).path).to eq(debates_path)
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
|
||||
scenario 'Trying to vote multiple times', :js do
|
||||
find('.in-favor a').click
|
||||
find('.in-favor a').click
|
||||
|
||||
within('.in-favor') do
|
||||
expect(page).to have_content "100%"
|
||||
end
|
||||
|
||||
within('.against') do
|
||||
expect(page).to have_content "0%"
|
||||
end
|
||||
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
end
|
||||
|
||||
feature 'Comments' do
|
||||
background do
|
||||
@manuela = create(:user)
|
||||
@pablo = create(:user)
|
||||
@debate = create(:debate)
|
||||
@comment = create(:comment, commentable: @debate)
|
||||
|
||||
login_as(@manuela)
|
||||
visit debate_path(@debate)
|
||||
end
|
||||
|
||||
scenario 'Show' do
|
||||
@@ -269,6 +273,8 @@ feature 'Votes' do
|
||||
end
|
||||
|
||||
scenario 'Create', :js do
|
||||
visit debate_path(@debate)
|
||||
|
||||
within("#comment_#{@comment.id}_votes") do
|
||||
find(".in_favor a").click
|
||||
|
||||
@@ -285,6 +291,8 @@ feature 'Votes' do
|
||||
end
|
||||
|
||||
scenario 'Update', :js do
|
||||
visit debate_path(@debate)
|
||||
|
||||
within("#comment_#{@comment.id}_votes") do
|
||||
find('.in_favor a').click
|
||||
find('.against a').click
|
||||
@@ -302,6 +310,8 @@ feature 'Votes' do
|
||||
end
|
||||
|
||||
scenario 'Trying to vote multiple times', :js do
|
||||
visit debate_path(@debate)
|
||||
|
||||
within("#comment_#{@comment.id}_votes") do
|
||||
find('.in_favor a').click
|
||||
find('.in_favor a').click
|
||||
@@ -317,6 +327,5 @@ feature 'Votes' do
|
||||
expect(page).to have_content "1 vote"
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
@@ -174,15 +174,6 @@ describe Debate do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#default_order' do
|
||||
let!(:economy) { create(:debate) }
|
||||
let!(:health) { create(:debate) }
|
||||
|
||||
it "returns debates ordered by last one first" do
|
||||
expect(Debate.all).to eq([health, economy])
|
||||
end
|
||||
end
|
||||
|
||||
describe '#anonymous_votes_ratio' do
|
||||
it "returns the percentage of anonymous votes of the total votes" do
|
||||
debate = create(:debate, cached_anonymous_votes_total: 25, cached_votes_total: 100)
|
||||
@@ -190,4 +181,64 @@ describe Debate do
|
||||
end
|
||||
end
|
||||
|
||||
describe '#hot_score' do
|
||||
let(:now) { Time.now }
|
||||
|
||||
it "increases for newer debates" do
|
||||
old = create(:debate, :with_hot_score, created_at: now - 1.day)
|
||||
new = create(:debate, :with_hot_score, created_at: now)
|
||||
expect(new.hot_score).to be > old.hot_score
|
||||
end
|
||||
|
||||
it "increases for debates with more comments" do
|
||||
more_comments = create(:debate, :with_hot_score, created_at: now, comments_count: 10)
|
||||
less_comments = create(:debate, :with_hot_score, created_at: now, comments_count: 1)
|
||||
expect(more_comments.hot_score).to be > less_comments.hot_score
|
||||
end
|
||||
|
||||
it "increases for debates with more positive votes" do
|
||||
more_likes = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 5)
|
||||
less_likes = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 1)
|
||||
expect(more_likes.hot_score).to be > less_likes.hot_score
|
||||
end
|
||||
|
||||
it "increases for debates with more confidence" do
|
||||
more_confidence = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 1000, cached_votes_up: 700)
|
||||
less_confidence = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 9)
|
||||
expect(more_confidence.hot_score).to be > less_confidence.hot_score
|
||||
end
|
||||
|
||||
it "decays in older debates, even if they have more votes" do
|
||||
older_more_voted = create(:debate, :with_hot_score, created_at: now - 2.days, cached_votes_total: 1000, cached_votes_up: 900)
|
||||
new_less_voted = create(:debate, :with_hot_score, created_at: now, cached_votes_total: 10, cached_votes_up: 9)
|
||||
expect(new_less_voted.hot_score).to be > older_more_voted.hot_score
|
||||
end
|
||||
|
||||
describe 'actions which affect it' do
|
||||
let(:debate) { create(:debate, :with_hot_score) }
|
||||
|
||||
it "increases with likes" do
|
||||
previous = debate.hot_score
|
||||
5.times { debate.register_vote(create(:user), true) }
|
||||
expect(previous).to be < debate.hot_score
|
||||
end
|
||||
|
||||
it "decreases with dislikes" do
|
||||
debate.register_vote(create(:user), true)
|
||||
previous = debate.hot_score
|
||||
3.times { debate.register_vote(create(:user), false) }
|
||||
expect(previous).to be > debate.hot_score
|
||||
end
|
||||
|
||||
it "increases with comments" do
|
||||
previous = debate.hot_score
|
||||
Comment.create(user: create(:user), commentable: debate, body: 'foo')
|
||||
expect(previous).to be < debate.hot_score
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
|
||||
|
||||
end
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
RSpec::Matchers.define :appear_before do |later_content|
|
||||
match do |earlier_content|
|
||||
page.body.index(earlier_content) < page.body.index(later_content)
|
||||
text = page.text
|
||||
text.index(earlier_content) < text.index(later_content)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
Reference in New Issue
Block a user