Commit d97fd2d2701ee84323db08bfda360aae800cb19c
1 parent
05ae50f0
Exists in
master
and in
1 other branch
Adding visitor_votes and visitor_ideas to all vote reponses
Showing
9 changed files
with
104 additions
and
23 deletions
Show diff stats
app/controllers/choices_controller.rb
@@ -60,8 +60,11 @@ class ChoicesController < InheritedResources::Base | @@ -60,8 +60,11 @@ class ChoicesController < InheritedResources::Base | ||
60 | 60 | ||
61 | @question = Question.find params[:question_id] | 61 | @question = Question.find params[:question_id] |
62 | 62 | ||
63 | + visitor_identifier = params['params']['auto'] | ||
64 | + visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) | ||
65 | + | ||
63 | respond_to do |format| | 66 | respond_to do |format| |
64 | - if @choice = current_user.create_choice(params['params']['auto'], @question, {:data => params['params']['data'], | 67 | + if @choice = current_user.create_choice(visitor_identifier, @question, {:data => params['params']['data'], |
65 | :local_identifier => params['params']['local_identifier']}) | 68 | :local_identifier => params['params']['local_identifier']}) |
66 | saved_choice_id = Proc.new { |options| options[:builder].tag!('saved_choice_id', @choice.id) } | 69 | saved_choice_id = Proc.new { |options| options[:builder].tag!('saved_choice_id', @choice.id) } |
67 | choice_status = Proc.new { |options| | 70 | choice_status = Proc.new { |options| |
@@ -71,7 +74,10 @@ class ChoicesController < InheritedResources::Base | @@ -71,7 +74,10 @@ class ChoicesController < InheritedResources::Base | ||
71 | 74 | ||
72 | Question.update_counters(@question.id, :inactive_choices_count => @choice.active? ? 0 : 1) | 75 | Question.update_counters(@question.id, :inactive_choices_count => @choice.active? ? 0 : 1) |
73 | 76 | ||
74 | - format.xml { render :xml => @choice.to_xml(:procs => [saved_choice_id, choice_status]), :status => :ok } | 77 | + visitor_votes = Proc.new { |options| options[:builder].tag!('visitor_votes', visitor.votes.count(:conditions => {:question_id => @question.id})) } |
78 | + visitor_ideas = Proc.new { |options| options[:builder].tag!('visitor_ideas', visitor.items.count) } | ||
79 | + | ||
80 | + format.xml { render :xml => @choice.to_xml(:procs => [saved_choice_id, choice_status, visitor_votes, visitor_ideas]), :status => :ok } | ||
75 | # format.xml { render :xml => @question.picked_prompt.to_xml(:methods => [:left_choice_text, :right_choice_text], :procs => [saved_choice_id, choice_status]), :status => :ok } | 81 | # format.xml { render :xml => @question.picked_prompt.to_xml(:methods => [:left_choice_text, :right_choice_text], :procs => [saved_choice_id, choice_status]), :status => :ok } |
76 | format.json { render :json => @question.to_json(:procs => [saved_choice_id, choice_status]), :status => :ok } | 82 | format.json { render :json => @question.to_json(:procs => [saved_choice_id, choice_status]), :status => :ok } |
77 | else | 83 | else |
app/controllers/prompts_controller.rb
@@ -84,12 +84,16 @@ class PromptsController < InheritedResources::Base | @@ -84,12 +84,16 @@ class PromptsController < InheritedResources::Base | ||
84 | end | 84 | end |
85 | 85 | ||
86 | 86 | ||
87 | - @a = current_user.record_appearance(visitor_identifier, next_prompt) | 87 | + visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) |
88 | + @a = current_user.record_appearance(visitor, next_prompt) | ||
88 | 89 | ||
89 | appearance_id = Proc.new { |options| options[:builder].tag!('appearance_id', @a.lookup) } | 90 | appearance_id = Proc.new { |options| options[:builder].tag!('appearance_id', @a.lookup) } |
91 | + | ||
92 | + visitor_votes = Proc.new { |options| options[:builder].tag!('visitor_votes', visitor.votes.count(:conditions => {:question_id => @question.id})) } | ||
93 | + visitor_ideas = Proc.new { |options| options[:builder].tag!('visitor_ideas', visitor.items.count) } | ||
90 | 94 | ||
91 | - format.xml { render :xml => next_prompt.to_xml(:procs => [appearance_id], :methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | ||
92 | - format.json { render :json => next_prompt.to_json(:procs => [appearance_id], :methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | 95 | + format.xml { render :xml => next_prompt.to_xml(:procs => [appearance_id, visitor_votes, visitor_ideas], :methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } |
96 | + format.json { render :json => next_prompt.to_json(:procs => [appearance_id, visitor_votes, visitor_ideas], :methods => [:left_choice_text, :right_choice_text, :left_choice_id, :right_choice_id]), :status => :ok } | ||
93 | else | 97 | else |
94 | format.xml { render :xml => c, :status => :unprocessable_entity } | 98 | format.xml { render :xml => c, :status => :unprocessable_entity } |
95 | format.json { render :json => c, :status => :unprocessable_entity } | 99 | format.json { render :json => c, :status => :unprocessable_entity } |
app/controllers/questions_controller.rb
@@ -74,7 +74,8 @@ class QuestionsController < InheritedResources::Base | @@ -74,7 +74,8 @@ class QuestionsController < InheritedResources::Base | ||
74 | # we sometimes request a question when no prompt is displayed | 74 | # we sometimes request a question when no prompt is displayed |
75 | # TODO It would be a good idea to find these places and treat them like barebones | 75 | # TODO It would be a good idea to find these places and treat them like barebones |
76 | if !visitor_identifier.blank? | 76 | if !visitor_identifier.blank? |
77 | - @a = current_user.record_appearance(visitor_identifier, @p) | 77 | + visitor = current_user.visitors.find_or_create_by_identifier(visitor_identifier) |
78 | + @a = current_user.record_appearance(visitor, @p) | ||
78 | logger.info("creating appearance!") | 79 | logger.info("creating appearance!") |
79 | else | 80 | else |
80 | @a = nil | 81 | @a = nil |
@@ -85,10 +86,15 @@ class QuestionsController < InheritedResources::Base | @@ -85,10 +86,15 @@ class QuestionsController < InheritedResources::Base | ||
85 | picked_prompt_id = Proc.new { |options| options[:builder].tag!('picked_prompt_id', @p.id) } | 86 | picked_prompt_id = Proc.new { |options| options[:builder].tag!('picked_prompt_id', @p.id) } |
86 | appearance_id = Proc.new { |options| options[:builder].tag!('appearance_id', @a.lookup) } | 87 | appearance_id = Proc.new { |options| options[:builder].tag!('appearance_id', @a.lookup) } |
87 | 88 | ||
89 | + visitor_votes = Proc.new { |options| options[:builder].tag!('visitor_votes', visitor.votes.count(:conditions => {:question_id => @question.id})) } | ||
90 | + visitor_ideas = Proc.new { |options| options[:builder].tag!('visitor_ideas', visitor.items.count) } | ||
91 | + | ||
88 | the_procs = [left_choice_text, right_choice_text, picked_prompt_id] | 92 | the_procs = [left_choice_text, right_choice_text, picked_prompt_id] |
89 | 93 | ||
90 | if @a | 94 | if @a |
91 | the_procs << appearance_id | 95 | the_procs << appearance_id |
96 | + the_procs << visitor_votes | ||
97 | + the_procs << visitor_ideas | ||
92 | end | 98 | end |
93 | 99 | ||
94 | show! do |format| | 100 | show! do |format| |
app/models/user.rb
@@ -39,9 +39,7 @@ class User < ActiveRecord::Base | @@ -39,9 +39,7 @@ class User < ActiveRecord::Base | ||
39 | #prompt.choices.each {|c| c.compute_score; c.save!} | 39 | #prompt.choices.each {|c| c.compute_score; c.save!} |
40 | end | 40 | end |
41 | 41 | ||
42 | - def record_appearance(visitor_identifier, prompt) | ||
43 | - visitor = visitors.find_or_create_by_identifier(visitor_identifier) | ||
44 | - | 42 | + def record_appearance(visitor, prompt) |
45 | a = Appearance.create(:voter => visitor, :prompt => prompt, :question_id => prompt.question_id, | 43 | a = Appearance.create(:voter => visitor, :prompt => prompt, :question_id => prompt.question_id, |
46 | :lookup => Digest::MD5.hexdigest(rand(10000000000).to_s + visitor.id.to_s + prompt.id.to_s) ) | 44 | :lookup => Digest::MD5.hexdigest(rand(10000000000).to_s + visitor.id.to_s + prompt.id.to_s) ) |
47 | end | 45 | end |
db/migrate/20100423154040_add_vistor_index_to_votes_table.rb
0 → 100644
spec/controllers/questions_controller_spec.rb
@@ -24,6 +24,10 @@ describe QuestionsController do | @@ -24,6 +24,10 @@ describe QuestionsController do | ||
24 | def mock_appearance(stubs={}) | 24 | def mock_appearance(stubs={}) |
25 | @mock_appearance||= mock_model(Appearance, stubs) | 25 | @mock_appearance||= mock_model(Appearance, stubs) |
26 | end | 26 | end |
27 | + | ||
28 | + def mock_visitor(stubs={}) | ||
29 | + @mock_visitor||= mock_model(Visitor, stubs) | ||
30 | + end | ||
27 | # | 31 | # |
28 | # describe "GET index" do | 32 | # describe "GET index" do |
29 | # it "assigns all questions as @questions" do | 33 | # it "assigns all questions as @questions" do |
@@ -39,26 +43,80 @@ describe QuestionsController do | @@ -39,26 +43,80 @@ describe QuestionsController do | ||
39 | mock_question.stub!(:picked_prompt).and_return(mock_prompt) | 43 | mock_question.stub!(:picked_prompt).and_return(mock_prompt) |
40 | end | 44 | end |
41 | 45 | ||
46 | + | ||
42 | it "assigns the requested question as @question" do | 47 | it "assigns the requested question as @question" do |
43 | Question.stub!(:find).with("37").and_return(mock_question) | 48 | Question.stub!(:find).with("37").and_return(mock_question) |
44 | #TODO it shouldn't call this unless we are generating an appearance, right? | 49 | #TODO it shouldn't call this unless we are generating an appearance, right? |
45 | 50 | ||
46 | get :show, :id => "37" | 51 | get :show, :id => "37" |
47 | assigns[:question].should equal(mock_question) | 52 | assigns[:question].should equal(mock_question) |
48 | - assigns[:prompt].should equal(mock_prompt) | 53 | + assigns[:p].should equal(mock_prompt) |
49 | assigns[:a].should be_nil | 54 | assigns[:a].should be_nil |
50 | end | 55 | end |
51 | 56 | ||
52 | - #TODO this is not a particularly intutive param to pass in order to create an appearance | ||
53 | - it "creates an appearance when a visitor identifier is a param" do | ||
54 | - @user.stub!(:record_appearance).with("somelongunique32charstring", mock_prompt).and_return(mock_appearance) | ||
55 | - get :show, :id => "37", :visitor_identifier => "somelongunique32charstring" | 57 | + |
58 | + it "does not create an appearance when the 'barebones' param is set" do | ||
59 | + get :show, :id => "37", :barebones => true | ||
56 | assigns[:question].should equal(mock_question) | 60 | assigns[:question].should equal(mock_question) |
57 | - assigns[:prompt].should equal(mock_prompt) | ||
58 | - assigns[:a].should equal(mock_appearance) | 61 | + assigns[:p].should be_nil |
62 | + assigns[:a].should be_nil | ||
63 | + end | ||
64 | + | ||
65 | + describe "creates an appearance" do | ||
66 | + before(:each) do | ||
67 | + @visitor_identifier = "somelongunique32charstring" | ||
68 | + #stub broken | ||
69 | + visitor_list = [mock_visitor] | ||
70 | + @user.stub!(:visitors).and_return(visitor_list) | ||
71 | + visitor_list.stub!(:find_or_create_by_identifier).and_return(mock_visitor) | ||
72 | + @user.stub!(:record_appearance).with(mock_visitor, mock_prompt).and_return(mock_appearance) | ||
73 | + end | ||
74 | + | ||
75 | + #TODO this is not a particularly intutive param to pass in order to create an appearance | ||
76 | + it "creates an appearance when a visitor identifier is a param" do | ||
77 | + get :show, :id => "37", :visitor_identifier => @visitor_identifier | ||
78 | + assigns[:question].should equal(mock_question) | ||
79 | + assigns[:p].should equal(mock_prompt) | ||
80 | + assigns[:a].should equal(mock_appearance) | ||
81 | + | ||
82 | + end | ||
59 | 83 | ||
84 | + it "does not create an appearance when the 'barebones' param is set, even when a visitor id is sent" do | ||
85 | + get :show, :id => "37", :barebones => true, :visitor_identifier => @visitor_identifier | ||
86 | + assigns[:question].should equal(mock_question) | ||
87 | + assigns[:p].should be_nil | ||
88 | + assigns[:a].should be_nil | ||
89 | + end | ||
90 | + | ||
91 | + describe "calls catchup algorithm" do | ||
92 | + before(:each) do | ||
93 | + mock_question.should_receive(:send_later).with(:add_prompt_to_queue) | ||
94 | + end | ||
95 | + | ||
96 | + | ||
97 | + #TODO Refactor out to use uses_catchup? | ||
98 | + it "should pop prompt from cached queue using the catchup algorithm if params dictate" do | ||
99 | + mock_question.should_receive(:pop_prompt_queue).and_return(mock_prompt) | ||
100 | + | ||
101 | + get :show, :id => "37", :visitor_identifier => @visitor_identifier, :algorithm => "catchup" | ||
102 | + assigns[:question].should equal(mock_question) | ||
103 | + assigns[:p].should equal(mock_prompt) | ||
104 | + assigns[:a].should equal(mock_appearance) | ||
105 | + end | ||
106 | + | ||
107 | + it "should handle cache misses gracefully" do | ||
108 | + mock_question.should_receive(:pop_prompt_queue).and_return(nil) | ||
109 | + mock_question.should_receive(:catchup_choose_prompt).and_return(mock_prompt) | ||
110 | + | ||
111 | + get :show, :id => "37", :visitor_identifier => @visitor_identifier, :algorithm => "catchup" | ||
112 | + assigns[:question].should equal(mock_question) | ||
113 | + assigns[:p].should equal(mock_prompt) | ||
114 | + assigns[:a].should equal(mock_appearance) | ||
115 | + end | ||
116 | + end | ||
60 | end | 117 | end |
61 | end | 118 | end |
119 | + | ||
62 | # | 120 | # |
63 | # describe "GET new" do | 121 | # describe "GET new" do |
64 | # it "assigns a new question as @question" do | 122 | # it "assigns a new question as @question" do |
spec/models/user_spec.rb
@@ -11,7 +11,8 @@ describe User do | @@ -11,7 +11,8 @@ describe User do | ||
11 | @rc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'goodbye gorgeous') | 11 | @rc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'goodbye gorgeous') |
12 | @prompt = Factory.create(:prompt, :question => @question, :tracking => 'sample', :left_choice => @lc, :right_choice => @rc) | 12 | @prompt = Factory.create(:prompt, :question => @question, :tracking => 'sample', :left_choice => @lc, :right_choice => @rc) |
13 | 13 | ||
14 | - @appearance = @aoi_clone.record_appearance("test visitor identifier", @prompt) | 14 | + @visitor = @aoi_clone.visitors.find_or_create_by_identifier("test_visitor_identifier") |
15 | + @appearance = @aoi_clone.record_appearance(@visitor, @prompt) | ||
15 | end | 16 | end |
16 | 17 | ||
17 | 18 |
spec/models/visitor_spec.rb
@@ -15,7 +15,9 @@ describe Visitor do | @@ -15,7 +15,9 @@ describe Visitor do | ||
15 | @lc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'hello gorgeous') | 15 | @lc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'hello gorgeous') |
16 | @rc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'goodbye gorgeous') | 16 | @rc = Factory.create(:choice, :question => @question, :creator => @johndoe, :data => 'goodbye gorgeous') |
17 | @prompt = Factory.create(:prompt, :question => @question, :tracking => 'sample', :left_choice => @lc, :right_choice => @rc) | 17 | @prompt = Factory.create(:prompt, :question => @question, :tracking => 'sample', :left_choice => @lc, :right_choice => @rc) |
18 | - @appearance = @aoi_clone.record_appearance("test visitor identifier", @prompt) | 18 | + |
19 | + @visitor = @aoi_clone.visitors.find_or_create_by_identifier("test_visitor_identifier") | ||
20 | + @appearance = @aoi_clone.record_appearance(@visitor, @prompt) | ||
19 | @valid_attributes = { | 21 | @valid_attributes = { |
20 | :site => @aoi_clone, | 22 | :site => @aoi_clone, |
21 | :identifier => "value for identifier", | 23 | :identifier => "value for identifier", |