Commit 94dfcc164c2ef39d59e10f4be07f170ad85d3dd1

Authored by Dhruv Kapadia
1 parent 73c400bb

First cut at implementing future prompts to support image preloading

app/models/question.rb
... ... @@ -144,8 +144,11 @@ class Question < ActiveRecord::Base
144 144 if params[:with_appearance] && visitor_identifier.present?
145 145 visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier)
146 146  
147   - last_appearance = visitor.appearances.find(:first, :conditions => {:question_id => self.id},
148   - :order => 'created_at DESC',
  147 + last_appearance = visitor.appearances.find(:first,
  148 + :conditions => {:question_id => self.id,
  149 + :answerable_id => nil
  150 + },
  151 + :order => 'id ASC',
149 152 :limit => 1)
150 153 if last_appearance.nil?|| last_appearance.answered? || !last_appearance.prompt.active?
151 154 @prompt = choose_prompt(:algorithm => params[:algorithm])
... ... @@ -156,6 +159,40 @@ class Question < ActiveRecord::Base
156 159 @prompt= @appearance.prompt
157 160 end
158 161  
  162 + if params[:future_prompts]
  163 + num_future = params[:future_prompts][:number].to_i rescue 1
  164 + num_future.times do |number|
  165 + offset = number + 1
  166 + last_appearance = visitor.appearances.find(:first,
  167 + :conditions => {:question_id => self.id,
  168 + :answerable_id => nil
  169 + },
  170 + :order => 'id ASC',
  171 + :offset => offset)
  172 + if last_appearance.nil?|| last_appearance.answered? || !last_appearance.prompt.active?
  173 + @future_prompt = choose_prompt(:algorithm => params[:algorithm])
  174 + @future_appearance = current_user.record_appearance(visitor, @future_prompt)
  175 + else
  176 + @future_appearance = last_appearance
  177 + @future_prompt= @future_appearance.prompt
  178 + end
  179 +
  180 + result.merge!({"future_appearance_id_#{offset}".to_sym => @future_appearance.lookup})
  181 + result.merge!({"future_prompt_id_#{offset}".to_sym => @future_prompt.id})
  182 +
  183 + ["left", "right"].each do |side|
  184 + ["text", "id"].each do |param|
  185 + choice = (side == "left") ? @future_prompt.left_choice : @future_prompt.right_choice
  186 + param_val = (param == "text") ? choice.data : choice.id
  187 +
  188 + result.merge!({"future_#{side}_choice_#{param}_#{offset}".to_sym => param_val})
  189 + end
  190 + end
  191 +
  192 + end
  193 +
  194 + end
  195 +
159 196 result.merge!({:appearance_id => @appearance.lookup})
160 197 else
161 198 # throw some error
... ...
spec/models/question_spec.rb
... ... @@ -112,6 +112,64 @@ describe Question do
112 112 @question_optional_information[:picked_prompt_id].should == saved_prompt_id
113 113 end
114 114  
  115 + it "should return future prompts for a given visitor when future prompt param is passed" do
  116 + params = {:id => 124, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true, :future_prompts => {:number => 1} }
  117 + @question_optional_information = @question.get_optional_information(params)
  118 + appearance_id= @question_optional_information[:appearance_id]
  119 + future_appearance_id_1 = @question_optional_information[:future_appearance_id_1]
  120 + future_prompt_id_1 = @question_optional_information[:future_prompt_id_1]
  121 +
  122 + #check that required attributes are included
  123 + appearance_id.should be_an_instance_of(String)
  124 + future_appearance_id_1.should be_an_instance_of(String)
  125 + future_prompt_id_1.should be_an_instance_of(Fixnum)
  126 +
  127 + #appearances should have unique lookups
  128 + appearance_id.should_not == future_appearance_id_1
  129 + # check that all required parameters for choices are available
  130 +
  131 + ['left', 'right'].each do |side|
  132 + ['text', 'id'].each do |param|
  133 + the_type = (param == 'text') ? String : Fixnum
  134 + @question_optional_information["future_#{side}_choice_#{param}_1".to_sym].should be_an_instance_of(the_type)
  135 + end
  136 + end
  137 +
  138 + end
  139 +
  140 + it "should return the same appearance for future prompts when future prompt param is passed" do
  141 + params = {:id => 124, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true, :future_prompts => {:number => 1} }
  142 + @question_optional_information = @question.get_optional_information(params)
  143 + saved_appearance_id = @question_optional_information[:appearance_id]
  144 + saved_future_appearance_id_1 = @question_optional_information[:future_appearance_id_1]
  145 +
  146 + @question_optional_information = @question.get_optional_information(params)
  147 + @question_optional_information[:appearance_id].should == saved_appearance_id
  148 + @question_optional_information[:future_appearance_id_1].should == saved_future_appearance_id_1
  149 + end
  150 +
  151 + it "should return the next future appearance in future prompts sequence after a vote is made" do
  152 + params = {:id => 124, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true, :future_prompts => {:number => 1} }
  153 + @question_optional_information = @question.get_optional_information(params)
  154 + appearance_id = @question_optional_information[:appearance_id]
  155 + prompt_id = @question_optional_information[:picked_prompt_id]
  156 + future_appearance_id_1 = @question_optional_information[:future_appearance_id_1]
  157 + future_prompt_id_1 = @question_optional_information[:future_prompt_id_1]
  158 +
  159 + vote_options = {:visitor_identifier => "jim",
  160 + :appearance_lookup => appearance_id,
  161 + :prompt => Prompt.find(prompt_id),
  162 + :direction => "left"}
  163 +
  164 + @aoi_clone.record_vote(vote_options)
  165 +
  166 + @question_optional_information = @question.get_optional_information(params)
  167 + @question_optional_information[:appearance_id].should_not == appearance_id
  168 + @question_optional_information[:appearance_id].should == future_appearance_id_1
  169 + @question_optional_information[:picked_prompt_id].should == future_prompt_id_1
  170 + @question_optional_information[:future_appearance_id_1].should_not == future_appearance_id_1
  171 + end
  172 +
115 173 it "should properly handle tracking the prompt cache hit rate when returning the same appearance when a visitor requests two prompts without voting" do
116 174 params = {:id => 124, :with_visitor_stats=> true, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true}
117 175 @question.clear_prompt_queue
... ...