diff --git a/app/models/skip.rb b/app/models/skip.rb index 009bb0e..ba39113 100644 --- a/app/models/skip.rb +++ b/app/models/skip.rb @@ -4,5 +4,5 @@ class Skip < ActiveRecord::Base belongs_to :prompt has_one :appearance, :as => :answerable - default_scope :conditions => {:valid_record => true} + default_scope :conditions => "#{table_name}.valid_record = 1" end diff --git a/app/models/visitor.rb b/app/models/visitor.rb index 9ce9424..0650641 100644 --- a/app/models/visitor.rb +++ b/app/models/visitor.rb @@ -25,7 +25,13 @@ class Visitor < ActiveRecord::Base if options[:appearance_lookup] @appearance = prompt.appearances.find_by_lookup(options.delete(:appearance_lookup)) return nil unless @appearance # don't allow people to fake appearance lookups - options.merge!(:appearance => @appearance) + + if @appearance.answered? + options.merge!(:valid_record => false) + options.merge!(:validity_information => "Appearance #{@appearance.id} already answered") + else + options.merge!(:appearance => @appearance) + end end choice = prompt.choices[ordinality] #we need to guarantee that the choices are in the right order (by position) @@ -45,7 +51,12 @@ class Visitor < ActiveRecord::Base if options[:appearance_lookup] @appearance = prompt.appearances.find_by_lookup(options.delete(:appearance_lookup)) return nil unless @appearance - options.merge!(:appearance => @appearance) + if @appearance.answered? + options.merge!(:valid_record => false) + options.merge!(:validity_information => "Appearance #{@appearance.id} already answered") + else + options.merge!(:appearance => @appearance) + end end options.merge!(:question_id => prompt.question_id, :prompt_id => prompt.id, :skipper_id => self.id) diff --git a/app/models/vote.rb b/app/models/vote.rb index 3f9681e..3705c82 100644 --- a/app/models/vote.rb +++ b/app/models/vote.rb @@ -18,7 +18,7 @@ class Vote < ActiveRecord::Base named_scope :with_voter_ids, lambda { |*args| {:conditions => {:voter_id=> args.first }} } named_scope :active, :include => :choice, :conditions => { 'choices.active' => true } - default_scope :conditions => {:valid_record => true} + default_scope :conditions => "#{table_name}.valid_record = 1" serialize :tracking diff --git a/spec/models/visitor_spec.rb b/spec/models/visitor_spec.rb index 84281a0..5b1845b 100644 --- a/spec/models/visitor_spec.rb +++ b/spec/models/visitor_spec.rb @@ -118,6 +118,46 @@ describe Visitor do s.should be_nil Skip.count.should == skip_count end + + it "should mark a skip as invalid if submitted with an already answered appearance" do + @appearance = @aoi_clone.record_appearance(@visitor, @prompt) + @optional_skip_params = {:appearance_lookup => @appearance.lookup} + allparams = @required_skip_params.merge(@optional_skip_params) + + valid_skip = @visitor.skip!(allparams) + @visitor.skips.count.should == 1 + @appearance.reload.answerable.should == valid_skip + + # we need to reset because vote_for deletes keys from the params + allparams = @required_skip_params.merge(@optional_skip_params) + invalid_skip = @visitor.skip!(allparams) + invalid_skip.should_not be_nil + + invalid_skip.valid_record.should be_false + invalid_skip.validity_information.should == "Appearance #{@appearance.id} already answered" + @appearance.reload.answerable.should == valid_skip + @visitor.reload.skips.count.should == 1 + end + + it "should mark a vote as invalid if submitted with an already answered appearance" do + @appearance = @aoi_clone.record_appearance(@visitor, @prompt) + @optional_vote_params = {:appearance_lookup => @appearance.lookup} + allparams = @required_vote_params.merge(@optional_vote_params) + + valid_vote = @visitor.vote_for!(allparams) + @visitor.votes.count.should == 1 + @appearance.reload.answerable.should == valid_vote + + # we need to reset because vote_for deletes keys from the params + allparams = @required_vote_params.merge(@optional_vote_params) + invalid_vote = @visitor.vote_for!(allparams) + invalid_vote.should_not be_nil + + invalid_vote.valid_record.should be_false + invalid_vote.validity_information.should == "Appearance #{@appearance.id} already answered" + @appearance.reload.answerable.should == valid_vote + @visitor.reload.votes.count.should == 1 + end it "should accurately update score counts after vote" do diff --git a/spec/models/vote_spec.rb b/spec/models/vote_spec.rb index 127ce6e..996191f 100644 --- a/spec/models/vote_spec.rb +++ b/spec/models/vote_spec.rb @@ -79,4 +79,32 @@ describe Vote do @prompt.right_choice.reload @prompt.right_choice.score.should be_close 33, 1 end + + it "should not display invalid votes by default" do + 5.times do + Factory.create(:vote) + end + Vote.count.should == 5 + + v = Vote.last + v.valid_record.should be_true + + v.valid_record = false + v.save + Vote.count.should == 4 + end + + it "should allow default valid_record behavior to be overriden by default" do + required_params = {:question => @question, :prompt => @prompt, + :choice => @prompt.left_choice, + :voter=> @question.site.default_visitor, + :loser_choice => @prompt.right_choice} + + vote = Vote.create!(required_params) + vote.valid_record.should be_true + + + vote = Vote.create!(required_params.merge!(:valid_record => false)) + vote.valid_record.should be_false + end end -- libgit2 0.21.2