rack-tracker 1.5.0 → 1.6.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 93dcd33285ad07b72e75cabe697bffa820b2212d
4
- data.tar.gz: 2cfbf93add60fb26e91bf9f703b3dda0bc9aff95
3
+ metadata.gz: 0a9cfcc30e5e0f2ad7537aaa11e73bcfeafe80fa
4
+ data.tar.gz: 7645b119a9d73df232c29ee86f2d55f43118403c
5
5
  SHA512:
6
- metadata.gz: c10ddd4e7a5abba1887219909bf4480c79a2b5775f81f072cab6cc40df914ec29b6dcce4eaf8609ff8087d284c154aaf6b34c64bb3ae5fb7c524d47c8b5fab26
7
- data.tar.gz: 42310ccab992b9d71cd5817e1c6cc989cc4271d13c2ac628b3673f12712f9c1a01221e64b27528b622b41dfe4d1d01b74cb2eec9e3f1e2fc5e825a390a0e282a
6
+ metadata.gz: ecea4935a9470f58ab52b413f0e6b984238d5db11d527fa5eaceeda5dac904bdcd65c804b2f0fe2680224b135e71c4443554f3d6d8f7aaa556c9b75b32d6c499
7
+ data.tar.gz: 6ecdf64a615c1bc9d46828c817e5836e5af6d64cc9ec5476fe19558b8c498a68211112386ef3838645828b5796e44e29da30cf4a81a94c4fa91c1604fd5cc648
@@ -2,9 +2,10 @@ language: ruby
2
2
  sudo: false
3
3
  rvm:
4
4
  - 2.1.10
5
- - 2.2.7
6
- - 2.3.4
7
- - 2.4.1
5
+ - 2.2.9
6
+ - 2.3.6
7
+ - 2.4.3
8
+ - 2.5.0
8
9
  - jruby-9.1.10.0
9
10
  gemfile:
10
11
  - Gemfile
@@ -1,3 +1,10 @@
1
+ # 1.6.0
2
+
3
+ * [BUGFIX] set wildcard to non-greedy for GTM body insertion #107
4
+ * [ENHANCEMENT] Test against Ruby 2.5 #104
5
+ * [ENHANCEMENT] Google Optimize container ID #103
6
+ * [ENHANCEMENT] Allow for dynamic Facebook Pixel options #101
7
+
1
8
  # 1.5.0
2
9
 
3
10
  * [ENHANCEMENT] facebook pixel now supports non-standard (custom) event names #93
data/README.md CHANGED
@@ -96,6 +96,7 @@ request.env['tracker'] = {
96
96
  * `:advertising` - Enables [Display Features](https://developers.google.com/analytics/devguides/collection/analyticsjs/display-features).
97
97
  * `:ecommerce` - Enables [Ecommerce Tracking](https://developers.google.com/analytics/devguides/collection/analyticsjs/ecommerce).
98
98
  * `:enhanced_ecommerce` - Enables [Enhanced Ecommerce Tracking](https://developers.google.com/analytics/devguides/collection/analyticsjs/enhanced-ecommerce)
99
+ * `:optimize` - pass [Google Optimize container ID](https://support.google.com/360suite/optimize/answer/6262084#example-combined-snippet) as value (e.g. `optimize: 'GTM-1234'`).
99
100
 
100
101
  #### Events
101
102
 
@@ -1,5 +1,6 @@
1
1
  class Rack::Tracker::FacebookPixel < Rack::Tracker::Handler
2
2
  self.position = :body
3
+ self.allowed_tracker_options = [:id]
3
4
 
4
5
  class Event < OpenStruct
5
6
  def write
@@ -7,12 +7,12 @@
7
7
  t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
8
8
  document,'script','//connect.facebook.net/en_US/fbevents.js');
9
9
 
10
- fbq('init', '<%= options[:id] %>');
10
+ fbq('init', '<%= tracker_options[:id] %>');
11
11
  fbq('track', "PageView");
12
12
  }
13
13
  </script>
14
14
  <noscript>
15
- <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=<%= options[:id] %>&ev=PageView&noscript=1"/>
15
+ <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id=<%= tracker_options[:id] %>&ev=PageView&noscript=1"/>
16
16
  </noscript>
17
17
 
18
18
  <% if events.any? %>
@@ -1,6 +1,6 @@
1
1
  class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
2
2
 
3
- ALLOWED_TRACKER_OPTIONS = [:cookie_domain, :user_id]
3
+ self.allowed_tracker_options = [:cookie_domain, :user_id]
4
4
 
5
5
  class Send < OpenStruct
6
6
  def initialize(attrs = {})
@@ -57,16 +57,6 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
57
57
  options[:tracker].respond_to?(:call) ? options[:tracker].call(env) : options[:tracker]
58
58
  end
59
59
 
60
- def tracker_options
61
- @tracker_options ||= {}.tap do |tracker_options|
62
- options.slice(*ALLOWED_TRACKER_OPTIONS).each do |key, value|
63
- if option_value = value.respond_to?(:call) ? value.call(env) : value
64
- tracker_options[key.to_s.camelize(:lower).to_sym] = option_value.to_s
65
- end
66
- end
67
- end
68
- end
69
-
70
60
  def ecommerce_events
71
61
  events.select {|e| e.kind_of?(Ecommerce) }
72
62
  end
@@ -74,4 +64,14 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
74
64
  def enhanced_ecommerce_events
75
65
  events.select {|e| e.kind_of?(EnhancedEcommerce) }
76
66
  end
67
+
68
+ private
69
+
70
+ def tracker_option_key(key)
71
+ key.to_s.camelize(:lower).to_sym
72
+ end
73
+
74
+ def tracker_option_value(value)
75
+ value.to_s
76
+ end
77
77
  end
@@ -20,6 +20,9 @@
20
20
  <% if options[:ecommerce] %>
21
21
  ga('require', 'ecommerce', 'ecommerce.js');
22
22
  <% end %>
23
+ <% if options[:optimize] %>
24
+ ga('require', '<%= options[:optimize] %>');
25
+ <% end %>
23
26
  <% if options[:anonymize_ip] %>
24
27
  ga('set', 'anonymizeIp', true);
25
28
  <% end %>
@@ -13,7 +13,7 @@ class Rack::Tracker::GoogleTagManager < Rack::Tracker::Handler
13
13
  response.sub! %r{<head.*>} do |m|
14
14
  m.to_s << self.render_head
15
15
  end
16
- response.sub! %r{<body.*>} do |m|
16
+ response.sub! %r{<body.*?>} do |m|
17
17
  m.to_s << self.render_body
18
18
  end
19
19
  response
@@ -13,6 +13,9 @@ class Rack::Tracker::Handler
13
13
  class_attribute :position
14
14
  self.position = :head
15
15
 
16
+ class_attribute :allowed_tracker_options
17
+ self.allowed_tracker_options = []
18
+
16
19
  attr_accessor :options
17
20
  attr_accessor :env
18
21
 
@@ -56,4 +59,28 @@ class Rack::Tracker::Handler
56
59
  def handler_name
57
60
  self.class.name.demodulize.underscore
58
61
  end
62
+
63
+ def tracker_options
64
+ @_tracker_options ||= {}.tap do |tracker_options|
65
+ options.slice(*allowed_tracker_options).each do |key, value|
66
+ if option_value = value.respond_to?(:call) ? value.call(env) : value
67
+ tracker_options[tracker_option_key(key)] = tracker_option_value(option_value)
68
+ end
69
+ end
70
+ end
71
+ end
72
+
73
+ private
74
+
75
+ # Transformations to be applied to tracker option keys.
76
+ # Override in descendants, if necessary.
77
+ def tracker_option_key(key)
78
+ key.to_sym
79
+ end
80
+
81
+ # Transformations to be applied to tracker option values.
82
+ # Override in descendants, if necessary.
83
+ def tracker_option_value(value)
84
+ value
85
+ end
59
86
  end
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Tracker
3
- VERSION = '1.5.0'
3
+ VERSION = '1.6.0'
4
4
  end
5
5
  end
@@ -1,6 +1,6 @@
1
1
  RSpec.describe Rack::Tracker::FacebookPixel do
2
2
  def env
3
- {}
3
+ { 'PIXEL_ID' => 'DYNAMIC_PIXEL_ID' }
4
4
  end
5
5
 
6
6
  it 'will be placed in the body' do
@@ -8,7 +8,7 @@ RSpec.describe Rack::Tracker::FacebookPixel do
8
8
  expect(described_class.new(env).position).to eq(:body)
9
9
  end
10
10
 
11
- describe 'with id' do
11
+ describe 'with static id' do
12
12
  subject { described_class.new(env, id: 'PIXEL_ID').render }
13
13
 
14
14
  it 'will push the tracking events to the queue' do
@@ -20,6 +20,18 @@ RSpec.describe Rack::Tracker::FacebookPixel do
20
20
  end
21
21
  end
22
22
 
23
+ describe 'with dynamic id' do
24
+ subject { described_class.new(env, id: lambda { |env| env['PIXEL_ID'] }).render }
25
+
26
+ it 'will push the tracking events to the queue' do
27
+ expect(subject).to match(%r{fbq\('init', 'DYNAMIC_PIXEL_ID'\)})
28
+ end
29
+
30
+ it 'will add the noscript fallback' do
31
+ expect(subject).to match(%r{https://www.facebook.com/tr\?id=DYNAMIC_PIXEL_ID&ev=PageView&noscript=1})
32
+ end
33
+ end
34
+
23
35
  describe 'with events' do
24
36
  def env
25
37
  {
@@ -53,28 +53,24 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
53
53
  end
54
54
 
55
55
  describe '#tracker_options' do
56
- before do
57
- stub_const("#{described_class}::ALLOWED_TRACKER_OPTIONS", [:some_option])
58
- end
59
-
60
56
  context 'with an allowed option configured with a static value' do
61
- subject { described_class.new(env, { some_option: 'value' }) }
57
+ subject { described_class.new(env, { user_id: 'value' }) }
62
58
 
63
59
  it 'returns hash with option set' do
64
- expect(subject.tracker_options).to eql ({ someOption: 'value' })
60
+ expect(subject.tracker_options).to eql ({ userId: 'value' })
65
61
  end
66
62
  end
67
63
 
68
64
  context 'with an allowed option configured with a block' do
69
- subject { described_class.new(env, { some_option: lambda { |env| return env[:misc] } }) }
65
+ subject { described_class.new(env, { user_id: lambda { |env| return env[:misc] } }) }
70
66
 
71
67
  it 'returns hash with option set' do
72
- expect(subject.tracker_options).to eql ({ someOption: 'foobar' })
68
+ expect(subject.tracker_options).to eql ({ userId: 'foobar' })
73
69
  end
74
70
  end
75
71
 
76
72
  context 'with an allowed option configured with a block returning nil' do
77
- subject { described_class.new(env, { some_option: lambda { |env| return env[:non_existing_key] } }) }
73
+ subject { described_class.new(env, { user_id: lambda { |env| return env[:non_existing_key] } }) }
78
74
 
79
75
  it 'returns an empty hash' do
80
76
  expect(subject.tracker_options).to eql ({})
@@ -192,7 +188,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
192
188
  describe "with custom domain" do
193
189
  subject { described_class.new(env, tracker: 'somebody', cookie_domain: "railslabs.com").render }
194
190
 
195
- it "will show asyncronous tracker with cookieDomain" do
191
+ it "will show asynchronous tracker with cookieDomain" do
196
192
  expect(subject).to match(%r{ga\('create', 'somebody', {\"cookieDomain\":\"railslabs.com\"}\)})
197
193
  expect(subject).to match(%r{ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)})
198
194
  end
@@ -201,7 +197,7 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
201
197
  describe "with user_id tracking" do
202
198
  subject { described_class.new(env, tracker: 'somebody', user_id: lambda { |env| return env[:user_id] } ).render }
203
199
 
204
- it "will show asyncronous tracker with userId" do
200
+ it "will show asynchronous tracker with userId" do
205
201
  expect(subject).to match(%r{ga\('create', 'somebody', {\"userId\":\"123\"}\)})
206
202
  expect(subject).to match(%r{ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)})
207
203
  end
@@ -239,6 +235,14 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
239
235
  end
240
236
  end
241
237
 
238
+ describe "with optimize" do
239
+ subject { described_class.new(env, tracker: 'happy', optimize: 'GTM-1234').render }
240
+
241
+ it "will require the optimize plugin with container ID" do
242
+ expect(subject).to match(%r{ga\('require', 'GTM-1234'\)})
243
+ end
244
+ end
245
+
242
246
  describe "with anonymizeIp" do
243
247
  subject { described_class.new(env, tracker: 'happy', anonymize_ip: true).render }
244
248
 
@@ -0,0 +1,38 @@
1
+ RSpec.describe Rack::Tracker::Handler do
2
+ def env
3
+ { misc: 'foobar' }
4
+ end
5
+
6
+ describe '#tracker_options' do
7
+ context 'without overriding allowed_tracker_options' do
8
+ subject { described_class.new(env, { some_option: 'value' }) }
9
+
10
+ it 'returns an empty hash' do
11
+ expect(subject.tracker_options).to eql ({})
12
+ end
13
+ end
14
+
15
+ context 'with overridden allowed_tracker_options' do
16
+ subject do
17
+ handler = described_class.new(env, {
18
+ static_option: 'value',
19
+ dynamic_option: lambda { |env| return env[:misc] },
20
+ dynamic_nil_option: lambda { |env| return env[:non_existent_key] },
21
+ non_allowed_option: 'value'
22
+ })
23
+
24
+ handler.allowed_tracker_options =
25
+ [:static_option, :dynamic_option, :dynamic_nil_option]
26
+
27
+ handler
28
+ end
29
+
30
+ it 'evaluates dynamic options, rejecting nonallowed and nil ones' do
31
+ expect(subject.tracker_options).to eql ({
32
+ static_option: 'value',
33
+ dynamic_option: 'foobar'
34
+ })
35
+ end
36
+ end
37
+ end
38
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rack-tracker
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.5.0
4
+ version: 1.6.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lars Brillert
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2017-10-23 00:00:00.000000000 Z
12
+ date: 2018-03-27 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -202,6 +202,7 @@ files:
202
202
  - spec/handler/google_adwords_conversion_spec.rb
203
203
  - spec/handler/google_analytics_spec.rb
204
204
  - spec/handler/google_tag_manager_spec.rb
205
+ - spec/handler/handler_spec.rb
205
206
  - spec/handler/hotjar_spec.rb
206
207
  - spec/handler/vwo_spec.rb
207
208
  - spec/handler/zanox_spec.rb
@@ -245,7 +246,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
245
246
  version: '0'
246
247
  requirements: []
247
248
  rubyforge_project:
248
- rubygems_version: 2.4.5.1
249
+ rubygems_version: 2.6.14
249
250
  signing_key:
250
251
  specification_version: 4
251
252
  summary: Tracking made easy
@@ -264,6 +265,7 @@ test_files:
264
265
  - spec/handler/google_adwords_conversion_spec.rb
265
266
  - spec/handler/google_analytics_spec.rb
266
267
  - spec/handler/google_tag_manager_spec.rb
268
+ - spec/handler/handler_spec.rb
267
269
  - spec/handler/hotjar_spec.rb
268
270
  - spec/handler/vwo_spec.rb
269
271
  - spec/handler/zanox_spec.rb