vero 0.9.1 → 0.10.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +15 -1
  3. data/Gemfile.lock +95 -73
  4. data/README.markdown +145 -121
  5. data/lib/generators/vero_generator.rb +18 -19
  6. data/lib/vero.rb +7 -3
  7. data/lib/vero/api.rb +14 -4
  8. data/lib/vero/api/base_api.rb +11 -10
  9. data/lib/vero/api/events/track_api.rb +5 -3
  10. data/lib/vero/api/users/delete_api.rb +21 -0
  11. data/lib/vero/api/users/edit_api.rb +5 -3
  12. data/lib/vero/api/users/edit_tags_api.rb +7 -5
  13. data/lib/vero/api/users/reidentify_api.rb +5 -3
  14. data/lib/vero/api/users/resubscribe_api.rb +3 -1
  15. data/lib/vero/api/users/track_api.rb +5 -3
  16. data/lib/vero/api/users/unsubscribe_api.rb +3 -1
  17. data/lib/vero/app.rb +4 -2
  18. data/lib/vero/config.rb +11 -8
  19. data/lib/vero/context.rb +9 -11
  20. data/lib/vero/context/api.rb +9 -7
  21. data/lib/vero/dsl.rb +3 -1
  22. data/lib/vero/railtie.rb +5 -3
  23. data/lib/vero/sender.rb +12 -31
  24. data/lib/vero/senders/base.rb +3 -1
  25. data/lib/vero/senders/delayed_job.rb +7 -7
  26. data/lib/vero/senders/invalid.rb +5 -3
  27. data/lib/vero/senders/resque.rb +8 -8
  28. data/lib/vero/senders/sidekiq.rb +3 -1
  29. data/lib/vero/senders/{thread.rb → sucker_punch.rb} +5 -3
  30. data/lib/vero/trackable.rb +4 -2
  31. data/lib/vero/trackable/base.rb +10 -9
  32. data/lib/vero/trackable/interface.rb +3 -1
  33. data/lib/vero/utility/ext.rb +3 -1
  34. data/lib/vero/utility/logger.rb +4 -6
  35. data/lib/vero/version.rb +3 -1
  36. data/lib/vero/view_helpers/javascript.rb +20 -20
  37. data/spec/lib/api/base_api_spec.rb +10 -8
  38. data/spec/lib/api/events/track_api_spec.rb +23 -21
  39. data/spec/lib/api/users/delete_api_spec.rb +33 -0
  40. data/spec/lib/api/users/edit_api_spec.rb +12 -10
  41. data/spec/lib/api/users/edit_tags_api_spec.rb +22 -20
  42. data/spec/lib/api/users/reidentify_spec.rb +16 -14
  43. data/spec/lib/api/users/resubscribe_api_spec.rb +16 -10
  44. data/spec/lib/api/users/track_api_spec.rb +21 -19
  45. data/spec/lib/api/users/unsubscribe_api_spec.rb +12 -10
  46. data/spec/lib/api_spec.rb +29 -24
  47. data/spec/lib/app_spec.rb +12 -10
  48. data/spec/lib/config_spec.rb +31 -29
  49. data/spec/lib/context_spec.rb +13 -11
  50. data/spec/lib/dsl_spec.rb +3 -1
  51. data/spec/lib/sender_spec.rb +12 -24
  52. data/spec/lib/senders/sidekiq_spec.rb +16 -9
  53. data/spec/lib/trackable_spec.rb +88 -114
  54. data/spec/lib/view_helpers_spec.rb +12 -8
  55. data/spec/spec_helper.rb +10 -4
  56. data/spec/support/base_config_shared_examples.rb +5 -3
  57. data/spec/support/user_support.rb +15 -7
  58. data/spec/support/vero_user_support.rb +4 -2
  59. data/vero.gemspec +14 -30
  60. metadata +30 -125
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  class Context
3
5
  include Vero::APIContext
@@ -6,27 +8,23 @@ module Vero
6
8
  def initialize(object = {})
7
9
  case object
8
10
  when Hash
9
- #stub
11
+ # stub
10
12
  when Vero::Context
11
13
  @config = object.config
12
14
  @subject = object.subject
13
15
  else
14
- object = Vero::Config.available_attributes.inject({}) do |hash, symbol|
16
+ object = Vero::Config.available_attributes.each_with_object({}) do |symbol, hash|
15
17
  hash[symbol] = object.respond_to?(symbol) ? object.send(symbol) : nil
16
- hash
17
18
  end
18
19
  end
20
+ return unless object.is_a?(Hash)
19
21
 
20
- if object.is_a?(Hash)
21
- @config = Vero::Config.new
22
- self.configure(object)
23
- end
22
+ @config = Vero::Config.new
23
+ configure(object)
24
24
  end
25
25
 
26
26
  def configure(hash = {}, &block)
27
- if hash.is_a?(Hash) && hash.any?
28
- @config.update_attributes(hash)
29
- end
27
+ @config.update_attributes(hash) if hash.is_a?(Hash) && hash.any?
30
28
 
31
29
  block.call(@config) if block_given?
32
30
  end
@@ -43,4 +41,4 @@ module Vero
43
41
  @config.configured?
44
42
  end
45
43
  end
46
- end
44
+ end
@@ -1,38 +1,40 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  module APIContext
3
5
  def track!(event_name, event_data, extras = {})
4
- options = {:data => event_data, :event_name => event_name, :identity => subject.to_vero, :extras => extras}
6
+ options = { data: event_data, event_name: event_name, identity: subject.to_vero, extras: extras }
5
7
  Vero::Api::Events.track!(options, self)
6
8
  end
7
9
 
8
10
  def identify!
9
11
  identity = subject.to_vero
10
- options = {:id => identity[:id], :email => identity[:email], :data => identity}
12
+ options = { id: identity[:id], email: identity[:email], data: identity }
11
13
  Vero::Api::Users.track!(options, self)
12
14
  end
13
15
 
14
16
  def update_user!
15
17
  identity = subject.to_vero
16
- options = {:id => identity[:id], :email => identity[:email], :changes => identity}
18
+ options = { id: identity[:id], email: identity[:email], changes: identity }
17
19
  Vero::Api::Users.edit_user!(options, self)
18
20
  end
19
21
 
20
22
  def update_user_tags!(add = [], remove = [])
21
23
  identity = subject.to_vero
22
- options = {:id => identity[:id], :email => identity[:email], :add => Array(add), :remove => Array(remove)}
24
+ options = { id: identity[:id], email: identity[:email], add: Array(add), remove: Array(remove) }
23
25
  Vero::Api::Users.edit_user_tags!(options, self)
24
26
  end
25
27
 
26
28
  def unsubscribe!
27
29
  identity = subject.to_vero
28
- options = {:id => identity[:id], :email => identity[:email]}
30
+ options = { id: identity[:id], email: identity[:email] }
29
31
  Vero::Api::Users.unsubscribe!(options, self)
30
32
  end
31
33
 
32
34
  def reidentify!(previous_id)
33
35
  identity = subject.to_vero
34
- options = {:id => previous_id, :new_id => identity[:id]}
36
+ options = { id: previous_id, new_id: identity[:id] }
35
37
  Vero::Api::Users.reidentify!(options, self)
36
38
  end
37
39
  end
38
- end
40
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  ##
3
5
  # A lightweight DSL for using the Vero API. You may find this desirable in
@@ -15,7 +17,7 @@ module Vero
15
17
  # end
16
18
  module DSL
17
19
  def vero
18
- @_vero_proxy ||= Proxy.new
20
+ @vero ||= Proxy.new
19
21
  end
20
22
 
21
23
  # :nodoc:
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vero/view_helpers/javascript'
2
4
 
3
5
  module Vero
4
6
  class Railtie < Rails::Railtie
5
- initializer "vero.view_helpers" do
6
- ActionView::Base.send :include, ViewHelpers::Javascript
7
+ initializer 'vero.view_helpers' do
8
+ ActionView::Base.include ViewHelpers::Javascript
7
9
  end
8
10
  end
9
- end
11
+ end
@@ -1,49 +1,30 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
 
3
5
  module Vero
4
- class SenderHash < ::Hash
6
+ class SenderLookup
5
7
  def [](key)
6
- if self.has_key?(key)
7
- super
8
- else
9
- klass_name = key.to_s.split("_").map(&:capitalize).join
8
+ klass_name = key.to_s.split('_').map(&:capitalize).join
9
+
10
+ if Vero::Senders.const_defined?(klass_name)
10
11
  Vero::Senders.const_get(klass_name)
12
+ else
13
+ Vero::Senders::Base
11
14
  end
12
15
  end
13
16
  end
14
17
 
15
18
  class Sender
16
19
  def self.senders
17
- t = Vero::SenderHash.new
18
-
19
- t.merge!({
20
- true => Vero::Senders::Invalid,
21
- false => Vero::Senders::Base,
22
- :none => Vero::Senders::Base,
23
- :thread => Vero::Senders::Invalid
24
- })
25
-
26
- if RUBY_VERSION !~ /1\.8\./
27
- t.merge!(
28
- true => Vero::Senders::Thread,
29
- :thread => Vero::Senders::Thread
30
- )
31
- end
32
-
33
- t
20
+ @senders ||= Vero::SenderLookup.new
34
21
  end
35
22
 
36
23
  def self.send(api_class, sender_strategy, domain, options)
37
- sender_class = if self.senders[sender_strategy]
38
- self.senders[sender_strategy]
39
- else
40
- self.senders[false]
41
- end
42
-
43
- (sender_class.new).call(api_class, domain, options)
44
- rescue => e
24
+ senders[sender_strategy].new.call(api_class, domain, options)
25
+ rescue StandardError => e
45
26
  options_s = JSON.dump(options)
46
- Vero::App.log(self.new, "method: #{api_class.name}, options: #{options_s}, error: #{e.message}")
27
+ Vero::App.log(new, "method: #{api_class.name}, options: #{options_s}, error: #{e.message}")
47
28
  raise e
48
29
  end
49
30
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
 
3
5
  module Vero
@@ -11,4 +13,4 @@ module Vero
11
13
  end
12
14
  end
13
15
  end
14
- end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'delayed_job'
3
5
 
@@ -9,13 +11,11 @@ module Vero
9
11
  options_s = JSON.dump(options)
10
12
  Vero::App.log(self, "method: #{api_class.name}, options: #{options_s}, response: delayed job queued")
11
13
  response
12
- rescue => e
13
- if e.message == "Could not find table 'delayed_jobs'"
14
- raise "To send ratings asynchronously, you must configure delayed_job. Run `rails generate delayed_job:active_record` then `rake db:migrate`."
15
- else
16
- raise e
17
- end
14
+ rescue StandardError => e
15
+ raise 'To send ratings asynchronously, you must configure delayed_job. Run `rails generate delayed_job:active_record` then `rake db:migrate`.' if e.message == "Could not find table 'delayed_jobs'"
16
+
17
+ raise e
18
18
  end
19
19
  end
20
20
  end
21
- end
21
+ end
@@ -1,9 +1,11 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  module Senders
3
5
  class Invalid
4
- def call(api_class, domain, options)
5
- raise "Vero sender not supported by your version of Ruby. Please change `config.async` to a valid sender. See https://github.com/getvero/vero for more information."
6
+ def call(_api_class, _domain, _options)
7
+ raise 'Vero sender not supported by your version of Ruby. Please change `config.async` to a valid sender. See https://github.com/getvero/vero for more information.'
6
8
  end
7
9
  end
8
10
  end
9
- end
11
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'resque'
3
5
 
@@ -5,15 +7,13 @@ module Vero
5
7
  class ResqueWorker
6
8
  @queue = :vero
7
9
 
8
- def self.perform(api_class_name, domain, options)
9
- api_class = eval(api_class_name)
10
- new_options = {}
11
- options.each do |k,v|
12
- new_options[k.to_sym] = v
10
+ def self.perform(api_class, domain, options)
11
+ new_options = options.each_with_object({}) do |(k, v), o|
12
+ o[k.to_sym] = v
13
13
  end
14
14
 
15
- api_class.new(domain, new_options).perform
16
- Vero::App.log(self, "method: #{api_class.name}, options: #{options.to_json}, response: resque job queued")
15
+ api_class.constantize.new(domain, new_options).perform
16
+ Vero::App.log(self, "method: #{api_class}, options: #{options.to_json}, response: resque job queued")
17
17
  end
18
18
  end
19
19
 
@@ -24,4 +24,4 @@ module Vero
24
24
  end
25
25
  end
26
26
  end
27
- end
27
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'sidekiq'
3
5
 
@@ -20,4 +22,4 @@ module Vero
20
22
  end
21
23
  end
22
24
  end
23
- end
25
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'json'
2
4
  require 'sucker_punch'
3
5
 
@@ -7,19 +9,19 @@ module Vero
7
9
 
8
10
  def perform(api_class, domain, options)
9
11
  new_options = {}
10
- options.each { |k,v| new_options[k.to_sym] = v }
12
+ options.each { |k, v| new_options[k.to_sym] = v }
11
13
 
12
14
  begin
13
15
  api_class.new(domain, new_options).perform
14
16
  Vero::App.log(self, "method: #{api_class.name}, options: #{options.to_json}, response: job performed")
15
- rescue => e
17
+ rescue StandardError => e
16
18
  Vero::App.log(self, "method: #{api_class.name}, options: #{options.to_json}, response: #{e.message}")
17
19
  end
18
20
  end
19
21
  end
20
22
 
21
23
  module Senders
22
- class Thread
24
+ class SuckerPunch
23
25
  def call(api_class, domain, options)
24
26
  Vero::SuckerPunchWorker.new.async.perform(api_class, domain, options)
25
27
  end
@@ -1,8 +1,10 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'vero/trackable/base'
2
4
  require 'vero/trackable/interface'
3
5
 
4
6
  module Vero
5
- module Trackable
7
+ module Trackable
6
8
  include Base
7
9
  include Interface
8
10
 
@@ -11,4 +13,4 @@ module Vero
11
13
  base.extend(Base::ClassMethods)
12
14
  end
13
15
  end
14
- end
16
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  module Trackable
3
5
  module Base
@@ -9,10 +11,10 @@ module Vero
9
11
  module ClassMethods
10
12
  def trackable(*args)
11
13
  @vero_trackable_map = case @vero_trackable_map
12
- when Array then (@vero_trackable_map << args).flatten
13
- else
14
- args
15
- end
14
+ when Array then (@vero_trackable_map << args).flatten
15
+ else
16
+ args
17
+ end
16
18
  end
17
19
 
18
20
  def trackable_map
@@ -27,15 +29,14 @@ module Vero
27
29
  def to_vero
28
30
  klass = self.class
29
31
  symbols, other = klass.trackable_map.partition { |i| i.is_a?(Symbol) }
30
-
31
- result = symbols.inject({}) do |hash, symbol|
32
+
33
+ result = symbols.each_with_object({}) do |symbol, hash|
32
34
  t = respond_to?(symbol) ? send(symbol) : nil
33
35
  hash[symbol] = t unless t.nil?
34
- hash
35
36
  end
36
37
 
37
38
  if other.is_a?(Array) && !other.empty?
38
- other.reject! { |i| !(i.is_a?(Hash) && i.has_key?(:extras)) }
39
+ other.select! { |i| (i.is_a?(Hash) && i.key?(:extras)) }
39
40
  other.each do |h|
40
41
  symbol = h[:extras]
41
42
  t = respond_to?(symbol, true) ? send(symbol) : nil
@@ -43,7 +44,7 @@ module Vero
43
44
  end
44
45
  end
45
46
 
46
- result[:email] = result.delete(:email_address) if result.has_key?(:email_address)
47
+ result[:email] = result.delete(:email_address) if result.key?(:email_address)
47
48
  result[:_user_type] = self.class.name
48
49
  result
49
50
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  module Trackable
3
5
  module Interface
@@ -14,4 +16,4 @@ module Vero
14
16
  end
15
17
  end
16
18
  end
17
- end
19
+ end
@@ -1,5 +1,7 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class Object
2
4
  def blank?
3
5
  respond_to?(:empty?) ? empty? : !self
4
6
  end
5
- end
7
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  module Utility
3
5
  module Logger
@@ -19,13 +21,9 @@ module Vero
19
21
  end
20
22
 
21
23
  def logger
22
- if defined?(Rails)
23
- Rails.logger
24
- else
25
- nil
26
- end
24
+ Rails.logger if defined?(Rails)
27
25
  end
28
26
  end
29
27
  end
30
28
  end
31
- end
29
+ end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
- VERSION = '0.9.1'
4
+ VERSION = '0.10.0'
3
5
  end
@@ -1,43 +1,43 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Vero
2
4
  module ViewHelpers
3
5
  module Javascript
4
6
  def vero_javascript_tag(method = :default, context = Vero::App.default_context)
5
- return "" unless context.configured?
7
+ return '' unless context.configured?
8
+
6
9
  config = context.config
7
10
 
8
- unless [:default, :mixpanel, :kissmetrics].include?(method)
9
- method = :default
10
- end
11
+ method = :default unless %i[default mixpanel kissmetrics].include?(method)
11
12
 
12
- method_name = method.to_s + "_vero_javascript_tag"
13
- self.send(method_name.to_sym, config.config_params)
13
+ method_name = "#{method}_vero_javascript_tag"
14
+ send(method_name.to_sym, config.config_params)
14
15
  end
15
16
 
16
17
  private
18
+
17
19
  def default_vero_javascript_tag(options = {})
18
- content_tag :script, {:type => "text/javascript"} do
19
- result = "var _veroq = _veroq || [];" +
20
- "setTimeout(function(){if(typeof window.Semblance==\"undefined\"){console.log(\"Vero did not load in time.\");for(var i=0;i<_veroq.length;i++){a=_veroq[i];if(a.length==3&&typeof a[2]==\"function\")a[2](null,false);}}},3000);" +
21
- "_veroq.push(['init', {" +
22
- options_to_string(options) +
23
- "}]);" +
24
- "(function() {var ve = document.createElement('script'); ve.type = 'text/javascript'; ve.async = true; ve.src = '//getvero.com/assets/m.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ve, s);})();"
20
+ content_tag :script, { type: 'text/javascript' } do
21
+ result = 'var _veroq = _veroq || [];' \
22
+ 'setTimeout(function(){if(typeof window.Semblance=="undefined"){console.log("Vero did not load in time.");for(var i=0;i<_veroq.length;i++){a=_veroq[i];if(a.length==3&&typeof a[2]=="function")a[2](null,false);}}},3000);' \
23
+ "_veroq.push(['init', {" +
24
+ options_to_string(options) +
25
+ '}]);' \
26
+ "(function() {var ve = document.createElement('script'); ve.type = 'text/javascript'; ve.async = true; ve.src = '//getvero.com/assets/m.js'; var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ve, s);})();"
25
27
  result.html_safe
26
28
  end.html_safe
27
29
  end
28
30
 
29
- def mixpanel_vero_javascript_tag(options = {})
30
- end
31
+ def mixpanel_vero_javascript_tag(options = {}); end
31
32
 
32
- def kissmetrics_vero_javascript_tag(options = {})
33
- end
33
+ def kissmetrics_vero_javascript_tag(options = {}); end
34
34
 
35
35
  def options_to_string(options)
36
- options = {} unless options.kind_of?(Hash)
36
+ options = {} unless options.is_a?(Hash)
37
37
 
38
38
  keys = options.keys.map(&:to_s)
39
- keys.sort.map { |k| "\"#{k}\": \"#{options[k.to_sym]}\"" }.join(", ")
39
+ keys.sort.map { |k| "\"#{k}\": \"#{options[k.to_sym]}\"" }.join(', ')
40
40
  end
41
41
  end
42
42
  end
43
- end
43
+ end