From 94dfcc164c2ef39d59e10f4be07f170ad85d3dd1 Mon Sep 17 00:00:00 2001 From: Dhruv Kapadia Date: Thu, 15 Jul 2010 12:24:15 -0400 Subject: [PATCH] First cut at implementing future prompts to support image preloading --- app/models/question.rb | 41 +++++++++++++++++++++++++++++++++++++++-- spec/models/question_spec.rb | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 97 insertions(+), 2 deletions(-) diff --git a/app/models/question.rb b/app/models/question.rb index 9a97d9b..0df5ec8 100644 --- a/app/models/question.rb +++ b/app/models/question.rb @@ -144,8 +144,11 @@ class Question < ActiveRecord::Base if params[:with_appearance] && visitor_identifier.present? visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) - last_appearance = visitor.appearances.find(:first, :conditions => {:question_id => self.id}, - :order => 'created_at DESC', + last_appearance = visitor.appearances.find(:first, + :conditions => {:question_id => self.id, + :answerable_id => nil + }, + :order => 'id ASC', :limit => 1) if last_appearance.nil?|| last_appearance.answered? || !last_appearance.prompt.active? @prompt = choose_prompt(:algorithm => params[:algorithm]) @@ -156,6 +159,40 @@ class Question < ActiveRecord::Base @prompt= @appearance.prompt end + if params[:future_prompts] + num_future = params[:future_prompts][:number].to_i rescue 1 + num_future.times do |number| + offset = number + 1 + last_appearance = visitor.appearances.find(:first, + :conditions => {:question_id => self.id, + :answerable_id => nil + }, + :order => 'id ASC', + :offset => offset) + if last_appearance.nil?|| last_appearance.answered? || !last_appearance.prompt.active? + @future_prompt = choose_prompt(:algorithm => params[:algorithm]) + @future_appearance = current_user.record_appearance(visitor, @future_prompt) + else + @future_appearance = last_appearance + @future_prompt= @future_appearance.prompt + end + + result.merge!({"future_appearance_id_#{offset}".to_sym => @future_appearance.lookup}) + result.merge!({"future_prompt_id_#{offset}".to_sym => @future_prompt.id}) + + ["left", "right"].each do |side| + ["text", "id"].each do |param| + choice = (side == "left") ? @future_prompt.left_choice : @future_prompt.right_choice + param_val = (param == "text") ? choice.data : choice.id + + result.merge!({"future_#{side}_choice_#{param}_#{offset}".to_sym => param_val}) + end + end + + end + + end + result.merge!({:appearance_id => @appearance.lookup}) else # throw some error diff --git a/spec/models/question_spec.rb b/spec/models/question_spec.rb index 63c8d72..1525ad3 100644 --- a/spec/models/question_spec.rb +++ b/spec/models/question_spec.rb @@ -112,6 +112,64 @@ describe Question do @question_optional_information[:picked_prompt_id].should == saved_prompt_id end + it "should return future prompts for a given visitor when future prompt param is passed" do + params = {:id => 124, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true, :future_prompts => {:number => 1} } + @question_optional_information = @question.get_optional_information(params) + appearance_id= @question_optional_information[:appearance_id] + future_appearance_id_1 = @question_optional_information[:future_appearance_id_1] + future_prompt_id_1 = @question_optional_information[:future_prompt_id_1] + + #check that required attributes are included + appearance_id.should be_an_instance_of(String) + future_appearance_id_1.should be_an_instance_of(String) + future_prompt_id_1.should be_an_instance_of(Fixnum) + + #appearances should have unique lookups + appearance_id.should_not == future_appearance_id_1 + # check that all required parameters for choices are available + + ['left', 'right'].each do |side| + ['text', 'id'].each do |param| + the_type = (param == 'text') ? String : Fixnum + @question_optional_information["future_#{side}_choice_#{param}_1".to_sym].should be_an_instance_of(the_type) + end + end + + end + + it "should return the same appearance for future prompts when future prompt param is passed" do + params = {:id => 124, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true, :future_prompts => {:number => 1} } + @question_optional_information = @question.get_optional_information(params) + saved_appearance_id = @question_optional_information[:appearance_id] + saved_future_appearance_id_1 = @question_optional_information[:future_appearance_id_1] + + @question_optional_information = @question.get_optional_information(params) + @question_optional_information[:appearance_id].should == saved_appearance_id + @question_optional_information[:future_appearance_id_1].should == saved_future_appearance_id_1 + end + + it "should return the next future appearance in future prompts sequence after a vote is made" do + params = {:id => 124, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true, :future_prompts => {:number => 1} } + @question_optional_information = @question.get_optional_information(params) + appearance_id = @question_optional_information[:appearance_id] + prompt_id = @question_optional_information[:picked_prompt_id] + future_appearance_id_1 = @question_optional_information[:future_appearance_id_1] + future_prompt_id_1 = @question_optional_information[:future_prompt_id_1] + + vote_options = {:visitor_identifier => "jim", + :appearance_lookup => appearance_id, + :prompt => Prompt.find(prompt_id), + :direction => "left"} + + @aoi_clone.record_vote(vote_options) + + @question_optional_information = @question.get_optional_information(params) + @question_optional_information[:appearance_id].should_not == appearance_id + @question_optional_information[:appearance_id].should == future_appearance_id_1 + @question_optional_information[:picked_prompt_id].should == future_prompt_id_1 + @question_optional_information[:future_appearance_id_1].should_not == future_appearance_id_1 + end + it "should properly handle tracking the prompt cache hit rate when returning the same appearance when a visitor requests two prompts without voting" do params = {:id => 124, :with_visitor_stats=> true, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true} @question.clear_prompt_queue -- libgit2 0.21.2