ga_events 2.1.0 → 4.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 205433864fd2efabf0cf787da0be314c9bc48fd644773d8df29f6ca66327ba43
4
- data.tar.gz: fa05cd8ee83f4b73fa23a3562e19d0ec2fcbb1a684c7ee49c357d0e78a54c3a7
3
+ metadata.gz: af13dc202f2b24f7fa7ba45345d90fea5158e4b50c5e55fbb6bbc68752c6083b
4
+ data.tar.gz: bbd3f2173bba05a2ce2d1dc4315a288b83b469810327dd2cbccd30799f6e595a
5
5
  SHA512:
6
- metadata.gz: 472515474d12c53c4f3d43b8c577a45776ed983149c8347940294ca1128e907d101f48054eee7c00468cafdc3f1e7aba33c3cdfa08f43d81ebc0bd25c91f884f
7
- data.tar.gz: 483bbdb595f20e852ec8f6b74366251e91e84b76cde7454721136d42cfd31586e36c88bd015ac6cbf321a673e2779e5f29b96cb345924d7606f648e36da67aa9
6
+ metadata.gz: cb529a2794580ae3c52a2a226c620b94ba79b278dc1171fcda5a27bdc511901b95f2d9243028285484a2a8d66af2feeb6a40539e82e5def320ed0974bf62e74e
7
+ data.tar.gz: 9b9adf95d667f066198b222cb45e233b83b03420e84a6743cd93cfba70b90bbaed7982b070d552f37e69c148a21800159a18223af176d6dac955049fe8f02971
data/.gitignore CHANGED
@@ -1,5 +1,8 @@
1
1
  *.gem
2
+ bin/rspec
2
3
  .bundle
3
4
  Gemfile.lock
4
5
  pkg
5
6
  vendor
7
+ .ruby-version
8
+ .tools-version
data/CHANGELOG.md CHANGED
@@ -40,7 +40,7 @@ The format suggested at http://keepachangelog.com/ is used.
40
40
  - Ensure category, action and label do not include any umlauts or ß chars
41
41
  - Fixed an error where events are remaining after a redirect
42
42
 
43
- ## 2.0.0 - 2018-04-03
43
+ ## 2.0.0 - 2020-11-20
44
44
 
45
45
  ### Removed
46
46
  - Support for rubies < 2.3
@@ -48,3 +48,45 @@ The format suggested at http://keepachangelog.com/ is used.
48
48
 
49
49
  ### Added
50
50
  - Compatibility for Rails 5
51
+
52
+ ## 2.1.0 - 2021-09-07
53
+
54
+ ### Added
55
+ - Optional user consent flag to prevent event flushing until consent was given
56
+
57
+ ## 3.0.0 - 2022-01-10
58
+
59
+ ### Added
60
+ - Universal Analytics Adapter can be configured to use `gtag.js` instead of
61
+ `analytics.js` event syntax
62
+ - [Breaking] The constructor interface has changed due to more configuration
63
+ options that differ between `analytics.js` and `gtag.js`.
64
+ - Universal Analytics Adapter can be configured to use a custom name for the
65
+ analytics object (defaults to `window.ga()` for `analytics.js` and
66
+ `window.gtag()` for `gtag.js`)
67
+
68
+ ## 4.0.0 - 2023-08-xx
69
+
70
+ ### Added
71
+ - Support for GA4 using the `GTagAdapter`
72
+
73
+ ### Breaking
74
+ - Dropped support for older rubies. The gem requires at least ruby 3.2 now
75
+ - UniversalAnalyticsAdapter and GoogleAnalyticsAdapter removed
76
+ - The `GaEvent::Event` constructor changed to conform to the new newer
77
+ GA4 event interface.
78
+
79
+ ```ruby
80
+ # 3.x and before
81
+ GaEvents::Event.new('category', 'action', 'label', 'value')
82
+
83
+ # 4.x onwards
84
+ GaEvents::Event.new('event_name', {
85
+ custom_dimension: 'xxx',
86
+ custom_dimension2: 'yyy'
87
+ })
88
+ ```
89
+ - Events that should be kept on redirects are no longer mixed into rails
90
+ flashes. Redirect events are stored inside a custom rack session variable
91
+ instead.
92
+
data/Gemfile CHANGED
@@ -7,5 +7,5 @@ gemspec
7
7
 
8
8
  gem 'pry'
9
9
  gem 'rake'
10
- gem 'rspec', '~> 3.1.0'
10
+ gem 'rspec', '~> 3.12.0'
11
11
  gem 'rubocop', '~> 0.79.0', require: false
data/README.md CHANGED
@@ -7,13 +7,13 @@ app.
7
7
  A rack middleware is automatically inserted into the stack. It transports
8
8
  the event data to the client. Normal requests get a DIV injected, Ajax requests
9
9
  get a data-pounded custom HTTP header appended. In case of redirects the data
10
- survives inside Rails' flash.
10
+ survives inside of rack a rack session.
11
11
  The asset pipeline-ready CoffeeScript extracts this data on the client-side and
12
- pushes it to Google Analytics via ga.js or Google Tag Manager.
12
+ pushes it to Google Analytics via gtag.js or Google Tag Manager.
13
13
 
14
14
  ## Dependencies
15
15
 
16
- * Ruby >= 2.3
16
+ * Ruby >= 3.2
17
17
  * Rails 4.2 onwards
18
18
  * jQuery
19
19
 
@@ -35,27 +35,35 @@ Add to the top of your `application.js` (but after requiring jQuery):
35
35
 
36
36
  After requiring `ga_events.js`, you have to choose an adapter.
37
37
 
38
- ### Google Analytics (ga.js)
38
+ ### Google Analytics 4 (gtag.js)
39
39
 
40
40
  ```javascript
41
41
  GaEvents.Event.adapter = function() {
42
- return new GaEvents.GoogleAnalyticsAdapter();
42
+ return new GaEvents.GTagAdapter();
43
43
  }
44
44
  ```
45
45
 
46
- ### Google Universal Analytics (analytics.js)
46
+ Optionally you can specify a custom tracker GA_MEASUREMENT_ID where you want
47
+ your events to be sent to:
47
48
 
48
49
  ```javascript
49
50
  GaEvents.Event.adapter = function() {
50
- return new GaEvents.GoogleUniversalAnalyticsAdapter();
51
+ return new GaEvents.GTagAdapter(
52
+ {tracker_name: "GA_MEASUREMENT_ID"}
53
+ );
51
54
  }
52
55
  ```
53
56
 
54
- Optionally you can specify a custom method to call and a custom tracker name:
57
+ #### Optional custom object name
58
+
59
+ The default names of the analytics object for `gtag.js` is `window.gtag()`. If
60
+ you have renamed your analytics object, you can specify the name:
55
61
 
56
62
  ```javascript
57
63
  GaEvents.Event.adapter = function() {
58
- return new GaEvents.GoogleUniversalAnalyticsAdapter("sendNow", "customTracker");
64
+ return new GaEvents.GTagAdapter(
65
+ {analytics_object_name: "analytics"} // calls window.analytics()
66
+ );
59
67
  }
60
68
  ```
61
69
 
@@ -98,24 +106,18 @@ HTTP header is added to the response.
98
106
  You can create a new event like this:
99
107
 
100
108
  ```ruby
101
- GaEvents::Event.new(category, action, label, value)
109
+ GaEvents::Event.new('example_event', { extra: 'dimension' })
102
110
  ```
103
111
 
104
112
  On the client-side there is a similar interface to GaEvents:
105
113
 
106
114
  ```javascript
107
- new GaEvents.Event(category, action, label, value)
115
+ new GaEvents.Event('example_event', { extra: 'dimension' })
108
116
  ```
109
117
 
110
118
  We have taken special care of tracking events while the DOM is loading.
111
119
  Events get collected until the DOM is ready and flushed afterwards.
112
120
 
113
- ### Default values
114
-
115
- While collecting hundreds of thousands of events on a daily basis in
116
- Google Analytics we found corrupted aggregated events when the event label or
117
- value is omitted. We now enforce a default label ("-") and value (1).
118
-
119
121
  ### Too many events
120
122
 
121
123
  Use something like this snippet to get informed of bloating HTTP headers with
@@ -161,5 +163,6 @@ Yes please! Use pull requests.
161
163
  ## More docs and tools
162
164
 
163
165
  * [Google Analytics: Event Tracking](https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide)
166
+ * [Google Universal Analytics: Event Tracking (gtag.js)](https://developers.google.com/analytics/devguides/collection/gtagjs/events)
164
167
  * [Google Tag Manager: Custom Events](http://support.google.com/tagmanager/answer/2574372#GoogleAnalytics)
165
- * [Chrome Web Store: Event Tracking Tracker](https://chrome.google.com/webstore/detail/event-tracking-tracker/npjkfahkbgoagkfpkidpjdemjjmmbcim)
168
+ * [Chrome Web Store: Tag Assistant](https://chrome.google.com/webstore/detail/tag-assistant-legacy-by-g/kejbdjndbnbjgmefkgdddjlbokphdefk)
data/Rakefile CHANGED
@@ -1,3 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new('spec')
7
+
8
+ task default: :spec
@@ -7,23 +7,27 @@ class GaEvents.Event
7
7
  adapter: null
8
8
  @list: []
9
9
  @may_flush: false
10
- @header_key: "X-GA-Events"
10
+ @header_key: "x-ga-events"
11
11
  @html_key: "ga-events"
12
12
  @require_user_consent: false
13
13
  @user_consent_given: false
14
14
  klass: @
15
15
 
16
- # Decompose a event-string (ruby side) into an event object.
17
- @from_string: (string) ->
18
- $.map string.split("$"), (part) =>
19
- [category, action, label, value] = part.split "|"
20
- new @(category, action, label, value)
16
+ # Decompose an event-string (ruby side) into an event object.
17
+ @from_json: (string) ->
18
+ events = JSON.parse(string)
19
+
20
+ $.map events, (event) =>
21
+ if event_name = event.__event__
22
+ delete event.__event__
23
+ new @(event_name, event)
21
24
 
22
25
  @from_dom: ->
23
- dom_events = $("div[data-#{@html_key}]").data @html_key
24
- @from_string dom_events if dom_events?
26
+ data_attribute = "data-#{@html_key}"
27
+ dom_events = $("div[#{data_attribute}]").attr data_attribute
28
+ @from_json dom_events if dom_events?
25
29
 
26
- # Events should not be send to an adapter unless the DOM has finished loading.
30
+ # Events should not be sent to an adapter unless the DOM has finished loading.
27
31
  @flush: ->
28
32
  return if @require_user_consent && !@user_consent_given
29
33
 
@@ -32,33 +36,18 @@ class GaEvents.Event
32
36
  @list = []
33
37
 
34
38
  # Add all events to a queue to flush them later
35
- constructor: (@category = "-", @action = "-", @label = "-", @value = 1) ->
39
+ constructor: (@event_name, @options = {}) ->
36
40
  @klass.list.push @
37
41
  @klass.flush()
38
42
 
39
- escape: (str) ->
40
- return unless str
41
- "#{str}".replace(/ä/g, "ae")
42
- .replace(/ö/g, "oe")
43
- .replace(/ü/g, "ue")
44
- .replace(/Ä/g, "Ae")
45
- .replace(/Ö/g, "Oe")
46
- .replace(/Ü/g, "Ue")
47
- .replace(/ß/g, "ss")
48
-
49
- to_hash: ->
50
- # Category, action and label must be escaped and of type string.
51
- action: @escape(@action)
52
- category: @escape(@category)
53
- label: @escape(@label)
54
- # Value has to be a positive integer or defaults to 1
55
- value: @to_positive_integer(@value)
56
-
57
- to_positive_integer: (n) ->
58
- if isFinite(n) and parseInt(n) >= 0 then parseInt n else 1
59
-
60
- # https://developers.google.com/analytics/devguides/collection/gajs/eventTrackerGuide#SettingUpEventTracking
61
- push_to_adapter: -> @klass.adapter().push @to_hash()
43
+ push_to_adapter: ->
44
+ if @is_valid_event_name()
45
+ @klass.adapter().push(@event_name, @options)
46
+ else
47
+ console.warn("GA4 event name \"#{@event_name}\" is invalid.") if console
48
+
49
+ # https://support.google.com/analytics/answer/13316687?hl=en#zippy=%2Cweb
50
+ is_valid_event_name: -> /^[a-z]+[a-z0-9_]*$/i.test(@event_name)
62
51
 
63
52
  jQuery =>
64
53
  @may_flush = true
@@ -66,7 +55,7 @@ class GaEvents.Event
66
55
 
67
56
  process_xhr = (xhr) =>
68
57
  xhr_events = xhr.getResponseHeader @header_key
69
- @from_string xhr_events if xhr_events?
58
+ @from_json decodeURIComponent(xhr_events) if xhr_events?
70
59
 
71
60
  $(document).ajaxComplete((_, xhr) -> process_xhr(xhr))
72
61
  $(document).on "turbolinks:request-end", (event) ->
@@ -76,32 +65,31 @@ class GaEvents.Event
76
65
  @from_dom()
77
66
 
78
67
 
68
+ class GaEvents.GTagAdapter
69
+ constructor: (options) ->
70
+ @analytics_object_name = options?.analytics_object_name || 'gtag'
71
+
72
+ # https://developers.google.com/analytics/devguides/migration/ua/analyticsjs-to-gtagjs#measure_pageviews_with_specified_trackers
73
+ @tracker_name = options?.tracker_name || false
74
+
75
+ push: (event_name, data) ->
76
+ data.send_to = @tracker_name if @tracker_name
77
+ window[@analytics_object_name]("event", event_name, data)
78
+
79
+ class GaEvents.NullAdapter
80
+ push: (event_name, data) -> console.log(event_name, data) if console?
81
+
79
82
  class GaEvents.GoogleTagManagerAdapter
80
83
  constructor: (@event = "ga_event") ->
81
- push: (data) ->
84
+
85
+ push: (event_name, data) ->
82
86
  data.event = @event
87
+ data.event_name = event_name
83
88
  data.non_interaction = true
84
89
  window.dataLayer.push data
85
90
 
86
- class GaEvents.GoogleUniversalAnalyticsAdapter
87
- constructor: (@method_call_name = "send", tracker_name) ->
88
- @method_call_name = "#{tracker_name}.#{@method_call_name}" if tracker_name
89
-
90
- push: (h) ->
91
- window.ga @method_call_name, "event", h.category, h.action, h.label,
92
- h.value, {"nonInteraction": true}
93
-
94
- class GaEvents.GoogleAnalyticsAdapter
95
- # Send events non_interactive => no influence on bounce rates
96
- push: (h) ->
97
- window._gaq.push(
98
- ["_trackEvent", h.category, h.action, h.label, h.value, true]
99
- )
100
-
101
- class GaEvents.NullAdapter
102
- push: (obj) -> console.log obj if console?
103
-
104
91
  class GaEvents.TestAdapter
105
- push: (obj) ->
92
+ push: (event_name, data) ->
93
+ loggedEvent = Object.assign({ event_name: event_name }, data)
106
94
  window.events = [] unless window.events?
107
- window.events.push obj
95
+ window.events.push(loggedEvent)
data/ga_events.gemspec CHANGED
@@ -25,6 +25,8 @@ Gem::Specification.new do |gem|
25
25
  gem.name = 'ga_events'
26
26
  gem.require_paths = ['lib']
27
27
  gem.version = GaEvents::VERSION
28
+ gem.licenses = ['MIT']
28
29
 
30
+ gem.required_ruby_version = '>= 3.2'
29
31
  gem.add_dependency 'rails', '>= 4.2'
30
32
  end
@@ -1,19 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GaEvents
4
- Event = Struct.new(:category, :action, :label, :value) do
4
+ class Event
5
+ attr_reader :event_name, :event_params
6
+
5
7
  # Default values are set here, see README.md for details.
6
- def initialize(category = '-', action = '-', label = '-', value = 1)
7
- super
8
+ def initialize(event_name, event_params = {})
9
+ @event_name = event_name
10
+ @event_params = event_params
8
11
  GaEvents::List << self
9
12
  end
10
13
 
11
14
  def to_s
12
- [category, action, label, value].join('|')
15
+ JSON.generate({ __event__: event_name, **event_params })
16
+ end
17
+
18
+ def to_h
19
+ { event_name:, event_params: event_params.symbolize_keys }
20
+ end
21
+
22
+ def deconstruct_keys(keys)
23
+ keys ? to_h.slice(*keys) : to_h
24
+ end
25
+
26
+ def self.from_hash(event_hash)
27
+ if event_name = event_hash.delete('__event__')
28
+ new(event_name, event_hash)
29
+ end
13
30
  end
14
31
 
15
- def self.from_string(str)
16
- new(*str.split('|'))
32
+ def ==(other)
33
+ self.class == other.class && event_name == other.event_name &&
34
+ event_params == other.event_params
17
35
  end
18
36
  end
19
37
  end
@@ -12,13 +12,18 @@ module GaEvents
12
12
  def_delegators :data, :<<, :present?
13
13
 
14
14
  def to_s
15
- data.collect(&:to_s).join('$')
15
+ "[#{data.collect(&:to_s).join(',')}]"
16
16
  end
17
17
 
18
18
  # Init list, optionally with a string of serialized events
19
19
  def init(str = nil)
20
20
  Thread.current[:ga_events] = []
21
- (str || '').split('$').each { |s| GaEvents::Event.from_string(s) }
21
+ if str.present?
22
+ raw_events = JSON.parse(str)
23
+ raw_events.each { |raw_event| GaEvents::Event.from_hash(raw_event) }
24
+ end
25
+ rescue JSON::ParserError
26
+ nil
22
27
  end
23
28
 
24
29
  private
@@ -4,6 +4,8 @@ require 'rack/utils'
4
4
 
5
5
  module GaEvents
6
6
  class Middleware
7
+ SESSION_GA_EVENTS_KEY = 'ga_events.events'
8
+
7
9
  def initialize(app)
8
10
  @app = app
9
11
  end
@@ -20,12 +22,11 @@ module GaEvents
20
22
  serialized = GaEvents::List.to_s
21
23
  if xhr_or_turbolinks?(request)
22
24
  # AJAX request
23
- headers['X-GA-Events'] = serialized
24
-
25
+ headers['x-ga-events'] = CGI.escapeURIComponent(serialized)
25
26
  elsif redirect?(status)
26
- # 30x/redirect? Then add event list to flash to survive the redirect.
27
- add_events_to_flash(env, serialized)
28
-
27
+ # 30x/redirect? Then add event list to rack session to survive the
28
+ # redirect.
29
+ add_events_to_session(env, serialized)
29
30
  elsif html?(status, headers)
30
31
  response = inject_div(response, serialized)
31
32
  end
@@ -37,23 +38,14 @@ module GaEvents
37
38
  private
38
39
 
39
40
  def init_event_list(env)
40
- flash = env['rack.session'] && env['rack.session']['flash'] &&
41
- env['rack.session']['flash']['flashes']
42
-
43
- # The key has to be removed from the flash here to ensure it does not
44
- # remain after the finished redirect. This copies the behaviour of the
45
- # "#use" and "#sweep" methods of the rails flash middleware:
46
- # https://github.com/rails/rails/blob/v3.2.14/actionpack/lib/action_dispatch/middleware/flash.rb#L220
47
- GaEvents::List.init(flash&.delete('ga_events'))
41
+ events = env['rack.session']&.delete(SESSION_GA_EVENTS_KEY)
42
+ GaEvents::List.init(events)
48
43
  end
49
44
 
50
- def add_events_to_flash env, serialized_data
51
- flash = env['rack.session'] && env['rack.session']['flash'] &&
52
- env['rack.session']['flash']['flashes']
53
-
54
- return unless flash
55
-
56
- flash['ga_events'] = serialized_data
45
+ def add_events_to_session env, serialized_data
46
+ if session = env.dig('rack.session')
47
+ session[SESSION_GA_EVENTS_KEY] = serialized_data
48
+ end
57
49
  end
58
50
 
59
51
  def normalize_response(response)
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module GaEvents
4
- VERSION = '2.1.0'
4
+ VERSION = '4.0.0'
5
5
  end
@@ -0,0 +1,68 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe GaEvents::Event do
4
+ it 'has a custom #to_s implementation ' do
5
+ expect(
6
+ described_class.new('test', { p1: 'my-action', p2: 'my-label' }).to_s
7
+ ).to eq('{"__event__":"test","p1":"my-action","p2":"my-label"}')
8
+ end
9
+
10
+ it 'can be restored from hash' do
11
+ initialized_event =
12
+ described_class.new(
13
+ 'test',
14
+ {
15
+ 'category' => 'my-category',
16
+ 'label' => 'my-label',
17
+ 'value' => 'my-value'
18
+ }
19
+ )
20
+ from_hash_event =
21
+ described_class.from_hash(
22
+ {
23
+ 'category' => 'my-category',
24
+ '__event__' => 'test',
25
+ 'label' => 'my-label',
26
+ 'value' => 'my-value'
27
+ }
28
+ )
29
+ expect(from_hash_event).to eq initialized_event
30
+ end
31
+
32
+ it 'adds itself to GaEvents::List' do
33
+ described_class.from_hash(
34
+ {
35
+ '__event__' => 'test',
36
+ 'category' => 'my-category',
37
+ 'label' => 'my-label',
38
+ 'value' => 'first-value'
39
+ }
40
+ )
41
+ described_class.new('clicked', { some: 'thing' })
42
+
43
+ expect(GaEvents::List.to_s).to eq(<<~EVENTS.tr("\n", ''))
44
+ [{"__event__":"test","category":"my-category","label":"my-label","value":"first-value"},
45
+ {"__event__":"clicked","some":"thing"}]
46
+ EVENTS
47
+ end
48
+
49
+ it 'can be initialized with a hash' do
50
+ expect(
51
+ described_class.new('one_value', { stars: 5 }).to_s
52
+ ).to eq '{"__event__":"one_value","stars":5}'
53
+ expect(
54
+ described_class.new('two_values', { stars: 5, mode: 'main' }).to_s
55
+ ).to eq '{"__event__":"two_values","stars":5,"mode":"main"}'
56
+ expect(
57
+ described_class.new('with_array', { list: [5, 'stars'] }).to_s
58
+ ).to eq '{"__event__":"with_array","list":[5,"stars"]}'
59
+ end
60
+
61
+ it 'can be pattern matched against' do
62
+ event = described_class.new('test', { stars: 5 })
63
+ event => {
64
+ event_name: 'test', event_params: { stars: Integer => five_stars }
65
+ }
66
+ expect(five_stars).to eq 5
67
+ end
68
+ end
data/spec/list_spec.rb ADDED
@@ -0,0 +1,40 @@
1
+ require 'spec_helper'
2
+
3
+ RSpec.describe 'GaEvents::List' do
4
+ describe '#to_s' do
5
+ it 'generates valid json' do
6
+ GaEvents::Event.new('clicked', { a: 'a' })
7
+ GaEvents::Event.new('clicked', { b: 'b' })
8
+ expect(JSON.parse(GaEvents::List.to_s)).to eq(
9
+ [
10
+ { '__event__' => 'clicked', 'a' => 'a' },
11
+ { '__event__' => 'clicked', 'b' => 'b' }
12
+ ]
13
+ )
14
+ end
15
+ end
16
+
17
+ it 'can be initialized with a json string' do
18
+ GaEvents::List.init(<<~JSON.squish)
19
+ [
20
+ { "__event__": "clicked", "a": "a" }
21
+ ]
22
+ JSON
23
+
24
+ expect(
25
+ GaEvents::List.send(:data).to_h { [_1.event_name, _1.event_params] }
26
+ ).to eq({ 'clicked' => { 'a' => 'a' } })
27
+ end
28
+
29
+ it 'can be initialized with a broken json string' do
30
+ GaEvents::List.init(<<~JSON.squish)
31
+ [
32
+ { "__event__": "clicked", "trailing": "comma triggers ParserError", }
33
+ ]
34
+ JSON
35
+
36
+ expect(
37
+ GaEvents::List.send(:data).to_h { [_1.event_name, _1.event_params] }
38
+ ).to be_empty
39
+ end
40
+ end
@@ -33,26 +33,26 @@ describe GaEvents::Middleware do
33
33
  context 'events present in GaEvents::List' do
34
34
  let(:app) do
35
35
  proc do |_|
36
- GaEvents::Event.new('category', 'action', 'label', 'value')
36
+ GaEvents::Event.new('test', { 'cool' => 'stuff' })
37
37
  [200, { 'Content-Type' => 'text/html' }, response_body]
38
38
  end
39
39
  end
40
40
 
41
- context 'there is no body closing tag' do
41
+ context 'when no body closing tag exists' do
42
42
  let(:response) { request.get('/') }
43
43
  it 'leaves everything as it was' do
44
44
  expect(response.body).to eq response_body
45
45
  end
46
46
  end
47
47
 
48
- context 'there exists body closing tag' do
48
+ context 'when a body closing tag exists' do
49
49
  let(:response) { request.get('/') }
50
50
  let(:response_body) { 'something awesome!</body>' }
51
51
 
52
52
  it 'injects data-ga-events' do
53
53
  expect(response.body).to eq(
54
54
  'something awesome!' \
55
- "<div data-ga-events='category|action|label|value'></div></body>"
55
+ "<div data-ga-events='[{\"__event__\":\"test\",\"cool\":\"stuff\"}]'></div></body>"
56
56
  )
57
57
  end
58
58
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ga_events
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.1.0
4
+ version: 4.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Dütsch
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2021-09-07 00:00:00.000000000 Z
12
+ date: 2023-08-09 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -49,10 +49,13 @@ files:
49
49
  - lib/ga_events/list.rb
50
50
  - lib/ga_events/middleware.rb
51
51
  - lib/ga_events/version.rb
52
+ - spec/event_spec.rb
53
+ - spec/list_spec.rb
52
54
  - spec/middleware_spec.rb
53
55
  - spec/spec_helper.rb
54
56
  homepage: https://github.com/Nix-wie-weg/ga_events
55
- licenses: []
57
+ licenses:
58
+ - MIT
56
59
  metadata: {}
57
60
  post_install_message:
58
61
  rdoc_options: []
@@ -62,14 +65,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
62
65
  requirements:
63
66
  - - ">="
64
67
  - !ruby/object:Gem::Version
65
- version: '0'
68
+ version: '3.2'
66
69
  required_rubygems_version: !ruby/object:Gem::Requirement
67
70
  requirements:
68
71
  - - ">="
69
72
  - !ruby/object:Gem::Version
70
73
  version: '0'
71
74
  requirements: []
72
- rubygems_version: 3.0.3
75
+ rubygems_version: 3.4.6
73
76
  signing_key:
74
77
  specification_version: 4
75
78
  summary: This gem allows you to annotate events everywhere in the code of your Rails
@@ -79,5 +82,7 @@ summary: This gem allows you to annotate events everywhere in the code of your R
79
82
  extracts this data on the client side and pushes it to Google Analytics via ga.js
80
83
  or Google Tag Manager.
81
84
  test_files:
85
+ - spec/event_spec.rb
86
+ - spec/list_spec.rb
82
87
  - spec/middleware_spec.rb
83
88
  - spec/spec_helper.rb