impressionist-cody 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/.github/workflows/main.yml +25 -0
  3. data/.gitignore +17 -0
  4. data/.rspec +1 -0
  5. data/.rubocop.yml +27 -0
  6. data/.rubocop_todo.yml +660 -0
  7. data/CHANGELOG.rdoc +96 -0
  8. data/Gemfile +22 -0
  9. data/LICENSE.txt +20 -0
  10. data/README.md +265 -0
  11. data/Rakefile +20 -0
  12. data/UPGRADE_GUIDE.md +13 -0
  13. data/app/assets/config/manifest.js +3 -0
  14. data/app/controllers/impressionist_controller.rb +166 -0
  15. data/app/models/impression.rb +2 -0
  16. data/app/models/impressionist/bots.rb +1468 -0
  17. data/app/models/impressionist/impressionable.rb +62 -0
  18. data/impressionist.gemspec +30 -0
  19. data/lib/generators/active_record/impressionist_generator.rb +22 -0
  20. data/lib/generators/active_record/templates/create_impressions_table.rb.erb +32 -0
  21. data/lib/generators/impressionist_generator.rb +13 -0
  22. data/lib/generators/mongo_mapper/impressionist_generator.rb +8 -0
  23. data/lib/generators/mongoid/impressionist_generator.rb +8 -0
  24. data/lib/generators/templates/impression.rb.erb +8 -0
  25. data/lib/impressionist/bots.rb +21 -0
  26. data/lib/impressionist/controllers/mongoid/impressionist_controller.rb +10 -0
  27. data/lib/impressionist/counter_cache.rb +76 -0
  28. data/lib/impressionist/engine.rb +45 -0
  29. data/lib/impressionist/is_impressionable.rb +23 -0
  30. data/lib/impressionist/load.rb +11 -0
  31. data/lib/impressionist/models/active_record/impression.rb +14 -0
  32. data/lib/impressionist/models/active_record/impressionist/impressionable.rb +12 -0
  33. data/lib/impressionist/models/mongo_mapper/impression.rb +18 -0
  34. data/lib/impressionist/models/mongo_mapper/impressionist/impressionable.rb +21 -0
  35. data/lib/impressionist/models/mongoid/impression.rb +26 -0
  36. data/lib/impressionist/models/mongoid/impressionist/impressionable.rb +28 -0
  37. data/lib/impressionist/rails_toggle.rb +26 -0
  38. data/lib/impressionist/setup_association.rb +53 -0
  39. data/lib/impressionist/update_counters.rb +77 -0
  40. data/lib/impressionist/version.rb +3 -0
  41. data/lib/impressionist.rb +12 -0
  42. data/logo.png +0 -0
  43. data/spec/controllers/articles_controller_spec.rb +113 -0
  44. data/spec/controllers/dummy_controller_spec.rb +13 -0
  45. data/spec/controllers/impressionist_uniqueness_spec.rb +463 -0
  46. data/spec/controllers/posts_controller_spec.rb +36 -0
  47. data/spec/controllers/widgets_controller_spec.rb +103 -0
  48. data/spec/counter_caching_spec.rb +49 -0
  49. data/spec/dummy/.ruby-version +1 -0
  50. data/spec/dummy/Rakefile +6 -0
  51. data/spec/dummy/app/assets/config/manifest.js +1 -0
  52. data/spec/dummy/app/assets/images/.keep +0 -0
  53. data/spec/dummy/app/assets/stylesheets/application.css +15 -0
  54. data/spec/dummy/app/channels/application_cable/channel.rb +4 -0
  55. data/spec/dummy/app/channels/application_cable/connection.rb +4 -0
  56. data/spec/dummy/app/controllers/application_controller.rb +2 -0
  57. data/spec/dummy/app/controllers/articles_controller.rb +22 -0
  58. data/spec/dummy/app/controllers/concerns/.keep +0 -0
  59. data/spec/dummy/app/controllers/dummy_controller.rb +6 -0
  60. data/spec/dummy/app/controllers/posts_controller.rb +23 -0
  61. data/spec/dummy/app/controllers/profiles_controller.rb +14 -0
  62. data/spec/dummy/app/controllers/widgets_controller.rb +12 -0
  63. data/spec/dummy/app/helpers/application_helper.rb +2 -0
  64. data/spec/dummy/app/javascript/packs/application.js +15 -0
  65. data/spec/dummy/app/jobs/application_job.rb +7 -0
  66. data/spec/dummy/app/mailers/application_mailer.rb +4 -0
  67. data/spec/dummy/app/models/application_record.rb +3 -0
  68. data/spec/dummy/app/models/article.rb +3 -0
  69. data/spec/dummy/app/models/concerns/.keep +0 -0
  70. data/spec/dummy/app/models/dummy.rb +7 -0
  71. data/spec/dummy/app/models/post.rb +3 -0
  72. data/spec/dummy/app/models/profile.rb +6 -0
  73. data/spec/dummy/app/models/user.rb +3 -0
  74. data/spec/dummy/app/models/widget.rb +3 -0
  75. data/spec/dummy/app/views/articles/index.html.erb +1 -0
  76. data/spec/dummy/app/views/articles/show.html.erb +1 -0
  77. data/spec/dummy/app/views/dummy/index.html.erb +0 -0
  78. data/spec/dummy/app/views/layouts/application.html.erb +14 -0
  79. data/spec/dummy/app/views/layouts/mailer.html.erb +13 -0
  80. data/spec/dummy/app/views/layouts/mailer.text.erb +1 -0
  81. data/spec/dummy/app/views/posts/edit.html.erb +0 -0
  82. data/spec/dummy/app/views/posts/index.html.erb +0 -0
  83. data/spec/dummy/app/views/posts/show.html.erb +0 -0
  84. data/spec/dummy/app/views/profiles/show.html.erb +3 -0
  85. data/spec/dummy/app/views/widgets/index.html.erb +0 -0
  86. data/spec/dummy/app/views/widgets/new.html.erb +0 -0
  87. data/spec/dummy/app/views/widgets/show.html.erb +0 -0
  88. data/spec/dummy/bin/rails +4 -0
  89. data/spec/dummy/bin/rake +4 -0
  90. data/spec/dummy/bin/setup +33 -0
  91. data/spec/dummy/config/application.rb +20 -0
  92. data/spec/dummy/config/boot.rb +5 -0
  93. data/spec/dummy/config/cable.yml +10 -0
  94. data/spec/dummy/config/database.yml +25 -0
  95. data/spec/dummy/config/environment.rb +5 -0
  96. data/spec/dummy/config/environments/development.rb +62 -0
  97. data/spec/dummy/config/environments/production.rb +112 -0
  98. data/spec/dummy/config/environments/test.rb +49 -0
  99. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  100. data/spec/dummy/config/initializers/assets.rb +12 -0
  101. data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
  102. data/spec/dummy/config/initializers/content_security_policy.rb +28 -0
  103. data/spec/dummy/config/initializers/cookies_serializer.rb +5 -0
  104. data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
  105. data/spec/dummy/config/initializers/impression.rb +8 -0
  106. data/spec/dummy/config/initializers/inflections.rb +16 -0
  107. data/spec/dummy/config/initializers/mime_types.rb +4 -0
  108. data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
  109. data/spec/dummy/config/locales/en.yml +33 -0
  110. data/spec/dummy/config/puma.rb +38 -0
  111. data/spec/dummy/config/routes.rb +4 -0
  112. data/spec/dummy/config/spring.rb +6 -0
  113. data/spec/dummy/config/storage.yml +34 -0
  114. data/spec/dummy/config.ru +5 -0
  115. data/spec/dummy/config.ru2 +4 -0
  116. data/spec/dummy/db/development.sqlite3 +0 -0
  117. data/spec/dummy/db/migrate/20110201153144_create_articles.rb +13 -0
  118. data/spec/dummy/db/migrate/20110210205028_create_posts.rb +13 -0
  119. data/spec/dummy/db/migrate/20111127184039_create_widgets.rb +15 -0
  120. data/spec/dummy/db/migrate/20150207135825_create_profiles.rb +10 -0
  121. data/spec/dummy/db/migrate/20150207140310_create_friendly_id_slugs.rb +18 -0
  122. data/spec/dummy/db/migrate/20200720143817_create_impressions_table.rb +32 -0
  123. data/spec/dummy/db/schema.rb +77 -0
  124. data/spec/dummy/lib/assets/.keep +0 -0
  125. data/spec/dummy/log/.keep +0 -0
  126. data/spec/dummy/log/development.log +129 -0
  127. data/spec/dummy/public/404.html +67 -0
  128. data/spec/dummy/public/422.html +67 -0
  129. data/spec/dummy/public/500.html +66 -0
  130. data/spec/dummy/public/apple-touch-icon-precomposed.png +0 -0
  131. data/spec/dummy/public/apple-touch-icon.png +0 -0
  132. data/spec/dummy/public/favicon.ico +0 -0
  133. data/spec/dummy/storage/.keep +0 -0
  134. data/spec/fixtures/articles.yml +3 -0
  135. data/spec/fixtures/impressions.yml +43 -0
  136. data/spec/fixtures/posts.yml +3 -0
  137. data/spec/fixtures/profiles.yml +4 -0
  138. data/spec/fixtures/widgets.yml +4 -0
  139. data/spec/initializers_spec.rb +21 -0
  140. data/spec/models/bots_spec.rb +25 -0
  141. data/spec/models/impression_spec.rb +66 -0
  142. data/spec/rails_generators/rails_generators_spec.rb +23 -0
  143. data/spec/rails_helper.rb +11 -0
  144. data/spec/rails_toggle_spec.rb +31 -0
  145. data/spec/setup_association_spec.rb +48 -0
  146. data/spec/spec_helper.rb +43 -0
  147. data/upgrade_migrations/version_0_3_0.rb +27 -0
  148. data/upgrade_migrations/version_0_4_0.rb +9 -0
  149. data/upgrade_migrations/version_1_5_2.rb +12 -0
  150. metadata +302 -0
@@ -0,0 +1,12 @@
1
+ require 'impressionist/load'
2
+
3
+ module Impressionist
4
+ # Define default ORM
5
+ mattr_accessor :orm
6
+ @@orm = :active_record
7
+
8
+ # Load configuration from initializer
9
+ def self.setup
10
+ yield self
11
+ end
12
+ end
data/logo.png ADDED
Binary file
@@ -0,0 +1,113 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'spec_helper'
4
+
5
+ describe ArticlesController, type: :controller do
6
+ fixtures :articles, :impressions, :posts, :widgets
7
+
8
+ render_views
9
+
10
+ it 'makes the impressionable_hash available' do
11
+ get :index
12
+ expect(response.body).to include('false')
13
+ end
14
+
15
+ it 'logs an impression with a message' do
16
+ get 'index'
17
+
18
+ latest_impression = Article.first.impressions.last
19
+
20
+ expect(Impression.all.size).to eq 12
21
+
22
+ expect(latest_impression.message).to eq 'this is a test article impression'
23
+ expect(latest_impression.controller_name).to eq 'articles'
24
+ expect(latest_impression.action_name).to eq 'index'
25
+ end
26
+
27
+ it 'logs an impression without a message' do
28
+ get :show, params: { id: 1 }
29
+
30
+ latest_impression = Article.first.impressions.last
31
+
32
+ expect(Impression.all.size).to eq 12
33
+
34
+ expect(latest_impression.message).to eq nil
35
+ expect(latest_impression.controller_name).to eq 'articles'
36
+ expect(latest_impression.action_name).to eq 'show'
37
+ end
38
+
39
+ it 'logs the user_id if user is authenticated (@current_user before_action method)' do
40
+ session[:user_id] = 123
41
+ get :show, params: { id: 1 }
42
+
43
+ expect(Article.first.impressions.last.user_id).to eq 123
44
+ end
45
+
46
+ it 'does not log the user_id if user is authenticated' do
47
+ get :show, params: { id: 1 }
48
+
49
+ expect(Article.first.impressions.last.user_id).to eq nil
50
+ end
51
+
52
+ it 'logs the request_hash, ip_address, referrer and session_hash' do
53
+ get :show, params: { id: 1 }
54
+
55
+ impression = Impression.last
56
+
57
+ expect(impression.request_hash.size).to eq 64
58
+ expect(impression.ip_address).to eq '0.0.0.0'
59
+ expect(impression.session_hash.size).to eq 32
60
+ expect(impression.referrer).to eq nil
61
+ end
62
+
63
+ # Capybara has change the way it works
64
+ # We need to pass :type options in order to make include helper methods
65
+ # see https://github.com/jnicklas/capybara#using-capybara-with-rspec
66
+ it 'logs the referrer when you click a link', type: :feature do
67
+ default_url_options[:host] = "test.host"
68
+
69
+ visit article_url(Article.first)
70
+ click_link 'Same Page'
71
+ expect(Impression.last.referrer).to eq 'http://test.host/articles/1'
72
+ end
73
+
74
+ it 'logs request with params (checked = true)' do
75
+ get :show, params: { id: 1, checked: true }
76
+
77
+ impression = Impression.last
78
+
79
+ expect(impression.params).to eq({ 'checked' => "true" })
80
+ expect(impression.request_hash.size).to eq 64
81
+ expect(impression.ip_address).to eq '0.0.0.0'
82
+ expect(impression.session_hash.size).to eq 32
83
+ expect(impression.referrer).to eq nil
84
+ end
85
+
86
+ it 'logs request with params: {}' do
87
+ get 'index'
88
+
89
+ impression = Impression.last
90
+
91
+ expect(impression.params).to eq({})
92
+ expect(impression.request_hash.size).to eq 64
93
+ expect(impression.ip_address).to eq '0.0.0.0'
94
+ expect(impression.session_hash.size).to eq 32
95
+ expect(impression.referrer).to eq nil
96
+ end
97
+
98
+ describe 'when filtering params' do
99
+ before do
100
+ @_filtered_params = Rails.application.config.filter_parameters
101
+ Rails.application.config.filter_parameters = [:password]
102
+ end
103
+
104
+ after do
105
+ Rails.application.config.filter_parameters = @_filtered_params
106
+ end
107
+
108
+ it 'values should not be recorded' do
109
+ get 'index', params: { password: 'best-password-ever' }
110
+ expect(Impression.last.params).to eq('password' => '[FILTERED]')
111
+ end
112
+ end
113
+ end
@@ -0,0 +1,13 @@
1
+ # frozen_string_literal: false
2
+
3
+ require 'spec_helper'
4
+
5
+ describe DummyController, type: :controller do
6
+ fixtures :impressions
7
+ render_views
8
+
9
+ it 'logs impression at the per action level on non-restful controller' do
10
+ get 'index'
11
+ expect(Impression.all.size).to eq 12
12
+ end
13
+ end
@@ -0,0 +1,463 @@
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
+ before do
6
+ @impression_count = Impression.all.size
7
+ end
8
+
9
+ describe "impressionist filter uniqueness" do
10
+ it "ignore uniqueness if not requested" do
11
+ controller.impressionist_subapp_filter
12
+ controller.impressionist_subapp_filter
13
+
14
+ expect(Impression.count).to eq(@impression_count + 2)
15
+ end
16
+
17
+ it "recognize unique session" do
18
+ allow(controller).to receive(:session_hash).and_return(request.session_options[:id])
19
+
20
+ controller.impressionist_subapp_filter(unique: [:session_hash])
21
+ controller.impressionist_subapp_filter(unique: [:session_hash])
22
+
23
+ expect(Impression.count).to eq(@impression_count + 1)
24
+ end
25
+
26
+ it "recognize unique ip" do
27
+ allow(controller).to receive(:remote_ip).and_return("1.2.3.4")
28
+
29
+ controller.impressionist_subapp_filter(unique: [:ip_address])
30
+ controller.impressionist_subapp_filter(unique: [:ip_address])
31
+
32
+ expect(Impression.count).to equal(@impression_count + 1)
33
+ end
34
+
35
+ it "recognize unique request" do
36
+ controller.impressionist_subapp_filter(unique: [:request_hash])
37
+ controller.impressionist_subapp_filter(unique: [:request_hash])
38
+
39
+ expect(Impression.count).to equal(@impression_count + 1)
40
+ end
41
+
42
+ it "recognize unique action" do
43
+ allow(controller).to receive(:action_name).and_return("test_action")
44
+
45
+ controller.impressionist_subapp_filter(unique: [:action_name])
46
+ controller.impressionist_subapp_filter(unique: [:action_name])
47
+
48
+ expect(Impression.count).to equal(@impression_count + 1)
49
+ end
50
+
51
+ it "recognize unique controller" do
52
+ allow(controller).to receive(:controller_name).and_return("post")
53
+
54
+ controller.impressionist_subapp_filter(unique: [:controller_name])
55
+ controller.impressionist_subapp_filter(unique: [:controller_name])
56
+ expect(Impression.count).to equal(@impression_count + 1)
57
+ end
58
+
59
+ it "recognize unique user" do
60
+ allow(controller).to receive(:user_id).and_return(42)
61
+
62
+ controller.impressionist_subapp_filter(unique: [:user_id])
63
+ controller.impressionist_subapp_filter(unique: [:user_id])
64
+
65
+ expect(Impression.count).to equal(@impression_count + 1)
66
+ end
67
+
68
+ it "recognize unique referer" do
69
+ allow(controller.request).to receive(:referer).and_return("http://foo/bar")
70
+
71
+ controller.impressionist_subapp_filter(unique: [:referrer])
72
+ controller.impressionist_subapp_filter(unique: [:referrer])
73
+
74
+ expect(Impression.count).to equal(@impression_count + 1)
75
+ end
76
+
77
+ it "recognize unique id" do
78
+ allow(controller).to receive(:params).and_return({ :id => "666" }) # for correct impressionable id in filter
79
+
80
+ controller.impressionist_subapp_filter(unique: [:impressionable_id])
81
+ controller.impressionist_subapp_filter(unique: [:impressionable_id])
82
+ expect(Impression.count).to equal(@impression_count + 1)
83
+ end
84
+
85
+ # extra redundant test for important controller and action combination.
86
+ it "recognize different controller and action" do
87
+ allow(controller).to receive(:controller_name).and_return("post")
88
+ allow(controller).to receive(:action_name).and_return("test_action")
89
+
90
+ controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
91
+ controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
92
+
93
+ expect(Impression.count).to equal(@impression_count + 1)
94
+
95
+ allow(controller).to receive(:action_name).and_return("another_action")
96
+
97
+ controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
98
+ controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
99
+
100
+ expect(Impression.count).to equal(@impression_count + 2)
101
+
102
+ allow(controller).to receive(:controller_name).and_return("article")
103
+
104
+ controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
105
+ controller.impressionist_subapp_filter(unique: [:controller_name, :action_name])
106
+
107
+ expect(Impression.count).to equal(@impression_count + 3)
108
+ end
109
+
110
+ it "recognize different action" do
111
+ allow(controller).to receive(:action_name).and_return("test_action")
112
+ controller.impressionist_subapp_filter(unique: [:action_name])
113
+ controller.impressionist_subapp_filter(unique: [:action_name])
114
+ expect(Impression.count).to equal(@impression_count + 1)
115
+ allow(controller).to receive(:action_name).and_return("another_action")
116
+ controller.impressionist_subapp_filter(unique: [:action_name])
117
+ controller.impressionist_subapp_filter(unique: [:action_name])
118
+ expect(Impression.count).to equal(@impression_count + 2)
119
+ end
120
+
121
+ it "recognize different controller" do
122
+ allow(controller).to receive(:controller_name).and_return("post")
123
+ controller.impressionist_subapp_filter(unique: [:controller_name])
124
+ controller.impressionist_subapp_filter(unique: [:controller_name])
125
+ expect(Impression.count).to equal(@impression_count + 1)
126
+ allow(controller).to receive(:controller_name).and_return("article")
127
+ controller.impressionist_subapp_filter(unique: [:controller_name])
128
+ controller.impressionist_subapp_filter(unique: [:controller_name])
129
+ expect(Impression.count).to equal(@impression_count + 2)
130
+ end
131
+
132
+ it "recognize different session" do
133
+ allow(controller).to receive(:session_hash).and_return("foo")
134
+ controller.impressionist_subapp_filter(unique: [:session_hash])
135
+ controller.impressionist_subapp_filter(unique: [:session_hash])
136
+ expect(Impression.count).to equal(@impression_count + 1)
137
+ allow(controller).to receive(:session_hash).and_return("bar")
138
+ controller.impressionist_subapp_filter(unique: [:session_hash])
139
+ controller.impressionist_subapp_filter(unique: [:session_hash])
140
+ expect(Impression.count).to equal(@impression_count + 2)
141
+ end
142
+
143
+ it "recognize different ip" do
144
+ allow(controller.request).to receive(:remote_ip).and_return("1.2.3.4")
145
+
146
+ controller.impressionist_subapp_filter(unique: [:ip_address])
147
+ controller.impressionist_subapp_filter(unique: [:ip_address])
148
+
149
+ expect(Impression.count).to equal(@impression_count + 1)
150
+
151
+ allow(controller.request).to receive(:remote_ip).and_return("5.6.7.8")
152
+
153
+ controller.impressionist_subapp_filter(unique: [:ip_address])
154
+ controller.impressionist_subapp_filter(unique: [:ip_address])
155
+
156
+ expect(Impression.count).to equal(@impression_count + 2)
157
+ end
158
+
159
+ it "recognize different referer" do
160
+ allow(controller.request).to receive(:referer).and_return("http://foo/bar")
161
+
162
+ controller.impressionist_subapp_filter(unique: [:referrer])
163
+ controller.impressionist_subapp_filter(unique: [:referrer])
164
+
165
+ expect(Impression.count).to equal(@impression_count + 1)
166
+
167
+ allow(controller.request).to receive(:referer).and_return("http://bar/fo")
168
+
169
+ controller.impressionist_subapp_filter(unique: [:referrer])
170
+ controller.impressionist_subapp_filter(unique: [:referrer])
171
+ expect(Impression.count).to equal(@impression_count + 2)
172
+ end
173
+
174
+ it "recognize different id" do
175
+ allow(controller).to receive(:params).and_return({ :id => "666" }) # for correct impressionable id in filter
176
+
177
+ controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
178
+ controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
179
+
180
+ allow(controller).to receive(:params).and_return({ :id => "42" }) # for correct impressionable id in filter
181
+
182
+ controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
183
+ controller.impressionist_subapp_filter(unique: [:impressionable_type, :impressionable_id])
184
+
185
+ expect(Impression.count).to equal(@impression_count + 2)
186
+ end
187
+
188
+ it "recognize combined uniqueness" do
189
+ allow(controller).to receive(:action_name).and_return("test_action")
190
+
191
+ controller.impressionist_subapp_filter(unique: [:ip_address, :request_hash, :action_name])
192
+ controller.impressionist_subapp_filter(unique: [:request_hash, :ip_address, :action_name])
193
+ controller.impressionist_subapp_filter(unique: [:request_hash, :action_name])
194
+ controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
195
+ controller.impressionist_subapp_filter(unique: [:ip_address, :request_hash])
196
+ controller.impressionist_subapp_filter(unique: [:action_name])
197
+ controller.impressionist_subapp_filter(unique: [:ip_address])
198
+ controller.impressionist_subapp_filter(unique: [:request_hash])
199
+
200
+ expect(Impression.count).to equal(@impression_count + 1)
201
+ end
202
+
203
+ it "recognize combined non-uniqueness" do
204
+ allow(controller).to receive(:action_name).and_return(nil)
205
+
206
+ controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
207
+
208
+ allow(controller).to receive(:action_name).and_return("test_action")
209
+
210
+ controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
211
+
212
+ allow(controller).to receive(:action_name).and_return("another_action")
213
+
214
+ controller.impressionist_subapp_filter(unique: [:ip_address, :action_name])
215
+
216
+ expect(Impression.count).to equal(@impression_count + 3)
217
+ end
218
+ end
219
+
220
+ describe "impressionist method uniqueness for impressionables" do
221
+ # in this test we reuse the post model. might break if model changes.
222
+
223
+ it "ignore uniqueness if not requested" do
224
+ impressionable = Post.create
225
+ controller.impressionist impressionable
226
+ controller.impressionist impressionable
227
+ expect(Impression.count).to equal(@impression_count + 2)
228
+ end
229
+
230
+ it "recognize unique session" do
231
+ allow(controller).to receive(:session_hash).and_return(request.session_options[:id])
232
+
233
+ impressionable = Post.create
234
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
235
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
236
+
237
+ expect(Impression.count).to equal(@impression_count + 1)
238
+ end
239
+
240
+ it "recognize unique ip" do
241
+ allow(controller.request).to receive(:remote_ip).and_return("1.2.3.4")
242
+
243
+ impressionable = Post.create
244
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
245
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
246
+
247
+ expect(Impression.count).to equal(@impression_count + 1)
248
+ end
249
+
250
+ it "recognize unique request" do
251
+ impressionable = Post.create
252
+ controller.impressionist(impressionable, nil, :unique => [:request_hash])
253
+ controller.impressionist(impressionable, nil, :unique => [:request_hash])
254
+
255
+ expect(Impression.count).to equal(@impression_count + 1)
256
+ end
257
+
258
+ it "recognize unique user" do
259
+ allow(controller).to receive(:user_id).and_return(666)
260
+
261
+ impressionable = Post.create
262
+ controller.impressionist(impressionable, nil, :unique => [:user_id])
263
+ controller.impressionist(impressionable, nil, :unique => [:user_id])
264
+
265
+ expect(Impression.count).to equal(@impression_count + 1)
266
+ end
267
+
268
+ it "recognize unique referer" do
269
+ allow(controller.request).to receive(:referer).and_return("http://foo/bar")
270
+
271
+ impressionable = Post.create
272
+ controller.impressionist(impressionable, nil, :unique => [:referrer])
273
+ controller.impressionist(impressionable, nil, :unique => [:referrer])
274
+
275
+ expect(Impression.count).to equal(@impression_count + 1)
276
+ end
277
+
278
+ it "recognize different session" do
279
+ impressionable = Post.create
280
+
281
+ allow(controller).to receive(:session_hash).and_return("foo")
282
+
283
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
284
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
285
+
286
+ expect(Impression.count).to equal(@impression_count + 1)
287
+
288
+ allow(controller).to receive(:session_hash).and_return("bar")
289
+
290
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
291
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
292
+
293
+ expect(Impression.count).to equal(@impression_count + 2)
294
+ end
295
+
296
+ it "recognize different ip" do
297
+ allow(controller.request).to receive(:remote_ip).and_return("1.2.3.4")
298
+
299
+ impressionable = Post.create
300
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
301
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
302
+
303
+ expect(Impression.count).to equal(@impression_count + 1)
304
+
305
+ allow(controller.request).to receive(:remote_ip).and_return("5.6.7.8")
306
+
307
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
308
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
309
+
310
+ expect(Impression.count).to equal(@impression_count + 2)
311
+ end
312
+
313
+ it "recognize different user" do
314
+ impressionable = Post.create
315
+
316
+ allow(controller).to receive(:user_id).and_return(666)
317
+
318
+ controller.impressionist(impressionable, nil, :unique => [:user_id])
319
+ controller.impressionist(impressionable, nil, :unique => [:user_id])
320
+
321
+ expect(Impression.count).to equal(@impression_count + 1)
322
+
323
+ allow(controller).to receive(:user_id).and_return(42)
324
+
325
+ controller.impressionist(impressionable, nil, :unique => [:user_id])
326
+ controller.impressionist(impressionable, nil, :unique => [:user_id])
327
+
328
+ expect(Impression.count).to equal(@impression_count + 2)
329
+ end
330
+
331
+ it "recognize combined uniqueness" do
332
+ impressionable = Post.create
333
+ allow(controller).to receive(:session_hash).and_return("foo")
334
+
335
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
336
+ controller.impressionist(impressionable, nil, :unique => [:request_hash, :ip_address, :session_hash])
337
+ controller.impressionist(impressionable, nil, :unique => [:request_hash, :session_hash])
338
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
339
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash])
340
+ controller.impressionist(impressionable, nil, :unique => [:session_hash])
341
+ controller.impressionist(impressionable, nil, :unique => [:ip_address])
342
+ controller.impressionist(impressionable, nil, :unique => [:request_hash])
343
+
344
+ expect(Impression.count).to equal(@impression_count + 1)
345
+ end
346
+
347
+ it "recognize combined non-uniqueness" do
348
+ impressionable = Post.create
349
+ allow(controller).to receive(:session_hash).and_return(nil)
350
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
351
+ allow(controller).to receive(:session_hash).and_return("foo")
352
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
353
+ allow(controller).to receive(:session_hash).and_return("bar")
354
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :session_hash])
355
+ expect(Impression.count).to equal(@impression_count + 3)
356
+ end
357
+ end
358
+
359
+ describe "impressionist filter and method uniqueness" do
360
+ it "recognize uniqueness" do
361
+ impressionable = Post.create
362
+ allow(controller).to receive(:controller_name).and_return("posts") # for correct impressionable type in filter
363
+ allow(controller).to receive(:params).and_return({ :id => impressionable.id.to_s }) # for correct impressionable id in filter
364
+ allow(controller).to receive(:session_hash).and_return("foo")
365
+ allow(controller.request).to receive(:remote_ip).and_return("1.2.3.4")
366
+ # order of the following methods is important for the test!
367
+ controller.impressionist_subapp_filter(unique: [:ip_address, :request_hash, :session_hash])
368
+ controller.impressionist(impressionable, nil, :unique => [:ip_address, :request_hash, :session_hash])
369
+ expect(Impression.count).to equal(@impression_count + 1)
370
+ end
371
+ end
372
+
373
+ describe 'impressionist with friendly id' do
374
+ it 'unique' do
375
+ impressionable = Profile.create({ username: 'test_profile', slug: 'test_profile' })
376
+
377
+ allow(controller).to receive(:controller_name).and_return('profile')
378
+ allow(controller).to receive(:action_name).and_return('show')
379
+ allow(controller).to receive(:params).and_return({ id: impressionable.slug })
380
+ allow(controller.request).to receive(:remote_ip).and_return('1.2.3.4')
381
+
382
+ controller.impressionist(impressionable, nil, :unique => [:impressionable_type, :impressionable_id])
383
+ controller.impressionist(impressionable, nil, :unique => [:impressionable_type, :impressionable_id])
384
+ expect(Impression.count).to equal(@impression_count + 1)
385
+ end
386
+ end
387
+
388
+ shared_examples_for 'an impressionable action' do
389
+ it 'record an impression' do
390
+ controller.impressionist_subapp_filter(condition)
391
+ expect(Impression.count).to equal(@impression_count + 1)
392
+ end
393
+ end
394
+
395
+ shared_examples_for 'an unimpressionable action' do
396
+ it 'record an impression' do
397
+ controller.impressionist_subapp_filter(condition)
398
+ expect(Impression.count).to equal(@impression_count)
399
+ end
400
+ end
401
+
402
+ describe "conditional impressions" do
403
+ describe ":if condition" do
404
+ context "true condition" do
405
+ before do
406
+ allow(controller).to receive(:true_condition).and_return(true)
407
+ end
408
+
409
+ it_behaves_like 'an impressionable action' do
410
+ let(:condition) { { if: :true_condition } }
411
+ end
412
+
413
+ it_behaves_like 'an impressionable action' do
414
+ let(:condition) { { if: -> { true } } }
415
+ end
416
+ end
417
+
418
+ context "false condition" do
419
+ before do
420
+ allow(controller).to receive(:false_condition).and_return(false)
421
+ end
422
+
423
+ it_behaves_like 'an unimpressionable action' do
424
+ let(:condition) { { if: :false_condition } }
425
+ end
426
+
427
+ it_behaves_like 'an unimpressionable action' do
428
+ let(:condition) { { if: -> { false } } }
429
+ end
430
+ end
431
+ end
432
+
433
+ describe ":unless condition" do
434
+ context "true condition" do
435
+ before do
436
+ allow(controller).to receive(:true_condition).and_return(true)
437
+ end
438
+
439
+ it_behaves_like 'an unimpressionable action' do
440
+ let(:condition) { { unless: :true_condition } }
441
+ end
442
+
443
+ it_behaves_like 'an unimpressionable action' do
444
+ let(:condition) { { unless: -> { true } } }
445
+ end
446
+ end
447
+
448
+ context "false condition" do
449
+ before do
450
+ allow(controller).to receive(:false_condition).and_return(false)
451
+ end
452
+
453
+ it_behaves_like 'an impressionable action' do
454
+ let(:condition) { { unless: :false_condition } }
455
+ end
456
+
457
+ it_behaves_like 'an impressionable action' do
458
+ let(:condition) { { unless: -> { false } } }
459
+ end
460
+ end
461
+ end
462
+ end
463
+ end
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe PostsController do
4
+ it "logs impression at the action level" do
5
+ get :show, params: { id: 1 }
6
+
7
+ expect(Impression.all.size).to eq 12
8
+
9
+ impression = Impression.last
10
+
11
+ expect(impression.controller_name).to eq "posts"
12
+ expect(impression.action_name).to eq "show"
13
+ expect(impression.impressionable_type).to eq "Post"
14
+ expect(impression.impressionable_id).to eq 1
15
+ end
16
+
17
+ it "logs the user_id if user is authenticated (current_user helper method)" do
18
+ session[:user_id] = 123
19
+ get :show, params: { id: 1 }
20
+ expect(Post.first.impressions.last.user_id).to eq 123
21
+ end
22
+
23
+ it "logs impression at the action level with params" do
24
+ get :show, params: { id: 1, checked: true }
25
+
26
+ expect(Impression.all.size).to eq 12
27
+
28
+ impression = Impression.last
29
+
30
+ expect(impression.params).to eq({ "checked" => "true" })
31
+ expect(impression.controller_name).to eq "posts"
32
+ expect(impression.action_name).to eq "show"
33
+ expect(impression.impressionable_type).to eq "Post"
34
+ expect(impression.impressionable_id).to eq 1
35
+ end
36
+ end