ga_events 1.0.1 → 1.1.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,15 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 2127aed8e42aa7cdf0f703a92841a4a6a0392a7d
4
- data.tar.gz: 35a89d2b3d7f419c3951b889bbc86ab627aee8ee
2
+ !binary "U0hBMQ==":
3
+ metadata.gz: !binary |-
4
+ N2FlNTM2ZmYyMDRlOTQ0MjRjZTZmNTNiZWQwMDBiOTgyNTM1MTNmYQ==
5
+ data.tar.gz: !binary |-
6
+ Mzk2ZmY4OGNlYjI0NTUzOWNkZTBjYjQyMDM3MmM4Y2VmNmIyZThmNA==
5
7
  SHA512:
6
- metadata.gz: 285032374bdfefe0dd823ace6fc89fbf8445eb167b3292f33212479d8a18f5fa2c1f39dfa7ee726bc5587ab668bf69fadc7a2e7e4eedf9fe0d9dc6225a3a9f2b
7
- data.tar.gz: 42a0012e1810332cdc2629ea7b50f79b8bae36fb1ac8c754e62eef49a2e55075e8fb70d8a9f78da7ba8d9114f8e6ab87adeb3df5a55a2ee4714866bf5814a9a9
8
+ metadata.gz: !binary |-
9
+ N2UxZGZiOTQ0NTI3ZmEyY2Y4ODY1NWY3ZmIzYTA4OWQzNWJjY2E0MWM4ZmYw
10
+ Njc2NzhjMzFjY2ZhYmZhZDczNjUzZTY2NzAwYTZiNTY5ZmYxNmQ0MzIzYzI5
11
+ NzY0MjA4NWRlZmMyOTZmMDc2OWNjYjU5MGM4ZTJhZTBkMGE1ZTM=
12
+ data.tar.gz: !binary |-
13
+ NDFlZjM5NjI3ODdiNjdmMWI4ZGMwMDE2MGI0MDQ4Y2UzOGE3NDA5NTQ5NTc1
14
+ MDYxNWJmZDkwMDJiNDY3YjYzZDM3YjkzNTMzZGZkYmNhMDRiYzY1MmE0Y2Zh
15
+ ZDY1MmYzNWQ4ZjVlOWQwNzJmZmU1ZmExYzg4MmVkNjJiMzM2MDA=
data/CHANGELOG.md ADDED
@@ -0,0 +1,17 @@
1
+ # Changelog
2
+ All notable changes to this project will be documented in this file.
3
+ The format suggested at http://keepachangelog.com/ is used.
4
+
5
+ ## 1.0.1 - 2014-04-29
6
+
7
+ ### Fixed
8
+ - Universal Analytics Adapter now marks event as non-interaction.
9
+
10
+ ## 1.1.0 - 2014-10-17
11
+
12
+ ### Added
13
+ - Some documentation regarding controller specs (closes #10)
14
+ - More middleware specs
15
+
16
+ ### Fixed
17
+ - Error returns white page
data/Gemfile CHANGED
@@ -2,3 +2,7 @@ source 'https://rubygems.org'
2
2
 
3
3
  # Specify your gem's dependencies in ga_events.gemspec
4
4
  gemspec
5
+
6
+ gem 'rake'
7
+ gem 'rspec', '~> 3.1.0'
8
+ gem 'pry'
data/README.md CHANGED
@@ -13,6 +13,7 @@ pushes it to Google Analytics via ga.js or Google Tag Manager.
13
13
 
14
14
  ## Dependencies
15
15
 
16
+ * Ruby >= 1.9
16
17
  * Rails 3.1 onwards
17
18
  * jQuery
18
19
 
@@ -32,9 +33,9 @@ Add to the top of your `application.js` (but after requiring jQuery):
32
33
  //= require ga_events.js
33
34
  ```
34
35
 
35
- After requiring `ga_events.js`, choose an adapter.
36
+ After requiring `ga_events.js`, you have to choose an adapter.
36
37
 
37
- For stock Google Analytics (ga.js) use:
38
+ ### Google Analytics (ga.js)
38
39
 
39
40
  ```javascript
40
41
  GaEvents.Event.adapter = function() {
@@ -42,7 +43,7 @@ GaEvents.Event.adapter = function() {
42
43
  }
43
44
  ```
44
45
 
45
- For Google Universal Analytics (analytics.js) use:
46
+ ### Google Universal Analytics (analytics.js)
46
47
 
47
48
  ```javascript
48
49
  GaEvents.Event.adapter = function() {
@@ -50,6 +51,16 @@ GaEvents.Event.adapter = function() {
50
51
  }
51
52
  ```
52
53
 
54
+ Optionally you can specify a custom method to call and a custom tracker name:
55
+
56
+ ```javascript
57
+ GaEvents.Event.adapter = function() {
58
+ return new GaEvents.GoogleUniversalAnalyticsAdapter("sendNow", "customTracker");
59
+ }
60
+ ```
61
+
62
+ ### Google TagManager
63
+
53
64
  If you are using Google Tag Manager you can add custom events which are then
54
65
  passed through to Google Analytics.
55
66
 
@@ -59,7 +70,9 @@ GaEvents.Event.adapter = function() {
59
70
  }
60
71
  ```
61
72
 
62
- If you are using a staging system you can use the `NullAdapter`.
73
+ ### Testing
74
+
75
+ For your testing pleasure we included `NullAdapter`.
63
76
 
64
77
  ```javascript
65
78
  GaEvents.Event.adapter = function() {
@@ -112,13 +125,29 @@ class ApplicationController < ActionController::Base
112
125
  end
113
126
  ```
114
127
 
128
+ ### Testing
129
+
130
+ Middlewares aren't loaded in controller specs, so you have to initialize
131
+ GaEvents by hand. You can do this eg. in your `spec_helper.rb`:
132
+
133
+ ```ruby
134
+ RSpec.configure do |config|
135
+ [...]
136
+ config.before(:each, type: :controller) do
137
+ GaEvents::List.init
138
+ end
139
+ end
140
+ ```
141
+
115
142
  ## Contributing
116
143
 
117
144
  Yes please! Use pull requests.
118
145
 
119
146
  ### Credits
120
147
 
121
- * [jhilden](https://github.com/jhilden) for ideas and Rails 4 support
148
+ * [danielbayerlein](https://github.com/danielbayerlein) former core committer
149
+ * [jhilden](https://github.com/jhilden) for ideas and bug reports
150
+ * [brain-geek](https://github.com/brain-geek) for bug fixes, specs, features
122
151
 
123
152
  ## More docs and tools
124
153
 
data/Rakefile CHANGED
@@ -1,2 +1,7 @@
1
1
  #!/usr/bin/env rake
2
- require "bundler/gem_tasks"
2
+ require 'bundler/gem_tasks'
3
+ require 'rspec/core/rake_task'
4
+
5
+ RSpec::Core::RakeTask.new('spec')
6
+
7
+ task default: :spec
@@ -61,9 +61,12 @@ class GaEvents.GoogleTagManagerAdapter
61
61
  window.dataLayer.push data
62
62
 
63
63
  class GaEvents.GoogleUniversalAnalyticsAdapter
64
+ constructor: (@method_call_name = "send", tracker_name) ->
65
+ @method_call_name = "#{tracker_name}.#{@method_call_name}" if tracker_name
66
+
64
67
  push: (h) ->
65
- window.ga "send", "event", h.category, h.action, h.label, h.value,
66
- {"nonInteraction": true}
68
+ window.ga @method_call_name, "event", h.category, h.action, h.label,
69
+ h.value, {"nonInteraction": true}
67
70
 
68
71
  class GaEvents.GoogleAnalyticsAdapter
69
72
  # Send events non_interactive => no influence on bounce rates
data/ga_events.gemspec CHANGED
@@ -2,12 +2,11 @@
2
2
  require File.expand_path('../lib/ga_events/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |gem|
5
- gem.authors = ['Florian Dütsch', 'Sven Winkler', 'Daniel Bayerlein']
5
+ gem.authors = ['Florian Dütsch', 'Sven Winkler']
6
6
  gem.email = ['florian.duetsch@nix-wie-weg.de',
7
- 'sven.winkler@nix-wie-weg.de',
8
- 'daniel.bayerlein@nix-wie-weg.de']
7
+ 'sven.winkler@nix-wie-weg.de']
9
8
  gem.description =
10
- %q{Google Analytics' Event Tracking everywhere in your Rails app}
9
+ "Google Analytics' Event Tracking everywhere in your Rails app)"
11
10
  gem.summary = 'This gem allows you to annotate events everywhere in ' \
12
11
  'the code of your Rails app. A rack middleware is ' \
13
12
  'automatically inserted into the stack. It transports ' \
@@ -19,11 +18,11 @@ Gem::Specification.new do |gem|
19
18
  'Tag Manager.'
20
19
  gem.homepage = 'https://github.com/Nix-wie-weg/ga_events'
21
20
 
22
- gem.files = `git ls-files`.split($\)
23
- gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
24
- gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
25
- gem.name = "ga_events"
26
- gem.require_paths = ["lib"]
21
+ gem.files = `git ls-files`.split($OUTPUT_RECORD_SEPARATOR)
22
+ gem.executables = gem.files.grep(/^bin\//).map { |f| File.basename(f) }
23
+ gem.test_files = gem.files.grep(/^(test|spec|features)\//)
24
+ gem.name = 'ga_events'
25
+ gem.require_paths = ['lib']
27
26
  gem.version = GaEvents::VERSION
28
27
 
29
28
  gem.add_dependency 'rails', '>= 3.1'
@@ -1,28 +1,29 @@
1
1
  # NOTE: Collecting the events is thread-safe, but will cause problems in an
2
2
  # asynchronous/evented environment.
3
3
 
4
- module GaEvents::List
5
- def self.<<(event)
6
- data << event
7
- end
4
+ require 'forwardable'
8
5
 
9
- def self.to_s
10
- data.collect(&:to_s).join('$')
11
- end
6
+ module GaEvents
7
+ module List
8
+ class << self
9
+ extend Forwardable
10
+ def_delegators :data, :<<, :present?
12
11
 
13
- def self.present?
14
- data.present?
15
- end
12
+ def to_s
13
+ data.collect(&:to_s).join('$')
14
+ end
16
15
 
17
- # Init list, optionally with a string of serialized events
18
- def self.init(str = nil)
19
- Thread.current[:ga_events] = []
20
- (str || '').split('$').each { |s| GaEvents::Event.from_string(s) }
21
- end
16
+ # Init list, optionally with a string of serialized events
17
+ def init(str = nil)
18
+ Thread.current[:ga_events] = []
19
+ (str || '').split('$').each { |s| GaEvents::Event.from_string(s) }
20
+ end
22
21
 
23
- def self.data
24
- Thread.current[:ga_events]
25
- end
22
+ private
26
23
 
27
- private_class_method :data
24
+ def data
25
+ Thread.current[:ga_events]
26
+ end
27
+ end
28
+ end
28
29
  end
@@ -5,17 +5,9 @@ module GaEvents
5
5
  def initialize(app)
6
6
  @app = app
7
7
  end
8
- def call(env)
9
- # Handle events stored in flash
10
- # Parts borrowed from Rails:
11
- # https://github.com/rails/rails/blob/v3.2.14/actionpack/lib/action_dispatch/middleware/flash.rb
12
- flash = env['rack.session'] && env['rack.session']['flash']
13
-
14
- # Fix for Rails 4
15
- flash &&= flash['flashes'] if Rails::VERSION::MAJOR > 3
16
-
17
- GaEvents::List.init(flash && flash['ga_events'])
18
8
 
9
+ def call(env)
10
+ init_event_list(env)
19
11
  status, headers, response = @app.call(env)
20
12
 
21
13
  headers = Rack::Utils::HeaderHash.new(headers)
@@ -30,17 +22,10 @@ module GaEvents
30
22
 
31
23
  elsif (300..399).include?(status)
32
24
  # 30x/redirect? Then add event list to flash to survive the redirect.
33
- flash_hash = env[ActionDispatch::Flash::KEY]
34
- flash_hash ||= ActionDispatch::Flash::FlashHash.new
35
- flash_hash['ga_events'] = serialized
36
- env[ActionDispatch::Flash::KEY] = flash_hash
37
-
38
- elsif is_html?(status, headers)
39
- body = response
40
- body = body.each.to_a.join if body.respond_to?(:each)
41
- body = body.sub('</body>',
42
- "<div data-ga-events='#{serialized}'></div>\\0")
43
- response = [body]
25
+ add_events_to_flash(env, serialized)
26
+
27
+ elsif html?(status, headers)
28
+ response = inject_div(response, serialized)
44
29
  end
45
30
  end
46
31
 
@@ -49,9 +34,39 @@ module GaEvents
49
34
 
50
35
  private
51
36
 
37
+ def init_event_list(env)
38
+ # Handle events stored in flash
39
+ # Parts borrowed from Rails:
40
+ # https://github.com/rails/rails/blob/v3.2.14/actionpack/lib/action_dispatch/middleware/flash.rb
41
+ flash = env['rack.session'] && env['rack.session']['flash']
42
+
43
+ # Fix for Rails 4
44
+ flash &&= flash['flashes'] if Rails::VERSION::MAJOR > 3
45
+
46
+ GaEvents::List.init(flash && flash['ga_events'])
47
+ end
48
+
49
+ def add_events_to_flash env, serialized_data
50
+ flash_hash = env[ActionDispatch::Flash::KEY]
51
+ flash_hash ||= ActionDispatch::Flash::FlashHash.new
52
+ flash_hash['ga_events'] = serialized_data
53
+ env[ActionDispatch::Flash::KEY] = flash_hash
54
+ end
55
+
56
+ def normalize_response(r)
57
+ r = r.body if r.respond_to?(:body)
58
+ r = r.join if r.respond_to?(:join)
59
+ r
60
+ end
61
+
62
+ def inject_div(response, serialized_data)
63
+ r = normalize_response(response)
64
+ [r.sub('</body>', "<div data-ga-events='#{serialized_data}'></div>\\0")]
65
+ end
66
+
52
67
  # Taken from:
53
68
  # https://github.com/rack/rack-contrib/blob/master/lib/rack/contrib/jsonp.rb
54
- def is_html?(status, headers)
69
+ def html?(status, headers)
55
70
  !Rack::Utils::STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
56
71
  headers.key?('Content-Type') &&
57
72
  headers['Content-Type'].include?('text/html')
@@ -1,3 +1,3 @@
1
1
  module GaEvents
2
- VERSION = '1.0.1'
2
+ VERSION = '1.1.0'
3
3
  end
@@ -0,0 +1,59 @@
1
+ require 'spec_helper'
2
+
3
+ describe GaEvents::Middleware do
4
+ let(:app) do
5
+ proc { [200, { 'Content-Type' => 'text/html' }, [response_body]] }
6
+ end
7
+ let(:response_body) { 'Hello, world.' }
8
+
9
+ let(:stack) { described_class.new(app) }
10
+ let(:request) { Rack::MockRequest.new(stack) }
11
+
12
+ describe 'Body code injection' do
13
+ context 'no events in GaEvents::List' do
14
+ context 'there is no body closing tag' do
15
+ let(:response) { request.get('/') }
16
+ it 'leaves everything as it was' do
17
+ expect(response.body).to eq response_body
18
+ end
19
+ end
20
+
21
+ context 'there exists body closing tag' do
22
+ let(:response) { request.get('/') }
23
+ let(:response_body) { 'something awesome!</body>' }
24
+
25
+ it 'leaves everything as it was' do
26
+ expect(response.body).to eq response_body
27
+ end
28
+ end
29
+ end
30
+
31
+ context 'events present in GaEvents::List' do
32
+ let(:app) do
33
+ proc do |_|
34
+ GaEvents::Event.new('category', 'action', 'label', 'value')
35
+ [200, { 'Content-Type' => 'text/html' }, response_body]
36
+ end
37
+ end
38
+
39
+ context 'there is no body closing tag' do
40
+ let(:response) { request.get('/') }
41
+ it 'leaves everything as it was' do
42
+ expect(response.body).to eq response_body
43
+ end
44
+ end
45
+
46
+ context 'there exists body closing tag' do
47
+ let(:response) { request.get('/') }
48
+ let(:response_body) { 'something awesome!</body>' }
49
+
50
+ it 'injects data-ga-events' do
51
+ expect(response.body).to eq(
52
+ 'something awesome!' \
53
+ "<div data-ga-events='category|action|label|value'></div></body>"
54
+ )
55
+ end
56
+ end
57
+ end
58
+ end
59
+ end
@@ -0,0 +1,18 @@
1
+ require 'bundler/setup'
2
+ require 'pry'
3
+ require 'rspec'
4
+ require 'rails'
5
+ require 'ga_events'
6
+
7
+ # Disabling old rspec 'should' syntax
8
+ RSpec.configure do |config|
9
+ config.expect_with :rspec do |c|
10
+ c.syntax = :expect
11
+ end
12
+
13
+ config.raise_errors_for_deprecations!
14
+
15
+ config.before do
16
+ GaEvents::List.init
17
+ end
18
+ end
metadata CHANGED
@@ -1,41 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ga_events
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.1
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Florian Dütsch
8
8
  - Sven Winkler
9
- - Daniel Bayerlein
10
9
  autorequire:
11
10
  bindir: bin
12
11
  cert_chain: []
13
- date: 2014-04-29 00:00:00.000000000 Z
12
+ date: 2014-10-17 00:00:00.000000000 Z
14
13
  dependencies:
15
14
  - !ruby/object:Gem::Dependency
16
15
  name: rails
17
16
  requirement: !ruby/object:Gem::Requirement
18
17
  requirements:
19
- - - ">="
18
+ - - ! '>='
20
19
  - !ruby/object:Gem::Version
21
20
  version: '3.1'
22
21
  type: :runtime
23
22
  prerelease: false
24
23
  version_requirements: !ruby/object:Gem::Requirement
25
24
  requirements:
26
- - - ">="
25
+ - - ! '>='
27
26
  - !ruby/object:Gem::Version
28
27
  version: '3.1'
29
- description: Google Analytics' Event Tracking everywhere in your Rails app
28
+ description: Google Analytics' Event Tracking everywhere in your Rails app)
30
29
  email:
31
30
  - florian.duetsch@nix-wie-weg.de
32
31
  - sven.winkler@nix-wie-weg.de
33
- - daniel.bayerlein@nix-wie-weg.de
34
32
  executables: []
35
33
  extensions: []
36
34
  extra_rdoc_files: []
37
35
  files:
38
- - ".gitignore"
36
+ - .gitignore
37
+ - CHANGELOG.md
39
38
  - Gemfile
40
39
  - LICENSE
41
40
  - README.md
@@ -49,6 +48,8 @@ files:
49
48
  - lib/ga_events/list.rb
50
49
  - lib/ga_events/middleware.rb
51
50
  - lib/ga_events/version.rb
51
+ - spec/middleware_spec.rb
52
+ - spec/spec_helper.rb
52
53
  homepage: https://github.com/Nix-wie-weg/ga_events
53
54
  licenses: []
54
55
  metadata: {}
@@ -58,17 +59,17 @@ require_paths:
58
59
  - lib
59
60
  required_ruby_version: !ruby/object:Gem::Requirement
60
61
  requirements:
61
- - - ">="
62
+ - - ! '>='
62
63
  - !ruby/object:Gem::Version
63
64
  version: '0'
64
65
  required_rubygems_version: !ruby/object:Gem::Requirement
65
66
  requirements:
66
- - - ">="
67
+ - - ! '>='
67
68
  - !ruby/object:Gem::Version
68
69
  version: '0'
69
70
  requirements: []
70
71
  rubyforge_project:
71
- rubygems_version: 2.2.2
72
+ rubygems_version: 2.4.1
72
73
  signing_key:
73
74
  specification_version: 4
74
75
  summary: This gem allows you to annotate events everywhere in the code of your Rails
@@ -77,4 +78,6 @@ summary: This gem allows you to annotate events everywhere in the code of your R
77
78
  a data-pounded custom HTTP header appended. The asset pipeline-ready CoffeeScript
78
79
  extracts this data on the client side and pushes it to Google Analytics via ga.js
79
80
  or Google Tag Manager.
80
- test_files: []
81
+ test_files:
82
+ - spec/middleware_spec.rb
83
+ - spec/spec_helper.rb