Added documentation for ability to set conditions for recording impressions. Also, Had to do some work to get the tests passing
Merge remote branch 'upstream/master' Conflicts: test_app/Gemfile.lock
This commit is contained in:
commit
e2ee248fba
|
@ -1,4 +1,4 @@
|
||||||
Gemfile.lock
|
Gemfile.lock
|
||||||
/test_app/db/migrate/20*
|
|
||||||
/test_app/db/schema.rb
|
/test_app/db/schema.rb
|
||||||
/pkg
|
/pkg
|
||||||
|
*~
|
||||||
|
|
19
README.md
19
README.md
|
@ -120,6 +120,25 @@ If you'd like to include only unique impressions in your count:
|
||||||
|
|
||||||
is_impressionable :counter_cache => { :column_name => :my_column, :unique => true }
|
is_impressionable :counter_cache => { :column_name => :my_column, :unique => true }
|
||||||
|
|
||||||
|
|
||||||
|
What if I only want to record unique impressions?
|
||||||
|
-------------------------------------------------
|
||||||
|
Maybe you only care about unique impressions and would like to eliminate unnecessary database calls. You can specify conditions for recording impressions in your controller:
|
||||||
|
|
||||||
|
# only record impression if the request has a unique combination of type, id, and session
|
||||||
|
impressionist :unique => [:impressionable_type, :impressionable_id, :session_hash]
|
||||||
|
|
||||||
|
# only record impression if the request has a unique combination of controller, action, and session
|
||||||
|
impressionist :unique => [:controller_name, :action_name, :session_hash]
|
||||||
|
|
||||||
|
# only record impression if session is unique
|
||||||
|
impressionist :unique => [:session_hash]
|
||||||
|
|
||||||
|
Or you can use the `impressionist` method directly:
|
||||||
|
|
||||||
|
impressionist(impressionable, "some message", :unique => [:session_hash])
|
||||||
|
|
||||||
|
|
||||||
Development Roadmap
|
Development Roadmap
|
||||||
-------------------
|
-------------------
|
||||||
* Automatic impression logging in views. For example, log initial view, and any partials called from initial view
|
* Automatic impression logging in views. For example, log initial view, and any partials called from initial view
|
||||||
|
|
|
@ -3,27 +3,23 @@ require 'digest/sha2'
|
||||||
module ImpressionistController
|
module ImpressionistController
|
||||||
module ClassMethods
|
module ClassMethods
|
||||||
def impressionist(opts={})
|
def impressionist(opts={})
|
||||||
before_filter { |c| c.impressionist_subapp_filter opts[:actions] }
|
before_filter { |c| c.impressionist_subapp_filter(opts[:actions], opts[:unique])}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
module InstanceMethods
|
module InstanceMethods
|
||||||
def self.included(base)
|
def self.included(base)
|
||||||
base.before_filter :impressionist_app_filter
|
base.before_filter :impressionist_app_filter
|
||||||
end
|
end
|
||||||
|
|
||||||
def impressionist(obj,message=nil)
|
def impressionist(obj,message=nil,opts={})
|
||||||
unless bypass
|
unless bypass
|
||||||
if obj.respond_to?("impressionable?")
|
if obj.respond_to?("impressionable?")
|
||||||
obj.impressions.create(:message=> message,
|
if unique_instance?(obj, opts[:unique])
|
||||||
:request_hash=> @impressionist_hash,
|
obj.impressions.create(associative_create_statement({:message => message}))
|
||||||
:session_hash=> request.session_options[:id],
|
end
|
||||||
:ip_address=> request.remote_ip,
|
|
||||||
:user_id=> user_id,
|
|
||||||
:controller_name=>controller_name,
|
|
||||||
:action_name=> action_name,
|
|
||||||
:referrer=>request.referer)
|
|
||||||
else
|
else
|
||||||
|
# we could create an impression anyway. for classes, too. why not?
|
||||||
raise "#{obj.class.to_s} is not impressionable!"
|
raise "#{obj.class.to_s} is not impressionable!"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
@ -33,31 +29,73 @@ module ImpressionistController
|
||||||
@impressionist_hash = Digest::SHA2.hexdigest(Time.now.to_f.to_s+rand(10000).to_s)
|
@impressionist_hash = Digest::SHA2.hexdigest(Time.now.to_f.to_s+rand(10000).to_s)
|
||||||
end
|
end
|
||||||
|
|
||||||
def impressionist_subapp_filter(actions=nil)
|
def impressionist_subapp_filter(actions=nil,unique_opts=nil)
|
||||||
unless bypass
|
unless bypass
|
||||||
actions.collect!{|a|a.to_s} unless actions.blank?
|
actions.collect!{|a|a.to_s} unless actions.blank?
|
||||||
if actions.blank? or actions.include?(action_name)
|
if (actions.blank? || actions.include?(action_name)) && unique?(unique_opts)
|
||||||
Impression.create(:controller_name=> controller_name,
|
Impression.create(direct_create_statement)
|
||||||
:action_name=> action_name,
|
|
||||||
:user_id=> user_id,
|
|
||||||
:request_hash=> @impressionist_hash,
|
|
||||||
:session_hash=> request.session_options[:id],
|
|
||||||
:ip_address=> request.remote_ip,
|
|
||||||
:impressionable_type=> controller_name.singularize.camelize,
|
|
||||||
:impressionable_id=> params[:id],
|
|
||||||
:referrer=>request.referer)
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def bypass
|
def bypass
|
||||||
Impressionist::Bots::WILD_CARDS.each do |wild_card|
|
Impressionist::Bots::WILD_CARDS.each do |wild_card|
|
||||||
return true if request.user_agent and request.user_agent.downcase.include? wild_card
|
return true if request.user_agent and request.user_agent.downcase.include? wild_card
|
||||||
end
|
end
|
||||||
Impressionist::Bots::LIST.include? request.user_agent
|
Impressionist::Bots::LIST.include? request.user_agent
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def unique_instance?(impressionable, unique_opts)
|
||||||
|
return unique_opts.blank? || impressionable.impressions.where(unique_query(unique_opts)).size == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
def unique?(unique_opts)
|
||||||
|
return unique_opts.blank? || Impression.where(unique_query(unique_opts)).size == 0
|
||||||
|
end
|
||||||
|
|
||||||
|
# creates the query to check for uniqueness
|
||||||
|
def unique_query(unique_opts)
|
||||||
|
full_statement = direct_create_statement
|
||||||
|
# reduce the full statement to the params we need for the specified unique options
|
||||||
|
unique_opts.reduce({}) do |query, param|
|
||||||
|
query[param] = full_statement[param]
|
||||||
|
query
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# creates a statment hash that contains default values for creating an impression via an AR relation.
|
||||||
|
def associative_create_statement(query_params={})
|
||||||
|
query_params.reverse_merge!(
|
||||||
|
:controller_name => controller_name,
|
||||||
|
:action_name => action_name,
|
||||||
|
:user_id => user_id,
|
||||||
|
:request_hash => @impressionist_hash,
|
||||||
|
:session_hash => session_hash,
|
||||||
|
:ip_address => request.remote_ip,
|
||||||
|
:referrer => request.referer
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# creates a statment hash that contains default values for creating an impression.
|
||||||
|
def direct_create_statement(query_params={})
|
||||||
|
query_params.reverse_merge!(
|
||||||
|
:impressionable_type => controller_name.singularize.camelize,
|
||||||
|
:impressionable_id=> params[:id]
|
||||||
|
)
|
||||||
|
associative_create_statement(query_params)
|
||||||
|
end
|
||||||
|
|
||||||
|
def session_hash
|
||||||
|
# # careful: request.session_options[:id] encoding in rspec test was ASCII-8BIT
|
||||||
|
# # that broke the database query for uniqueness. not sure if this is a testing only issue.
|
||||||
|
# str = request.session_options[:id]
|
||||||
|
# logger.debug "Encoding: #{str.encoding.inspect}"
|
||||||
|
# # request.session_options[:id].encode("ISO-8859-1")
|
||||||
|
request.session_options[:id]
|
||||||
|
end
|
||||||
|
|
||||||
#use both @current_user and current_user helper
|
#use both @current_user and current_user helper
|
||||||
def user_id
|
def user_id
|
||||||
user_id = @current_user ? @current_user.id : nil rescue nil
|
user_id = @current_user ? @current_user.id : nil rescue nil
|
||||||
|
|
|
@ -3,7 +3,7 @@ source 'http://rubygems.org'
|
||||||
gem 'rails', '3.1'
|
gem 'rails', '3.1'
|
||||||
gem 'sqlite3-ruby', :require => 'sqlite3'
|
gem 'sqlite3-ruby', :require => 'sqlite3'
|
||||||
gem 'impressionist', :path=>"#{File.dirname(__FILE__)}/../"
|
gem 'impressionist', :path=>"#{File.dirname(__FILE__)}/../"
|
||||||
gem "pg"
|
#gem "pg"
|
||||||
|
|
||||||
group :development do
|
group :development do
|
||||||
gem 'ZenTest'
|
gem 'ZenTest'
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
PATH
|
PATH
|
||||||
remote: /Users/coryschires/Desktop/work/applications/impressionist
|
remote: /Users/coryschires/Desktop/impressionist
|
||||||
specs:
|
specs:
|
||||||
impressionist (0.4.0)
|
impressionist (0.4.0)
|
||||||
|
|
||||||
|
@ -45,7 +45,7 @@ GEM
|
||||||
autotest-standalone (4.5.8)
|
autotest-standalone (4.5.8)
|
||||||
bcrypt-ruby (3.0.1)
|
bcrypt-ruby (3.0.1)
|
||||||
builder (3.0.0)
|
builder (3.0.0)
|
||||||
capybara (1.1.1)
|
capybara (1.1.2)
|
||||||
mime-types (>= 1.16)
|
mime-types (>= 1.16)
|
||||||
nokogiri (>= 1.3.3)
|
nokogiri (>= 1.3.3)
|
||||||
rack (>= 1.0.0)
|
rack (>= 1.0.0)
|
||||||
|
@ -54,23 +54,23 @@ GEM
|
||||||
xpath (~> 0.1.4)
|
xpath (~> 0.1.4)
|
||||||
childprocess (0.2.2)
|
childprocess (0.2.2)
|
||||||
ffi (~> 1.0.6)
|
ffi (~> 1.0.6)
|
||||||
cucumber (1.1.0)
|
cucumber (1.1.3)
|
||||||
builder (>= 2.1.2)
|
builder (>= 2.1.2)
|
||||||
diff-lcs (>= 1.1.2)
|
diff-lcs (>= 1.1.2)
|
||||||
gherkin (~> 2.5.0)
|
gherkin (~> 2.6.7)
|
||||||
json (>= 1.4.6)
|
json (>= 1.4.6)
|
||||||
term-ansicolor (>= 1.0.6)
|
term-ansicolor (>= 1.0.6)
|
||||||
cucumber-rails (1.1.1)
|
cucumber-rails (1.2.0)
|
||||||
capybara (>= 1.1.1)
|
capybara (>= 1.1.1)
|
||||||
cucumber (>= 1.1.0)
|
cucumber (>= 1.1.1)
|
||||||
nokogiri (>= 1.5.0)
|
nokogiri (>= 1.5.0)
|
||||||
daemons (1.0.10)
|
daemons (1.0.10)
|
||||||
database_cleaner (0.6.7)
|
database_cleaner (0.7.0)
|
||||||
diff-lcs (1.1.3)
|
diff-lcs (1.1.3)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
ffi (1.0.9)
|
ffi (1.0.11)
|
||||||
gem_plugin (0.2.3)
|
gem_plugin (0.2.3)
|
||||||
gherkin (2.5.4)
|
gherkin (2.6.8)
|
||||||
json (>= 1.4.6)
|
json (>= 1.4.6)
|
||||||
hike (1.2.1)
|
hike (1.2.1)
|
||||||
i18n (0.6.0)
|
i18n (0.6.0)
|
||||||
|
@ -88,8 +88,7 @@ GEM
|
||||||
gem_plugin (~> 0.2.3)
|
gem_plugin (~> 0.2.3)
|
||||||
multi_json (1.0.3)
|
multi_json (1.0.3)
|
||||||
nokogiri (1.5.0)
|
nokogiri (1.5.0)
|
||||||
pg (0.11.0)
|
polyglot (0.3.3)
|
||||||
polyglot (0.3.2)
|
|
||||||
rack (1.3.5)
|
rack (1.3.5)
|
||||||
rack-cache (1.0.3)
|
rack-cache (1.0.3)
|
||||||
rack (>= 0.4)
|
rack (>= 0.4)
|
||||||
|
@ -130,28 +129,28 @@ GEM
|
||||||
activesupport (~> 3.0)
|
activesupport (~> 3.0)
|
||||||
railties (~> 3.0)
|
railties (~> 3.0)
|
||||||
rspec (~> 2.7.0)
|
rspec (~> 2.7.0)
|
||||||
rubyzip (0.9.4)
|
rubyzip (0.9.5)
|
||||||
selenium-webdriver (2.10.0)
|
selenium-webdriver (2.13.0)
|
||||||
childprocess (>= 0.2.1)
|
childprocess (>= 0.2.1)
|
||||||
ffi (= 1.0.9)
|
ffi (~> 1.0.9)
|
||||||
json_pure
|
json_pure
|
||||||
rubyzip
|
rubyzip
|
||||||
spork (0.8.5)
|
spork (0.8.5)
|
||||||
sprockets (2.0.3)
|
sprockets (2.0.3)
|
||||||
hike (~> 1.2)
|
hike (~> 1.2)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
tilt (!= 1.3.0, ~> 1.1)
|
tilt (~> 1.1, != 1.3.0)
|
||||||
sqlite3 (1.3.4)
|
sqlite3 (1.3.4)
|
||||||
sqlite3-ruby (1.3.3)
|
sqlite3-ruby (1.3.3)
|
||||||
sqlite3 (>= 1.3.3)
|
sqlite3 (>= 1.3.3)
|
||||||
systemu (2.4.0)
|
systemu (2.4.1)
|
||||||
term-ansicolor (1.0.7)
|
term-ansicolor (1.0.7)
|
||||||
thor (0.14.6)
|
thor (0.14.6)
|
||||||
tilt (1.3.3)
|
tilt (1.3.3)
|
||||||
treetop (1.4.10)
|
treetop (1.4.10)
|
||||||
polyglot
|
polyglot
|
||||||
polyglot (>= 0.3.1)
|
polyglot (>= 0.3.1)
|
||||||
tzinfo (0.3.30)
|
tzinfo (0.3.31)
|
||||||
xpath (0.1.4)
|
xpath (0.1.4)
|
||||||
nokogiri (~> 1.3)
|
nokogiri (~> 1.3)
|
||||||
|
|
||||||
|
@ -169,7 +168,6 @@ DEPENDENCIES
|
||||||
impressionist!
|
impressionist!
|
||||||
launchy
|
launchy
|
||||||
mongrel (= 1.2.0.pre2)
|
mongrel (= 1.2.0.pre2)
|
||||||
pg
|
|
||||||
rails (= 3.1)
|
rails (= 3.1)
|
||||||
rspec
|
rspec
|
||||||
rspec-rails
|
rspec-rails
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
# This controller imports the impressionist module to make the modules methods available for testing
|
||||||
|
class DummyController < ActionController::Base
|
||||||
|
|
||||||
|
impressionist
|
||||||
|
|
||||||
|
end
|
|
@ -1,5 +1,6 @@
|
||||||
class WidgetsController < ApplicationController
|
class WidgetsController < ApplicationController
|
||||||
impressionist :actions=>[:show,:index]
|
impressionist :actions=>[:show,:index], :unique => [:controller_name,:action_name,:impressionable_id]
|
||||||
|
|
||||||
def show
|
def show
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -8,4 +9,5 @@ class WidgetsController < ApplicationController
|
||||||
|
|
||||||
def new
|
def new
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
|
@ -0,0 +1,7 @@
|
||||||
|
# We don't really care about this model. It's just being used to test the uniqueness controller
|
||||||
|
# specs. Nevertheless, we need a model because the counter caching functionality expects it.
|
||||||
|
#
|
||||||
|
class Dummy < ActiveRecord::Base
|
||||||
|
self.abstract_class = true # doesn't need to be backed by an actual table
|
||||||
|
is_impressionable
|
||||||
|
end
|
|
@ -6,28 +6,19 @@ development:
|
||||||
pool: 5
|
pool: 5
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
|
|
||||||
# Warning: The database defined as "test" will be erased and
|
test: &test
|
||||||
# re-generated from your development database when you run "rake".
|
|
||||||
# Do not set this db to the same as development or production.
|
|
||||||
#test: &test
|
|
||||||
# adapter: sqlite3
|
|
||||||
# database: db/test.sqlite3
|
|
||||||
# pool: 5
|
|
||||||
# timeout: 5000
|
|
||||||
|
|
||||||
test:
|
|
||||||
adapter: sqlite3
|
adapter: sqlite3
|
||||||
database: db/test.sqlite3
|
database: db/test.sqlite3
|
||||||
pool: 5
|
pool: 5
|
||||||
timeout: 5000
|
timeout: 5000
|
||||||
|
|
||||||
pg_test:
|
#pg_test:
|
||||||
adapter: postgresql
|
# adapter: postgresql
|
||||||
database: impressionist_test
|
# database: impressionist_test
|
||||||
username: johnmcaliley
|
# username: johnmcaliley
|
||||||
password:
|
# password:
|
||||||
host: localhost
|
# host: localhost
|
||||||
encoding: UTF8
|
# encoding: UTF8
|
||||||
|
|
||||||
production:
|
production:
|
||||||
adapter: sqlite3
|
adapter: sqlite3
|
||||||
|
|
|
@ -0,0 +1,15 @@
|
||||||
|
class CreateWidgets < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :widgets do |t|
|
||||||
|
t.string :name
|
||||||
|
t.integer :impressions_count
|
||||||
|
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
drop_table :widgets
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
class CreateImpressionsTable < ActiveRecord::Migration
|
||||||
|
def self.up
|
||||||
|
create_table :impressions, :force => true do |t|
|
||||||
|
t.string :impressionable_type
|
||||||
|
t.integer :impressionable_id
|
||||||
|
t.integer :user_id
|
||||||
|
t.string :controller_name
|
||||||
|
t.string :action_name
|
||||||
|
t.string :view_name
|
||||||
|
t.string :request_hash
|
||||||
|
t.string :session_hash
|
||||||
|
t.string :ip_address
|
||||||
|
t.string :message
|
||||||
|
t.string :referrer
|
||||||
|
t.timestamps
|
||||||
|
end
|
||||||
|
add_index :impressions, [:impressionable_type, :impressionable_id, :request_hash], :name => "poly_request_index", :unique => false
|
||||||
|
add_index :impressions, [:impressionable_type, :impressionable_id, :ip_address], :name => "poly_ip_index", :unique => false
|
||||||
|
add_index :impressions, [:impressionable_type, :impressionable_id, :session_hash], :name => "poly_session_index", :unique => false
|
||||||
|
add_index :impressions, [:controller_name,:action_name,:request_hash], :name => "controlleraction_request_index", :unique => false
|
||||||
|
add_index :impressions, [:controller_name,:action_name,:ip_address], :name => "controlleraction_ip_index", :unique => false
|
||||||
|
add_index :impressions, [:controller_name,:action_name,:session_hash], :name => "controlleraction_session_index", :unique => false
|
||||||
|
add_index :impressions, :user_id
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.down
|
||||||
|
remove_index :impressions, :name => :poly_request_index
|
||||||
|
remove_index :impressions, :name => :poly_ip_index
|
||||||
|
remove_index :impressions, :name => :poly_session_index
|
||||||
|
remove_index :impressions, :name => :controlleraction_request_index
|
||||||
|
remove_index :impressions, :name => :controlleraction_ip_index
|
||||||
|
remove_index :impressions, :name => :controlleraction_session_index
|
||||||
|
remove_index :impressions, :user_id
|
||||||
|
|
||||||
|
drop_table :impressions
|
||||||
|
end
|
||||||
|
end
|
|
@ -95,4 +95,31 @@ describe WidgetsController do
|
||||||
get "show", :id=> 1
|
get "show", :id=> 1
|
||||||
Impression.all.size.should eq 11
|
Impression.all.size.should eq 11
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe "impressionist unique options" do
|
||||||
|
|
||||||
|
it "should log unique impressions at the per action level" do
|
||||||
|
get "show", :id=> 1
|
||||||
|
Impression.all.size.should eq 12
|
||||||
|
get "show", :id=> 2
|
||||||
|
Impression.all.size.should eq 13
|
||||||
|
get "show", :id => 2
|
||||||
|
Impression.all.size.should eq 13
|
||||||
|
get "index"
|
||||||
|
Impression.all.size.should eq 14
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should log unique impressions only once per id" do
|
||||||
|
get "show", :id=> 1
|
||||||
|
Impression.all.size.should eq 12
|
||||||
|
get "show", :id=> 2
|
||||||
|
Impression.all.size.should eq 13
|
||||||
|
get "show", :id => 2
|
||||||
|
Impression.all.size.should eq 13
|
||||||
|
get "index"
|
||||||
|
Impression.all.size.should eq 14
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,312 @@
|
||||||
|
require "spec_helper.rb"
|
||||||
|
|
||||||
|
# we use the posts controller as it uses the impressionsist module. any such controller would do.
|
||||||
|
describe DummyController do
|
||||||
|
|
||||||
|
before do
|
||||||
|
@impression_count = Impression.all.size
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "impressionist filter uniqueness" do
|
||||||
|
|
||||||
|
it "should ignore uniqueness if not requested" do
|
||||||
|
controller.impressionist_subapp_filter(nil, nil)
|
||||||
|
controller.impressionist_subapp_filter(nil, nil)
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique session" do
|
||||||
|
# the following line was necessary as session hash returned a binary string (ASCII-8BIT encoded)
|
||||||
|
controller.stub!(:session_hash).and_return(request.session_options[:id].encode("ISO-8859-1"))
|
||||||
|
controller.impressionist_subapp_filter(nil, [:session_hash])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:session_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique ip" do
|
||||||
|
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique request" do
|
||||||
|
controller.impressionist_subapp_filter(nil, [:request_hash])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:request_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique action" do
|
||||||
|
controller.stub!(:action_name).and_return("test_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique controller" do
|
||||||
|
controller.stub!(:controller_name).and_return("post")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique user" do
|
||||||
|
controller.stub!(:user_id).and_return(42)
|
||||||
|
controller.impressionist_subapp_filter(nil, [:user_id])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:user_id])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique referer" do
|
||||||
|
controller.request.stub!(:referer).and_return("http://foo/bar")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:referrer])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:referrer])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique id" do
|
||||||
|
controller.stub!(:params).and_return({:id => "666"}) # for correct impressionable id in filter
|
||||||
|
controller.impressionist_subapp_filter(nil, [:impressionable_id])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:impressionable_id])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
# extra redundant test for important controller and action combination.
|
||||||
|
it "should recognize different controller and action" do
|
||||||
|
controller.stub!(:controller_name).and_return("post")
|
||||||
|
controller.stub!(:action_name).and_return("test_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.stub!(:action_name).and_return("another_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
controller.stub!(:controller_name).and_return("article")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name, :action_name])
|
||||||
|
Impression.should have(@impression_count + 3).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different action" do
|
||||||
|
controller.stub!(:action_name).and_return("test_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.stub!(:action_name).and_return("another_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different controller" do
|
||||||
|
controller.stub!(:controller_name).and_return("post")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.stub!(:controller_name).and_return("article")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:controller_name])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different session" do
|
||||||
|
controller.stub!(:session_hash).and_return("foo")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:session_hash])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:session_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.stub!(:session_hash).and_return("bar")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:session_hash])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:session_hash])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different ip" do
|
||||||
|
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.request.stub!(:remote_ip).and_return("5.6.7.8")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different referer" do
|
||||||
|
controller.request.stub!(:referer).and_return("http://foo/bar")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:referrer])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:referrer])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.request.stub!(:referer).and_return("http://bar/fo")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:referrer])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:referrer])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different id" do
|
||||||
|
controller.stub!(:params).and_return({:id => "666"}) # for correct impressionable id in filter
|
||||||
|
controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id])
|
||||||
|
controller.stub!(:params).and_return({:id => "42"}) # for correct impressionable id in filter
|
||||||
|
controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:impressionable_type, :impressionable_id])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize combined uniqueness" do
|
||||||
|
controller.stub!(:action_name).and_return("test_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:request_hash, :ip_address, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:request_hash, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:action_name])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address])
|
||||||
|
controller.impressionist_subapp_filter(nil, [:request_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize combined non-uniqueness" do
|
||||||
|
controller.stub!(:action_name).and_return(nil)
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :action_name])
|
||||||
|
controller.stub!(:action_name).and_return("test_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :action_name])
|
||||||
|
controller.stub!(:action_name).and_return("another_action")
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :action_name])
|
||||||
|
Impression.should have(@impression_count + 3).records
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "impressionist method uniqueness for impressionables" do
|
||||||
|
|
||||||
|
# in this test we reuse the post model. might break if model changes.
|
||||||
|
|
||||||
|
it "should ignore uniqueness if not requested" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist impressionable
|
||||||
|
controller.impressionist impressionable
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique session" do
|
||||||
|
# the following line was necessary as session hash returned a binary string (ASCII-8BIT encoded)
|
||||||
|
controller.stub!(:session_hash).and_return(request.session_options[:id].encode("ISO-8859-1"))
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique ip" do
|
||||||
|
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique request" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:request_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:request_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique user" do
|
||||||
|
controller.stub!(:user_id).and_return(666)
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize unique referer" do
|
||||||
|
controller.request.stub!(:referer).and_return("http://foo/bar")
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:referrer])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:referrer])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different session" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.stub!(:session_hash).and_return("foo")
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.stub!(:session_hash).and_return("bar")
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different ip" do
|
||||||
|
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.request.stub!(:remote_ip).and_return("5.6.7.8")
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize different user" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.stub!(:user_id).and_return(666)
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
controller.stub!(:user_id).and_return(42)
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
||||||
|
Impression.should have(@impression_count + 2).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize combined uniqueness" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.stub!(:session_hash).and_return("foo")
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:request_hash, :ip_address, :session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:request_hash, :session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:request_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
it "should recognize combined non-uniqueness" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.stub!(:session_hash).and_return(nil)
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
||||||
|
controller.stub!(:session_hash).and_return("foo")
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
||||||
|
controller.stub!(:session_hash).and_return("bar")
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
||||||
|
Impression.should have(@impression_count + 3).records
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "impressionist filter and method uniqueness" do
|
||||||
|
|
||||||
|
it "should recognize uniqueness" do
|
||||||
|
impressionable = Post.create
|
||||||
|
controller.stub!(:controller_name).and_return("posts") # for correct impressionable type in filter
|
||||||
|
controller.stub!(:params).and_return({:id => impressionable.id.to_s}) # for correct impressionable id in filter
|
||||||
|
controller.stub!(:session_hash).and_return("foo")
|
||||||
|
controller.request.stub!(:remote_ip).and_return("1.2.3.4")
|
||||||
|
# order of the following methods is important for the test!
|
||||||
|
controller.impressionist_subapp_filter(nil, [:ip_address, :request_hash, :session_hash])
|
||||||
|
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
|
||||||
|
Impression.should have(@impression_count + 1).records
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
require 'spec_helper'
|
require 'spec_helper'
|
||||||
require 'systemu'
|
require 'systemu'
|
||||||
|
|
||||||
|
# FIXME this test might break the others if run before them
|
||||||
|
#
|
||||||
describe Impressionist do
|
describe Impressionist do
|
||||||
fixtures :articles,:impressions,:posts
|
fixtures :articles,:impressions,:posts
|
||||||
it "should delete existing migration and generate the migration file" do
|
it "should delete existing migration and generate the migration file" do
|
||||||
|
|
|
@ -24,4 +24,10 @@ RSpec.configure do |config|
|
||||||
# examples within a transaction, remove the following line or assign false
|
# examples within a transaction, remove the following line or assign false
|
||||||
# instead of true.
|
# instead of true.
|
||||||
config.use_transactional_fixtures = true
|
config.use_transactional_fixtures = true
|
||||||
|
|
||||||
|
# make the rails logger usable in the tests as logger.xxx "..."
|
||||||
|
def logger
|
||||||
|
Rails.logger
|
||||||
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue