rack-tracker 0.4.0 → 0.4.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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 06a5db11fbd86405523dbc25c7be6f8b81f2149d
4
- data.tar.gz: 900ce6c698fe6db41c3cf073bf3c523e3056a366
3
+ metadata.gz: 656cd1cec1764543d2ab1814545365c34fc143b9
4
+ data.tar.gz: e801a731569b709bbe9ab85273c047a36e9be3ba
5
5
  SHA512:
6
- metadata.gz: 300d2b933c171c031439480702b5e64cf824d25fc8d4e2007d6eb2d09d9852447306b5a56621b520367b20bcbafeafc967cd0ac61f04a28faa24b0e02a680202
7
- data.tar.gz: 4f2e384af4d3a3da6fd48f2210f11a92c37b31adb156f47cea6f104743720717f8df2a05965c2935cd5456ba59820dd8c4049f4d985b78caa572e06210d8e87d
6
+ metadata.gz: 3151dfd25013fc27de6cdb6dea1659164d2acb9541fbb128d98e2cc0b53f7dd25fd91d09c1f540a0f3142547068edc90d2374a46a7d2dd4ef2ef27425e192f05
7
+ data.tar.gz: ca4f109a8821ab137328b4c2f402e2e793d52882b3566ba128727049e36cc29dd68cd5ee9ada73db452eee08b972370544918c679380674c185cfffd01cc70e5
data/CHANGELOG.md CHANGED
@@ -1,4 +1,6 @@
1
- # master
1
+ # 0.4.1
2
+
3
+ * [ENHANCEMENT] support zanox mastertag and tracking events
2
4
 
3
5
  # 0.4.0
4
6
 
data/README.md CHANGED
@@ -25,6 +25,8 @@ but to get you started we're shipping support for the following services out of
25
25
  * [Facebook](#facebook)
26
26
  * [Visual Website Optimizer (VWO)](#visual-website-optimizer-vwo)
27
27
  * [GoSquared](#gosquared)
28
+ * [Criteo](#criteo)
29
+ * [Zanox](#zanox)
28
30
 
29
31
 
30
32
  ## Installation
@@ -328,6 +330,8 @@ It will render the following to the site source:
328
330
 
329
331
  [Criteo](http://www.criteo.com/) retargeting service.
330
332
 
333
+ #### Basic configuration
334
+
331
335
  ```
332
336
  config.middleware.use(Rack::Tracker) do
333
337
  handler :criteo, { set_account: '1234' }
@@ -335,13 +339,85 @@ end
335
339
  ```
336
340
 
337
341
  Other global criteo handler options are:
338
- * `setCustomerId` (value can be a static or a dynamic, e.g. `lambda { |env| env['rack.session']['user_id'] }`)
339
- * `setSiteType` (`m`, `t`, `d`)
342
+ * `set_customer_id: 'x'`
343
+ * `set_site_type: 'd'` - possible values are `m` (mobile), `t` (tablet), `d` (desktop)
344
+
345
+ Option values can be either static or dynamic by providing a lambda being reevaluated for each request, e.g. `set_customer_id: lambda { |env| env['rack.session']['user_id'] }`
346
+
347
+ #### Tracking events
348
+
349
+ This will track a basic event:
350
+
351
+ ```
352
+ def show
353
+ tracker do |t|
354
+ t.criteo :view_item, { item: 'P0001' }
355
+ end
356
+ end
357
+ ```
358
+
359
+ This will render to the follwing code in the JS:
360
+
361
+ ```
362
+ window.criteo_q.push({"event": "viewItem", "item": "P001" });
363
+ ```
364
+
365
+ The first argument for `t.criteo` is always the criteo event (e.g. `:view_item`, `:view_list`, `:track_transaction`, `:view_basket`) and the second argument are additional properties for the event.
366
+
367
+ Another example
368
+
369
+ ```
370
+ t.criteo :track_transaction, { id: 'id', item: { id: "P0038", price: "6.54", quantity: 1 } }
371
+ ```
372
+
373
+ ### Zanox
374
+
375
+ [Zanox](http://www.zanox.com/us/)
376
+
377
+ #### Basic Configuration
378
+
379
+ ```
380
+ config.middleware.use(Rack::Tracker) do
381
+ handler :zanox, { account_id: '1234' }
382
+ end
383
+ ```
384
+
385
+ #### Mastertag
386
+
387
+ This is an example of a mastertag:
388
+
389
+ ```
390
+ def show
391
+ tracker do |t|
392
+ t.zanox :mastertag, { id: "25GHTE9A07DF67DFG90T" }
393
+ end
394
+ end
395
+ ```
396
+
397
+ This will render to the follwing code in the JS:
398
+
399
+ ```
400
+ window._zx.push({"id": "25GHTE9A07DF67DFG90T"});
401
+ ```
402
+
403
+ #### Conversion tracking
404
+
405
+ This is an example of a lead event:
406
+
407
+ ```
408
+ def show
409
+ tracker do |t|
410
+ t.zanox :track, { order_i_d: 'DEFC-4321'}
411
+ end
412
+ end
413
+ ```
414
+
415
+ This is an example of a sale event:
340
416
 
341
417
  ```
342
418
  def show
343
419
  tracker do |t|
344
- t.criteo :track, { event: 'viewItem', item: 'P0001' }
420
+ t.zanox :track, { customer_i_d: '123456', order_i_d: 'DEFC-4321', currency_symbol: 'EUR', total_price: '150.00'}
345
421
  end
346
422
  end
347
423
  ```
@@ -0,0 +1,36 @@
1
+ class Rack::Tracker::Criteo < Rack::Tracker::Handler
2
+
3
+ TRACKER_EVENTS = {
4
+ # event name => event key name, e.g. { event: 'setSiteType', type: '' }
5
+ set_site_type: :type,
6
+ set_account: :account,
7
+ set_customer_id: :id
8
+ }
9
+
10
+ class Event < OpenStruct
11
+ def write
12
+ to_h.to_json
13
+ end
14
+ end
15
+
16
+ self.position = :body
17
+
18
+ # global events (setSiteType, setAccount, ...) for each tracker instance
19
+ def tracker_events
20
+ @tracker_events ||= [].tap do |tracker_events|
21
+ options.slice(*TRACKER_EVENTS.keys).each do |key, value|
22
+ if option_value = value.respond_to?(:call) ? value.call(env) : value
23
+ tracker_events << Event.new(:event => "#{key}".camelize(:lower), TRACKER_EVENTS[key] => "#{option_value}")
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ def render
30
+ Tilt.new( File.join( File.dirname(__FILE__), 'template', 'criteo.erb') ).render(self)
31
+ end
32
+
33
+ def self.track(name, event_name, event_args = {})
34
+ { name.to_s => [{ 'class_name' => 'Event', 'event' => event_name.to_s.camelize(:lower) }.merge(event_args)] }
35
+ end
36
+ end
@@ -0,0 +1,9 @@
1
+ <% if events.any? %>
2
+ <script type='text/javascript' src='//static.criteo.net/js/ld/ld.js' async='true'></script>
3
+ <script type='text/javascript'>
4
+ window.criteo_q = window.criteo_q || [];
5
+ <% (tracker_events + events).each do |event| %>
6
+ window.criteo_q.push(<%= event.write %>);
7
+ <% end %>
8
+ </script>
9
+ <% end %>
@@ -23,13 +23,26 @@ class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler
23
23
 
24
24
  class EnhancedEcommerce < OpenStruct
25
25
  def write
26
- ["ec:#{self.type}", self.to_h.except(:type).compact.stringify_values].to_json.gsub(/\[|\]/, '')
26
+ hash = self.to_h
27
+ label = hash[:label]
28
+ attributes = hash.except(:label, :type).compact.stringify_values
29
+
30
+ [
31
+ "ec:#{self.type}",
32
+ label,
33
+ attributes.empty? ? nil : attributes
34
+ ].compact.to_json.gsub(/\[|\]/, '')
27
35
  end
28
36
  end
29
37
 
30
38
  class Ecommerce < OpenStruct
31
39
  def write
32
- ["ecommerce:#{self.type}", self.to_h.except(:type).compact.stringify_values].to_json.gsub(/\[|\]/, '')
40
+ attributes = self.to_h.except(:type).compact.stringify_values
41
+
42
+ [
43
+ "ecommerce:#{self.type}",
44
+ attributes
45
+ ].to_json.gsub(/\[|\]/, '')
33
46
  end
34
47
  end
35
48
 
@@ -14,7 +14,7 @@
14
14
  <% if options[:advertising] %>
15
15
  ga('require', 'displayfeatures');
16
16
  <% end %>
17
- <% if options[:enhanced_ecommerce] && enhanced_ecommerce_events.any? %>
17
+ <% if options[:enhanced_ecommerce] %>
18
18
  ga('require', 'ec');
19
19
  <% end %>
20
20
  <% if options[:ecommerce] %>
@@ -1,5 +1,5 @@
1
1
  module Rack
2
2
  class Tracker
3
- VERSION = '0.4.0'
3
+ VERSION = '0.4.1'
4
4
  end
5
5
  end
@@ -1,4 +1,4 @@
1
- class Vwo < Rack::Tracker::Handler
1
+ class Rack::Tracker::Vwo < Rack::Tracker::Handler
2
2
  def render
3
3
  Tilt.new( File.join( File.dirname(__FILE__), 'template', 'vwo.erb') ).render(self)
4
4
  end
@@ -0,0 +1,26 @@
1
+ <% if mastertag %>
2
+
3
+ <div class="zx_<%= mastertag.id %> zx_mediaslot">
4
+ <script type="text/javascript">
5
+ window._zx = window._zx || [];
6
+ window._zx.push({"id": "<%= mastertag.id %>"});
7
+ (function(d) {
8
+ var s = d.createElement("script"); s.async = true;
9
+ s.src = (d.location.protocol == "https:" ? "https:" : "http:") + "//static.zanox.com/scripts/zanox.js";
10
+ var a = d.getElementsByTagName("script")[0]; a.parentNode.insertBefore(s, a);
11
+ }(document));
12
+ </script>
13
+ </div>
14
+
15
+ <% end %>
16
+
17
+ <% tracking_events.each do |event| %>
18
+
19
+ <script type="text/javascript" src="https://ad.zanox.com/ppl/?<%= options[:account_id] %>&mode=[[1]]&<%= event.write %>">
20
+ </script>
21
+
22
+ <noscript>
23
+ <img src="https://ad.zanox.com/ppl/?<%= options[:account_id] %>&mode=[[2]]&<%= event.write %>" width="1" height="1" />
24
+ </noscript>
25
+
26
+ <% end %>
@@ -0,0 +1,37 @@
1
+ class Rack::Tracker::Zanox < Rack::Tracker::Handler
2
+
3
+ # name of the handler
4
+ # everything after is passed as options
5
+ class Mastertag < OpenStruct
6
+ end
7
+
8
+ class Track < OpenStruct
9
+ # Example: OrderID=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[23.40]]
10
+ def write
11
+ to_h.map do |k,v|
12
+ "#{k.to_s.camelize}=[[#{v}]]"
13
+ end.join('&')
14
+ end
15
+ end
16
+
17
+ self.position = :body
18
+
19
+ def mastertag
20
+ # First event should be stronger, e.g. one signs up and gets redirected to homepage
21
+ # "sign up" should be tracked instead of "view homepage"
22
+ events.select{ |event| event.class.to_s.demodulize == 'Mastertag' }.first
23
+ end
24
+
25
+ def tracking_events
26
+ events.select{ |event| event.class.to_s.demodulize == 'Track' }
27
+ end
28
+
29
+ def render
30
+ Tilt.new( File.join( File.dirname(__FILE__), 'template', 'zanox.erb') ).render(self)
31
+ end
32
+
33
+ # this is called with additional arguments to t.zanox
34
+ def self.track(name, *event)
35
+ { name.to_s => [event.last.merge('class_name' => event.first.to_s.capitalize)] }
36
+ end
37
+ end
data/lib/rack/tracker.rb CHANGED
@@ -17,6 +17,8 @@ require "rack/tracker/google_adwords_conversion/google_adwords_conversion"
17
17
  require "rack/tracker/facebook/facebook"
18
18
  require "rack/tracker/vwo/vwo"
19
19
  require "rack/tracker/go_squared/go_squared"
20
+ require "rack/tracker/criteo/criteo"
21
+ require "rack/tracker/zanox/zanox"
20
22
 
21
23
  module Rack
22
24
  class Tracker
data/rack-tracker.gemspec CHANGED
@@ -18,14 +18,14 @@ Gem::Specification.new do |spec|
18
18
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
19
  spec.require_paths = ["lib"]
20
20
 
21
- spec.add_dependency "rack", ">= 1.4.0"
22
- spec.add_dependency "tilt", "~> 1.4.1"
21
+ spec.add_dependency "rack", ">= 1.4"
22
+ spec.add_dependency "tilt", ">= 1.4"
23
23
  spec.add_dependency 'activesupport', '>= 3.0'
24
24
 
25
25
  spec.add_development_dependency 'actionpack', '>= 3.0'
26
26
  spec.add_development_dependency "bundler", "~> 1.5"
27
27
  spec.add_development_dependency "rake"
28
- spec.add_development_dependency "rspec", "~> 3.0.0"
29
- spec.add_development_dependency "capybara", "~> 2.4.1"
28
+ spec.add_development_dependency "rspec", "~> 3.2"
29
+ spec.add_development_dependency "capybara", "~> 2.4"
30
30
  spec.add_development_dependency "pry"
31
31
  end
@@ -0,0 +1,122 @@
1
+ RSpec.describe Rack::Tracker::Criteo do
2
+
3
+ describe Rack::Tracker::Criteo::Event do
4
+
5
+ subject { described_class.new(event: "viewItem", item: 'P001') }
6
+
7
+ describe '#write' do
8
+ specify { expect(subject.write).to eq("{\"event\":\"viewItem\",\"item\":\"P001\"}") }
9
+ end
10
+ end
11
+
12
+ def env
13
+ {}
14
+ end
15
+
16
+ it 'will be placed in the body' do
17
+ expect(described_class.position).to eq(:body)
18
+ expect(described_class.new(env).position).to eq(:body)
19
+ end
20
+
21
+ describe '#render' do
22
+ context 'with events' do
23
+ let(:env) {
24
+ {
25
+ 'tracker' => {
26
+ 'criteo' =>
27
+ [
28
+ {
29
+ 'event' => 'viewItem',
30
+ 'item' => 'P001',
31
+ 'class_name' => 'Event'
32
+ }
33
+ ]
34
+ }
35
+ }
36
+ }
37
+
38
+ subject { described_class.new(env).render }
39
+
40
+ it 'will push the tracking events to the queue' do
41
+ expect(subject).to include 'window.criteo_q.push({"event":"viewItem","item":"P001"});'
42
+ end
43
+ end
44
+
45
+ context 'without events' do
46
+ let(:env) {
47
+ {
48
+ 'tracker' => {
49
+ 'criteo' => []
50
+ }
51
+ }
52
+ }
53
+
54
+ subject { described_class.new(env, { user_id: ->(env){ '123' } }).render }
55
+
56
+ it 'should render nothing' do
57
+ expect(subject).to eql ""
58
+ end
59
+ end
60
+ end
61
+
62
+ describe '#tracker_events' do
63
+ subject { described_class.new(env, options) }
64
+
65
+ context 'nil value' do
66
+ let(:options) { { set_account: nil } }
67
+
68
+ it 'should ignore option' do
69
+ expect(subject.tracker_events).to match_array []
70
+ end
71
+ end
72
+
73
+ context 'static string value' do
74
+ let(:options) { { set_account: '1234' } }
75
+
76
+ it 'should set the value' do
77
+ expect(subject.tracker_events).to match_array [
78
+ Rack::Tracker::Criteo::Event.new(event: 'setAccount', account: '1234')
79
+ ]
80
+ end
81
+ end
82
+
83
+ context 'static integer value' do
84
+ let(:options) { { set_customer_id: 1234 } }
85
+
86
+ it 'should set the value as string' do
87
+ expect(subject.tracker_events).to match_array [
88
+ Rack::Tracker::Criteo::Event.new(event: 'setCustomerId', id: '1234')
89
+ ]
90
+ end
91
+ end
92
+
93
+ context 'unsupported option' do
94
+ let(:options) { { unsupported: "option" } }
95
+
96
+ subject { described_class.new(env, options) }
97
+
98
+ it 'should ignore the option' do
99
+ expect(subject.tracker_events).to match_array []
100
+ end
101
+ end
102
+
103
+ context 'proc returning value' do
104
+ let(:options) { { set_site_type: ->(env){ 'm' } } }
105
+
106
+ it 'should set the value' do
107
+ expect(subject.tracker_events).to match_array [
108
+ Rack::Tracker::Criteo::Event.new(event: 'setSiteType', type: 'm')
109
+ ]
110
+ end
111
+ end
112
+
113
+ context 'proc returning nil' do
114
+ let(:options) { { set_account: ->(env){ nil } } }
115
+
116
+ it 'should ignore the option' do
117
+ expect(subject.tracker_events).to match_array []
118
+ end
119
+ end
120
+ end
121
+
122
+ end
@@ -91,6 +91,8 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
91
91
  end
92
92
 
93
93
  describe "with events" do
94
+ subject { described_class.new(env, tracker: 'somebody').render }
95
+
94
96
  describe "default" do
95
97
  def env
96
98
  {'tracker' => {
@@ -100,7 +102,6 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
100
102
  }}
101
103
  end
102
104
 
103
- subject { described_class.new(env, tracker: 'somebody').render }
104
105
  it "will show events" do
105
106
  expect(subject).to match(%r{ga\(\"send\",{\"hitType\":\"event\",\"eventCategory\":\"Users\",\"eventAction\":\"Login\",\"eventLabel\":\"Standard\"}\)})
106
107
  end
@@ -113,7 +114,6 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
113
114
  ]}}
114
115
  end
115
116
 
116
- subject { described_class.new(env, tracker: 'somebody').render }
117
117
  it "will show events with values" do
118
118
  expect(subject).to match(%r{ga\(\"send\",{\"hitType\":\"event\",\"eventCategory\":\"Users\",\"eventAction\":\"Login\",\"eventLabel\":\"Standard\",\"eventValue\":\"5\"}\)},)
119
119
  end
@@ -132,12 +132,17 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
132
132
  end
133
133
 
134
134
  subject { described_class.new(env, tracker: 'somebody', ecommerce: true).render }
135
+
135
136
  it "will add items" do
136
- expect(subject).to match(%r{ga\(\"ecommerce:addItem\",#{{id: '1234', name: 'Fluffy Pink Bunnies', sku: 'DD23444', category: 'Party Toys', price: '11.99', quantity: '1'}.to_json}})
137
+ attributes = { id: '1234', name: 'Fluffy Pink Bunnies', sku: 'DD23444', category: 'Party Toys', price: '11.99', quantity: '1' }.to_json
138
+ expect(subject).to match(%r{ga\(\"ecommerce:addItem\",#{attributes}\);})
137
139
  end
140
+
138
141
  it "will add transaction" do
139
- expect(subject).to match(%r{ga\(\"ecommerce:addTransaction\",#{{id: '1234', affiliation: 'Acme Clothing', revenue: '11.99', shipping: '5', tax: '1.29', currency: 'EUR'}.to_json}})
142
+ attributes = { id: '1234', affiliation: 'Acme Clothing', revenue: '11.99', shipping: '5', tax: '1.29', currency: 'EUR' }.to_json
143
+ expect(subject).to match(%r{ga\(\"ecommerce:addTransaction\",#{attributes}\);})
140
144
  end
145
+
141
146
  it "will submit cart" do
142
147
  expect(subject).to match(%r{ga\('ecommerce:send'\);})
143
148
  end
@@ -150,18 +155,20 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
150
155
  {'tracker' => {
151
156
  'google_analytics' => [
152
157
  { 'class_name' => 'EnhancedEcommerce', 'type' => 'addProduct', 'id' => 'P12345', 'name' => 'Android Warhol T-Shirt', 'category' => 'Apparel', 'brand' => 'Google', 'variant' => 'black', 'price' => '29.20', 'coupon' => 'APPARELSALE', 'quantity' => 1 },
153
- { 'class_name' => 'EnhancedEcommerce', 'type' => 'setAction', 'id' => 'T12345', 'affiliation' => 'Google Store - Online', 'revenue' => '37.39', 'tax' => '2.85', 'shipping' => '5.34', 'coupon' => 'SUMMER2013' }
158
+ { 'class_name' => 'EnhancedEcommerce', 'type' => 'setAction', 'label' => 'purchase' }
154
159
  ]
155
160
  }}
156
161
  end
157
162
 
158
163
  subject { described_class.new(env, tracker: 'somebody', enhanced_ecommerce: true).render }
164
+
159
165
  it "will add product" do
160
- expect(subject).to match(%r{ga\(\"ec:addProduct\",#{{id: 'P12345', name: 'Android Warhol T-Shirt', category: 'Apparel', brand: 'Google', variant: 'black', price: '29.20', coupon: 'APPARELSALE', quantity: '1'}.to_json}})
166
+ attributes = { id: 'P12345', name: 'Android Warhol T-Shirt', category: 'Apparel', brand: 'Google', variant: 'black', price: '29.20', coupon: 'APPARELSALE', quantity: '1' }.to_json
167
+ expect(subject).to match(%r{ga\(\"ec:addProduct\",#{attributes}\);})
161
168
  end
162
169
 
163
170
  it "will add action" do
164
- expect(subject).to match(%r{ga\(\"ec:setAction\",#{{id: 'T12345', affiliation: 'Google Store - Online', revenue: '37.39', tax: '2.85', shipping: '5.34', coupon: 'SUMMER2013'}.to_json}})
171
+ expect(subject).to match(%r{ga\(\"ec:setAction\",\"purchase\"\);})
165
172
  end
166
173
  end
167
174
  end
@@ -217,28 +224,10 @@ RSpec.describe Rack::Tracker::GoogleAnalytics do
217
224
  end
218
225
 
219
226
  describe "with enhanced ecommerce" do
220
- describe "without events" do
221
- subject { described_class.new(env, tracker: 'happy', enhanced_ecommerce: true).render }
227
+ subject { described_class.new(env, tracker: 'happy', enhanced_ecommerce: true).render }
222
228
 
223
- it "will require the enhanced ecommerce plugin" do
224
- expect(subject).to_not match(%r{ga\('require', 'ec'\)})
225
- end
226
- end
227
-
228
- describe "with events" do
229
- def env
230
- {'tracker' => {
231
- 'google_analytics' => [
232
- { 'class_name' => 'EnhancedEcommerce', 'type' => 'addProduct', 'id' => 'P12345', 'name' => 'Android Warhol T-Shirt', 'category' => 'Apparel', 'brand' => 'Google', 'variant' => 'black', 'price' => '29.20', 'coupon' => 'APPARELSALE', 'quantity' => 1 },
233
- ]
234
- }}
235
- end
236
-
237
- subject { described_class.new(env, tracker: 'happy', enhanced_ecommerce: true).render }
238
-
239
- it "will require the enhanced ecommerce plugin" do
240
- expect(subject).to match(%r{ga\('require', 'ec'\)})
241
- end
229
+ it "will require the enhanced ecommerce plugin" do
230
+ expect(subject).to match(%r{ga\('require', 'ec'\)})
242
231
  end
243
232
  end
244
233
 
@@ -0,0 +1,98 @@
1
+ RSpec.describe Rack::Tracker::Zanox do
2
+
3
+ describe Rack::Tracker::Zanox::Track do
4
+
5
+ subject { described_class.new(order_i_d: 'DEFC-4321', currency_symbol: 'EUR', total_price: '150.00') }
6
+
7
+ describe '#write' do
8
+ specify { expect(subject.write).to eq "OrderID=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]" }
9
+ end
10
+ end
11
+
12
+ def env
13
+ {}
14
+ end
15
+
16
+ it 'will be placed in the body' do
17
+ expect(described_class.position).to eq(:body)
18
+ expect(described_class.new(env).position).to eq(:body)
19
+ end
20
+
21
+ describe '#render a sale #tracking_event' do
22
+ context 'with events' do
23
+ let(:env) {
24
+ {
25
+ 'tracker' => {
26
+ 'zanox' =>
27
+ [
28
+ {
29
+ 'CustomerID' => '123456',
30
+ 'OrderId' => 'DEFC-4321',
31
+ 'CurrencySymbol' => 'EUR',
32
+ 'TotalPrice' => '150.00',
33
+ 'class_name' => 'Track'
34
+ }
35
+ ]
36
+ }
37
+ }
38
+ }
39
+
40
+ subject { described_class.new(env, options).render }
41
+ let(:options) { { account_id: '123456H123456' } }
42
+
43
+ it 'will display the correct tracking events' do
44
+ expect(subject).to include "https://ad.zanox.com/ppl/?123456H123456&mode=[[1]]&CustomerID=[[123456]]&OrderId=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]"
45
+ end
46
+ end
47
+ end
48
+
49
+ describe '#render a lead #tracking_event' do
50
+ context 'with events' do
51
+ let(:env) {
52
+ {
53
+ 'tracker' => {
54
+ 'zanox' =>
55
+ [
56
+ {
57
+ 'OrderId' => 'DEFC-4321',
58
+ 'class_name' => 'Track'
59
+ }
60
+ ]
61
+ }
62
+ }
63
+ }
64
+
65
+ subject { described_class.new(env, options).render }
66
+ let(:options) { { account_id: '123456H123456' } }
67
+
68
+ it 'will display the correct tracking events' do
69
+ expect(subject).to include "https://ad.zanox.com/ppl/?123456H123456&mode=[[1]]&OrderId=[[DEFC-4321]]"
70
+ end
71
+ end
72
+ end
73
+
74
+ describe '#render a #mastertag event' do
75
+ context 'with events' do
76
+ let(:env) {
77
+ {
78
+ 'tracker' => {
79
+ 'zanox' =>
80
+ [
81
+ {
82
+ 'id' => '12345678D2345',
83
+ 'class_name' => 'Mastertag'
84
+ }
85
+ ]
86
+ }
87
+ }
88
+ }
89
+
90
+ subject { described_class.new(env, options).render }
91
+ let(:options) { { account_id: '123456H123456' } }
92
+
93
+ it 'will display the correct tracking events' do
94
+ expect(subject).to include 'window._zx.push({"id": "12345678D2345"});'
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,44 @@
1
+ require 'support/capybara_app_helper'
2
+
3
+ RSpec.describe "Criteo Integration" do
4
+ before do
5
+ setup_app(action: :criteo) do |tracker|
6
+ tracker.handler(:criteo, {
7
+ set_account: '1234',
8
+ set_customer_id: ->(env){ '4711' },
9
+ set_site_type: ->(env){ 'm' }
10
+ })
11
+ end
12
+ visit '/'
13
+ end
14
+
15
+ subject { page }
16
+
17
+ it 'should include all the events' do
18
+ # tracker_events
19
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setAccount\",\"account\":\"1234\"});"
20
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setSiteType\",\"type\":\"m\"});"
21
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setCustomerId\",\"id\":\"4711\"});"
22
+
23
+ # events
24
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"viewItem\",\"item\":\"P001\"});"
25
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"viewList\",\"item\":[\"P001\",\"P002\"]});"
26
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"trackTransaction\",\"id\":\"id\",\"item\":{\"id\":\"P0038\",\"price\":\"6.54\",\"quantity\":1}});"
27
+ expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"viewBasket\",\"item\":[{\"id\":\"P001\",\"price\":\"6.54\",\"quantity\":1},{\"id\":\"P0038\",\"price\":\"2.99\",\"quantity\":1}]});"
28
+ end
29
+
30
+ describe 'adjust tracker position via options' do
31
+ before do
32
+ setup_app(action: :criteo) do |tracker|
33
+ tracker.handler :criteo, { set_account: '1234', position: :head }
34
+ end
35
+ visit '/'
36
+ end
37
+
38
+ it "will be placed in the specified tag" do
39
+ expect(page.find("body")).to_not have_content('criteo')
40
+ expect(page.find("head")).to have_content("{\"event\":\"setAccount\",\"account\":\"1234\"}")
41
+ end
42
+
43
+ end
44
+ end
@@ -28,6 +28,5 @@ RSpec.describe "Google Analytics Integration" do
28
28
  expect(page.find("head")).to_not have_content('U-XXX-Y')
29
29
  expect(page.find("body")).to have_content('ga("ecommerce:addItem",{"id":"1234","name":"Fluffy Pink Bunnies","sku":"DD23444","category":"Party Toys","price":"11.99","quantity":"1"})')
30
30
  end
31
-
32
31
  end
33
32
  end
@@ -0,0 +1,25 @@
1
+ require 'support/capybara_app_helper'
2
+
3
+ RSpec.describe "Zanox Integration" do
4
+
5
+ before do
6
+ setup_app(action: :zanox) do |tracker|
7
+ tracker.handler(:zanox, { account_id: '12345H123456789' } )
8
+ end
9
+
10
+ visit '/'
11
+ end
12
+
13
+ subject { page }
14
+
15
+ it 'should include the mastertag event' do
16
+ expect(page.find("body")).to have_content "window._zx.push({\"id\": \"blurg567\"});"
17
+ end
18
+
19
+ it 'should include the track event' do
20
+ expect(page).to have_xpath "//script[contains(@src,'12345H123456789&mode=[[1]]&CustomerID=[[123456]]&OrderID=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]')]"
21
+ end
22
+ end
23
+
24
+
25
+
@@ -64,4 +64,22 @@ class MetalController < ActionController::Metal
64
64
  end
65
65
  render "metal/index"
66
66
  end
67
+
68
+ def criteo
69
+ tracker do |t|
70
+ t.criteo :view_item, { item: 'P001' }
71
+ t.criteo :view_list, { item: ['P001', 'P002'] }
72
+ t.criteo :track_transaction, { id: 'id', item: { id: "P0038", price:"6.54", quantity:1 } }
73
+ t.criteo :view_basket, { item: [{ id: "P001", price:"6.54", quantity:1 }, { id: "P0038", price:"2.99", quantity:1 }] }
74
+ end
75
+ render 'metal/index'
76
+ end
77
+
78
+ def zanox
79
+ tracker do |t|
80
+ t.zanox :mastertag, { id: 'blurg567'}
81
+ t.zanox :track, { customer_i_d: '123456', order_i_d: 'DEFC-4321', currency_symbol: 'EUR', total_price: '150.00'}
82
+ end
83
+ render 'metal/index'
84
+ end
67
85
  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: 0.4.0
4
+ version: 0.4.1
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: 2015-03-23 00:00:00.000000000 Z
12
+ date: 2015-05-22 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
@@ -17,28 +17,28 @@ dependencies:
17
17
  requirements:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
- version: 1.4.0
20
+ version: '1.4'
21
21
  type: :runtime
22
22
  prerelease: false
23
23
  version_requirements: !ruby/object:Gem::Requirement
24
24
  requirements:
25
25
  - - ">="
26
26
  - !ruby/object:Gem::Version
27
- version: 1.4.0
27
+ version: '1.4'
28
28
  - !ruby/object:Gem::Dependency
29
29
  name: tilt
30
30
  requirement: !ruby/object:Gem::Requirement
31
31
  requirements:
32
- - - "~>"
32
+ - - ">="
33
33
  - !ruby/object:Gem::Version
34
- version: 1.4.1
34
+ version: '1.4'
35
35
  type: :runtime
36
36
  prerelease: false
37
37
  version_requirements: !ruby/object:Gem::Requirement
38
38
  requirements:
39
- - - "~>"
39
+ - - ">="
40
40
  - !ruby/object:Gem::Version
41
- version: 1.4.1
41
+ version: '1.4'
42
42
  - !ruby/object:Gem::Dependency
43
43
  name: activesupport
44
44
  requirement: !ruby/object:Gem::Requirement
@@ -101,28 +101,28 @@ dependencies:
101
101
  requirements:
102
102
  - - "~>"
103
103
  - !ruby/object:Gem::Version
104
- version: 3.0.0
104
+ version: '3.2'
105
105
  type: :development
106
106
  prerelease: false
107
107
  version_requirements: !ruby/object:Gem::Requirement
108
108
  requirements:
109
109
  - - "~>"
110
110
  - !ruby/object:Gem::Version
111
- version: 3.0.0
111
+ version: '3.2'
112
112
  - !ruby/object:Gem::Dependency
113
113
  name: capybara
114
114
  requirement: !ruby/object:Gem::Requirement
115
115
  requirements:
116
116
  - - "~>"
117
117
  - !ruby/object:Gem::Version
118
- version: 2.4.1
118
+ version: '2.4'
119
119
  type: :development
120
120
  prerelease: false
121
121
  version_requirements: !ruby/object:Gem::Requirement
122
122
  requirements:
123
123
  - - "~>"
124
124
  - !ruby/object:Gem::Version
125
- version: 2.4.1
125
+ version: '2.4'
126
126
  - !ruby/object:Gem::Dependency
127
127
  name: pry
128
128
  requirement: !ruby/object:Gem::Requirement
@@ -156,6 +156,8 @@ files:
156
156
  - Rakefile
157
157
  - lib/rack/tracker.rb
158
158
  - lib/rack/tracker/controller.rb
159
+ - lib/rack/tracker/criteo/criteo.rb
160
+ - lib/rack/tracker/criteo/template/criteo.erb
159
161
  - lib/rack/tracker/extensions.rb
160
162
  - lib/rack/tracker/facebook/facebook.rb
161
163
  - lib/rack/tracker/facebook/template/facebook.erb
@@ -173,18 +175,23 @@ files:
173
175
  - lib/rack/tracker/version.rb
174
176
  - lib/rack/tracker/vwo/template/vwo.erb
175
177
  - lib/rack/tracker/vwo/vwo.rb
178
+ - lib/rack/tracker/zanox/template/zanox.erb
179
+ - lib/rack/tracker/zanox/zanox.rb
176
180
  - rack-tracker.gemspec
177
181
  - spec/fixtures/another_handler.erb
178
182
  - spec/fixtures/dummy.erb
179
183
  - spec/fixtures/track_all_the_things.erb
180
184
  - spec/fixtures/views/layouts/application.html.erb
181
185
  - spec/fixtures/views/metal/index.html.erb
186
+ - spec/handler/criteo_spec.rb
182
187
  - spec/handler/facebook_spec.rb
183
188
  - spec/handler/go_squared_spec.rb
184
189
  - spec/handler/google_adwords_conversion_spec.rb
185
190
  - spec/handler/google_analytics_spec.rb
186
191
  - spec/handler/google_tag_manager_spec.rb
187
192
  - spec/handler/vwo_spec.rb
193
+ - spec/handler/zanox_spec.rb
194
+ - spec/integration/criteo_integration_spec.rb
188
195
  - spec/integration/facebook_integration_spec.rb
189
196
  - spec/integration/go_squared_integration_spec.rb
190
197
  - spec/integration/google_adwords_conversion_integration_spec.rb
@@ -192,6 +199,7 @@ files:
192
199
  - spec/integration/google_tag_manager_integration_spec.rb
193
200
  - spec/integration/rails_integration_spec.rb
194
201
  - spec/integration/vwo_integration_spec.rb
202
+ - spec/integration/zanox_integration_spec.rb
195
203
  - spec/spec_helper.rb
196
204
  - spec/support/capybara_app_helper.rb
197
205
  - spec/support/fake_handler.rb
@@ -220,7 +228,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
220
228
  version: '0'
221
229
  requirements: []
222
230
  rubyforge_project:
223
- rubygems_version: 2.4.3
231
+ rubygems_version: 2.2.2
224
232
  signing_key:
225
233
  specification_version: 4
226
234
  summary: Tracking made easy
@@ -230,12 +238,15 @@ test_files:
230
238
  - spec/fixtures/track_all_the_things.erb
231
239
  - spec/fixtures/views/layouts/application.html.erb
232
240
  - spec/fixtures/views/metal/index.html.erb
241
+ - spec/handler/criteo_spec.rb
233
242
  - spec/handler/facebook_spec.rb
234
243
  - spec/handler/go_squared_spec.rb
235
244
  - spec/handler/google_adwords_conversion_spec.rb
236
245
  - spec/handler/google_analytics_spec.rb
237
246
  - spec/handler/google_tag_manager_spec.rb
238
247
  - spec/handler/vwo_spec.rb
248
+ - spec/handler/zanox_spec.rb
249
+ - spec/integration/criteo_integration_spec.rb
239
250
  - spec/integration/facebook_integration_spec.rb
240
251
  - spec/integration/go_squared_integration_spec.rb
241
252
  - spec/integration/google_adwords_conversion_integration_spec.rb
@@ -243,6 +254,7 @@ test_files:
243
254
  - spec/integration/google_tag_manager_integration_spec.rb
244
255
  - spec/integration/rails_integration_spec.rb
245
256
  - spec/integration/vwo_integration_spec.rb
257
+ - spec/integration/zanox_integration_spec.rb
246
258
  - spec/spec_helper.rb
247
259
  - spec/support/capybara_app_helper.rb
248
260
  - spec/support/fake_handler.rb