Commit 94dfcc164c2ef39d59e10f4be07f170ad85d3dd1
1 parent
73c400bb
Exists in
master
and in
1 other branch
First cut at implementing future prompts to support image preloading
Showing
2 changed files
with
97 additions
and
2 deletions
Show diff stats
app/models/question.rb
@@ -144,8 +144,11 @@ class Question < ActiveRecord::Base | @@ -144,8 +144,11 @@ class Question < ActiveRecord::Base | ||
144 | if params[:with_appearance] && visitor_identifier.present? | 144 | if params[:with_appearance] && visitor_identifier.present? |
145 | visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) | 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 | :limit => 1) | 152 | :limit => 1) |
150 | if last_appearance.nil?|| last_appearance.answered? || !last_appearance.prompt.active? | 153 | if last_appearance.nil?|| last_appearance.answered? || !last_appearance.prompt.active? |
151 | @prompt = choose_prompt(:algorithm => params[:algorithm]) | 154 | @prompt = choose_prompt(:algorithm => params[:algorithm]) |
@@ -156,6 +159,40 @@ class Question < ActiveRecord::Base | @@ -156,6 +159,40 @@ class Question < ActiveRecord::Base | ||
156 | @prompt= @appearance.prompt | 159 | @prompt= @appearance.prompt |
157 | end | 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 | result.merge!({:appearance_id => @appearance.lookup}) | 196 | result.merge!({:appearance_id => @appearance.lookup}) |
160 | else | 197 | else |
161 | # throw some error | 198 | # throw some error |
spec/models/question_spec.rb
@@ -112,6 +112,64 @@ describe Question do | @@ -112,6 +112,64 @@ describe Question do | ||
112 | @question_optional_information[:picked_prompt_id].should == saved_prompt_id | 112 | @question_optional_information[:picked_prompt_id].should == saved_prompt_id |
113 | end | 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 | it "should properly handle tracking the prompt cache hit rate when returning the same appearance when a visitor requests two prompts without voting" do | 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 | params = {:id => 124, :with_visitor_stats=> true, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true} | 174 | params = {:id => 124, :with_visitor_stats=> true, :visitor_identifier => "jim", :with_prompt => true, :with_appearance => true} |
117 | @question.clear_prompt_queue | 175 | @question.clear_prompt_queue |