impressionist2 1.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +13 -0
- data/.rspec +1 -0
- data/.travis.yml +26 -0
- data/CHANGELOG.rdoc +82 -0
- data/Gemfile +26 -0
- data/LICENSE.txt +20 -0
- data/README.md +250 -0
- data/Rakefile +34 -0
- data/app/controllers/impressionist_controller.rb +146 -0
- data/app/models/impression.rb +2 -0
- data/app/models/impressionist/bots.rb +1468 -0
- data/app/models/impressionist/impressionable.rb +62 -0
- data/gemfiles/rails32.gemfile +30 -0
- data/gemfiles/rails40.gemfile +30 -0
- data/gemfiles/rails50.gemfile +30 -0
- data/impressionist2.gemspec +23 -0
- data/lib/generators/active_record/impressionist_generator.rb +22 -0
- data/lib/generators/active_record/templates/create_impressions_table.rb +32 -0
- data/lib/generators/impressionist_generator.rb +13 -0
- data/lib/generators/mongo_mapper/impressionist_generator.rb +8 -0
- data/lib/generators/mongoid/impressionist_generator.rb +8 -0
- data/lib/generators/templates/impression.rb +8 -0
- data/lib/impressionist/bots.rb +21 -0
- data/lib/impressionist/controllers/mongoid/impressionist_controller.rb +10 -0
- data/lib/impressionist/counter_cache.rb +73 -0
- data/lib/impressionist/engine.rb +30 -0
- data/lib/impressionist/is_impressionable.rb +23 -0
- data/lib/impressionist/load.rb +11 -0
- data/lib/impressionist/models/active_record/impression.rb +14 -0
- data/lib/impressionist/models/active_record/impressionist/impressionable.rb +12 -0
- data/lib/impressionist/models/mongo_mapper/impression.rb +18 -0
- data/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb +21 -0
- data/lib/impressionist/models/mongoid/impression.rb +25 -0
- data/lib/impressionist/models/mongoid/impressionist/impressionable.rb +28 -0
- data/lib/impressionist/rails_toggle.rb +26 -0
- data/lib/impressionist/setup_association.rb +49 -0
- data/lib/impressionist/update_counters.rb +69 -0
- data/lib/impressionist/version.rb +3 -0
- data/lib/impressionist.rb +12 -0
- data/logo.png +0 -0
- data/tests/README +11 -0
- data/tests/spec/minitest_helper.rb +4 -0
- data/tests/spec/rails_toggle_spec.rb +38 -0
- data/tests/spec/setup_association_spec.rb +56 -0
- data/tests/test_app/.gitignore +18 -0
- data/tests/test_app/.rspec +1 -0
- data/tests/test_app/Gemfile +51 -0
- data/tests/test_app/README +256 -0
- data/tests/test_app/README.rdoc +261 -0
- data/tests/test_app/Rakefile +7 -0
- data/tests/test_app/app/assets/images/rails.png +0 -0
- data/tests/test_app/app/assets/javascripts/application.js +13 -0
- data/tests/test_app/app/assets/stylesheets/application.css +13 -0
- data/tests/test_app/app/controllers/application_controller.rb +8 -0
- data/tests/test_app/app/controllers/articles_controller.rb +18 -0
- data/tests/test_app/app/controllers/dummy_controller.rb +8 -0
- data/tests/test_app/app/controllers/posts_controller.rb +23 -0
- data/tests/test_app/app/controllers/profiles_controller.rb +14 -0
- data/tests/test_app/app/controllers/widgets_controller.rb +12 -0
- data/tests/test_app/app/helpers/application_helper.rb +2 -0
- data/tests/test_app/app/mailers/.gitkeep +0 -0
- data/tests/test_app/app/models/.gitkeep +0 -0
- data/tests/test_app/app/models/article.rb +3 -0
- data/tests/test_app/app/models/dummy.rb +7 -0
- data/tests/test_app/app/models/post.rb +3 -0
- data/tests/test_app/app/models/profile.rb +6 -0
- data/tests/test_app/app/models/user.rb +3 -0
- data/tests/test_app/app/models/widget.rb +3 -0
- data/tests/test_app/app/views/articles/index.html.erb +1 -0
- data/tests/test_app/app/views/articles/show.html.erb +1 -0
- data/tests/test_app/app/views/dummy/index.html.erb +0 -0
- data/tests/test_app/app/views/layouts/application.html.erb +14 -0
- data/tests/test_app/app/views/posts/edit.html.erb +0 -0
- data/tests/test_app/app/views/posts/index.html.erb +0 -0
- data/tests/test_app/app/views/posts/show.html.erb +0 -0
- data/tests/test_app/app/views/profiles/show.html.erb +3 -0
- data/tests/test_app/app/views/widgets/index.html.erb +0 -0
- data/tests/test_app/app/views/widgets/new.html.erb +0 -0
- data/tests/test_app/app/views/widgets/show.html.erb +0 -0
- data/tests/test_app/config/application.rb +59 -0
- data/tests/test_app/config/boot.rb +6 -0
- data/tests/test_app/config/cucumber.yml +8 -0
- data/tests/test_app/config/database.yml +30 -0
- data/tests/test_app/config/environment.rb +5 -0
- data/tests/test_app/config/environments/development.rb +37 -0
- data/tests/test_app/config/environments/pg_test.rb +35 -0
- data/tests/test_app/config/environments/production.rb +67 -0
- data/tests/test_app/config/environments/test.rb +37 -0
- data/tests/test_app/config/initializers/backtrace_silencers.rb +7 -0
- data/tests/test_app/config/initializers/impression.rb +8 -0
- data/tests/test_app/config/initializers/inflections.rb +15 -0
- data/tests/test_app/config/initializers/mime_types.rb +5 -0
- data/tests/test_app/config/initializers/secret_token.rb +7 -0
- data/tests/test_app/config/initializers/session_store.rb +8 -0
- data/tests/test_app/config/initializers/wrap_parameters.rb +14 -0
- data/tests/test_app/config/locales/en.yml +5 -0
- data/tests/test_app/config/routes.rb +4 -0
- data/tests/test_app/config.ru +4 -0
- data/tests/test_app/db/migrate/20110201153144_create_articles.rb +13 -0
- data/tests/test_app/db/migrate/20110210205028_create_posts.rb +13 -0
- data/tests/test_app/db/migrate/20111127184039_create_widgets.rb +15 -0
- data/tests/test_app/db/migrate/20130719024021_create_impressions_table.rb +32 -0
- data/tests/test_app/db/migrate/20150207135825_create_profiles.rb +10 -0
- data/tests/test_app/db/migrate/20150207140310_create_friendly_id_slugs.rb +18 -0
- data/tests/test_app/db/schema.rb +80 -0
- data/tests/test_app/db/seeds.rb +7 -0
- data/tests/test_app/lib/assets/.gitkeep +0 -0
- data/tests/test_app/lib/tasks/.gitkeep +0 -0
- data/tests/test_app/lib/tasks/cucumber.rake +53 -0
- data/tests/test_app/log/.gitkeep +0 -0
- data/tests/test_app/public/404.html +26 -0
- data/tests/test_app/public/422.html +26 -0
- data/tests/test_app/public/500.html +25 -0
- data/tests/test_app/public/favicon.ico +0 -0
- data/tests/test_app/public/images/rails.png +0 -0
- data/tests/test_app/public/index.html +241 -0
- data/tests/test_app/public/javascripts/application.js +2 -0
- data/tests/test_app/public/javascripts/controls.js +965 -0
- data/tests/test_app/public/javascripts/dragdrop.js +974 -0
- data/tests/test_app/public/javascripts/effects.js +1123 -0
- data/tests/test_app/public/javascripts/prototype.js +6001 -0
- data/tests/test_app/public/javascripts/rails.js +175 -0
- data/tests/test_app/public/robots.txt +5 -0
- data/tests/test_app/public/stylesheets/.gitkeep +0 -0
- data/tests/test_app/script/cucumber +10 -0
- data/tests/test_app/script/rails +6 -0
- data/tests/test_app/spec/controllers/articles_controller_spec.rb +76 -0
- data/tests/test_app/spec/controllers/dummy_controller_spec.rb +11 -0
- data/tests/test_app/spec/controllers/impressionist_uniqueness_spec.rb +396 -0
- data/tests/test_app/spec/controllers/posts_controller_spec.rb +28 -0
- data/tests/test_app/spec/controllers/widgets_controller_spec.rb +91 -0
- data/tests/test_app/spec/fixtures/articles.yml +3 -0
- data/tests/test_app/spec/fixtures/impressions.yml +43 -0
- data/tests/test_app/spec/fixtures/posts.yml +3 -0
- data/tests/test_app/spec/fixtures/profiles.yml +4 -0
- data/tests/test_app/spec/fixtures/widgets.yml +4 -0
- data/tests/test_app/spec/initializers/initializers_spec.rb +20 -0
- data/tests/test_app/spec/models/bots_spec.rb +27 -0
- data/tests/test_app/spec/models/counter_caching_spec.rb +51 -0
- data/tests/test_app/spec/models/model_spec.rb +70 -0
- data/tests/test_app/spec/rails_generators/rails_generators_spec.rb +23 -0
- data/tests/test_app/spec/spec_helper.rb +43 -0
- data/upgrade_migrations/version_0_3_0.rb +27 -0
- data/upgrade_migrations/version_0_4_0.rb +9 -0
- metadata +314 -0
@@ -0,0 +1,175 @@
|
|
1
|
+
(function() {
|
2
|
+
// Technique from Juriy Zaytsev
|
3
|
+
// http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/
|
4
|
+
function isEventSupported(eventName) {
|
5
|
+
var el = document.createElement('div');
|
6
|
+
eventName = 'on' + eventName;
|
7
|
+
var isSupported = (eventName in el);
|
8
|
+
if (!isSupported) {
|
9
|
+
el.setAttribute(eventName, 'return;');
|
10
|
+
isSupported = typeof el[eventName] == 'function';
|
11
|
+
}
|
12
|
+
el = null;
|
13
|
+
return isSupported;
|
14
|
+
}
|
15
|
+
|
16
|
+
function isForm(element) {
|
17
|
+
return Object.isElement(element) && element.nodeName.toUpperCase() == 'FORM'
|
18
|
+
}
|
19
|
+
|
20
|
+
function isInput(element) {
|
21
|
+
if (Object.isElement(element)) {
|
22
|
+
var name = element.nodeName.toUpperCase()
|
23
|
+
return name == 'INPUT' || name == 'SELECT' || name == 'TEXTAREA'
|
24
|
+
}
|
25
|
+
else return false
|
26
|
+
}
|
27
|
+
|
28
|
+
var submitBubbles = isEventSupported('submit'),
|
29
|
+
changeBubbles = isEventSupported('change')
|
30
|
+
|
31
|
+
if (!submitBubbles || !changeBubbles) {
|
32
|
+
// augment the Event.Handler class to observe custom events when needed
|
33
|
+
Event.Handler.prototype.initialize = Event.Handler.prototype.initialize.wrap(
|
34
|
+
function(init, element, eventName, selector, callback) {
|
35
|
+
init(element, eventName, selector, callback)
|
36
|
+
// is the handler being attached to an element that doesn't support this event?
|
37
|
+
if ( (!submitBubbles && this.eventName == 'submit' && !isForm(this.element)) ||
|
38
|
+
(!changeBubbles && this.eventName == 'change' && !isInput(this.element)) ) {
|
39
|
+
// "submit" => "emulated:submit"
|
40
|
+
this.eventName = 'emulated:' + this.eventName
|
41
|
+
}
|
42
|
+
}
|
43
|
+
)
|
44
|
+
}
|
45
|
+
|
46
|
+
if (!submitBubbles) {
|
47
|
+
// discover forms on the page by observing focus events which always bubble
|
48
|
+
document.on('focusin', 'form', function(focusEvent, form) {
|
49
|
+
// special handler for the real "submit" event (one-time operation)
|
50
|
+
if (!form.retrieve('emulated:submit')) {
|
51
|
+
form.on('submit', function(submitEvent) {
|
52
|
+
var emulated = form.fire('emulated:submit', submitEvent, true)
|
53
|
+
// if custom event received preventDefault, cancel the real one too
|
54
|
+
if (emulated.returnValue === false) submitEvent.preventDefault()
|
55
|
+
})
|
56
|
+
form.store('emulated:submit', true)
|
57
|
+
}
|
58
|
+
})
|
59
|
+
}
|
60
|
+
|
61
|
+
if (!changeBubbles) {
|
62
|
+
// discover form inputs on the page
|
63
|
+
document.on('focusin', 'input, select, texarea', function(focusEvent, input) {
|
64
|
+
// special handler for real "change" events
|
65
|
+
if (!input.retrieve('emulated:change')) {
|
66
|
+
input.on('change', function(changeEvent) {
|
67
|
+
input.fire('emulated:change', changeEvent, true)
|
68
|
+
})
|
69
|
+
input.store('emulated:change', true)
|
70
|
+
}
|
71
|
+
})
|
72
|
+
}
|
73
|
+
|
74
|
+
function handleRemote(element) {
|
75
|
+
var method, url, params;
|
76
|
+
|
77
|
+
var event = element.fire("ajax:before");
|
78
|
+
if (event.stopped) return false;
|
79
|
+
|
80
|
+
if (element.tagName.toLowerCase() === 'form') {
|
81
|
+
method = element.readAttribute('method') || 'post';
|
82
|
+
url = element.readAttribute('action');
|
83
|
+
params = element.serialize();
|
84
|
+
} else {
|
85
|
+
method = element.readAttribute('data-method') || 'get';
|
86
|
+
url = element.readAttribute('href');
|
87
|
+
params = {};
|
88
|
+
}
|
89
|
+
|
90
|
+
new Ajax.Request(url, {
|
91
|
+
method: method,
|
92
|
+
parameters: params,
|
93
|
+
evalScripts: true,
|
94
|
+
|
95
|
+
onComplete: function(request) { element.fire("ajax:complete", request); },
|
96
|
+
onSuccess: function(request) { element.fire("ajax:success", request); },
|
97
|
+
onFailure: function(request) { element.fire("ajax:failure", request); }
|
98
|
+
});
|
99
|
+
|
100
|
+
element.fire("ajax:after");
|
101
|
+
}
|
102
|
+
|
103
|
+
function handleMethod(element) {
|
104
|
+
var method = element.readAttribute('data-method'),
|
105
|
+
url = element.readAttribute('href'),
|
106
|
+
csrf_param = $$('meta[name=csrf-param]')[0],
|
107
|
+
csrf_token = $$('meta[name=csrf-token]')[0];
|
108
|
+
|
109
|
+
var form = new Element('form', { method: "POST", action: url, style: "display: none;" });
|
110
|
+
element.parentNode.insert(form);
|
111
|
+
|
112
|
+
if (method !== 'post') {
|
113
|
+
var field = new Element('input', { type: 'hidden', name: '_method', value: method });
|
114
|
+
form.insert(field);
|
115
|
+
}
|
116
|
+
|
117
|
+
if (csrf_param) {
|
118
|
+
var param = csrf_param.readAttribute('content'),
|
119
|
+
token = csrf_token.readAttribute('content'),
|
120
|
+
field = new Element('input', { type: 'hidden', name: param, value: token });
|
121
|
+
form.insert(field);
|
122
|
+
}
|
123
|
+
|
124
|
+
form.submit();
|
125
|
+
}
|
126
|
+
|
127
|
+
|
128
|
+
document.on("click", "*[data-confirm]", function(event, element) {
|
129
|
+
var message = element.readAttribute('data-confirm');
|
130
|
+
if (!confirm(message)) event.stop();
|
131
|
+
});
|
132
|
+
|
133
|
+
document.on("click", "a[data-remote]", function(event, element) {
|
134
|
+
if (event.stopped) return;
|
135
|
+
handleRemote(element);
|
136
|
+
event.stop();
|
137
|
+
});
|
138
|
+
|
139
|
+
document.on("click", "a[data-method]", function(event, element) {
|
140
|
+
if (event.stopped) return;
|
141
|
+
handleMethod(element);
|
142
|
+
event.stop();
|
143
|
+
});
|
144
|
+
|
145
|
+
document.on("submit", function(event) {
|
146
|
+
var element = event.findElement(),
|
147
|
+
message = element.readAttribute('data-confirm');
|
148
|
+
if (message && !confirm(message)) {
|
149
|
+
event.stop();
|
150
|
+
return false;
|
151
|
+
}
|
152
|
+
|
153
|
+
var inputs = element.select("input[type=submit][data-disable-with]");
|
154
|
+
inputs.each(function(input) {
|
155
|
+
input.disabled = true;
|
156
|
+
input.writeAttribute('data-original-value', input.value);
|
157
|
+
input.value = input.readAttribute('data-disable-with');
|
158
|
+
});
|
159
|
+
|
160
|
+
var element = event.findElement("form[data-remote]");
|
161
|
+
if (element) {
|
162
|
+
handleRemote(element);
|
163
|
+
event.stop();
|
164
|
+
}
|
165
|
+
});
|
166
|
+
|
167
|
+
document.on("ajax:after", "form", function(event, element) {
|
168
|
+
var inputs = element.select("input[type=submit][disabled=true][data-disable-with]");
|
169
|
+
inputs.each(function(input) {
|
170
|
+
input.value = input.readAttribute('data-original-value');
|
171
|
+
input.removeAttribute('data-original-value');
|
172
|
+
input.disabled = false;
|
173
|
+
});
|
174
|
+
});
|
175
|
+
})();
|
File without changes
|
@@ -0,0 +1,10 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
vendored_cucumber_bin = Dir["#{File.dirname(__FILE__)}/../vendor/{gems,plugins}/cucumber*/bin/cucumber"].first
|
4
|
+
if vendored_cucumber_bin
|
5
|
+
load File.expand_path(vendored_cucumber_bin)
|
6
|
+
else
|
7
|
+
require 'rubygems' unless ENV['NO_RUBYGEMS']
|
8
|
+
require 'cucumber'
|
9
|
+
load Cucumber::BINARY
|
10
|
+
end
|
@@ -0,0 +1,6 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
|
3
|
+
|
4
|
+
APP_PATH = File.expand_path('../../config/application', __FILE__)
|
5
|
+
require File.expand_path('../../config/boot', __FILE__)
|
6
|
+
require 'rails/commands'
|
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe ArticlesController do
|
4
|
+
fixtures :articles,:impressions,:posts,:widgets
|
5
|
+
|
6
|
+
render_views
|
7
|
+
|
8
|
+
it "should make the impressionable_hash available" do
|
9
|
+
get "index"
|
10
|
+
response.body.include?("false").should eq true
|
11
|
+
end
|
12
|
+
|
13
|
+
it "should log an impression with a message" do
|
14
|
+
get "index"
|
15
|
+
Impression.all.size.should eq 12
|
16
|
+
Article.first.impressions.last.message.should eq "this is a test article impression"
|
17
|
+
Article.first.impressions.last.controller_name.should eq "articles"
|
18
|
+
Article.first.impressions.last.action_name.should eq "index"
|
19
|
+
end
|
20
|
+
|
21
|
+
it "should log an impression without a message" do
|
22
|
+
get "show", :id=> 1
|
23
|
+
Impression.all.size.should eq 12
|
24
|
+
Article.first.impressions.last.message.should eq nil
|
25
|
+
Article.first.impressions.last.controller_name.should eq "articles"
|
26
|
+
Article.first.impressions.last.action_name.should eq "show"
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should log the user_id if user is authenticated (@current_user before_filter method)" do
|
30
|
+
session[:user_id] = 123
|
31
|
+
get "show", :id=> 1
|
32
|
+
Article.first.impressions.last.user_id.should eq 123
|
33
|
+
end
|
34
|
+
|
35
|
+
it "should not log the user_id if user is authenticated" do
|
36
|
+
get "show", :id=> 1
|
37
|
+
Article.first.impressions.last.user_id.should eq nil
|
38
|
+
end
|
39
|
+
|
40
|
+
it "should log the request_hash, ip_address, referrer and session_hash" do
|
41
|
+
get "show", :id=> 1
|
42
|
+
Impression.last.request_hash.size.should eq 64
|
43
|
+
Impression.last.ip_address.should eq "0.0.0.0"
|
44
|
+
Impression.last.session_hash.size.should eq 32
|
45
|
+
Impression.last.referrer.should eq nil
|
46
|
+
end
|
47
|
+
|
48
|
+
# Capybara has change the way it works
|
49
|
+
# We need to pass :type options in order to make include helper methods
|
50
|
+
# see https://github.com/jnicklas/capybara#using-capybara-with-rspec
|
51
|
+
it "should log the referrer when you click a link", :type => :feature do
|
52
|
+
visit article_url(Article.first)
|
53
|
+
click_link "Same Page"
|
54
|
+
Impression.last.referrer.should eq "http://test.host/articles/1"
|
55
|
+
end
|
56
|
+
|
57
|
+
it "should log request with params (checked = true)" do
|
58
|
+
get "show", id: 1, checked: true
|
59
|
+
Impression.last.params.should eq({"checked"=>true})
|
60
|
+
Impression.last.request_hash.size.should eq 64
|
61
|
+
Impression.last.ip_address.should eq "0.0.0.0"
|
62
|
+
Impression.last.session_hash.size.should eq 32
|
63
|
+
Impression.last.referrer.should eq nil
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should log request with params {}" do
|
67
|
+
get "index"
|
68
|
+
Impression.last.params.should eq({})
|
69
|
+
Impression.last.request_hash.size.should eq 64
|
70
|
+
Impression.last.ip_address.should eq "0.0.0.0"
|
71
|
+
Impression.last.session_hash.size.should eq 32
|
72
|
+
Impression.last.referrer.should eq nil
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
|
@@ -0,0 +1,396 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
# we use the posts controller as it uses the impressionsist module. any such controller would do.
|
4
|
+
describe DummyController do
|
5
|
+
|
6
|
+
before do
|
7
|
+
@impression_count = Impression.all.size
|
8
|
+
end
|
9
|
+
|
10
|
+
describe "impressionist filter uniqueness" do
|
11
|
+
|
12
|
+
it "should ignore uniqueness if not requested" do
|
13
|
+
controller.impressionist_subapp_filter
|
14
|
+
controller.impressionist_subapp_filter
|
15
|
+
Impression.should have(@impression_count + 2).records
|
16
|
+
end
|
17
|
+
|
18
|
+
it "should recognize unique session" do
|
19
|
+
controller.stub(:session_hash).and_return(request.session_options[:id])
|
20
|
+
controller.impressionist_subapp_filter(unique: [:session_hash])
|
21
|
+
controller.impressionist_subapp_filter(unique: [:session_hash])
|
22
|
+
Impression.should have(@impression_count + 1).records
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should recognize unique ip" do
|
26
|
+
controller.request.stub(:remote_ip).and_return("1.2.3.4")
|
27
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
28
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
29
|
+
Impression.should have(@impression_count + 1).records
|
30
|
+
end
|
31
|
+
|
32
|
+
it "should recognize unique request" do
|
33
|
+
controller.impressionist_subapp_filter(unique: [:request_hash])
|
34
|
+
controller.impressionist_subapp_filter(unique: [:request_hash])
|
35
|
+
Impression.should have(@impression_count + 1).records
|
36
|
+
end
|
37
|
+
|
38
|
+
it "should recognize unique action" do
|
39
|
+
controller.stub(:action_name).and_return("test_action")
|
40
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
41
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
42
|
+
Impression.should have(@impression_count + 1).records
|
43
|
+
end
|
44
|
+
|
45
|
+
it "should recognize unique controller" do
|
46
|
+
controller.stub(:controller_name).and_return("post")
|
47
|
+
controller.impressionist_subapp_filter(unique: [:controller_name])
|
48
|
+
controller.impressionist_subapp_filter(unique: [:controller_name])
|
49
|
+
Impression.should have(@impression_count + 1).records
|
50
|
+
end
|
51
|
+
|
52
|
+
it "should recognize unique user" do
|
53
|
+
controller.stub(:user_id).and_return(42)
|
54
|
+
controller.impressionist_subapp_filter(unique: [:user_id])
|
55
|
+
controller.impressionist_subapp_filter(unique: [:user_id])
|
56
|
+
Impression.should have(@impression_count + 1).records
|
57
|
+
end
|
58
|
+
|
59
|
+
it "should recognize unique referer" do
|
60
|
+
controller.request.stub(:referer).and_return("http://foo/bar")
|
61
|
+
controller.impressionist_subapp_filter(unique: [:referrer])
|
62
|
+
controller.impressionist_subapp_filter(unique: [:referrer])
|
63
|
+
Impression.should have(@impression_count + 1).records
|
64
|
+
end
|
65
|
+
|
66
|
+
it "should recognize unique id" do
|
67
|
+
controller.stub(:params).and_return({:id => "666"}) # for correct impressionable id in filter
|
68
|
+
controller.impressionist_subapp_filter(unique: [:impressionable_id])
|
69
|
+
controller.impressionist_subapp_filter(unique: [:impressionable_id])
|
70
|
+
Impression.should have(@impression_count + 1).records
|
71
|
+
end
|
72
|
+
|
73
|
+
# extra redundant test for important controller and action combination.
|
74
|
+
it "should recognize different controller and action" do
|
75
|
+
controller.stub(:controller_name).and_return("post")
|
76
|
+
controller.stub(:action_name).and_return("test_action")
|
77
|
+
controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
|
78
|
+
controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
|
79
|
+
Impression.should have(@impression_count + 1).records
|
80
|
+
controller.stub(:action_name).and_return("another_action")
|
81
|
+
controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
|
82
|
+
controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
|
83
|
+
Impression.should have(@impression_count + 2).records
|
84
|
+
controller.stub(:controller_name).and_return("article")
|
85
|
+
controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
|
86
|
+
controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
|
87
|
+
Impression.should have(@impression_count + 3).records
|
88
|
+
end
|
89
|
+
|
90
|
+
it "should recognize different action" do
|
91
|
+
controller.stub(:action_name).and_return("test_action")
|
92
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
93
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
94
|
+
Impression.should have(@impression_count + 1).records
|
95
|
+
controller.stub(:action_name).and_return("another_action")
|
96
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
97
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
98
|
+
Impression.should have(@impression_count + 2).records
|
99
|
+
end
|
100
|
+
|
101
|
+
it "should recognize different controller" do
|
102
|
+
controller.stub(:controller_name).and_return("post")
|
103
|
+
controller.impressionist_subapp_filter(unique: [:controller_name])
|
104
|
+
controller.impressionist_subapp_filter(unique: [:controller_name])
|
105
|
+
Impression.should have(@impression_count + 1).records
|
106
|
+
controller.stub(:controller_name).and_return("article")
|
107
|
+
controller.impressionist_subapp_filter(unique: [:controller_name])
|
108
|
+
controller.impressionist_subapp_filter(unique: [:controller_name])
|
109
|
+
Impression.should have(@impression_count + 2).records
|
110
|
+
end
|
111
|
+
|
112
|
+
it "should recognize different session" do
|
113
|
+
controller.stub(:session_hash).and_return("foo")
|
114
|
+
controller.impressionist_subapp_filter(unique: [:session_hash])
|
115
|
+
controller.impressionist_subapp_filter(unique: [:session_hash])
|
116
|
+
Impression.should have(@impression_count + 1).records
|
117
|
+
controller.stub(:session_hash).and_return("bar")
|
118
|
+
controller.impressionist_subapp_filter(unique: [:session_hash])
|
119
|
+
controller.impressionist_subapp_filter(unique: [:session_hash])
|
120
|
+
Impression.should have(@impression_count + 2).records
|
121
|
+
end
|
122
|
+
|
123
|
+
it "should recognize different ip" do
|
124
|
+
controller.request.stub(:remote_ip).and_return("1.2.3.4")
|
125
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
126
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
127
|
+
Impression.should have(@impression_count + 1).records
|
128
|
+
controller.request.stub(:remote_ip).and_return("5.6.7.8")
|
129
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
130
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
131
|
+
Impression.should have(@impression_count + 2).records
|
132
|
+
end
|
133
|
+
|
134
|
+
it "should recognize different referer" do
|
135
|
+
controller.request.stub(:referer).and_return("http://foo/bar")
|
136
|
+
controller.impressionist_subapp_filter(unique: [:referrer])
|
137
|
+
controller.impressionist_subapp_filter(unique: [:referrer])
|
138
|
+
Impression.should have(@impression_count + 1).records
|
139
|
+
controller.request.stub(:referer).and_return("http://bar/fo")
|
140
|
+
controller.impressionist_subapp_filter(unique: [:referrer])
|
141
|
+
controller.impressionist_subapp_filter(unique: [:referrer])
|
142
|
+
Impression.should have(@impression_count + 2).records
|
143
|
+
end
|
144
|
+
|
145
|
+
it "should recognize different id" do
|
146
|
+
controller.stub(:params).and_return({:id => "666"}) # for correct impressionable id in filter
|
147
|
+
controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
|
148
|
+
controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
|
149
|
+
controller.stub(:params).and_return({:id => "42"}) # for correct impressionable id in filter
|
150
|
+
controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
|
151
|
+
controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
|
152
|
+
Impression.should have(@impression_count + 2).records
|
153
|
+
end
|
154
|
+
|
155
|
+
it "should recognize combined uniqueness" do
|
156
|
+
controller.stub(:action_name).and_return("test_action")
|
157
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :request_hash, :action_name])
|
158
|
+
controller.impressionist_subapp_filter(unique: [:request_hash, :ip_address, :action_name])
|
159
|
+
controller.impressionist_subapp_filter(unique: [:request_hash, :action_name])
|
160
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
|
161
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :request_hash])
|
162
|
+
controller.impressionist_subapp_filter(unique: [:action_name])
|
163
|
+
controller.impressionist_subapp_filter(unique: [:ip_address])
|
164
|
+
controller.impressionist_subapp_filter(unique: [:request_hash])
|
165
|
+
Impression.should have(@impression_count + 1).records
|
166
|
+
end
|
167
|
+
|
168
|
+
it "should recognize combined non-uniqueness" do
|
169
|
+
controller.stub(:action_name).and_return(nil)
|
170
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
|
171
|
+
controller.stub(:action_name).and_return("test_action")
|
172
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
|
173
|
+
controller.stub(:action_name).and_return("another_action")
|
174
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
|
175
|
+
Impression.should have(@impression_count + 3).records
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
|
180
|
+
describe "impressionist method uniqueness for impressionables" do
|
181
|
+
|
182
|
+
# in this test we reuse the post model. might break if model changes.
|
183
|
+
|
184
|
+
it "should ignore uniqueness if not requested" do
|
185
|
+
impressionable = Post.create
|
186
|
+
controller.impressionist impressionable
|
187
|
+
controller.impressionist impressionable
|
188
|
+
Impression.should have(@impression_count + 2).records
|
189
|
+
end
|
190
|
+
|
191
|
+
it "should recognize unique session" do
|
192
|
+
controller.stub(:session_hash).and_return(request.session_options[:id])
|
193
|
+
impressionable = Post.create
|
194
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
195
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
196
|
+
Impression.should have(@impression_count + 1).records
|
197
|
+
end
|
198
|
+
|
199
|
+
it "should recognize unique ip" do
|
200
|
+
controller.request.stub(:remote_ip).and_return("1.2.3.4")
|
201
|
+
impressionable = Post.create
|
202
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
203
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
204
|
+
Impression.should have(@impression_count + 1).records
|
205
|
+
end
|
206
|
+
|
207
|
+
it "should recognize unique request" do
|
208
|
+
impressionable = Post.create
|
209
|
+
controller.impressionist(impressionable, nil, :unique => [:request_hash])
|
210
|
+
controller.impressionist(impressionable, nil, :unique => [:request_hash])
|
211
|
+
Impression.should have(@impression_count + 1).records
|
212
|
+
end
|
213
|
+
|
214
|
+
it "should recognize unique user" do
|
215
|
+
controller.stub(:user_id).and_return(666)
|
216
|
+
impressionable = Post.create
|
217
|
+
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
218
|
+
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
219
|
+
Impression.should have(@impression_count + 1).records
|
220
|
+
end
|
221
|
+
|
222
|
+
it "should recognize unique referer" do
|
223
|
+
controller.request.stub(:referer).and_return("http://foo/bar")
|
224
|
+
impressionable = Post.create
|
225
|
+
controller.impressionist(impressionable, nil, :unique => [:referrer])
|
226
|
+
controller.impressionist(impressionable, nil, :unique => [:referrer])
|
227
|
+
Impression.should have(@impression_count + 1).records
|
228
|
+
end
|
229
|
+
|
230
|
+
it "should recognize different session" do
|
231
|
+
impressionable = Post.create
|
232
|
+
controller.stub(:session_hash).and_return("foo")
|
233
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
234
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
235
|
+
Impression.should have(@impression_count + 1).records
|
236
|
+
controller.stub(:session_hash).and_return("bar")
|
237
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
238
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
239
|
+
Impression.should have(@impression_count + 2).records
|
240
|
+
end
|
241
|
+
|
242
|
+
it "should recognize different ip" do
|
243
|
+
controller.request.stub(:remote_ip).and_return("1.2.3.4")
|
244
|
+
impressionable = Post.create
|
245
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
246
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
247
|
+
Impression.should have(@impression_count + 1).records
|
248
|
+
controller.request.stub(:remote_ip).and_return("5.6.7.8")
|
249
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
250
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
251
|
+
Impression.should have(@impression_count + 2).records
|
252
|
+
end
|
253
|
+
|
254
|
+
it "should recognize different user" do
|
255
|
+
impressionable = Post.create
|
256
|
+
controller.stub(:user_id).and_return(666)
|
257
|
+
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
258
|
+
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
259
|
+
Impression.should have(@impression_count + 1).records
|
260
|
+
controller.stub(:user_id).and_return(42)
|
261
|
+
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
262
|
+
controller.impressionist(impressionable, nil, :unique => [:user_id])
|
263
|
+
Impression.should have(@impression_count + 2).records
|
264
|
+
end
|
265
|
+
|
266
|
+
it "should recognize combined uniqueness" do
|
267
|
+
impressionable = Post.create
|
268
|
+
controller.stub(:session_hash).and_return("foo")
|
269
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
|
270
|
+
controller.impressionist(impressionable, nil, :unique => [:request_hash, :ip_address, :session_hash])
|
271
|
+
controller.impressionist(impressionable, nil, :unique => [:request_hash, :session_hash])
|
272
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
273
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash])
|
274
|
+
controller.impressionist(impressionable, nil, :unique => [:session_hash])
|
275
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address])
|
276
|
+
controller.impressionist(impressionable, nil, :unique => [:request_hash])
|
277
|
+
Impression.should have(@impression_count + 1).records
|
278
|
+
end
|
279
|
+
|
280
|
+
it "should recognize combined non-uniqueness" do
|
281
|
+
impressionable = Post.create
|
282
|
+
controller.stub(:session_hash).and_return(nil)
|
283
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
284
|
+
controller.stub(:session_hash).and_return("foo")
|
285
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
286
|
+
controller.stub(:session_hash).and_return("bar")
|
287
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
|
288
|
+
Impression.should have(@impression_count + 3).records
|
289
|
+
end
|
290
|
+
|
291
|
+
end
|
292
|
+
|
293
|
+
describe "impressionist filter and method uniqueness" do
|
294
|
+
|
295
|
+
it "should recognize uniqueness" do
|
296
|
+
impressionable = Post.create
|
297
|
+
controller.stub(:controller_name).and_return("posts") # for correct impressionable type in filter
|
298
|
+
controller.stub(:params).and_return({:id => impressionable.id.to_s}) # for correct impressionable id in filter
|
299
|
+
controller.stub(:session_hash).and_return("foo")
|
300
|
+
controller.request.stub(:remote_ip).and_return("1.2.3.4")
|
301
|
+
# order of the following methods is important for the test!
|
302
|
+
controller.impressionist_subapp_filter(unique: [:ip_address, :request_hash, :session_hash])
|
303
|
+
controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
|
304
|
+
Impression.should have(@impression_count + 1).records
|
305
|
+
end
|
306
|
+
|
307
|
+
end
|
308
|
+
|
309
|
+
describe 'impressionist with friendly id' do
|
310
|
+
it 'should unique' do
|
311
|
+
impressionable = Profile.create({username: 'test_profile', slug: 'test_profile'})
|
312
|
+
|
313
|
+
controller.stub(:controller_name).and_return('profile')
|
314
|
+
controller.stub(:action_name).and_return('show')
|
315
|
+
controller.stub(:params).and_return({id: impressionable.slug})
|
316
|
+
controller.request.stub(:remote_ip).and_return('1.2.3.4')
|
317
|
+
|
318
|
+
controller.impressionist(impressionable, nil, :unique => [:impressionable_type, :impressionable_id])
|
319
|
+
controller.impressionist(impressionable, nil, :unique => [:impressionable_type, :impressionable_id])
|
320
|
+
Impression.should have(@impression_count + 1).records
|
321
|
+
end
|
322
|
+
end
|
323
|
+
|
324
|
+
shared_examples_for 'an impressionable action' do
|
325
|
+
it 'should record an impression' do
|
326
|
+
controller.impressionist_subapp_filter(condition)
|
327
|
+
Impression.should have(@impression_count + 1).records
|
328
|
+
end
|
329
|
+
end
|
330
|
+
|
331
|
+
shared_examples_for 'an unimpressionable action' do
|
332
|
+
it 'should record an impression' do
|
333
|
+
controller.impressionist_subapp_filter(condition)
|
334
|
+
Impression.should have(@impression_count).records
|
335
|
+
end
|
336
|
+
end
|
337
|
+
|
338
|
+
describe "conditional impressions" do
|
339
|
+
describe ":if condition" do
|
340
|
+
context "true condition" do
|
341
|
+
before do
|
342
|
+
controller.stub(:true_condition).and_return(true)
|
343
|
+
end
|
344
|
+
it_behaves_like 'an impressionable action' do
|
345
|
+
let(:condition) {{ if: :true_condition }}
|
346
|
+
end
|
347
|
+
|
348
|
+
it_behaves_like 'an impressionable action' do
|
349
|
+
let(:condition) {{ if: lambda { true } }}
|
350
|
+
end
|
351
|
+
end
|
352
|
+
|
353
|
+
context "false condition" do
|
354
|
+
before do
|
355
|
+
controller.stub(:false_condition).and_return(false)
|
356
|
+
end
|
357
|
+
it_behaves_like 'an unimpressionable action' do
|
358
|
+
let(:condition) {{ if: :false_condition }}
|
359
|
+
end
|
360
|
+
|
361
|
+
it_behaves_like 'an unimpressionable action' do
|
362
|
+
let(:condition) {{ if: lambda { false } }}
|
363
|
+
end
|
364
|
+
end
|
365
|
+
end
|
366
|
+
|
367
|
+
describe ":unless condition" do
|
368
|
+
context "true condition" do
|
369
|
+
before do
|
370
|
+
controller.stub(:true_condition).and_return(true)
|
371
|
+
end
|
372
|
+
it_behaves_like 'an unimpressionable action' do
|
373
|
+
let(:condition) {{ unless: :true_condition }}
|
374
|
+
end
|
375
|
+
|
376
|
+
it_behaves_like 'an unimpressionable action' do
|
377
|
+
let(:condition) {{ unless: lambda { true } }}
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
context "false condition" do
|
382
|
+
before do
|
383
|
+
controller.stub(:false_condition).and_return(false)
|
384
|
+
end
|
385
|
+
it_behaves_like 'an impressionable action' do
|
386
|
+
let(:condition) {{ unless: :false_condition }}
|
387
|
+
end
|
388
|
+
|
389
|
+
it_behaves_like 'an impressionable action' do
|
390
|
+
let(:condition) {{ unless: lambda { false } }}
|
391
|
+
end
|
392
|
+
end
|
393
|
+
end
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|