From 1368841b82f9f6f207750500836bf71ee1869d37 Mon Sep 17 00:00:00 2001 From: Michael Bumann Date: Tue, 3 Mar 2020 19:50:18 +0100 Subject: [PATCH] Hello rubocop --- .rubocop.yml | 20 +++ Gemfile | 3 + Rakefile | 4 +- lib/rack/tracker.rb | 73 +++++---- lib/rack/tracker/bing/bing.rb | 4 +- lib/rack/tracker/controller.rb | 10 +- lib/rack/tracker/criteo/criteo.rb | 9 +- lib/rack/tracker/drift/drift.rb | 2 + lib/rack/tracker/extensions.rb | 67 ++++---- lib/rack/tracker/facebook/facebook.rb | 5 +- .../tracker/facebook_pixel/facebook_pixel.rb | 2 + lib/rack/tracker/go_squared/go_squared.rb | 8 +- .../google_adwords_conversion.rb | 2 + .../google_analytics/google_analytics.rb | 25 +-- .../tracker/google_global/google_global.rb | 16 +- .../google_tag_manager/google_tag_manager.rb | 15 +- lib/rack/tracker/handler.rb | 25 ++- lib/rack/tracker/handler_delegator.rb | 16 +- lib/rack/tracker/heap/heap.rb | 2 + lib/rack/tracker/hotjar/hotjar.rb | 2 + lib/rack/tracker/hubspot/hubspot.rb | 2 + lib/rack/tracker/javascript_helper.rb | 23 +-- lib/rack/tracker/railtie.rb | 4 +- lib/rack/tracker/version.rb | 2 + lib/rack/tracker/vwo/vwo.rb | 2 + lib/rack/tracker/zanox/zanox.rb | 13 +- rack-tracker.gemspec | 41 ++--- spec/benchmark/tracker_injection_benchmark.rb | 2 + spec/handler/bing_spec.rb | 34 ++-- spec/handler/criteo_spec.rb | 59 ++++--- spec/handler/drift_spec.rb | 2 + spec/handler/facebook_pixel_spec.rb | 52 +++--- spec/handler/facebook_spec.rb | 31 ++-- spec/handler/go_squared_spec.rb | 28 ++-- .../handler/google_adwords_conversion_spec.rb | 48 +++--- spec/handler/google_analytics_spec.rb | 154 +++++++++--------- spec/handler/google_global_spec.rb | 134 ++++++++------- spec/handler/google_tag_manager_spec.rb | 25 +-- spec/handler/handler_spec.rb | 14 +- spec/handler/heap_spec.rb | 2 + spec/handler/hotjar_spec.rb | 2 + spec/handler/hubspot_spec.rb | 3 +- spec/handler/vwo_spec.rb | 6 +- spec/handler/zanox_spec.rb | 83 +++++----- spec/integration/bing_integration_spec.rb | 9 +- spec/integration/criteo_integration_spec.rb | 39 ++--- spec/integration/drift_integration_spec.rb | 2 + spec/integration/facebook_integration_spec.rb | 6 +- .../facebook_pixel_integration_spec.rb | 8 +- .../go_squared_integration_spec.rb | 24 +-- ...gle_adwords_conversion_integration_spec.rb | 11 +- .../google_analytics_integration_spec.rb | 37 +++-- .../google_global_integration_spec.rb | 30 ++-- .../google_tag_manager_integration_spec.rb | 28 ++-- spec/integration/heap_integration_spec.rb | 4 +- spec/integration/hotjar_integration_spec.rb | 4 +- spec/integration/hubspot_integration_spec.rb | 11 +- spec/integration/rails_integration_spec.rb | 8 +- spec/integration/vwo_integration_spec.rb | 6 +- spec/integration/zanox_integration_spec.rb | 15 +- spec/spec_helper.rb | 4 +- spec/support/capybara_app_helper.rb | 4 +- spec/support/fake_handler.rb | 7 +- spec/support/metal_controller.rb | 48 +++--- spec/tracker/controller_spec.rb | 11 +- spec/tracker/handler_delegator_spec.rb | 8 +- spec/tracker/handler_set_spec.rb | 13 +- spec/tracker/javascript_helper_spec.rb | 28 ++-- spec/tracker/tracker_spec.rb | 58 +++---- 69 files changed, 812 insertions(+), 687 deletions(-) create mode 100644 .rubocop.yml diff --git a/.rubocop.yml b/.rubocop.yml new file mode 100644 index 0000000..445bb72 --- /dev/null +++ b/.rubocop.yml @@ -0,0 +1,20 @@ +# The behavior of RuboCop can be controlled via the .rubocop.yml +# configuration file. It makes it possible to enable/disable +# certain cops (checks) and to alter their behavior if they accept +# any parameters. The file can be placed either in your home +# directory or in some project directory. +# +# RuboCop will start looking for the configuration file in the directory +# where the inspected file is and continue its way up to the root directory. +# +# See https://github.com/rubocop-hq/rubocop/blob/master/manual/configuration.md +# + +Layout/LineLength: + Max: 150 + Exclude: + - 'spec/**/*_spec.rb' + +Metrics/BlockLength: + Exclude: + - 'spec/**/*_spec.rb' diff --git a/Gemfile b/Gemfile index 927117b..854d616 100644 --- a/Gemfile +++ b/Gemfile @@ -1,4 +1,7 @@ +# frozen_string_literal: true + source 'https://rubygems.org' # Specify your gem's dependencies in rack-tracker.gemspec gemspec +gem 'rubocop' diff --git a/Rakefile b/Rakefile index c382fee..82bb534 100644 --- a/Rakefile +++ b/Rakefile @@ -1,4 +1,6 @@ -require "bundler/gem_tasks" +# frozen_string_literal: true + +require 'bundler/gem_tasks' require 'rspec/core/rake_task' RSpec::Core::RakeTask.new(:spec) diff --git a/lib/rack/tracker.rb b/lib/rack/tracker.rb index ed0a07e..91411a3 100644 --- a/lib/rack/tracker.rb +++ b/lib/rack/tracker.rb @@ -1,32 +1,34 @@ -require "rack" -require "tilt" -require "active_support/core_ext/class/attribute" -require "active_support/core_ext/hash" -require "active_support/json" -require "active_support/inflector" - -require "rack/tracker/version" -require "rack/tracker/extensions" -require "rack/tracker/javascript_helper" +# frozen_string_literal: true + +require 'rack' +require 'tilt' +require 'active_support/core_ext/class/attribute' +require 'active_support/core_ext/hash' +require 'active_support/json' +require 'active_support/inflector' + +require 'rack/tracker/version' +require 'rack/tracker/extensions' +require 'rack/tracker/javascript_helper' require 'rack/tracker/railtie' if defined?(Rails) -require "rack/tracker/handler" -require "rack/tracker/handler_delegator" -require "rack/tracker/controller" -require "rack/tracker/google_analytics/google_analytics" -require "rack/tracker/google_global/google_global" -require "rack/tracker/google_tag_manager/google_tag_manager" -require "rack/tracker/google_adwords_conversion/google_adwords_conversion" -require "rack/tracker/facebook/facebook" -require "rack/tracker/facebook_pixel/facebook_pixel" -require "rack/tracker/vwo/vwo" -require "rack/tracker/go_squared/go_squared" -require "rack/tracker/criteo/criteo" -require "rack/tracker/zanox/zanox" -require "rack/tracker/hotjar/hotjar" -require "rack/tracker/bing/bing" -require "rack/tracker/hubspot/hubspot" -require "rack/tracker/drift/drift" -require "rack/tracker/heap/heap" +require 'rack/tracker/handler' +require 'rack/tracker/handler_delegator' +require 'rack/tracker/controller' +require 'rack/tracker/google_analytics/google_analytics' +require 'rack/tracker/google_global/google_global' +require 'rack/tracker/google_tag_manager/google_tag_manager' +require 'rack/tracker/google_adwords_conversion/google_adwords_conversion' +require 'rack/tracker/facebook/facebook' +require 'rack/tracker/facebook_pixel/facebook_pixel' +require 'rack/tracker/vwo/vwo' +require 'rack/tracker/go_squared/go_squared' +require 'rack/tracker/criteo/criteo' +require 'rack/tracker/zanox/zanox' +require 'rack/tracker/hotjar/hotjar' +require 'rack/tracker/bing/bing' +require 'rack/tracker/hubspot/hubspot' +require 'rack/tracker/drift/drift' +require 'rack/tracker/heap/heap' module Rack class Tracker @@ -40,17 +42,16 @@ def initialize(app, &block) def call(env) @status, @headers, @body = @app.call(env) return [@status, @headers, @body] unless html? + response = Rack::Response.new([], @status, @headers) env[EVENT_TRACKING_KEY] ||= {} - if session = env["rack.session"] - env[EVENT_TRACKING_KEY].deep_merge!(session.delete(EVENT_TRACKING_KEY) || {}) { |key, old, new| Array.wrap(old) + Array.wrap(new) } + if (session = env['rack.session']) + env[EVENT_TRACKING_KEY].deep_merge!(session.delete(EVENT_TRACKING_KEY) || {}) { |_key, old, new| Array.wrap(old) + Array.wrap(new) } end - if response.redirection? && session - session[EVENT_TRACKING_KEY] = env[EVENT_TRACKING_KEY] - end + session[EVENT_TRACKING_KEY] = env[EVENT_TRACKING_KEY] if response.redirection? && session @body.each { |fragment| response.write inject(env, fragment) } @body.close if @body.respond_to?(:close) @@ -60,7 +61,9 @@ def call(env) private - def html?; @headers['Content-Type'] =~ /html/; end + def html? + @headers['Content-Type'] =~ /html/ + end def inject(env, response) duplicated_response = response.dup @@ -90,7 +93,7 @@ def initialize(&block) # handler :google_analytics, { tracker: 'U-XXXXX-Y' } # end # - def handler(name, configuration = {}, &block) + def handler(name, configuration = {}) # we need here "something" (which is atm the handler struct) # to postpone the initialization of the handler, # to give it the env and configuration options when the result of the handler is injected into the response. diff --git a/lib/rack/tracker/bing/bing.rb b/lib/rack/tracker/bing/bing.rb index f7e71c7..d94eba5 100644 --- a/lib/rack/tracker/bing/bing.rb +++ b/lib/rack/tracker/bing/bing.rb @@ -1,5 +1,6 @@ -class Rack::Tracker::Bing < Rack::Tracker::Handler +# frozen_string_literal: true +class Rack::Tracker::Bing < Rack::Tracker::Handler class Conversion < OpenStruct end @@ -8,5 +9,4 @@ class Conversion < OpenStruct def tracker options[:tracker].respond_to?(:call) ? options[:tracker].call(env) : options[:tracker] end - end diff --git a/lib/rack/tracker/controller.rb b/lib/rack/tracker/controller.rb index 801a52a..5694626 100644 --- a/lib/rack/tracker/controller.rb +++ b/lib/rack/tracker/controller.rb @@ -1,10 +1,12 @@ +# frozen_string_literal: true + module Rack class Tracker module Controller - def tracker(&block) - if block_given? - yield(Rack::Tracker::HandlerDelegator.new(respond_to?(:request) ? request.env : env)) - end + def tracker + return unless block_given? + + yield(Rack::Tracker::HandlerDelegator.new(respond_to?(:request) ? request.env : env)) end end end diff --git a/lib/rack/tracker/criteo/criteo.rb b/lib/rack/tracker/criteo/criteo.rb index 5a71c7b..3415149 100644 --- a/lib/rack/tracker/criteo/criteo.rb +++ b/lib/rack/tracker/criteo/criteo.rb @@ -1,12 +1,13 @@ -class Rack::Tracker::Criteo < Rack::Tracker::Handler +# frozen_string_literal: true +class Rack::Tracker::Criteo < Rack::Tracker::Handler TRACKER_EVENTS = { # event name => event key name, e.g. { event: 'setSiteType', type: '' } set_site_type: :type, set_account: :account, set_customer_id: :id, set_email: :email - } + }.freeze class Event < OpenStruct def write @@ -20,8 +21,8 @@ def write def tracker_events @tracker_events ||= [].tap do |tracker_events| options.slice(*TRACKER_EVENTS.keys).each do |key, value| - if option_value = value.respond_to?(:call) ? value.call(env) : value - tracker_events << Event.new(:event => "#{key}".camelize(:lower), TRACKER_EVENTS[key] => "#{option_value}") + if (option_value = value.respond_to?(:call) ? value.call(env) : value) + tracker_events << Event.new(:event => key.to_s.camelize(:lower), TRACKER_EVENTS[key] => option_value.to_s) end end end diff --git a/lib/rack/tracker/drift/drift.rb b/lib/rack/tracker/drift/drift.rb index fb7fe34..08e3e14 100644 --- a/lib/rack/tracker/drift/drift.rb +++ b/lib/rack/tracker/drift/drift.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class Rack::Tracker::Drift < Rack::Tracker::Handler end diff --git a/lib/rack/tracker/extensions.rb b/lib/rack/tracker/extensions.rb index bfbe832..aaadadd 100644 --- a/lib/rack/tracker/extensions.rb +++ b/lib/rack/tracker/extensions.rb @@ -1,17 +1,20 @@ +# frozen_string_literal: true + require 'ostruct' # Backport of 2.0.0 stdlib ostruct#to_h class OpenStruct - def to_h - @table.dup - end unless method_defined? :to_h + unless method_defined? :to_h + def to_h + @table.dup + end + end end class Hash def stringify_values - inject({}) do |options, (key, value)| + each_with_object({}) do |(key, value), options| options[key] = value.to_s - options end end @@ -20,13 +23,13 @@ def compact end def deep_merge!(other_hash, &block) - other_hash.each_pair do |k,v| + other_hash.each_pair do |k, v| tv = self[k] - if tv.is_a?(Hash) && v.is_a?(Hash) - self[k] = tv.deep_merge(v, &block) - else - self[k] = block && tv ? block.call(k, tv, v) : v - end + self[k] = if tv.is_a?(Hash) && v.is_a?(Hash) + tv.deep_merge(v, &block) + else + block && tv ? block.call(k, tv, v) : v + end end self end @@ -35,30 +38,36 @@ def deep_merge!(other_hash, &block) # Destructively convert all keys by using the block operation. # This includes the keys from the root hash and from all # nested hashes. - def deep_transform_keys!(&block) - _deep_transform_keys_in_object!(self, &block) - end unless method_defined? :deep_transform_keys! + unless method_defined? :deep_transform_keys! + def deep_transform_keys!(&block) + _deep_transform_keys_in_object!(self, &block) + end + end - def _deep_transform_keys_in_object!(object, &block) - case object - when Hash - object.keys.each do |key| - value = object.delete(key) - object[yield(key)] = _deep_transform_keys_in_object!(value, &block) + unless method_defined? :_deep_transform_keys_in_object! + def _deep_transform_keys_in_object!(object, &block) + case object + when Hash + object.keys.each do |key| + value = object.delete(key) + object[yield(key)] = _deep_transform_keys_in_object!(value, &block) + end + object + when Array + object.map! { |e| _deep_transform_keys_in_object!(e, &block) } + else + object end - object - when Array - object.map! {|e| _deep_transform_keys_in_object!(e, &block)} - else - object end - end unless method_defined? :_deep_transform_keys_in_object! + end # NOTE Back ported from Rails 4 to 3 # Destructively convert all keys to strings. # This includes the keys from the root hash and from all # nested hashes. - def deep_stringify_keys! - deep_transform_keys!{ |key| key.to_s } - end unless method_defined? :deep_stringify_keys! + unless method_defined? :deep_stringify_keys! + def deep_stringify_keys! + deep_transform_keys!(&:to_s) + end + end end diff --git a/lib/rack/tracker/facebook/facebook.rb b/lib/rack/tracker/facebook/facebook.rb index 67a9311..9919e5c 100644 --- a/lib/rack/tracker/facebook/facebook.rb +++ b/lib/rack/tracker/facebook/facebook.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class Rack::Tracker::Facebook < Rack::Tracker::Handler class Event < OpenStruct def write - ['track', self.id, to_h.except(:id).compact].to_json + ['track', id, to_h.except(:id).compact].to_json end end @@ -10,5 +12,4 @@ def write def self.track(name, *event) { name.to_s => [event.last.merge('class_name' => 'Event')] } end - end diff --git a/lib/rack/tracker/facebook_pixel/facebook_pixel.rb b/lib/rack/tracker/facebook_pixel/facebook_pixel.rb index f6015dd..b182c86 100644 --- a/lib/rack/tracker/facebook_pixel/facebook_pixel.rb +++ b/lib/rack/tracker/facebook_pixel/facebook_pixel.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Rack::Tracker::FacebookPixel < Rack::Tracker::Handler self.position = :body self.allowed_tracker_options = [:id] diff --git a/lib/rack/tracker/go_squared/go_squared.rb b/lib/rack/tracker/go_squared/go_squared.rb index 7885d0a..f387195 100644 --- a/lib/rack/tracker/go_squared/go_squared.rb +++ b/lib/rack/tracker/go_squared/go_squared.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class Rack::Tracker::GoSquared < Rack::Tracker::Handler class VisitorName < OpenStruct def write - ['set', 'visitorName', self.name].to_json.gsub(/\[|\]/, '') + ['set', 'visitorName', name].to_json.gsub(/\[|\]/, '') end end @@ -20,10 +22,10 @@ def trackers end def visitor_name - events.select{|e| e.kind_of?(VisitorName) }.first + events.select { |e| e.is_a?(VisitorName) }.first end def visitor_info - events.select{|e| e.kind_of?(VisitorInfo) }.first + events.select { |e| e.is_a?(VisitorInfo) }.first end end diff --git a/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb b/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb index ecdf652..f765ffc 100644 --- a/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb +++ b/lib/rack/tracker/google_adwords_conversion/google_adwords_conversion.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Rack::Tracker::GoogleAdwordsConversion < Rack::Tracker::Handler class Conversion < OpenStruct end diff --git a/lib/rack/tracker/google_analytics/google_analytics.rb b/lib/rack/tracker/google_analytics/google_analytics.rb index f33663b..760142f 100644 --- a/lib/rack/tracker/google_analytics/google_analytics.rb +++ b/lib/rack/tracker/google_analytics/google_analytics.rb @@ -1,9 +1,10 @@ -class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler +# frozen_string_literal: true - self.allowed_tracker_options = [:cookie_domain, :user_id] +class Rack::Tracker::GoogleAnalytics < Rack::Tracker::Handler + self.allowed_tracker_options = %i[cookie_domain user_id] def initialize(env, options = {}) - options[:explicit_pageview] = true if !options.has_key?(:explicit_pageview) + options[:explicit_pageview] = true unless options.key?(:explicit_pageview) super(env, options) end @@ -18,22 +19,22 @@ def write end def event - { hitType: self.type }.merge(attributes.stringify_values).compact + { hitType: type }.merge(attributes.stringify_values).compact end def attributes - Hash[to_h.slice(:category, :action, :label, :value).map { |k,v| [self.type.to_s + k.to_s.capitalize, v] }] + Hash[to_h.slice(:category, :action, :label, :value).map { |k, v| [type.to_s + k.to_s.capitalize, v] }] end end class EnhancedEcommerce < OpenStruct def write - hash = self.to_h + hash = to_h label = hash[:label] attributes = hash.except(:label, :type).compact.stringify_values [ - "ec:#{self.type}", + "ec:#{type}", label, attributes.empty? ? nil : attributes ].compact.to_json.gsub(/\[|\]/, '') @@ -42,10 +43,10 @@ def write class Ecommerce < OpenStruct def write - attributes = self.to_h.except(:type).compact.stringify_values + attributes = to_h.except(:type).compact.stringify_values [ - "ecommerce:#{self.type}", + "ecommerce:#{type}", attributes ].to_json.gsub(/\[|\]/, '') end @@ -54,7 +55,7 @@ def write class Parameter < OpenStruct include Rack::Tracker::JavaScriptHelper def write - ['set', self.to_h.to_a].flatten.map { |v| %Q{'#{j(v)}'} }.join ', ' + ['set', to_h.to_a].flatten.map { |v| %('#{j(v)}') }.join ', ' end end @@ -63,11 +64,11 @@ def tracker end def ecommerce_events - events.select {|e| e.kind_of?(Ecommerce) } + events.select { |e| e.is_a?(Ecommerce) } end def enhanced_ecommerce_events - events.select {|e| e.kind_of?(EnhancedEcommerce) } + events.select { |e| e.is_a?(EnhancedEcommerce) } end def pageview_url_script diff --git a/lib/rack/tracker/google_global/google_global.rb b/lib/rack/tracker/google_global/google_global.rb index 5ccb817..929559d 100644 --- a/lib/rack/tracker/google_global/google_global.rb +++ b/lib/rack/tracker/google_global/google_global.rb @@ -1,7 +1,9 @@ +# frozen_string_literal: true + class Rack::Tracker::GoogleGlobal < Rack::Tracker::Handler - self.allowed_tracker_options = [:cookie_domain, :user_id, - :link_attribution, :allow_display_features, :anonymize_ip, - :custom_map, :optimize_id] + self.allowed_tracker_options = %i[cookie_domain user_id + link_attribution allow_display_features anonymize_ip + custom_map optimize_id] class Page < OpenStruct def params @@ -10,8 +12,8 @@ def params end class Event < OpenStruct - PREFIXED_PARAMS = %i[category label] - SKIP_PARAMS = %i[action] + PREFIXED_PARAMS = %i[category label].freeze + SKIP_PARAMS = %i[action].freeze def params Hash[to_h.except(*SKIP_PARAMS).map { |key, value| [param_key(key), value] }] @@ -59,8 +61,8 @@ def call_tracker(tracker) def invalid_tracker?(tracker) if tracker[:id].to_s.strip == '' $stdout.puts <<~WARN - WARNING: One of the trackers specified for Rack::Tracker handler 'google_global' is empty. - Trackers: #{options[:trackers]} + WARNING: One of the trackers specified for Rack::Tracker handler 'google_global' is empty. + Trackers: #{options[:trackers]} WARN true diff --git a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb index 2db9d2b..77f53f4 100644 --- a/lib/rack/tracker/google_tag_manager/google_tag_manager.rb +++ b/lib/rack/tracker/google_tag_manager/google_tag_manager.rb @@ -1,5 +1,6 @@ -class Rack::Tracker::GoogleTagManager < Rack::Tracker::Handler +# frozen_string_literal: true +class Rack::Tracker::GoogleTagManager < Rack::Tracker::Handler class Push < OpenStruct def write to_h.to_json @@ -10,11 +11,11 @@ def inject(response) # Sub! is enough, in well formed html there's only one head or body tag. # Block syntax need to be used, otherwise backslashes in input will mess the output. # @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50 - response.sub! %r{} do |m| - m.to_s << self.render_head + response.sub! // do |m| + m.to_s << render_head end - response.sub! %r{} do |m| - m.to_s << self.render_body + response.sub! // do |m| + m.to_s << render_body end response end @@ -24,10 +25,10 @@ def container end def render_head - Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_tag_manager_head.erb') ).render(self) + Tilt.new(File.join(File.dirname(__FILE__), 'template', 'google_tag_manager_head.erb')).render(self) end def render_body - Tilt.new( File.join( File.dirname(__FILE__), 'template', 'google_tag_manager_body.erb') ).render(self) + Tilt.new(File.join(File.dirname(__FILE__), 'template', 'google_tag_manager_body.erb')).render(self) end end diff --git a/lib/rack/tracker/handler.rb b/lib/rack/tracker/handler.rb index 2e31195..c9c5397 100644 --- a/lib/rack/tracker/handler.rb +++ b/lib/rack/tracker/handler.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + class Rack::Tracker::Handler class << self def process_track(env, method_name, *args, &block) @@ -25,7 +27,7 @@ def track(name, *event) def initialize(env, options = {}) self.env = env self.options = options - self.position = options[:position] if options.has_key?(:position) + self.position = options[:position] if options.key?(:position) end def events @@ -34,20 +36,19 @@ def events end def render - Tilt.new(File.join(File.dirname(__FILE__), handler_name, 'template', "#{handler_name}.erb") ).render(self) + Tilt.new(File.join(File.dirname(__FILE__), handler_name, 'template', "#{handler_name}.erb")).render(self) end def inject(response) # default to not inject this tracker if the DNT HTTP header is set # if the DO_NOT_RESPECT_DNT_HEADER config is set the DNT header is ignored :( - please do respect the DNT header! - if self.dnt_header_opt_out? && !self.options.has_key?(:DO_NOT_RESPECT_DNT_HEADER) - return response - end + return response if dnt_header_opt_out? && !options.key?(:DO_NOT_RESPECT_DNT_HEADER) + # Sub! is enough, in well formed html there's only one head or body tag. # Block syntax need to be used, otherwise backslashes in input will mess the output. # @see http://stackoverflow.com/a/4149087/518204 and https://github.com/railslove/rack-tracker/issues/50 - response.sub! %r{} do |m| - self.render << m.to_s + response.sub! %r{} do |m| + render << m.to_s end response end @@ -55,9 +56,9 @@ def inject(response) def write_event(event) event.deep_stringify_keys! # for consistent hash access use strings (keys from the session are always strings anyway) if env.key?('tracker') - self.env['tracker'].deep_merge!(event) { |key, old, new| Array.wrap(old) + Array.wrap(new) } + env['tracker'].deep_merge!(event) { |_key, old, new| Array.wrap(old) + Array.wrap(new) } else - self.env['tracker'] = event + env['tracker'] = event end end @@ -69,16 +70,14 @@ def tracker_options @_tracker_options ||= {}.tap do |tracker_options| options.slice(*allowed_tracker_options).each do |key, value| option_value = value.respond_to?(:call) ? value.call(env) : value - unless option_value.nil? - tracker_options[tracker_option_key(key)] = tracker_option_value(option_value) - end + tracker_options[tracker_option_key(key)] = tracker_option_value(option_value) unless option_value.nil? end end end # the request has set the DO NOT TRACK (DNT) and has opted to get not tracked (DNT=1) def dnt_header_opt_out? - self.env['HTTP_DNT'] && self.env['HTTP_DNT'].to_s == '1' + env['HTTP_DNT'] && env['HTTP_DNT'].to_s == '1' end private diff --git a/lib/rack/tracker/handler_delegator.rb b/lib/rack/tracker/handler_delegator.rb index f968fa9..59f4503 100644 --- a/lib/rack/tracker/handler_delegator.rb +++ b/lib/rack/tracker/handler_delegator.rb @@ -1,8 +1,8 @@ +# frozen_string_literal: true + class Rack::Tracker::HandlerDelegator class << self - def handler(method_name) - new.handler(method_name) - end + delegate :handler, to: :new end attr_accessor :env @@ -24,15 +24,13 @@ def respond_to?(method_name, include_private = false) end def handler(method_name) - return method_name if method_name.kind_of?(Class) + return method_name if method_name.is_a?(Class) _handler = method_name.to_s.camelize ["Rack::Tracker::#{_handler}", _handler].detect do |const| - begin - return const.constantize - rescue NameError - false - end + return const.constantize + rescue NameError + false end raise ArgumentError, "No such Handler: #{_handler}" diff --git a/lib/rack/tracker/heap/heap.rb b/lib/rack/tracker/heap/heap.rb index dac9efb..6b0a2f7 100644 --- a/lib/rack/tracker/heap/heap.rb +++ b/lib/rack/tracker/heap/heap.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class Rack::Tracker::Heap < Rack::Tracker::Handler end diff --git a/lib/rack/tracker/hotjar/hotjar.rb b/lib/rack/tracker/hotjar/hotjar.rb index 482e5d3..8635587 100644 --- a/lib/rack/tracker/hotjar/hotjar.rb +++ b/lib/rack/tracker/hotjar/hotjar.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class Rack::Tracker::Hotjar < Rack::Tracker::Handler end diff --git a/lib/rack/tracker/hubspot/hubspot.rb b/lib/rack/tracker/hubspot/hubspot.rb index 162b07c..733c297 100644 --- a/lib/rack/tracker/hubspot/hubspot.rb +++ b/lib/rack/tracker/hubspot/hubspot.rb @@ -1,2 +1,4 @@ +# frozen_string_literal: true + class Rack::Tracker::Hubspot < Rack::Tracker::Handler end diff --git a/lib/rack/tracker/javascript_helper.rb b/lib/rack/tracker/javascript_helper.rb index 02ccdfb..9be92fe 100644 --- a/lib/rack/tracker/javascript_helper.rb +++ b/lib/rack/tracker/javascript_helper.rb @@ -1,17 +1,18 @@ +# frozen_string_literal: true + # This module is extracted from Rails to provide reliable javascript escaping. # # @see https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/javascript_helper.rb module Rack::Tracker::JavaScriptHelper - JS_ESCAPE_MAP = { - '\\' => '\\\\', - ' '<\/', - "\r\n" => '\n', - "\n" => '\n', - "\r" => '\n', - '"' => '\\"', - "'" => "\\'" - } + '\\' => '\\\\', + ' '<\/', + "\r\n" => '\n', + "\n" => '\n', + "\r" => '\n', + '"' => '\\"', + "'" => "\\'" + }.freeze JS_ESCAPE_MAP["\342\200\250".force_encoding(Encoding::UTF_8).encode!] = '
' JS_ESCAPE_MAP["\342\200\251".force_encoding(Encoding::UTF_8).encode!] = '
' @@ -24,11 +25,11 @@ module Rack::Tracker::JavaScriptHelper # $('some_element').replaceWith('<%=j render 'some/element_template' %>'); def escape_javascript(javascript) if javascript - javascript.to_s.gsub(/(\\|<\/|\r\n|\342\200\250|\342\200\251|[\n\r"'])/u) { |match| JS_ESCAPE_MAP[match] } + javascript.to_s.gsub(%r{(\\|= 1.4" - spec.add_dependency "tilt", ">= 1.4" spec.add_dependency 'activesupport', '>= 3.0' + spec.add_dependency 'rack', '>= 1.4' + spec.add_dependency 'tilt', '>= 1.4' spec.add_development_dependency 'actionpack', '>= 3.0' - spec.add_development_dependency "bundler", ">= 1.16" - spec.add_development_dependency "rake" - spec.add_development_dependency "rspec", "~> 3.2" - spec.add_development_dependency "capybara", "~> 2.4" - spec.add_development_dependency "pry" - if RUBY_VERSION < "2.0" - spec.add_development_dependency "mime-types", "< 3.0" - spec.add_development_dependency "addressable", "< 2.5" + spec.add_development_dependency 'bundler', '>= 1.16' + spec.add_development_dependency 'capybara', '~> 2.4' + spec.add_development_dependency 'pry' + spec.add_development_dependency 'rake' + spec.add_development_dependency 'rspec', '~> 3.2' + if RUBY_VERSION < '2.0' + spec.add_development_dependency 'addressable', '< 2.5' + spec.add_development_dependency 'mime-types', '< 3.0' end end diff --git a/spec/benchmark/tracker_injection_benchmark.rb b/spec/benchmark/tracker_injection_benchmark.rb index 2874eb1..f986b5e 100644 --- a/spec/benchmark/tracker_injection_benchmark.rb +++ b/spec/benchmark/tracker_injection_benchmark.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' require 'benchmark' diff --git a/spec/handler/bing_spec.rb b/spec/handler/bing_spec.rb index 843752a..e17a758 100644 --- a/spec/handler/bing_spec.rb +++ b/spec/handler/bing_spec.rb @@ -1,53 +1,53 @@ -RSpec.describe Rack::Tracker::Bing do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::Bing do it 'will be placed in the body' do expect(described_class.position).to eq(:body) end - describe "with events" do + describe 'with events' do subject { described_class.new(env, tracker: 'somebody').render } - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'bing' => [ { 'class_name' => 'Conversion', 'category' => 'Users', 'action' => 'Login', 'label' => 'Standard', 'value' => 10 } ] - }} + } } end - it "will show event initialiser" do - expect(subject).to include "window.uetq = window.uetq || [];" + it 'will show event initialiser' do + expect(subject).to include 'window.uetq = window.uetq || [];' end - it "will show events" do + it 'will show events' do expect(subject).to include "window.uetq.push({ 'ec': 'Users', 'ea': 'Login', 'el': 'Standard', 'ev': 10 });" end end end - describe "with multiple events" do + describe 'with multiple events' do subject { described_class.new(env, tracker: 'somebody').render } - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'bing' => [ { 'class_name' => 'Conversion', 'category' => 'Users', 'action' => 'Login', 'label' => 'Standard', 'value' => 10 }, { 'class_name' => 'Conversion', 'category' => 'Users', 'action' => 'Logout', 'label' => 'Standard', 'value' => 5 } ] - }} + } } end - it "will show event initialiser" do - expect(subject).to include "window.uetq = window.uetq || [];" + it 'will show event initialiser' do + expect(subject).to include 'window.uetq = window.uetq || [];' end - it "will show events" do + it 'will show events' do expect(subject).to include "window.uetq.push({ 'ec': 'Users', 'ea': 'Login', 'el': 'Standard', 'ev': 10 });" expect(subject).to include "window.uetq.push({ 'ec': 'Users', 'ea': 'Logout', 'el': 'Standard', 'ev': 5 });" end end end - -end \ No newline at end of file +end diff --git a/spec/handler/criteo_spec.rb b/spec/handler/criteo_spec.rb index 8feded3..d12efde 100644 --- a/spec/handler/criteo_spec.rb +++ b/spec/handler/criteo_spec.rb @@ -1,11 +1,11 @@ -RSpec.describe Rack::Tracker::Criteo do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::Criteo do describe Rack::Tracker::Criteo::Event do - - subject { described_class.new(event: "viewItem", item: 'P001') } + subject { described_class.new(event: 'viewItem', item: 'P001') } describe '#write' do - specify { expect(subject.write).to eq("{\"event\":\"viewItem\",\"item\":\"P001\"}") } + specify { expect(subject.write).to eq('{"event":"viewItem","item":"P001"}') } end end @@ -20,20 +20,20 @@ def env describe '#render' do context 'with events' do - let(:env) { + let(:env) do { 'tracker' => { - 'criteo' => - [ - { - 'event' => 'viewItem', - 'item' => 'P001', - 'class_name' => 'Event' - } - ] + 'criteo' => + [ + { + 'event' => 'viewItem', + 'item' => 'P001', + 'class_name' => 'Event' + } + ] } } - } + end subject { described_class.new(env).render } @@ -43,18 +43,18 @@ def env end context 'without events' do - let(:env) { + let(:env) do { 'tracker' => { 'criteo' => [] } } - } + end - subject { described_class.new(env, { user_id: ->(env){ '123' } }).render } + subject { described_class.new(env, { user_id: ->(_env) { '123' } }).render } - it 'should render nothing' do - expect(subject).to eql "" + it 'renders nothing' do + expect(subject).to eql '' end end end @@ -65,7 +65,7 @@ def env context 'nil value' do let(:options) { { set_account: nil } } - it 'should ignore option' do + it 'ignores option' do expect(subject.tracker_events).to match_array [] end end @@ -73,7 +73,7 @@ def env context 'static string value' do let(:options) { { set_account: '1234' } } - it 'should set the value' do + it 'sets the value' do expect(subject.tracker_events).to match_array [ Rack::Tracker::Criteo::Event.new(event: 'setAccount', account: '1234') ] @@ -83,7 +83,7 @@ def env context 'static integer value' do let(:options) { { set_customer_id: 1234 } } - it 'should set the value as string' do + it 'sets the value as string' do expect(subject.tracker_events).to match_array [ Rack::Tracker::Criteo::Event.new(event: 'setCustomerId', id: '1234') ] @@ -91,19 +91,19 @@ def env end context 'unsupported option' do - let(:options) { { unsupported: "option" } } + let(:options) { { unsupported: 'option' } } subject { described_class.new(env, options) } - it 'should ignore the option' do + it 'ignores the option' do expect(subject.tracker_events).to match_array [] end end context 'proc returning value' do - let(:options) { { set_site_type: ->(env){ 'm' } } } + let(:options) { { set_site_type: ->(_env) { 'm' } } } - it 'should set the value' do + it 'sets the value' do expect(subject.tracker_events).to match_array [ Rack::Tracker::Criteo::Event.new(event: 'setSiteType', type: 'm') ] @@ -111,12 +111,11 @@ def env end context 'proc returning nil' do - let(:options) { { set_account: ->(env){ nil } } } + let(:options) { { set_account: ->(_env) { nil } } } - it 'should ignore the option' do + it 'ignores the option' do expect(subject.tracker_events).to match_array [] end end end - -end \ No newline at end of file +end diff --git a/spec/handler/drift_spec.rb b/spec/handler/drift_spec.rb index 5f96374..399a225 100644 --- a/spec/handler/drift_spec.rb +++ b/spec/handler/drift_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::Drift do def env { foo: 'bar' } diff --git a/spec/handler/facebook_pixel_spec.rb b/spec/handler/facebook_pixel_spec.rb index 9716529..47709f4 100644 --- a/spec/handler/facebook_pixel_spec.rb +++ b/spec/handler/facebook_pixel_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::FacebookPixel do def env { 'PIXEL_ID' => 'DYNAMIC_PIXEL_ID' } @@ -12,7 +14,7 @@ def env subject { described_class.new(env, id: 'PIXEL_ID').render } it 'will push the tracking events to the queue' do - expect(subject).to match(%r{fbq\('init', 'PIXEL_ID'\)}) + expect(subject).to match(/fbq\('init', 'PIXEL_ID'\)/) end it 'will add the noscript fallback' do @@ -21,10 +23,10 @@ def env end describe 'with dynamic id' do - subject { described_class.new(env, id: lambda { |env| env['PIXEL_ID'] }).render } + subject { described_class.new(env, id: ->(env) { env['PIXEL_ID'] }).render } it 'will push the tracking events to the queue' do - expect(subject).to match(%r{fbq\('init', 'DYNAMIC_PIXEL_ID'\)}) + expect(subject).to match(/fbq\('init', 'DYNAMIC_PIXEL_ID'\)/) end it 'will add the noscript fallback' do @@ -36,34 +38,34 @@ def env def env { 'tracker' => { - 'facebook_pixel' => - [ - { - 'type' => 'Purchase', - 'class_name' => 'Track', - 'options' => - { - 'value' => '23', - 'currency' => 'EUR' - } - },{ - 'type' => 'FrequentShopper', - 'class_name' => 'TrackCustom', - 'options' => - { - 'purchases' => 8, - 'category' => 'Sport' - } - } - ] + 'facebook_pixel' => + [ + { + 'type' => 'Purchase', + 'class_name' => 'Track', + 'options' => + { + 'value' => '23', + 'currency' => 'EUR' + } + }, { + 'type' => 'FrequentShopper', + 'class_name' => 'TrackCustom', + 'options' => + { + 'purchases' => 8, + 'category' => 'Sport' + } + } + ] } } end subject { described_class.new(env).render } it 'will push the tracking events to the queue' do - expect(subject).to match(%r{"track", "Purchase", \{"value":"23","currency":"EUR"\}}) - expect(subject).to match(%r{"trackCustom", "FrequentShopper", \{"purchases":8,"category":"Sport"\}}) + expect(subject).to match(/"track", "Purchase", \{"value":"23","currency":"EUR"\}/) + expect(subject).to match(/"trackCustom", "FrequentShopper", \{"purchases":8,"category":"Sport"\}/) end it 'will add the noscript fallback' do diff --git a/spec/handler/facebook_spec.rb b/spec/handler/facebook_spec.rb index 6a24738..456cd63 100644 --- a/spec/handler/facebook_spec.rb +++ b/spec/handler/facebook_spec.rb @@ -1,10 +1,11 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::Facebook do describe Rack::Tracker::Facebook::Event do - - subject { described_class.new({id: 'id', foo: 'bar'}) } + subject { described_class.new({ id: 'id', foo: 'bar' }) } describe '#write' do - specify { expect(subject.write).to eq(['track', 'id', {foo: 'bar'}].to_json) } + specify { expect(subject.write).to eq(['track', 'id', { foo: 'bar' }].to_json) } end end @@ -21,8 +22,8 @@ def env subject { described_class.new(env, custom_audience: 'custom_audience_id').render } it 'will push the tracking events to the queue' do - expect(subject).to match(%r{window._fbq.push\(\["addPixelId", "custom_audience_id"\]\)}) - expect(subject).to match(%r{window._fbq.push\(\["track", "PixelInitialized", \{\}\]\)}) + expect(subject).to match(/window._fbq.push\(\["addPixelId", "custom_audience_id"\]\)/) + expect(subject).to match(/window._fbq.push\(\["track", "PixelInitialized", \{\}\]\)/) end it 'will add the noscript fallback' do @@ -34,22 +35,22 @@ def env def env { 'tracker' => { - 'facebook' => - [ - { - 'id' => '123456789', - 'value' => '23', - 'currency' => 'EUR', - 'class_name' => 'Event' - } - ] + 'facebook' => + [ + { + 'id' => '123456789', + 'value' => '23', + 'currency' => 'EUR', + 'class_name' => 'Event' + } + ] } } end subject { described_class.new(env).render } it 'will push the tracking events to the queue' do - expect(subject).to match(%r{\["track","123456789",\{"value":"23","currency":"EUR"\}\]}) + expect(subject).to match(/\["track","123456789",\{"value":"23","currency":"EUR"\}\]/) end it 'will add the noscript fallback' do diff --git a/spec/handler/go_squared_spec.rb b/spec/handler/go_squared_spec.rb index 4d15bab..7898074 100644 --- a/spec/handler/go_squared_spec.rb +++ b/spec/handler/go_squared_spec.rb @@ -1,7 +1,8 @@ -RSpec.describe Rack::Tracker::GoSquared do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::GoSquared do def env - {misc: 'foobar'} + { misc: 'foobar' } end it 'will be placed in the head' do @@ -9,38 +10,37 @@ def env expect(described_class.new(env).position).to eq(:head) end - describe "with events" do - describe "visitor name" do + describe 'with events' do + describe 'visitor name' do def env - {'tracker' => { + { 'tracker' => { 'go_squared' => [ { 'class_name' => 'VisitorName', 'name' => 'John Doe' } ] - }} + } } end subject { described_class.new(env, tracker: '12345').render } - it "will show the right name" do - expect(subject).to match(%r{_gs\(\"set\",\"visitorName\",\"John Doe\"\)}) + it 'will show the right name' do + expect(subject).to match(/_gs\(\"set\",\"visitorName\",\"John Doe\"\)/) end end - describe "visitor details" do + describe 'visitor details' do def env - {'tracker' => { + { 'tracker' => { 'go_squared' => [ { 'class_name' => 'VisitorInfo', 'age' => 35, 'favorite_food' => 'pizza' } ] - }} + } } end subject { described_class.new(env, tracker: '12345').render } - it "will show the right properties" do - expect(subject).to match(%r{_gs\(\"set\",\"visitor\",{\"age\":35,\"favorite_food\":\"pizza\"}\)}) + it 'will show the right properties' do + expect(subject).to match(/_gs\(\"set\",\"visitor\",{\"age\":35,\"favorite_food\":\"pizza\"}\)/) end end end - end diff --git a/spec/handler/google_adwords_conversion_spec.rb b/spec/handler/google_adwords_conversion_spec.rb index 52536cf..26b0443 100644 --- a/spec/handler/google_adwords_conversion_spec.rb +++ b/spec/handler/google_adwords_conversion_spec.rb @@ -1,5 +1,6 @@ -RSpec.describe Rack::Tracker::GoogleAdwordsConversion do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::GoogleAdwordsConversion do def env { misc: 'foobar', @@ -13,23 +14,24 @@ def env expect(described_class.new(env, position: :body).position).to eq(:body) end - describe "with events" do - describe "default" do + describe 'with events' do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_adwords_conversion' => [ - { 'class_name' => 'Conversion', 'id' => 123456, 'language' => 'en', 'format' => '3', 'color' => 'ffffff', 'label' => 'Conversion Label' } + { 'class_name' => 'Conversion', 'id' => 123_456, 'language' => 'en', 'format' => '3', 'color' => 'ffffff', 'label' => 'Conversion Label' } ] - }} + } } end subject { described_class.new(env).render } + it 'will show events' do - expect(subject).to match(%r{var google_conversion_id = 123456;}) - expect(subject).to match(%r{var google_conversion_language = 'en';}) - expect(subject).to match(%r{var google_conversion_format = '3';}) - expect(subject).to match(%r{var google_conversion_color = 'ffffff';}) - expect(subject).to match(%r{var google_conversion_label = 'Conversion Label';}) + expect(subject).to match(/var google_conversion_id = 123456;/) + expect(subject).to match(/var google_conversion_language = 'en';/) + expect(subject).to match(/var google_conversion_format = '3';/) + expect(subject).to match(/var google_conversion_color = 'ffffff';/) + expect(subject).to match(/var google_conversion_label = 'Conversion Label';/) expect(subject).to match(%r{}) end end @@ -37,11 +39,13 @@ def env describe 'with options' do context 'when there are no params for the handler' do - let(:options) { { id: 123456, - language: 'en', - format: '3', - color: 'ffffff', - label: 'Conversion Label' } } + let(:options) do + { id: 123_456, + language: 'en', + format: '3', + color: 'ffffff', + label: 'Conversion Label' } + end let(:env) do { 'tracker' => { @@ -55,12 +59,12 @@ def env subject { described_class.new(env, options).render } it 'will show events by using default options' do - expect(subject).to match(%r{var google_conversion_id = 123456;}) - expect(subject).to match(%r{var google_conversion_language = 'en';}) - expect(subject).to match(%r{var google_conversion_format = '3';}) - expect(subject).to match(%r{var google_conversion_color = 'ffffff';}) - expect(subject).to match(%r{var google_conversion_label = 'Conversion Label';}) - expect(subject).to match(%r{var google_conversion_value = 10.0;}) + expect(subject).to match(/var google_conversion_id = 123456;/) + expect(subject).to match(/var google_conversion_language = 'en';/) + expect(subject).to match(/var google_conversion_format = '3';/) + expect(subject).to match(/var google_conversion_color = 'ffffff';/) + expect(subject).to match(/var google_conversion_label = 'Conversion Label';/) + expect(subject).to match(/var google_conversion_value = 10.0;/) expect(subject).to match(%r{}) end end diff --git a/spec/handler/google_analytics_spec.rb b/spec/handler/google_analytics_spec.rb index 6951a02..447b15e 100644 --- a/spec/handler/google_analytics_spec.rb +++ b/spec/handler/google_analytics_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::GoogleAnalytics do def env { @@ -62,7 +64,7 @@ def env end context 'with an allowed option configured with a block' do - subject { described_class.new(env, { user_id: lambda { |env| return env[:misc] } }) } + subject { described_class.new(env, { user_id: ->(env) { return env[:misc] } }) } it 'returns hash with option set' do expect(subject.tracker_options).to eql ({ userId: 'foobar' }) @@ -70,7 +72,7 @@ def env end context 'with an allowed option configured with a block returning nil' do - subject { described_class.new(env, { user_id: lambda { |env| return env[:non_existing_key] } }) } + subject { described_class.new(env, { user_id: ->(env) { return env[:non_existing_key] } }) } it 'returns an empty hash' do expect(subject.tracker_options).to eql ({}) @@ -86,215 +88,215 @@ def env end end - describe "with events" do + describe 'with events' do subject { described_class.new(env, tracker: 'somebody').render } - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_analytics' => [ { 'class_name' => 'Send', 'category' => 'Users', 'action' => 'Login', 'label' => 'Standard' } ] - }} + } } end - it "will show events" do - expect(subject).to match(%r{ga\(\"send\",{\"hitType\":\"event\",\"eventCategory\":\"Users\",\"eventAction\":\"Login\",\"eventLabel\":\"Standard\"}\)}) + it 'will show events' do + expect(subject).to match(/ga\(\"send\",{\"hitType\":\"event\",\"eventCategory\":\"Users\",\"eventAction\":\"Login\",\"eventLabel\":\"Standard\"}\)/) end end - describe "with a event value" do + describe 'with a event value' do def env - {'tracker' => { 'google_analytics' => [ - { 'class_name' => 'Send', category: "Users", action: "Login", label: "Standard", value: "5" } - ]}} + { 'tracker' => { 'google_analytics' => [ + { 'class_name' => 'Send', :category => 'Users', :action => 'Login', :label => 'Standard', :value => '5' } + ] } } end - it "will show events with values" do - expect(subject).to match(%r{ga\(\"send\",{\"hitType\":\"event\",\"eventCategory\":\"Users\",\"eventAction\":\"Login\",\"eventLabel\":\"Standard\",\"eventValue\":\"5\"}\)},) + it 'will show events with values' do + expect(subject).to match(/ga\(\"send\",{\"hitType\":\"event\",\"eventCategory\":\"Users\",\"eventAction\":\"Login\",\"eventLabel\":\"Standard\",\"eventValue\":\"5\"}\)/) end end end describe 'with ecommerce events' do - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_analytics' => [ { 'class_name' => 'Ecommerce', 'type' => 'addItem', 'id' => '1234', 'name' => 'Fluffy Pink Bunnies', 'sku' => 'DD23444', 'category' => 'Party Toys', 'price' => '11.99', 'quantity' => '1' }, { 'class_name' => 'Ecommerce', 'type' => 'addTransaction', 'id' => '1234', 'affiliation' => 'Acme Clothing', 'revenue' => 11.99, 'shipping' => '5', 'tax' => '1.29', 'currency' => 'EUR' } ] - }} + } } end subject { described_class.new(env, tracker: 'somebody', ecommerce: true).render } - it "will add items" do + it 'will add items' do attributes = { id: '1234', name: 'Fluffy Pink Bunnies', sku: 'DD23444', category: 'Party Toys', price: '11.99', quantity: '1' }.to_json - expect(subject).to match(%r{ga\(\"ecommerce:addItem\",#{attributes}\);}) + expect(subject).to match(/ga\(\"ecommerce:addItem\",#{attributes}\);/) end - it "will add transaction" do + it 'will add transaction' do attributes = { id: '1234', affiliation: 'Acme Clothing', revenue: '11.99', shipping: '5', tax: '1.29', currency: 'EUR' }.to_json - expect(subject).to match(%r{ga\(\"ecommerce:addTransaction\",#{attributes}\);}) + expect(subject).to match(/ga\(\"ecommerce:addTransaction\",#{attributes}\);/) end - it "will submit cart" do - expect(subject).to match(%r{ga\('ecommerce:send'\);}) + it 'will submit cart' do + expect(subject).to match(/ga\('ecommerce:send'\);/) end end end describe 'with enhanced ecommerce events' do - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_analytics' => [ { '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 }, { 'class_name' => 'EnhancedEcommerce', 'type' => 'setAction', 'label' => 'purchase' } ] - }} + } } end subject { described_class.new(env, tracker: 'somebody', enhanced_ecommerce: true).render } - it "will add product" do + it 'will add product' do attributes = { id: 'P12345', name: 'Android Warhol T-Shirt', category: 'Apparel', brand: 'Google', variant: 'black', price: '29.20', coupon: 'APPARELSALE', quantity: '1' }.to_json - expect(subject).to match(%r{ga\(\"ec:addProduct\",#{attributes}\);}) + expect(subject).to match(/ga\(\"ec:addProduct\",#{attributes}\);/) end - it "will add action" do - expect(subject).to match(%r{ga\(\"ec:setAction\",\"purchase\"\);}) + it 'will add action' do + expect(subject).to match(/ga\(\"ec:setAction\",\"purchase\"\);/) end end end describe 'with parameters events' do def env - {'tracker' => { + { 'tracker' => { 'google_analytics' => [ - { 'class_name' => 'Parameter', 'dimension1' => 'pink' }, + { 'class_name' => 'Parameter', 'dimension1' => 'pink' } ] - }} + } } end subject { described_class.new(env, tracker: 'somebody').render } - it "will render dimension parameter" do - expect(subject).to match(%r{ga\('set', 'dimension1', 'pink'}) + it 'will render dimension parameter' do + expect(subject).to match(/ga\('set', 'dimension1', 'pink'/) end end - describe "with custom domain" do - subject { described_class.new(env, tracker: 'somebody', cookie_domain: "railslabs.com").render } + describe 'with custom domain' do + subject { described_class.new(env, tracker: 'somebody', cookie_domain: 'railslabs.com').render } - it "will show asynchronous tracker with cookieDomain" do - expect(subject).to match(%r{ga\('create', 'somebody', {\"cookieDomain\":\"railslabs.com\"}\)}) - expect(subject).to match(%r{ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)}) + it 'will show asynchronous tracker with cookieDomain' do + expect(subject).to match(/ga\('create', 'somebody', {\"cookieDomain\":\"railslabs.com\"}\)/) + expect(subject).to match(/ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)/) end end - describe "with user_id tracking" do - subject { described_class.new(env, tracker: 'somebody', user_id: lambda { |env| return env[:user_id] } ).render } + describe 'with user_id tracking' do + subject { described_class.new(env, tracker: 'somebody', user_id: ->(env) { return env[:user_id] }).render } - it "will show asynchronous tracker with userId" do - expect(subject).to match(%r{ga\('create', 'somebody', {\"userId\":\"123\"}\)}) - expect(subject).to match(%r{ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)}) + it 'will show asynchronous tracker with userId' do + expect(subject).to match(/ga\('create', 'somebody', {\"userId\":\"123\"}\)/) + expect(subject).to match(/ga\('send', 'pageview', window\.location\.pathname \+ window\.location\.search\)/) end end - describe "with enhanced_link_attribution" do + describe 'with enhanced_link_attribution' do subject { described_class.new(env, tracker: 'happy', enhanced_link_attribution: true).render } - it "will embedded the linkid plugin script" do - expect(subject).to match(%r{linkid.js}) + it 'will embedded the linkid plugin script' do + expect(subject).to match(/linkid.js/) end end - describe "with advertising" do + describe 'with advertising' do subject { described_class.new(env, tracker: 'happy', advertising: true).render } - it "will require displayfeatures" do - expect(subject).to match(%r{ga\('require', 'displayfeatures'\)}) + it 'will require displayfeatures' do + expect(subject).to match(/ga\('require', 'displayfeatures'\)/) end end - describe "with enhanced ecommerce" do + describe 'with enhanced ecommerce' do subject { described_class.new(env, tracker: 'happy', enhanced_ecommerce: true).render } - it "will require the enhanced ecommerce plugin" do - expect(subject).to match(%r{ga\('require', 'ec'\)}) + it 'will require the enhanced ecommerce plugin' do + expect(subject).to match(/ga\('require', 'ec'\)/) end end - describe "with ecommerce" do + describe 'with ecommerce' do subject { described_class.new(env, tracker: 'happy', ecommerce: true).render } - it "will require the ecommerce plugin" do - expect(subject).to match(%r{ga\('require', 'ecommerce', 'ecommerce\.js'\)}) + it 'will require the ecommerce plugin' do + expect(subject).to match(/ga\('require', 'ecommerce', 'ecommerce\.js'\)/) end end - describe "with optimize" do + describe 'with optimize' do subject { described_class.new(env, tracker: 'happy', optimize: 'GTM-1234').render } - it "will require the optimize plugin with container ID" do - expect(subject).to match(%r{ga\('require', 'GTM-1234'\)}) + it 'will require the optimize plugin with container ID' do + expect(subject).to match(/ga\('require', 'GTM-1234'\)/) end end - describe "with anonymizeIp" do + describe 'with anonymizeIp' do subject { described_class.new(env, tracker: 'happy', anonymize_ip: true).render } - it "will set anonymizeIp to true" do - expect(subject).to match(%r{ga\('set', 'anonymizeIp', true\)}) + it 'will set anonymizeIp to true' do + expect(subject).to match(/ga\('set', 'anonymizeIp', true\)/) end end - describe "with dynamic tracker" do - subject { described_class.new(env, { tracker: lambda { |env| return env[:misc] }}).render } + describe 'with dynamic tracker' do + subject { described_class.new(env, { tracker: ->(env) { return env[:misc] } }).render } it 'will call tracker lambdas to obtain tracking codes' do - expect(subject).to match(%r{ga\('create', 'foobar', {}\)}) + expect(subject).to match(/ga\('create', 'foobar', {}\)/) end end describe 'adjusted bounce rate' do subject { described_class.new(env, tracker: 'afake', adjusted_bounce_rate_timeouts: [15, 30]).render } - it "will add timeouts to push read events" do - expect(subject).to include %q{setTimeout(function() { ga('send', 'event', '15_seconds', 'read'); },15000)} - expect(subject).to include %q{setTimeout(function() { ga('send', 'event', '30_seconds', 'read'); },30000)} + it 'will add timeouts to push read events' do + expect(subject).to include "setTimeout(function() { ga('send', 'event', '15_seconds', 'read'); },15000)" + expect(subject).to include "setTimeout(function() { ga('send', 'event', '30_seconds', 'read'); },30000)" end end describe '#pageview_url_script' do context 'without custom pageview url script' do - subject { described_class.new(env, {} ) } + subject { described_class.new(env, {}) } it 'returns return the custom pageview url script' do - expect(subject.pageview_url_script).to eql ("window.location.pathname + window.location.search") + expect(subject.pageview_url_script).to eql 'window.location.pathname + window.location.search' end end context 'with a custom pageview url script' do - subject { described_class.new(env, { pageview_url_script: "{ 'page': location.pathname + location.search + location.hash }"}) } + subject { described_class.new(env, { pageview_url_script: "{ 'page': location.pathname + location.search + location.hash }" }) } it 'returns return the custom pageview url script' do - expect(subject.pageview_url_script).to eql ("{ 'page': location.pathname + location.search + location.hash }") + expect(subject.pageview_url_script).to eql "{ 'page': location.pathname + location.search + location.hash }" end end context 'with explicit_pageview disabled' do - subject { described_class.new(env, {tracker: 'afake', explicit_pageview: false }).render } + subject { described_class.new(env, { tracker: 'afake', explicit_pageview: false }).render } it 'does not send a pageview event' do - expect(subject).not_to include %q{ga('send', 'pageview',} + expect(subject).not_to include "ga('send', 'pageview'," end end context 'defaults to sending the pageview event' do - subject { described_class.new(env, {tracker: 'afake'}).render } + subject { described_class.new(env, { tracker: 'afake' }).render } it 'does not send a pageview event' do expect(subject).to include "ga('send', 'pageview'" diff --git a/spec/handler/google_global_spec.rb b/spec/handler/google_global_spec.rb index 0858020..1dfbcf2 100644 --- a/spec/handler/google_global_spec.rb +++ b/spec/handler/google_global_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::GoogleGlobal do def env { @@ -22,7 +24,7 @@ def env end context 'with an allowed option configured with a block' do - subject { described_class.new(env, user_id: lambda { |env| return env[:misc] }) } + subject { described_class.new(env, user_id: ->(env) { return env[:misc] }) } it 'returns hash with option set' do expect(subject.tracker_options).to eql ({ user_id: 'foobar' }) @@ -30,7 +32,7 @@ def env end context 'with an allowed option configured with a block returning nil' do - subject { described_class.new(env, user_id: lambda { |env| return env[:non_existing_key] }) } + subject { described_class.new(env, user_id: ->(env) { return env[:non_existing_key] }) } it 'returns an empty hash' do expect(subject.tracker_options).to eql ({}) @@ -56,7 +58,7 @@ def env end context 'with option configured with a block' do - subject { described_class.new(env, set: lambda { |env| return { option: env[:misc] } }) } + subject { described_class.new(env, set: ->(env) { return { option: env[:misc] } }) } it 'returns hash with option set' do expect(subject.set_options).to eql ({ option: 'foobar' }) @@ -64,161 +66,169 @@ def env end context 'with option configured with a block returning nil' do - subject { described_class.new(env, set: lambda { |env| return env[:non_existing_key] }) } + subject { described_class.new(env, set: ->(env) { return env[:non_existing_key] }) } it 'returns nil' do expect(subject.set_options).to be nil end end end - describe "with custom domain" do - let(:tracker) { { id: 'somebody'}} - let(:options) { { cookie_domain: "railslabs.com", trackers: [tracker] } } + + describe 'with custom domain' do + let(:tracker) { { id: 'somebody' } } + let(:options) { { cookie_domain: 'railslabs.com', trackers: [tracker] } } + subject { described_class.new(env, options).render } - it "will show asyncronous tracker with cookie_domain" do - expect(subject).to match(%r{gtag\('config', 'somebody', {\"cookie_domain\":\"railslabs.com\"}\)}) + it 'will show asyncronous tracker with cookie_domain' do + expect(subject).to match(/gtag\('config', 'somebody', {\"cookie_domain\":\"railslabs.com\"}\)/) end end - describe "with user_id tracking" do - let(:tracker) { { id: 'somebody'}} - let(:options) { { user_id: lambda { |env| return env[:user_id] }, trackers: [tracker] } } + describe 'with user_id tracking' do + let(:tracker) { { id: 'somebody' } } + let(:options) { { user_id: ->(env) { return env[:user_id] }, trackers: [tracker] } } + subject { described_class.new(env, options).render } - it "will show asyncronous tracker with userId" do - expect(subject).to match(%r{gtag\('config', 'somebody', {\"user_id\":\"123\"}\)}) + it 'will show asyncronous tracker with userId' do + expect(subject).to match(/gtag\('config', 'somebody', {\"user_id\":\"123\"}\)/) end end - describe "with link_attribution" do - let(:tracker) { { id: 'happy'}} + describe 'with link_attribution' do + let(:tracker) { { id: 'happy' } } let(:options) { { link_attribution: true, trackers: [tracker] } } + subject { described_class.new(env, options).render } - it "will show asyncronous tracker with link_attribution" do - expect(subject).to match(%r{gtag\('config', 'happy', {\"link_attribution\":true}\)}) + it 'will show asyncronous tracker with link_attribution' do + expect(subject).to match(/gtag\('config', 'happy', {\"link_attribution\":true}\)/) end end - describe "with allow_display_features" do - let(:tracker) { { id: 'happy'}} + describe 'with allow_display_features' do + let(:tracker) { { id: 'happy' } } let(:options) { { allow_display_features: false, trackers: [tracker] } } + subject { described_class.new(env, options).render } - it "will disable display features" do - expect(subject).to match(%r{gtag\('config', 'happy', {\"allow_display_features\":false}\)}) + it 'will disable display features' do + expect(subject).to match(/gtag\('config', 'happy', {\"allow_display_features\":false}\)/) end end - describe "with anonymizeIp" do - let(:tracker) { { id: 'happy'}} + describe 'with anonymizeIp' do + let(:tracker) { { id: 'happy' } } let(:options) { { anonymize_ip: true, trackers: [tracker] } } + subject { described_class.new(env, options).render } - it "will set anonymizeIp to true" do - expect(subject).to match(%r{gtag\('config', 'happy', {\"anonymize_ip\":true}\)}) + it 'will set anonymizeIp to true' do + expect(subject).to match(/gtag\('config', 'happy', {\"anonymize_ip\":true}\)/) end end - describe "with dynamic tracker" do - let(:tracker) { { id: lambda { |env| return env[:misc] } }} + describe 'with dynamic tracker' do + let(:tracker) { { id: ->(env) { return env[:misc] } } } let(:options) { { trackers: [tracker] } } + subject { described_class.new(env, options).render } it 'will call tracker lambdas to obtain tracking codes' do - expect(subject).to match(%r{gtag\('config', 'foobar', {}\)}) + expect(subject).to match(/gtag\('config', 'foobar', {}\)/) end end - describe "with empty tracker" do - let(:present_tracker) { { id: 'present' }} - let(:empty_tracker) { { id: lambda { |env| return } }} + describe 'with empty tracker' do + let(:present_tracker) { { id: 'present' } } + let(:empty_tracker) { { id: ->(_env) { return } } } let(:options) { { trackers: [present_tracker, empty_tracker] } } + subject { described_class.new(env, options).render } it 'will not render config' do - expect(subject).to match(%r{gtag\('config', 'present', {}\)}) - expect(subject).not_to match(%r{gtag\('config', '', {}\)}) + expect(subject).to match(/gtag\('config', 'present', {}\)/) + expect(subject).not_to match(/gtag\('config', '', {}\)/) end end - describe "with set options" do + describe 'with set options' do let(:tracker) { { id: 'with_options' } } let(:options) { { trackers: [tracker], set: { foo: 'bar' } } } + subject { described_class.new(env, options).render } it 'will show set command' do - expect(subject).to match(%r{gtag\('set', {\"foo\":\"bar\"}\)}) + expect(subject).to match(/gtag\('set', {\"foo\":\"bar\"}\)/) end end - describe "with virtual pages" do + describe 'with virtual pages' do subject { described_class.new(env, trackers: [{ id: 'somebody' }]).render } - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_global' => [ { 'class_name' => 'Page', 'path' => '/virtual_page' } ] - }} + } } end - it "will show virtual page" do + it 'will show virtual page' do expect(subject).to match(%r{gtag\('config', 'somebody', {\"page_path\":\"/virtual_page\"}\);}) end end - describe "with a event value" do + describe 'with a event value' do def env - {'tracker' => { + { 'tracker' => { 'google_global' => [ { 'class_name' => 'Page', 'path' => '/virtual_page', 'location' => 'https://example.com/virtual_page', 'title' => 'Virtual Page' } ] - }} + } } end - it "will show virtual page" do + it 'will show virtual page' do expect(subject).to match(%r{gtag\('config', 'somebody', {\"page_title\":\"Virtual Page\",\"page_location\":\"https:\/\/example.com\/virtual_page\",\"page_path\":\"/virtual_page\"}\);}) end end end - describe "with events" do + describe 'with events' do subject { described_class.new(env, trackers: [{ id: 'somebody' }]).render } - describe "default" do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_global' => [ { 'class_name' => 'Event', 'action' => 'login' } ] - }} + } } end - it "will show the event" do - expect(subject).to match(%r{gtag\('event', 'login', {}\);}) + it 'will show the event' do + expect(subject).to match(/gtag\('event', 'login', {}\);/) end end - describe "with event parameters" do + describe 'with event parameters' do def env - {'tracker' => { + { 'tracker' => { 'google_global' => [ { 'class_name' => 'Event', - 'action' => 'login', - 'category' => 'engagement', - 'label' => 'Github', - 'value' => 5, - 'transaction_id' => 1001, - } + 'action' => 'login', + 'category' => 'engagement', + 'label' => 'Github', + 'value' => 5, + 'transaction_id' => 1001 } ] - }} + } } end - it "will show event" do - expect(subject).to match(%r{gtag\('event', 'login', {\"event_category\":\"engagement\",\"event_label\":\"Github\",\"value\":5,\"transaction_id\":1001}\);}) + it 'will show event' do + expect(subject).to match(/gtag\('event', 'login', {\"event_category\":\"engagement\",\"event_label\":\"Github\",\"value\":5,\"transaction_id\":1001}\);/) end end end diff --git a/spec/handler/google_tag_manager_spec.rb b/spec/handler/google_tag_manager_spec.rb index ed1e147..523b9cc 100644 --- a/spec/handler/google_tag_manager_spec.rb +++ b/spec/handler/google_tag_manager_spec.rb @@ -1,5 +1,6 @@ -RSpec.describe Rack::Tracker::GoogleTagManager do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::GoogleTagManager do def env { misc: 'foobar', @@ -7,29 +8,29 @@ def env } end - describe "with events" do - describe "default" do + describe 'with events' do + describe 'default' do def env - {'tracker' => { + { 'tracker' => { 'google_tag_manager' => [ - { 'class_name' => 'Push', 'page' => 'Cart', 'price' => 50, 'content_ids' => ['sku_1', 'sku_2', 'sku_3'] } + { 'class_name' => 'Push', 'page' => 'Cart', 'price' => 50, 'content_ids' => %w[sku_1 sku_2 sku_3] } ] - }} + } } end subject { described_class.new(env, container: 'somebody').render_head } - it "will show events" do - expect(subject).to match(%r{"page":"Cart","price":50,"content_ids":\["sku_1","sku_2","sku_3"\]}) + + it 'will show events' do + expect(subject).to match(/"page":"Cart","price":50,"content_ids":\["sku_1","sku_2","sku_3"\]/) end end end - describe "with dynamic tracker" do - subject { described_class.new(env, { container: lambda { |env| return env[:misc] }}).render_head } + describe 'with dynamic tracker' do + subject { described_class.new(env, { container: ->(env) { return env[:misc] } }).render_head } it 'will call tracker lambdas to obtain tracking codes' do - expect(subject).to match(%r{\(window,document,'script','dataLayer','foobar'\)}) + expect(subject).to match(/\(window,document,'script','dataLayer','foobar'\)/) end end - end diff --git a/spec/handler/handler_spec.rb b/spec/handler/handler_spec.rb index 2fabeff..a89a1ce 100644 --- a/spec/handler/handler_spec.rb +++ b/spec/handler/handler_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::Handler do def env { misc: 'foobar' } @@ -15,14 +17,14 @@ def env context 'with overridden allowed_tracker_options' do subject do handler = described_class.new(env, { - static_option: 'value', - dynamic_option: lambda { |env| return env[:misc] }, - dynamic_nil_option: lambda { |env| return env[:non_existent_key] }, - non_allowed_option: 'value' - }) + static_option: 'value', + dynamic_option: ->(env) { return env[:misc] }, + dynamic_nil_option: ->(env) { return env[:non_existent_key] }, + non_allowed_option: 'value' + }) handler.allowed_tracker_options = - [:static_option, :dynamic_option, :dynamic_nil_option] + %i[static_option dynamic_option dynamic_nil_option] handler end diff --git a/spec/handler/heap_spec.rb b/spec/handler/heap_spec.rb index 7e48df4..7d59201 100644 --- a/spec/handler/heap_spec.rb +++ b/spec/handler/heap_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::Heap do def env { foo: 'bar' } diff --git a/spec/handler/hotjar_spec.rb b/spec/handler/hotjar_spec.rb index c4a5855..698df29 100644 --- a/spec/handler/hotjar_spec.rb +++ b/spec/handler/hotjar_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + RSpec.describe Rack::Tracker::Hotjar do def env { foo: 'bar' } diff --git a/spec/handler/hubspot_spec.rb b/spec/handler/hubspot_spec.rb index ea36178..a6ff5a7 100644 --- a/spec/handler/hubspot_spec.rb +++ b/spec/handler/hubspot_spec.rb @@ -1,5 +1,6 @@ -RSpec.describe Rack::Tracker::Hubspot do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::Hubspot do def env { misc: '42' } end diff --git a/spec/handler/vwo_spec.rb b/spec/handler/vwo_spec.rb index 5b4fab6..1e6a7aa 100644 --- a/spec/handler/vwo_spec.rb +++ b/spec/handler/vwo_spec.rb @@ -1,12 +1,12 @@ -RSpec.describe Rack::Tracker::Vwo do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::Vwo do def env - {misc: 'foobar'} + { misc: 'foobar' } end it 'will be placed in the head' do expect(described_class.position).to eq(:head) expect(described_class.new(env).position).to eq(:head) end - end diff --git a/spec/handler/zanox_spec.rb b/spec/handler/zanox_spec.rb index dbf374d..0735e5c 100644 --- a/spec/handler/zanox_spec.rb +++ b/spec/handler/zanox_spec.rb @@ -1,20 +1,19 @@ -RSpec.describe Rack::Tracker::Zanox do +# frozen_string_literal: true +RSpec.describe Rack::Tracker::Zanox do describe Rack::Tracker::Zanox::Sale do - subject { described_class.new(order_i_d: 'DEFC-4321', currency_symbol: 'EUR', total_price: '150.00') } describe '#write' do - specify { expect(subject.write).to eq "OrderID=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]" } + specify { expect(subject.write).to eq 'OrderID=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]' } end end describe Rack::Tracker::Zanox::Mastertag do - - subject { described_class.new(id: "25GHTE9A07DF67DFG90T", category: 'Swimming', amount: '3.50', products: [{amount: '5', currency: 'EUR'}, {amount: '6', currency: 'USD'}]) } + subject { described_class.new(id: '25GHTE9A07DF67DFG90T', category: 'Swimming', amount: '3.50', products: [{ amount: '5', currency: 'EUR' }, { amount: '6', currency: 'USD' }]) } describe '#write' do - specify { expect(subject.write).to eq "var zx_category = \"Swimming\";\nvar zx_amount = \"3.50\";\nvar zx_products = [{\"amount\":\"5\",\"currency\":\"EUR\"},{\"amount\":\"6\",\"currency\":\"USD\"}];"} + specify { expect(subject.write).to eq "var zx_category = \"Swimming\";\nvar zx_amount = \"3.50\";\nvar zx_products = [{\"amount\":\"5\",\"currency\":\"EUR\"},{\"amount\":\"6\",\"currency\":\"USD\"}];" } end end @@ -29,75 +28,77 @@ def env describe '#render #sale_events' do context 'with events' do - let(:env) { + let(:env) do { 'tracker' => { - 'zanox' => - [ - { - 'CustomerID' => '123456', - 'OrderId' => 'DEFC-4321', - 'CurrencySymbol' => 'EUR', - 'TotalPrice' => '150.00', - 'class_name' => 'Sale', - } - ] + 'zanox' => + [ + { + 'CustomerID' => '123456', + 'OrderId' => 'DEFC-4321', + 'CurrencySymbol' => 'EUR', + 'TotalPrice' => '150.00', + 'class_name' => 'Sale' + } + ] } } - } + end subject { described_class.new(env, options).render } + let(:options) { { account_id: '123456H123456' } } it 'will display the correct tracking events' do - expect(subject).to include "https://ad.zanox.com/pps/?123456H123456&mode=[[1]]&CustomerID=[[123456]]&OrderId=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]" + expect(subject).to include 'https://ad.zanox.com/pps/?123456H123456&mode=[[1]]&CustomerID=[[123456]]&OrderId=[[DEFC-4321]]&CurrencySymbol=[[EUR]]&TotalPrice=[[150.00]]' end end end describe '#render #lead_events' do context 'with events' do - let(:env) { + let(:env) do { 'tracker' => { - 'zanox' => - [ - { - 'OrderId' => 'DEFC-4321', - 'class_name' => 'Lead' - } - ] + 'zanox' => + [ + { + 'OrderId' => 'DEFC-4321', + 'class_name' => 'Lead' + } + ] } } - } + end subject { described_class.new(env, options).render } + let(:options) { { account_id: '123456H123456' } } it 'will display the correct tracking events' do - expect(subject).to include "https://ad.zanox.com/ppl/?123456H123456&mode=[[1]]&OrderId=[[DEFC-4321]]" + expect(subject).to include 'https://ad.zanox.com/ppl/?123456H123456&mode=[[1]]&OrderId=[[DEFC-4321]]' end end end describe '#render a #mastertag event' do context 'with events' do - let(:env) { + let(:env) do { 'tracker' => { - 'zanox' => - [ - { - 'id' => '12345678D2345', - 'class_name' => 'Mastertag', - 'category' => 'Sewing', - 'identifier' => '234', - 'amount' => '5.90' - } - ] + 'zanox' => + [ + { + 'id' => '12345678D2345', + 'class_name' => 'Mastertag', + 'category' => 'Sewing', + 'identifier' => '234', + 'amount' => '5.90' + } + ] } } - } + end subject { described_class.new(env, options).render } diff --git a/spec/integration/bing_integration_spec.rb b/spec/integration/bing_integration_spec.rb index e68b8fd..ad95f16 100644 --- a/spec/integration/bing_integration_spec.rb +++ b/spec/integration/bing_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Bing Integration" do +RSpec.describe 'Bing Integration' do before do setup_app(action: :bing) do |tracker| tracker.handler :bing, { tracker: '12345678' } @@ -10,8 +12,7 @@ subject { page } - it "embeds the script tag with tracker" do - expect(page.find("body")).to have_content('var o = {ti: "12345678"};') + it 'embeds the script tag with tracker' do + expect(page.find('body')).to have_content('var o = {ti: "12345678"};') end - end diff --git a/spec/integration/criteo_integration_spec.rb b/spec/integration/criteo_integration_spec.rb index aa3df67..ae43490 100644 --- a/spec/integration/criteo_integration_spec.rb +++ b/spec/integration/criteo_integration_spec.rb @@ -1,32 +1,34 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Criteo Integration" do +RSpec.describe 'Criteo Integration' do before do setup_app(action: :criteo) do |tracker| tracker.handler(:criteo, { - set_account: '1234', - set_customer_id: ->(env){ '4711' }, - set_site_type: ->(env){ 'm' }, - set_email: 'user@test.com' - }) + set_account: '1234', + set_customer_id: ->(_env) { '4711' }, + set_site_type: ->(_env) { 'm' }, + set_email: 'user@test.com' + }) end visit '/' end subject { page } - it 'should include all the events' do + it 'includes all the events' do # tracker_events - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setAccount\",\"account\":\"1234\"});" - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setSiteType\",\"type\":\"m\"});" - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setCustomerId\",\"id\":\"4711\"});" - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"setEmail\",\"email\":\"user@test.com\"});" + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"setAccount","account":"1234"});' + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"setSiteType","type":"m"});' + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"setCustomerId","id":"4711"});' + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"setEmail","email":"user@test.com"});' # events - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"viewItem\",\"item\":\"P001\"});" - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"viewList\",\"item\":[\"P001\",\"P002\"]});" - expect(page.find("body")).to have_content "window.criteo_q.push({\"event\":\"trackTransaction\",\"id\":\"id\",\"item\":{\"id\":\"P0038\",\"price\":\"6.54\",\"quantity\":1}});" - 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}]});" + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"viewItem","item":"P001"});' + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"viewList","item":["P001","P002"]});' + expect(page.find('body')).to have_content 'window.criteo_q.push({"event":"trackTransaction","id":"id","item":{"id":"P0038","price":"6.54","quantity":1}});' + 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}]});' end describe 'adjust tracker position via options' do @@ -37,10 +39,9 @@ visit '/' end - it "will be placed in the specified tag" do - expect(page.find("body")).to_not have_content('criteo') - expect(page.find("head")).to have_content("{\"event\":\"setAccount\",\"account\":\"1234\"}") + it 'will be placed in the specified tag' do + expect(page.find('body')).not_to have_content('criteo') + expect(page.find('head')).to have_content('{"event":"setAccount","account":"1234"}') end - end end diff --git a/spec/integration/drift_integration_spec.rb b/spec/integration/drift_integration_spec.rb index 498538f..cbf10a2 100644 --- a/spec/integration/drift_integration_spec.rb +++ b/spec/integration/drift_integration_spec.rb @@ -1,3 +1,5 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' RSpec.describe 'Drift Integration' do diff --git a/spec/integration/facebook_integration_spec.rb b/spec/integration/facebook_integration_spec.rb index 456359a..96e9ddc 100644 --- a/spec/integration/facebook_integration_spec.rb +++ b/spec/integration/facebook_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Facebook Integration" do +RSpec.describe 'Facebook Integration' do before do setup_app(action: :facebook) do |tracker| tracker.handler :facebook, { custom_audience: 'my-audience' } @@ -10,7 +12,7 @@ subject { page } - it "embeds the script tag with tracking event from the controller action" do + it 'embeds the script tag with tracking event from the controller action' do expect(page).to have_content('window._fbq.push(["addPixelId", "my-audience"]);') expect(page.body).to include('https://www.facebook.com/tr?id=my-audience&ev=PixelInitialized') expect(page).to have_content('window._fbq.push(["track","conversion-event",{"value":"1","currency":"EUR"}]);') diff --git a/spec/integration/facebook_pixel_integration_spec.rb b/spec/integration/facebook_pixel_integration_spec.rb index 07af9f0..5e245ce 100644 --- a/spec/integration/facebook_pixel_integration_spec.rb +++ b/spec/integration/facebook_pixel_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Facebook Pixel Integration" do +RSpec.describe 'Facebook Pixel Integration' do before do setup_app(action: :facebook_pixel) do |tracker| tracker.handler :facebook_pixel, { id: 'PIXEL_ID' } @@ -10,7 +12,7 @@ subject { page } - it "embeds the script tag with tracking event from the controller action" do + it 'embeds the script tag with tracking event from the controller action' do expect(page).to have_content("fbq('init', 'PIXEL_ID');") expect(page.body).to include('https://www.facebook.com/tr?id=PIXEL_ID&ev=PageView&noscript=1') end @@ -20,7 +22,7 @@ expect(page.body).to match(/fbq\("track", "CompleteRegistration", {\"value\":0.75,\"currency\":\"EUR\"}\);/) end - it "can use non-standard event names for audience building" do + it 'can use non-standard event names for audience building' do expect(page.body).to match(/fbq\("trackCustom", "FrequentShopper", {\"purchases\":24,\"category\":\"Sport\"}/) end end diff --git a/spec/integration/go_squared_integration_spec.rb b/spec/integration/go_squared_integration_spec.rb index d530c6d..97f9b78 100644 --- a/spec/integration/go_squared_integration_spec.rb +++ b/spec/integration/go_squared_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "GoSquared Integration" do +RSpec.describe 'GoSquared Integration' do subject { page } before do @@ -18,39 +20,39 @@ visit '/' end - it "adds the tracker to the page" do + it 'adds the tracker to the page' do expect(page).to have_content("_gs('123456');") end - it "adds the visitorName to the page" do + it 'adds the visitorName to the page' do expect(page).to have_content('_gs("set","visitorName","John Doe");') end - it "adds the visitor to the page" do + it 'adds the visitor to the page' do expect(page).to have_content('_gs("set","visitor",{"age":35,"favorite_food":"pizza"});') end - it "sets anonymizeIp" do + it 'sets anonymizeIp' do expect(page).to have_content("_gs('set', 'anonymizeIp', true);") end - it "sets cookieDomain" do + it 'sets cookieDomain' do expect(page).to have_content("_gs('set', 'cookieDomain', 'domain.com');") end - it "sets useCookies" do + it 'sets useCookies' do expect(page).to have_content("_gs('set', 'useCookies', true);") end - it "sets trackHash" do + it 'sets trackHash' do expect(page).to have_content("_gs('set', 'trackHash', true);") end - it "sets trackLocal" do + it 'sets trackLocal' do expect(page).to have_content("_gs('set', 'trackLocal', true);") end - it "sets trackParams" do + it 'sets trackParams' do expect(page).to have_content("_gs('set', 'trackParams', true);") end @@ -64,7 +66,7 @@ visit '/' end - it "adds the tracker to the page" do + it 'adds the tracker to the page' do expect(page).to have_content("_gs('12345', 'primaryTracker');") expect(page).to have_content("_gs('67890', 'secondaryTracker');") end diff --git a/spec/integration/google_adwords_conversion_integration_spec.rb b/spec/integration/google_adwords_conversion_integration_spec.rb index 2e64ce9..2563e65 100644 --- a/spec/integration/google_adwords_conversion_integration_spec.rb +++ b/spec/integration/google_adwords_conversion_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Google Adwords Conversion Integration" do +RSpec.describe 'Google Adwords Conversion Integration' do before do setup_app(action: :google_adwords_conversion) do |tracker| tracker.handler :google_adwords_conversion @@ -10,9 +12,8 @@ subject { page } - it "embeds the script tag with tracking event from the controller action" do - expect(page.find("body")).to have_content("var google_conversion_id = 123456;\nvar google_conversion_language = 'en';\nvar google_conversion_format = '3';\nvar google_conversion_color = 'ffffff';\nvar google_conversion_label = 'Conversion Label';") - expect(page.find("body")).to have_xpath("//img[@src=\"//www.googleadservices.com/pagead/conversion/123456/?label=Conversion%20Label&guid=ON&script=0\"]") + it 'embeds the script tag with tracking event from the controller action' do + expect(page.find('body')).to have_content("var google_conversion_id = 123456;\nvar google_conversion_language = 'en';\nvar google_conversion_format = '3';\nvar google_conversion_color = 'ffffff';\nvar google_conversion_label = 'Conversion Label';") + expect(page.find('body')).to have_xpath('//img[@src="//www.googleadservices.com/pagead/conversion/123456/?label=Conversion%20Label&guid=ON&script=0"]') end - end diff --git a/spec/integration/google_analytics_integration_spec.rb b/spec/integration/google_analytics_integration_spec.rb index ba59ea2..2183a68 100644 --- a/spec/integration/google_analytics_integration_spec.rb +++ b/spec/integration/google_analytics_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Google Analytics Integration" do +RSpec.describe 'Google Analytics Integration' do before do setup_app(action: :google_analytics) do |tracker| tracker.handler :google_analytics, { tracker: 'U-XXX-Y' } @@ -10,14 +12,14 @@ subject { page } - it "embeds the script tag with tracking event from the controller action" do - expect(page.find("head")).to have_content('ga("ecommerce:addItem",{"id":"1234","name":"Fluffy Pink Bunnies","sku":"DD23444","category":"Party Toys","price":"11.99","quantity":"1"})') - expect(page.find("head")).to have_content('ga("ecommerce:addTransaction",{"id":"1234","affiliation":"Acme Clothing","revenue":"11.99","shipping":"5","tax":"1.29"})') - expect(page.find("head")).to have_content('ga("send",{"hitType":"event","eventCategory":"button","eventAction":"click","eventLabel":"nav-buttons","eventValue":"X"})') + it 'embeds the script tag with tracking event from the controller action' do + expect(page.find('head')).to have_content('ga("ecommerce:addItem",{"id":"1234","name":"Fluffy Pink Bunnies","sku":"DD23444","category":"Party Toys","price":"11.99","quantity":"1"})') + expect(page.find('head')).to have_content('ga("ecommerce:addTransaction",{"id":"1234","affiliation":"Acme Clothing","revenue":"11.99","shipping":"5","tax":"1.29"})') + expect(page.find('head')).to have_content('ga("send",{"hitType":"event","eventCategory":"button","eventAction":"click","eventLabel":"nav-buttons","eventValue":"X"})') end - it "will have default pageview url script" do - expect(page.find("head")).to have_content("ga('send', 'pageview', window.location.pathname + window.location.search);") + it 'will have default pageview url script' do + expect(page.find('head')).to have_content("ga('send', 'pageview', window.location.pathname + window.location.search);") end describe 'adjust tracker position via options' do @@ -28,9 +30,9 @@ visit '/' end - it "will be placed in the specified tag" do - expect(page.find("head")).to_not have_content('U-XXX-Y') - 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"})') + it 'will be placed in the specified tag' do + expect(page.find('head')).not_to have_content('U-XXX-Y') + 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"})') end end @@ -42,29 +44,28 @@ visit '/' end - it "will not mess up the html" do + it 'will not mess up the html' do expect(page.find('head')).to have_content('U-XXX-Y') # Backslashes are also escaped, thus \' becomes in \\\' in output - expect(page.find('head')).to have_content %q{Some escaped \\\\\\'value} + expect(page.find('head')).to have_content "Some escaped \\\\\\'value" end - it "automatically escape javascript in dimensions" do + it 'automatically escape javascript in dimensions' do expect(page.find('head')).to have_content('U-XXX-Y') - expect(page.find('head')).to have_content %q{Author\\'s name} + expect(page.find('head')).to have_content "Author\\'s name" end end describe 'Use custom pageview script' do before do setup_app(action: :google_analytics) do |tracker| - tracker.handler :google_analytics, { tracker: 'U-XXX-Y', pageview_url_script: "{ 'page': location.pathname + location.search + location.hash }"} + tracker.handler :google_analytics, { tracker: 'U-XXX-Y', pageview_url_script: "{ 'page': location.pathname + location.search + location.hash }" } end visit '/' end - it "will use the custom pageview script for the pageview event" do - expect(page.find("head")).to have_content("ga('send', 'pageview', { 'page': location.pathname + location.search + location.hash });") + it 'will use the custom pageview script for the pageview event' do + expect(page.find('head')).to have_content("ga('send', 'pageview', { 'page': location.pathname + location.search + location.hash });") end end - end diff --git a/spec/integration/google_global_integration_spec.rb b/spec/integration/google_global_integration_spec.rb index 14df465..44d2529 100644 --- a/spec/integration/google_global_integration_spec.rb +++ b/spec/integration/google_global_integration_spec.rb @@ -1,6 +1,8 @@ +# frozen_string_literal: true + require 'support/capybara_app_helper' -RSpec.describe "Google Global Integration Integration" do +RSpec.describe 'Google Global Integration Integration' do before do setup_app(action: :google_global) do |tracker| tracker.handler :google_global, tracker_options @@ -10,32 +12,32 @@ let(:tracker_options) { { trackers: [{ id: 'U-XXX-Y' }] } } - it "embeds the script tag with tracking event from the controller action" do - expect(page.find("head")).to have_content('U-XXX-Y') + it 'embeds the script tag with tracking event from the controller action' do + expect(page.find('head')).to have_content('U-XXX-Y') end describe 'adjust tracker position via options' do let(:tracker_options) { { trackers: [{ id: 'U-XXX-Y' }], position: :body } } - it "will be placed in the specified tag" do - expect(page.find("head")).to_not have_content('U-XXX-Y') - expect(page.find("body")).to have_content('U-XXX-Y') + it 'will be placed in the specified tag' do + expect(page.find('head')).not_to have_content('U-XXX-Y') + expect(page.find('body')).to have_content('U-XXX-Y') end end - describe "handles empty tracker id" do - let(:tracker_options) { { trackers: [{ id: nil }, { id: "" }, { id: " " }] } } + describe 'handles empty tracker id' do + let(:tracker_options) { { trackers: [{ id: nil }, { id: '' }, { id: ' ' }] } } - it "does not inject scripts" do - expect(page.find("head")).to_not have_content("