Commit 9f0ec712f3369a626f7484d3cd24ef9acfb0e295
1 parent
18da412d
Exists in
master
and in
1 other branch
Rewriting skips model, providing support
Showing
9 changed files
with
124 additions
and
31 deletions
Show diff stats
app/controllers/prompts_controller.rb
... | ... | @@ -53,9 +53,7 @@ class PromptsController < InheritedResources::Base |
53 | 53 | @prompt = @question.prompts.find(params[:id]) |
54 | 54 | |
55 | 55 | time_viewed = params['params']['time_viewed'] |
56 | - | |
57 | 56 | visitor_identifier = params['params']['auto'] |
58 | - | |
59 | 57 | appearance_lookup = params['params']['appearance_lookup'] |
60 | 58 | |
61 | 59 | case direction |
... | ... | @@ -71,6 +69,7 @@ class PromptsController < InheritedResources::Base |
71 | 69 | respond_to do |format| |
72 | 70 | if successful |
73 | 71 | #catchup_marketplace_ids = [120, 117, 1, 116] |
72 | + #TODO refactor into question model | |
74 | 73 | if @question.uses_catchup? |
75 | 74 | logger.info("Question #{@question.id} is using catchup algorithm!") |
76 | 75 | next_prompt = @question.pop_prompt_queue |
... | ... | @@ -125,12 +124,45 @@ class PromptsController < InheritedResources::Base |
125 | 124 | authenticate |
126 | 125 | logger.info "#{current_user.inspect} is skipping." |
127 | 126 | @question = Question.find(params[:question_id]) |
128 | - @prompt = @question.prompts.find(params[:id], :include => [{ :left_choice => :item }, { :right_choice => :item }]) | |
127 | + @prompt = @question.prompts.find(params[:id]) #, :include => [{ :left_choice => :item }, { :right_choice => :item }]) | |
128 | + | |
129 | + time_viewed = params['params']['time_viewed'] | |
130 | + raise "time_viewed cannot be nil" if time_viewed.nil? | |
131 | + | |
132 | + visitor_identifier = params['params']['auto'] | |
133 | + raise "visitor identifier cannot be nil" if visitor_identifier.nil? | |
134 | + appearance_lookup = params['params']['appearance_lookup'] | |
135 | + raise "appearance_lookup cannot be nil" if appearance_lookup.nil? | |
136 | + | |
137 | + skip_reason = params['params']['skip_reason'] # optional parameter | |
129 | 138 | |
130 | 139 | |
131 | 140 | respond_to do |format| |
132 | - if @skip = current_user.record_skip(params['params']['auto'], @prompt) | |
133 | - format.xml { render :xml => @question.picked_prompt.to_xml(:methods => [:left_choice_text, :right_choice_text]), :status => :ok } | |
141 | + if @skip = current_user.record_skip(visitor_identifier, appearance_lookup, @prompt, time_viewed, :skip_reason => skip_reason) | |
142 | + | |
143 | + if @question.uses_catchup? | |
144 | + logger.info("Question #{@question.id} is using catchup algorithm!") | |
145 | + @next_prompt = @question.pop_prompt_queue | |
146 | + if @next_prompt.nil? | |
147 | + logger.info("Catchup prompt cache miss! Nothing in prompt_queue") | |
148 | + @next_prompt = @question.catchup_choose_prompt | |
149 | + end | |
150 | + @question.send_later :add_prompt_to_queue | |
151 | + else | |
152 | + @next_prompt = @question.picked_prompt | |
153 | + end | |
154 | + | |
155 | + | |
156 | + visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) | |
157 | + @a = current_user.record_appearance(visitor, @next_prompt) | |
158 | + | |
159 | + appearance_id = Proc.new { |options| options[:builder].tag!('appearance_id', @a.lookup) } | |
160 | + | |
161 | + visitor_votes = Proc.new { |options| options[:builder].tag!('visitor_votes', visitor.votes.count(:conditions => {:question_id => @question.id})) } | |
162 | + visitor_ideas = Proc.new { |options| options[:builder].tag!('visitor_ideas', visitor.items.count) } | |
163 | + | |
164 | + | |
165 | + format.xml { render :xml => @question.picked_prompt.to_xml(:procs => [appearance_id, visitor_votes, visitor_ideas],:methods => [:left_choice_text, :right_choice_text]), :status => :ok } | |
134 | 166 | format.json { render :json => @question.picked_prompt.to_json, :status => :ok } |
135 | 167 | else |
136 | 168 | format.xml { render :xml => @skip, :status => :unprocessable_entity } | ... | ... |
app/models/user.rb
... | ... | @@ -45,10 +45,9 @@ class User < ActiveRecord::Base |
45 | 45 | end |
46 | 46 | |
47 | 47 | |
48 | - def record_skip(visitor_identifier, prompt) | |
48 | + def record_skip(visitor_identifier, appearance_lookup, prompt, time_viewed, options = {}) | |
49 | 49 | visitor = visitors.find_or_create_by_identifier(visitor_identifier) |
50 | - question = prompt.question | |
51 | - visitor.skip!(prompt) | |
50 | + visitor.skip!(appearance_lookup, prompt, time_viewed, options) | |
52 | 51 | end |
53 | 52 | |
54 | 53 | def activate_question(question_id, options) | ... | ... |
app/models/visitor.rb
... | ... | @@ -18,6 +18,7 @@ class Visitor < ActiveRecord::Base |
18 | 18 | |
19 | 19 | def vote_for!(appearance_lookup, prompt, ordinality, time_viewed) |
20 | 20 | @a = Appearance.find_by_lookup(appearance_lookup) |
21 | + #make votefor fail if we cant find the appearance | |
21 | 22 | choices = prompt.choices |
22 | 23 | choice = choices[ordinality] #we need to guarantee that the choices are in the right order (by position) |
23 | 24 | other_choices = choices - [choice] |
... | ... | @@ -37,7 +38,12 @@ class Visitor < ActiveRecord::Base |
37 | 38 | |
38 | 39 | end |
39 | 40 | |
40 | - def skip!(prompt) | |
41 | - prompt_skip = skips.create!(:prompt => prompt) | |
41 | + def skip!(appearance_lookup, prompt, time_viewed, options = {}) | |
42 | + @a = Appearance.find_by_lookup(appearance_lookup) | |
43 | + | |
44 | + skip_create_options = { :question_id => prompt.question_id, :prompt_id => prompt.id, :skipper_id=> self.id, :time_viewed => time_viewed, :appearance_id => @a.id} | |
45 | + | |
46 | + prompt_skip = skips.create!(skip_create_options.merge(options)) | |
47 | + | |
42 | 48 | end |
43 | 49 | end | ... | ... |
... | ... | @@ -0,0 +1,19 @@ |
1 | +class CreateSkipsModel < ActiveRecord::Migration | |
2 | + def self.up | |
3 | + create_table :skips do |table| | |
4 | + table.text :tracking | |
5 | + table.integer :site_id | |
6 | + table.integer :skipper_id | |
7 | + table.integer :question_id | |
8 | + table.integer :prompt_id | |
9 | + table.integer :appearance_id | |
10 | + table.integer :time_viewed #msecs | |
11 | + table.timestamps | |
12 | + end | |
13 | + | |
14 | + end | |
15 | + | |
16 | + def self.down | |
17 | + drop_table :skips | |
18 | + end | |
19 | +end | ... | ... |
spec/controllers/prompts_controller_spec.rb
1 | 1 | require File.expand_path(File.dirname(__FILE__) + '/../spec_helper') |
2 | 2 | |
3 | 3 | describe PromptsController do |
4 | + def sign_in_as(user) | |
5 | + @controller.current_user = user | |
6 | + return user | |
7 | + end | |
8 | + # | |
9 | + before(:each) do | |
10 | + @aoi_clone = Factory.create(:user) | |
11 | + sign_in_as(@user = Factory(:email_confirmed_user)) | |
12 | + @johndoe = Factory.create(:visitor, :identifier => 'johndoe', :site => @aoi_clone) | |
13 | + @question = Factory.create(:question, :name => 'which do you like better?', :site => @aoi_clone, :creator => @aoi_clone.default_visitor) | |
14 | + @lc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'hello gorgeous') | |
15 | + @rc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'goodbye gorgeous') | |
16 | + @prompt = Factory.create(:prompt, :question => @question, :tracking => 'sample', :left_choice => @lc, :right_choice => @rc) | |
17 | + | |
18 | + @visitor = @aoi_clone.visitors.find_or_create_by_identifier("test_visitor_identifier") | |
19 | + @appearance = @aoi_clone.record_appearance(@visitor, @prompt) | |
20 | + end | |
21 | + # | |
4 | 22 | |
5 | - def mock_prompt(stubs={}) | |
6 | - @mock_prompt ||= mock_model(Prompt, stubs) | |
7 | - end | |
8 | - | |
9 | - before(:each) do | |
10 | - @aoi_clone = Factory.create(:user) | |
11 | - @question = Factory.create(:question, :site => @aoi_clone, :creator => @aoi_clone.default_visitor) | |
12 | - end | |
13 | - | |
14 | - describe "GET index" do | |
15 | - it "assigns all prompts as @prompts" do | |
23 | +# describe "GET index" do | |
24 | +# it "assigns all prompts as @prompts" do | |
16 | 25 | # Question.stub!(:find).with(:all).and_return(@question) |
17 | 26 | # Question.stub!(:prompts).with(:all).and_return([mock_prompt]) |
18 | - get :index, :question_id => @question.id | |
19 | - assigns[:prompts].should == [mock_prompt] | |
20 | - end | |
21 | - end | |
27 | +# get :index, :question_id => @question.id | |
28 | +# assigns[:prompts].should == [@prompt] | |
29 | +# end | |
30 | +# end | |
22 | 31 | |
23 | 32 | describe "GET show" do |
24 | 33 | it "assigns the requested prompt as @prompt" do |
25 | -# Question.stub!(:find).with(:all).and_return(@question) | |
26 | -# Prompt.stub!(:find).with("37").and_return(mock_prompt) | |
27 | - get :show, :id => "37", :question_id => @question.id | |
28 | - assigns[:prompt].should equal(mock_prompt) | |
34 | + get :show, :id => @prompt.id, :question_id => @question.id | |
35 | + assigns[:prompt].should == @prompt | |
29 | 36 | end |
30 | 37 | end |
38 | + | |
39 | + describe "POST skip" do | |
40 | + it "records a skip, responds with next prompt" do | |
41 | + post :skip, :id => @prompt.id, :question_id => @question.id, :params => {:auto => @visitor, :time_viewed => 30, :appearance_lookup => @appearance.lookup} | |
42 | + assigns[:next_prompt].should_not == @prompt | |
43 | + assigns[:next_prompt].should_not be_nil | |
44 | + assigns[:a].should_not be_nil | |
45 | + assigns[:a].should_not == @appearance | |
46 | + assigns[:skip].should_not be_nil | |
47 | + end | |
48 | + end | |
49 | + | |
31 | 50 | end | ... | ... |
spec/models/user_spec.rb
spec/models/visitor_spec.rb
... | ... | @@ -47,7 +47,7 @@ describe Visitor do |
47 | 47 | it "should be able to skip a prompt" do |
48 | 48 | #@prompt = @question.prompts.first |
49 | 49 | @prompt.should_not be_nil |
50 | - v = @v.skip! @prompt | |
50 | + v = @v.skip! @appearance.lookup, @prompt, 304 | |
51 | 51 | end |
52 | 52 | |
53 | 53 | it "should accurately update score counts after vote" do | ... | ... |