Commit 9c36c839854314d4d3510389fe72edec70fec82a
1 parent
f9071a75
Exists in
master
and in
1 other branch
Bug in cached score computation, test case
Showing
4 changed files
with
64 additions
and
1 deletions
Show diff stats
app/models/visitor.rb
@@ -25,6 +25,10 @@ class Visitor < ActiveRecord::Base | @@ -25,6 +25,10 @@ class Visitor < ActiveRecord::Base | ||
25 | 25 | ||
26 | loser_choice = other_choices.first | 26 | loser_choice = other_choices.first |
27 | votes.create!(:question_id => prompt.question_id, :prompt_id => prompt.id, :voter_id=> self.id, :choice_id => choice.id, :loser_choice_id => loser_choice.id) | 27 | votes.create!(:question_id => prompt.question_id, :prompt_id => prompt.id, :voter_id=> self.id, :choice_id => choice.id, :loser_choice_id => loser_choice.id) |
28 | + # Votes count is a cached value, creating the vote above will increment it in the db, but to get the proper score, we need to increment it in the current object | ||
29 | + # The updated votes_count object is not saved to the db, so we don't need to worry about double counting | ||
30 | + # Alternatively, we could just do choice.reload, but that results in another db read | ||
31 | + choice.votes_count +=1 | ||
28 | choice.compute_score! #update score after win | 32 | choice.compute_score! #update score after win |
29 | end | 33 | end |
30 | 34 |
config/environments/test.rb
@@ -0,0 +1,20 @@ | @@ -0,0 +1,20 @@ | ||
1 | +class UpdateIncorrectScores < ActiveRecord::Migration | ||
2 | + def self.up | ||
3 | + | ||
4 | + # some scores were computed incorrectly as a result of a bug | ||
5 | + # This only affected the cached value of the score, so we only need to recalculate the correct score | ||
6 | + # for those choices voted on in the last few days | ||
7 | + startDate = 2.days.ago | ||
8 | + votes = Vote.find(:all, :conditions => ['created_at > ?', startDate]) | ||
9 | + toupdate = votes.inject(Set.new){|updatethese, v| updatethese << v.choice_id} | ||
10 | + choices = Choice.find(:all, :conditions => {'id' => toupdate.to_a}) | ||
11 | + | ||
12 | + choices.each do |c| | ||
13 | + c.compute_score! | ||
14 | + end | ||
15 | + | ||
16 | + end | ||
17 | + | ||
18 | + def self.down | ||
19 | + end | ||
20 | +end |
spec/models/visitor_spec.rb
@@ -6,6 +6,7 @@ describe Visitor do | @@ -6,6 +6,7 @@ describe Visitor do | ||
6 | it {should have_many :questions} | 6 | it {should have_many :questions} |
7 | it {should have_many :votes} | 7 | it {should have_many :votes} |
8 | it {should have_many :skips} | 8 | it {should have_many :skips} |
9 | + it {should have_many :clicks} | ||
9 | 10 | ||
10 | before(:each) do | 11 | before(:each) do |
11 | @aoi_clone = Factory.create(:user, :email => "pius@alum.mit.edu", :password => "password", :password_confirmation => "password", :id => 8) | 12 | @aoi_clone = Factory.create(:user, :email => "pius@alum.mit.edu", :password => "password", :password_confirmation => "password", :id => 8) |
@@ -29,6 +30,9 @@ describe Visitor do | @@ -29,6 +30,9 @@ describe Visitor do | ||
29 | 30 | ||
30 | it "should be able to determine ownership of a question" do | 31 | it "should be able to determine ownership of a question" do |
31 | @v.owns?(Question.new).should be_false | 32 | @v.owns?(Question.new).should be_false |
33 | + | ||
34 | + ownedquestion = Factory.create(:question, :site => @aoi_clone, :creator=> @johndoe) | ||
35 | + @johndoe.owns?(ownedquestion).should be_true | ||
32 | end | 36 | end |
33 | 37 | ||
34 | it "should be able to vote for a prompt" do | 38 | it "should be able to vote for a prompt" do |
@@ -37,10 +41,41 @@ describe Visitor do | @@ -37,10 +41,41 @@ describe Visitor do | ||
37 | v = @v.vote_for! @prompt, 0 | 41 | v = @v.vote_for! @prompt, 0 |
38 | end | 42 | end |
39 | 43 | ||
40 | - it "should be able to vote for a prompt" do | 44 | + it "should be able to skip a prompt" do |
41 | #@prompt = @question.prompts.first | 45 | #@prompt = @question.prompts.first |
42 | @prompt.should_not be_nil | 46 | @prompt.should_not be_nil |
43 | v = @v.skip! @prompt | 47 | v = @v.skip! @prompt |
44 | end | 48 | end |
49 | + | ||
50 | + it "should accurately update score counts after vote" do | ||
51 | + prev_winner_score = @lc.score | ||
52 | + prev_loser_score = @rc.score | ||
53 | + | ||
54 | + vote = @v.vote_for! @prompt, 0 | ||
55 | + | ||
56 | + @lc.reload | ||
57 | + @rc.reload | ||
58 | + | ||
59 | + @lc.score.should > prev_winner_score | ||
60 | + @rc.score.should < prev_loser_score | ||
61 | + end | ||
62 | + | ||
63 | + it "should accurately update win and loss totals after vote" do | ||
64 | + prev_winner_wins = @lc.wins | ||
65 | + prev_winner_losses = @lc.losses | ||
66 | + prev_loser_losses = @rc.losses | ||
67 | + prev_loser_wins = @rc.wins | ||
68 | + | ||
69 | + vote = @v.vote_for! @prompt, 0 | ||
70 | + | ||
71 | + @lc.reload | ||
72 | + @rc.reload | ||
73 | + | ||
74 | + @lc.wins.should == prev_winner_wins + 1 | ||
75 | + @lc.losses.should == prev_winner_losses | ||
76 | + @rc.losses.should == prev_loser_losses + 1 | ||
77 | + @rc.wins.should == prev_winner_wins | ||
78 | + end | ||
79 | + | ||
45 | 80 | ||
46 | end | 81 | end |