ga_events 1.0.1 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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