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 | 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 | ... | ... |