Merge pull request #12 from coryschires/master
Merged in the counter caching code. Added docs for previous pull request concerning recording unique impressions
This commit is contained in:
commit
85a714ff21
|
@ -1,5 +1,4 @@
|
|||
Gemfile.lock
|
||||
/test_app/db/migrate/20*
|
||||
/test_app/db/schema.rb
|
||||
/pkg
|
||||
*~
|
||||
|
|
56
README.md
56
README.md
|
@ -5,20 +5,14 @@ impressionist
|
|||
|
||||
A lightweight plugin that logs impressions per action or manually per model
|
||||
|
||||
I would not call this a stable plugin yet, although I have been running it in prod with no problems. Use at your own risk ;-)
|
||||
------------------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
NOTE: If you are upgrading from a version prior to 0.4.0, you will need to run this migration after the upgrade:
|
||||
|
||||
https://github.com/charlotte-ruby/impressionist/blob/master/upgrade_migrations/version_0_4_0.rb
|
||||
|
||||
If you don't run this migration you will receive this error: Unknown attribute : referrer
|
||||
|
||||
|
||||
What does this thing do?
|
||||
------------------------
|
||||
Logs an impression... and I use that term loosely. It can log page impressions (technically action impressions), but it is not limited to that.
|
||||
You can log impressions multiple times per request. And you can also attach it to a model. The goal of this project is to provide customizable
|
||||
stats that are immediately accessible in your application as opposed to using G Analytics and pulling data using their API. You can attach custom
|
||||
Logs an impression... and I use that term loosely. It can log page impressions (technically action impressions), but it is not limited to that.
|
||||
You can log impressions multiple times per request. And you can also attach it to a model. The goal of this project is to provide customizable
|
||||
stats that are immediately accessible in your application as opposed to using G Analytics and pulling data using their API. You can attach custom
|
||||
messages to impressions. No reporting yet.. this thingy just creates the data.
|
||||
|
||||
What about bots?
|
||||
|
@ -28,7 +22,7 @@ http://www.user-agents.org/allagents.xml
|
|||
|
||||
Which versions of Rails and Ruby is this compatible with?
|
||||
---------------------------------------------------------
|
||||
Rails 3.0.x and Ruby 1.9.2 (also tested on REE 1.8.7) - Sorry, but you need to upgrade if you are using Rails 2. You know you want to anyways.. all the cool kids are doing it ;-)
|
||||
Rails 3.0.4 and Ruby 1.9.2 (also tested on REE 1.8.7) - Sorry, but you need to upgrade if you are using Rails 2. You know you want to anyways.. all the cool kids are doing it ;-)
|
||||
|
||||
Installation
|
||||
------------
|
||||
|
@ -101,17 +95,49 @@ Usage
|
|||
6. Get the unique impression count from a model filtered by IP address. This in turn will give you impressions with unique request_hash, since rows with the same request_hash will have the same IP address.
|
||||
|
||||
@widget.impressionist_count(:filter=>:ip_address)
|
||||
|
||||
|
||||
7. Get the unique impression count from a model filtered by session hash. Same as #6 regarding request hash. This may be more desirable than filtering by IP address depending on your situation, since filtering by IP may ignore visitors that use the same IP. The downside to this filtering is that a user could clear session data in their browser and skew the results.
|
||||
|
||||
@widget.impressionist_count(:filter=>:session_hash)
|
||||
|
||||
|
||||
8. Get total impression count. This may return more than 1 impression per http request, depending on how you are logging impressions
|
||||
|
||||
@widget.impressionist_count(:filter=>:all)
|
||||
|
||||
Logging impressions for authenticated users happens automatically. If you have a current_user helper or use @current_user in your before_filter to set your authenticated user, current_user.id will be written to the user_id field in the impressions table.
|
||||
|
||||
Adding a counter cache
|
||||
----------------------
|
||||
Impressionist makes it easy to add a `counter_cache` column to your model. The most basic configuration looks like:
|
||||
|
||||
is_impressionable :counter_cache => true
|
||||
|
||||
This will automatically increment the `impressions_count` column in the included model. Note: You'll need to add that column to your model. If you'd like specific a different column name, you can:
|
||||
|
||||
is_impressionable :counter_cache => { :column_name => :my_column }
|
||||
|
||||
If you'd like to include only unique impressions in your count:
|
||||
|
||||
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
|
||||
-------------------
|
||||
|
@ -121,14 +147,14 @@ Development Roadmap
|
|||
* AB testing integration
|
||||
|
||||
Contributing to impressionist
|
||||
-----------------------------
|
||||
-----------------------------
|
||||
* Check out the latest master to make sure the feature hasn't been implemented or the bug hasn't been fixed yet
|
||||
* Check out the issue tracker to make sure someone already hasn't requested it and/or contributed it
|
||||
* Fork the project
|
||||
* Start a feature/bugfix branch
|
||||
* Commit and push until you are happy with your contribution
|
||||
* Make sure to add rpsec tests for it. Patches or features without tests will be ignored. Also, try to write better tests than I do ;-)
|
||||
* If adding engine controller or view functionality, use HAML and Inherited Resources.
|
||||
* If adding engine controller or view functionality, use HAML and Inherited Resources.
|
||||
* All testing is done inside a small Rails app (test_app). You will find specs within this app.
|
||||
|
||||
Copyright (c) 2011 John McAliley. See LICENSE.txt for further details.
|
||||
|
|
|
@ -1,3 +1,16 @@
|
|||
class Impression < ActiveRecord::Base
|
||||
belongs_to :impressionable, :polymorphic=>true
|
||||
|
||||
after_save :update_impressions_counter_cache
|
||||
|
||||
private
|
||||
|
||||
def update_impressions_counter_cache
|
||||
impressionable_class = self.impressionable_type.constantize
|
||||
|
||||
if impressionable_class.counter_cache_options
|
||||
resouce = impressionable_class.find(self.impressionable_id)
|
||||
resouce.try(:update_counter_cache)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,15 +1,38 @@
|
|||
module Impressionist
|
||||
module Impressionable
|
||||
def is_impressionable
|
||||
has_many :impressions, :as=>:impressionable
|
||||
include InstanceMethods
|
||||
|
||||
def self.included(base)
|
||||
base.extend ClassMethods
|
||||
base.send(:include, InstanceMethods)
|
||||
end
|
||||
|
||||
|
||||
module ClassMethods
|
||||
attr_accessor :cache_options
|
||||
@cache_options = nil
|
||||
|
||||
def is_impressionable(options={})
|
||||
has_many :impressions, :as=>:impressionable
|
||||
@cache_options = options[:counter_cache]
|
||||
end
|
||||
|
||||
def counter_cache_options
|
||||
if @cache_options
|
||||
options = { :column_name => :impressions_count, :unique => false }
|
||||
options.merge!(@cache_options) if @cache_options.is_a?(Hash)
|
||||
options
|
||||
end
|
||||
end
|
||||
|
||||
def counter_caching?
|
||||
counter_cache_options.present?
|
||||
end
|
||||
end
|
||||
|
||||
module InstanceMethods
|
||||
def impressionable?
|
||||
true
|
||||
end
|
||||
|
||||
|
||||
def impressionist_count(options={})
|
||||
options.reverse_merge!(:filter=>:request_hash, :start_date=>nil, :end_date=>Time.now)
|
||||
imps = options[:start_date].blank? ? impressions : impressions.where("created_at>=? and created_at<=?",options[:start_date],options[:end_date])
|
||||
|
@ -18,7 +41,14 @@ module Impressionist
|
|||
end
|
||||
imps.all.size
|
||||
end
|
||||
|
||||
|
||||
def update_counter_cache
|
||||
cache_options = self.class.counter_cache_options
|
||||
column_name = cache_options[:column_name].to_sym
|
||||
count = cache_options[:unique] ? impressionist_count(:filter => :ip_address) : impressionist_count
|
||||
update_attribute(column_name, count)
|
||||
end
|
||||
|
||||
# OLD METHODS - DEPRECATE IN V0.5
|
||||
def impression_count(start_date=nil,end_date=Time.now)
|
||||
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=>:all})
|
||||
|
@ -27,14 +57,15 @@ module Impressionist
|
|||
def unique_impression_count(start_date=nil,end_date=Time.now)
|
||||
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :request_hash})
|
||||
end
|
||||
|
||||
|
||||
def unique_impression_count_ip(start_date=nil,end_date=Time.now)
|
||||
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :ip_address})
|
||||
end
|
||||
|
||||
|
||||
def unique_impression_count_session(start_date=nil,end_date=Time.now)
|
||||
impressionist_count({:start_date=>start_date, :end_date=>end_date, :filter=> :session_hash})
|
||||
end
|
||||
end
|
||||
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,11 +2,11 @@ require "impressionist"
|
|||
require "rails"
|
||||
|
||||
module Impressionist
|
||||
class Engine < Rails::Engine
|
||||
class Engine < Rails::Engine
|
||||
initializer 'impressionist.extend_ar' do |app|
|
||||
ActiveRecord::Base.extend Impressionist::Impressionable
|
||||
ActiveRecord::Base.send(:include, Impressionist::Impressionable)
|
||||
end
|
||||
|
||||
|
||||
initializer 'impressionist.controller' do
|
||||
ActiveSupport.on_load(:action_controller) do
|
||||
include ImpressionistController::InstanceMethods
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
PATH
|
||||
remote: /home/mio/prog/projects/impressionist
|
||||
remote: /Users/coryschires/Desktop/impressionist
|
||||
specs:
|
||||
impressionist (0.4.0)
|
||||
|
||||
|
@ -45,7 +45,7 @@ GEM
|
|||
autotest-standalone (4.5.8)
|
||||
bcrypt-ruby (3.0.1)
|
||||
builder (3.0.0)
|
||||
capybara (1.1.1)
|
||||
capybara (1.1.2)
|
||||
mime-types (>= 1.16)
|
||||
nokogiri (>= 1.3.3)
|
||||
rack (>= 1.0.0)
|
||||
|
@ -54,10 +54,10 @@ GEM
|
|||
xpath (~> 0.1.4)
|
||||
childprocess (0.2.2)
|
||||
ffi (~> 1.0.6)
|
||||
cucumber (1.1.1)
|
||||
cucumber (1.1.3)
|
||||
builder (>= 2.1.2)
|
||||
diff-lcs (>= 1.1.2)
|
||||
gherkin (~> 2.6.0)
|
||||
gherkin (~> 2.6.7)
|
||||
json (>= 1.4.6)
|
||||
term-ansicolor (>= 1.0.6)
|
||||
cucumber-rails (1.2.0)
|
||||
|
@ -65,12 +65,12 @@ GEM
|
|||
cucumber (>= 1.1.1)
|
||||
nokogiri (>= 1.5.0)
|
||||
daemons (1.0.10)
|
||||
database_cleaner (0.6.7)
|
||||
database_cleaner (0.7.0)
|
||||
diff-lcs (1.1.3)
|
||||
erubis (2.7.0)
|
||||
ffi (1.0.9)
|
||||
ffi (1.0.11)
|
||||
gem_plugin (0.2.3)
|
||||
gherkin (2.6.2)
|
||||
gherkin (2.6.8)
|
||||
json (>= 1.4.6)
|
||||
hike (1.2.1)
|
||||
i18n (0.6.0)
|
||||
|
@ -129,10 +129,10 @@ GEM
|
|||
activesupport (~> 3.0)
|
||||
railties (~> 3.0)
|
||||
rspec (~> 2.7.0)
|
||||
rubyzip (0.9.4)
|
||||
selenium-webdriver (2.10.0)
|
||||
rubyzip (0.9.5)
|
||||
selenium-webdriver (2.13.0)
|
||||
childprocess (>= 0.2.1)
|
||||
ffi (= 1.0.9)
|
||||
ffi (~> 1.0.9)
|
||||
json_pure
|
||||
rubyzip
|
||||
spork (0.8.5)
|
||||
|
|
|
@ -2,5 +2,5 @@
|
|||
class DummyController < ActionController::Base
|
||||
|
||||
impressionist
|
||||
|
||||
|
||||
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
|
|
@ -0,0 +1,3 @@
|
|||
class Widget < ActiveRecord::Base
|
||||
is_impressionable :counter_cache => true
|
||||
end
|
|
@ -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
|
|
@ -1,14 +1,14 @@
|
|||
require 'spec_helper.rb'
|
||||
|
||||
describe ArticlesController do
|
||||
fixtures :articles,:impressions,:posts
|
||||
fixtures :articles,:impressions,:posts,:widgets
|
||||
render_views
|
||||
|
||||
|
||||
it "should make the impressionable_hash available" do
|
||||
get "index"
|
||||
response.body.include?("false").should eq true
|
||||
end
|
||||
|
||||
|
||||
it "should log an impression with a message" do
|
||||
get "index"
|
||||
Impression.all.size.should eq 12
|
||||
|
@ -16,7 +16,7 @@ describe ArticlesController do
|
|||
Article.first.impressions.last.controller_name.should eq "articles"
|
||||
Article.first.impressions.last.action_name.should eq "index"
|
||||
end
|
||||
|
||||
|
||||
it "should log an impression without a message" do
|
||||
get "show", :id=> 1
|
||||
Impression.all.size.should eq 12
|
||||
|
@ -24,18 +24,18 @@ describe ArticlesController do
|
|||
Article.first.impressions.last.controller_name.should eq "articles"
|
||||
Article.first.impressions.last.action_name.should eq "show"
|
||||
end
|
||||
|
||||
|
||||
it "should log the user_id if user is authenticated (@current_user before_filter method)" do
|
||||
session[:user_id] = 123
|
||||
get "show", :id=> 1
|
||||
Article.first.impressions.last.user_id.should eq 123
|
||||
end
|
||||
|
||||
|
||||
it "should not log the user_id if user is authenticated" do
|
||||
get "show", :id=> 1
|
||||
Article.first.impressions.last.user_id.should eq nil
|
||||
end
|
||||
|
||||
|
||||
it "should log the request_hash, ip_address, referrer and session_hash" do
|
||||
get "show", :id=> 1
|
||||
Impression.last.request_hash.size.should eq 64
|
||||
|
@ -43,13 +43,13 @@ describe ArticlesController do
|
|||
Impression.last.session_hash.size.should eq 32
|
||||
Impression.last.referrer.should eq nil
|
||||
end
|
||||
|
||||
|
||||
it "should log the referrer when you click a link" do
|
||||
visit article_url(Article.first)
|
||||
click_link "Same Page"
|
||||
Impression.last.referrer.should eq "http://test.host/articles/1"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe PostsController do
|
||||
it "should log impression at the action level" do
|
||||
|
@ -60,7 +60,7 @@ describe PostsController do
|
|||
Impression.last.impressionable_type.should eq "Post"
|
||||
Impression.last.impressionable_id.should eq 1
|
||||
end
|
||||
|
||||
|
||||
it "should log the user_id if user is authenticated (current_user helper method)" do
|
||||
session[:user_id] = 123
|
||||
get "show", :id=> 1
|
||||
|
@ -69,6 +69,12 @@ describe PostsController do
|
|||
end
|
||||
|
||||
describe WidgetsController do
|
||||
|
||||
before(:each) do
|
||||
@widget = Widget.find(1)
|
||||
Widget.stub(:find).and_return(@widget)
|
||||
end
|
||||
|
||||
it "should log impression at the per action level" do
|
||||
get "show", :id=> 1
|
||||
Impression.all.size.should eq 12
|
||||
|
@ -77,17 +83,17 @@ describe WidgetsController do
|
|||
get "new"
|
||||
Impression.all.size.should eq 13
|
||||
end
|
||||
|
||||
|
||||
it "should not log impression when user-agent is in wildcard list" do
|
||||
request.stub!(:user_agent).and_return('somebot')
|
||||
get "show", :id=> 1
|
||||
Impression.all.size.should eq 11
|
||||
end
|
||||
|
||||
|
||||
it "should not log impression when user-agent is in the bot list" do
|
||||
request.stub!(:user_agent).and_return('Acoon Robot v1.50.001')
|
||||
get "show", :id=> 1
|
||||
Impression.all.size.should eq 11
|
||||
Impression.all.size.should eq 11
|
||||
end
|
||||
|
||||
describe "impressionist unique options" do
|
||||
|
@ -117,4 +123,3 @@ describe WidgetsController do
|
|||
end
|
||||
|
||||
end
|
||||
|
|
@ -2,19 +2,19 @@ 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
|
||||
|
||||
@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"))
|
||||
|
@ -22,58 +22,58 @@ describe DummyController do
|
|||
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("test_controller")
|
||||
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
|
||||
|
||||
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("test_controller")
|
||||
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])
|
||||
|
@ -82,12 +82,12 @@ describe DummyController do
|
|||
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("another_controller")
|
||||
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])
|
||||
|
@ -98,18 +98,18 @@ describe DummyController do
|
|||
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("test_controller")
|
||||
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("another_controller")
|
||||
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])
|
||||
|
@ -120,7 +120,7 @@ describe DummyController do
|
|||
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])
|
||||
|
@ -131,7 +131,7 @@ describe DummyController do
|
|||
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])
|
||||
|
@ -142,7 +142,7 @@ describe DummyController do
|
|||
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])
|
||||
|
@ -152,7 +152,7 @@ describe DummyController do
|
|||
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])
|
||||
|
@ -165,7 +165,7 @@ describe DummyController do
|
|||
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])
|
||||
|
@ -174,21 +174,21 @@ describe DummyController do
|
|||
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
|
||||
|
||||
end
|
||||
|
||||
describe "impressionist method uniqueness for impressionables" do
|
||||
|
||||
|
||||
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"))
|
||||
|
@ -197,7 +197,7 @@ describe DummyController do
|
|||
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
|
||||
|
@ -205,22 +205,22 @@ describe DummyController do
|
|||
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
|
||||
|
||||
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
|
||||
|
@ -228,7 +228,7 @@ describe DummyController do
|
|||
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")
|
||||
|
@ -240,7 +240,7 @@ describe DummyController do
|
|||
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
|
||||
|
@ -252,7 +252,7 @@ describe DummyController do
|
|||
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)
|
||||
|
@ -264,7 +264,7 @@ describe DummyController do
|
|||
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")
|
||||
|
@ -278,7 +278,7 @@ describe DummyController do
|
|||
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)
|
||||
|
@ -289,11 +289,11 @@ describe DummyController do
|
|||
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
|
||||
|
@ -305,8 +305,8 @@ describe DummyController do
|
|||
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
|
||||
Impression.should have(@impression_count + 1).records
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
||||
end
|
||||
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
one:
|
||||
id: 1
|
||||
name: A Widget
|
||||
impressions_count: 0
|
|
@ -0,0 +1,30 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Impression do
|
||||
fixtures :widgets
|
||||
|
||||
before(:each) do
|
||||
@widget = Widget.find(1)
|
||||
Impression.destroy_all
|
||||
end
|
||||
|
||||
describe "self#counter_caching?" do
|
||||
it "should know when counter caching is enabled" do
|
||||
Widget.should be_counter_caching
|
||||
end
|
||||
|
||||
it "should know when counter caching is disabled" do
|
||||
Article.should_not be_counter_caching
|
||||
end
|
||||
end
|
||||
|
||||
describe "#update_counter_cache" do
|
||||
it "should update the counter cache column to reflect the correct number of impressions" do
|
||||
lambda {
|
||||
Impression.create(:impressionable_type => @widget.class.name, :impressionable_id => @widget.id)
|
||||
@widget.reload
|
||||
}.should change(@widget, :impressions_count).from(0).to(1)
|
||||
end
|
||||
end
|
||||
|
||||
end
|
|
@ -49,6 +49,8 @@ describe Impression do
|
|||
@article.impressionist_count(:filter=>:session_hash).should eq 7
|
||||
end
|
||||
|
||||
|
||||
|
||||
#OLD COUNT METHODS. DEPRECATE SOON
|
||||
it "should return the impression count with no date range specified" do
|
||||
@article.impression_count.should eq 11
|
||||
|
|
Loading…
Reference in New Issue