test_track_rails_client 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (98) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +62 -7
  3. data/Rakefile +8 -4
  4. data/app/models/test_track/analytics/mixpanel_client.rb +2 -5
  5. data/app/models/test_track/analytics/safe_wrapper.rb +4 -4
  6. data/app/models/test_track/config_updater.rb +2 -2
  7. data/app/models/test_track/fake/split_registry.rb +2 -2
  8. data/app/models/test_track/notify_assignment_job.rb +3 -4
  9. data/app/models/test_track/offline_session.rb +6 -4
  10. data/app/models/test_track/remote/split_registry.rb +2 -2
  11. data/app/models/test_track/remote/visitor.rb +2 -2
  12. data/app/models/test_track/session.rb +12 -73
  13. data/app/models/test_track/unsynced_assignments_notifier.rb +2 -4
  14. data/app/models/test_track/vary_dsl.rb +5 -1
  15. data/app/models/test_track/visitor.rb +0 -11
  16. data/lib/test_track_rails_client/version.rb +1 -1
  17. data/vendor/gems/fakeable_her/fakeable_her.gemspec +2 -3
  18. data/vendor/gems/her/her.gemspec +4 -5
  19. data/vendor/gems/her/lib/her/api.rb +1 -1
  20. data/vendor/gems/her/lib/her/model/associations/association_proxy.rb +1 -2
  21. data/vendor/gems/her/lib/her/model/orm.rb +41 -29
  22. data/vendor/gems/her/lib/her/model/parse.rb +1 -0
  23. data/vendor/gems/her/lib/her/model/relation.rb +21 -6
  24. data/vendor/gems/her/lib/her/version.rb +1 -1
  25. metadata +52 -139
  26. data/app/models/test_track/create_alias_job.rb +0 -18
  27. data/vendor/gems/her/CONTRIBUTING.md +0 -26
  28. data/vendor/gems/her/Gemfile +0 -10
  29. data/vendor/gems/her/README.md +0 -1023
  30. data/vendor/gems/her/Rakefile +0 -11
  31. data/vendor/gems/her/UPGRADE.md +0 -101
  32. data/vendor/gems/her/gemfiles/Gemfile.activemodel-3.2.x +0 -7
  33. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.0 +0 -7
  34. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.1 +0 -7
  35. data/vendor/gems/her/gemfiles/Gemfile.activemodel-4.2 +0 -7
  36. data/vendor/gems/her/spec/api_spec.rb +0 -114
  37. data/vendor/gems/her/spec/collection_spec.rb +0 -26
  38. data/vendor/gems/her/spec/error_collection_spec.rb +0 -33
  39. data/vendor/gems/her/spec/json_api/model_spec.rb +0 -168
  40. data/vendor/gems/her/spec/middleware/accept_json_spec.rb +0 -10
  41. data/vendor/gems/her/spec/middleware/first_level_parse_json_spec.rb +0 -62
  42. data/vendor/gems/her/spec/middleware/json_api_parser_spec.rb +0 -32
  43. data/vendor/gems/her/spec/middleware/second_level_parse_json_spec.rb +0 -35
  44. data/vendor/gems/her/spec/model/associations/association_proxy_spec.rb +0 -31
  45. data/vendor/gems/her/spec/model/associations_spec.rb +0 -504
  46. data/vendor/gems/her/spec/model/attributes_spec.rb +0 -404
  47. data/vendor/gems/her/spec/model/callbacks_spec.rb +0 -145
  48. data/vendor/gems/her/spec/model/dirty_spec.rb +0 -110
  49. data/vendor/gems/her/spec/model/http_spec.rb +0 -165
  50. data/vendor/gems/her/spec/model/introspection_spec.rb +0 -76
  51. data/vendor/gems/her/spec/model/nested_attributes_spec.rb +0 -134
  52. data/vendor/gems/her/spec/model/orm_spec.rb +0 -791
  53. data/vendor/gems/her/spec/model/parse_spec.rb +0 -372
  54. data/vendor/gems/her/spec/model/paths_spec.rb +0 -347
  55. data/vendor/gems/her/spec/model/relation_spec.rb +0 -226
  56. data/vendor/gems/her/spec/model/validations_spec.rb +0 -42
  57. data/vendor/gems/her/spec/model_spec.rb +0 -31
  58. data/vendor/gems/her/spec/spec_helper.rb +0 -27
  59. data/vendor/gems/her/spec/support/extensions/array.rb +0 -5
  60. data/vendor/gems/her/spec/support/extensions/hash.rb +0 -5
  61. data/vendor/gems/her/spec/support/macros/her_macros.rb +0 -17
  62. data/vendor/gems/her/spec/support/macros/model_macros.rb +0 -36
  63. data/vendor/gems/her/spec/support/macros/request_macros.rb +0 -27
  64. data/vendor/gems/publicsuffix-ruby/CHANGELOG.md +0 -236
  65. data/vendor/gems/publicsuffix-ruby/Gemfile +0 -3
  66. data/vendor/gems/publicsuffix-ruby/LICENSE.txt +0 -22
  67. data/vendor/gems/publicsuffix-ruby/README.md +0 -151
  68. data/vendor/gems/publicsuffix-ruby/Rakefile +0 -109
  69. data/vendor/gems/publicsuffix-ruby/lib/definitions.txt +0 -11467
  70. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/domain.rb +0 -387
  71. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/errors.rb +0 -53
  72. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/list.rb +0 -302
  73. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/rule.rb +0 -373
  74. data/vendor/gems/publicsuffix-ruby/lib/public_suffix/version.rb +0 -23
  75. data/vendor/gems/publicsuffix-ruby/lib/public_suffix.rb +0 -131
  76. data/vendor/gems/publicsuffix-ruby/public_suffix.gemspec +0 -39
  77. data/vendor/gems/publicsuffix-ruby/test/acceptance_test.rb +0 -42
  78. data/vendor/gems/publicsuffix-ruby/test/test_helper.rb +0 -6
  79. data/vendor/gems/publicsuffix-ruby/test/unit/domain_test.rb +0 -170
  80. data/vendor/gems/publicsuffix-ruby/test/unit/errors_test.rb +0 -23
  81. data/vendor/gems/publicsuffix-ruby/test/unit/list_test.rb +0 -179
  82. data/vendor/gems/publicsuffix-ruby/test/unit/public_suffix_test.rb +0 -115
  83. data/vendor/gems/publicsuffix-ruby/test/unit/rule_test.rb +0 -307
  84. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/capybara_configuration.rb +0 -98
  85. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/matchers.rb +0 -151
  86. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rspec_configuration.rb +0 -34
  87. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/html_safe.rb +0 -15
  88. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/raw.rb +0 -15
  89. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop/cop/betterment/safe_concat.rb +0 -15
  90. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/rubocop.rb +0 -3
  91. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/shared_examples/betterment_application_examples.rb +0 -43
  92. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/shared_examples.rb +0 -1
  93. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/site_prism_configuration.rb +0 -42
  94. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/site_prism_dropdown.rb +0 -17
  95. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/version.rb +0 -3
  96. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers/webmock_configuration.rb +0 -8
  97. data/vendor/gems/ruby_spec_helpers/lib/ruby_spec_helpers.rb +0 -2
  98. data/vendor/gems/ruby_spec_helpers/ruby_spec_helpers.gemspec +0 -25
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 907a4c144a91bae9ff7be92b2275ed72760731e1
4
- data.tar.gz: e19a1990632c47427b20d3bab81d5b71a1046488
3
+ metadata.gz: 6eefba329c2d3bcbf7e2ec64800ac65ae8d5b389
4
+ data.tar.gz: 9227d7cca55324a963b399c65d48088d917b143e
5
5
  SHA512:
6
- metadata.gz: 07ffbb3a5ee2fd8d8bcdf89a1d4268f34cdfe45b530e42b32186be058588eaa3946574274fc5c4887c6b861fa8f13b0290c8c253567347f0bbe68185603994fb
7
- data.tar.gz: 7742bbea0b0b764185a15440d5d8c32b3731e2d7f06db9b9350f5aa50b75b17f2aca7fe56e66b6a728577c4d7cfb23379c0bba65ada2dd81de856a870244111c
6
+ metadata.gz: 9496d2f71697004936ed0896e6805d32723b067ea93c6915ec07ac75b81371e1ddd2b0b697961f7ba188a22f77d45abe912e7b306355c34d449af4ef16bfd9bb
7
+ data.tar.gz: 4981fc0c2992de2469ff3d82b45a8a24af5d1dcef4ae70aa0dd615e77c4519c0210eba62f5b39b5239b8d5383dc53c49b41e2f3c9710bd4c374f4b4dc042c329
data/README.md CHANGED
@@ -15,7 +15,7 @@ If you're looking to do client-side assignment, then check out our [JS client](h
15
15
  * [Tracking visitor logins](#tracking-visitor-logins)
16
16
  * [Tracking signups](#tracking-signups)
17
17
  * [Testing splits](#testing-splits)
18
- * [Custom Analytics](#custom-analytics)
18
+ * [Analytics](#analytics)
19
19
  * [Upgrading](#upgrading)
20
20
  * [How to Contribute](#how-to-contribute)
21
21
 
@@ -335,8 +335,9 @@ it "shows the right info" do
335
335
  end
336
336
  ```
337
337
 
338
- ## Custom Analytics
339
- By default, TestTrack will use Mixpanel as an analytics backend. If you wish to use another provider, you can set the `analytics` attribute on `TestTrack` with your custom client. You should do this in a Rails initializer.
338
+ ## Analytics
339
+
340
+ TestTrack does not offer built-in functionality for analyzing the results of split tests. TestTrack does provide hooks to easily integrate with your preferred analytics tool. By default, TestTrack will use Mixpanel as an analytics backend. If you wish to use another tool, you can set the `analytics` attribute on `TestTrack` with your custom client. You should do this in a Rails initializer.
340
341
 
341
342
  ```ruby
342
343
  # config/initializers/test_track.rb
@@ -350,18 +351,72 @@ Your client must implement the following methods:
350
351
  #
351
352
  # @param visitor_id [String] TestTrack's unique visitor identification key
352
353
  # @param assignment [TestTrack::Assignment] The assignment model itself
353
- # @param properties [String] Any additional properties, currently only utilized for Mixpanel's UniqueId
354
- def track_assignment(visitor_id, assignment, properties)
354
+ def track_assignment(visitor_id, assignment)
355
355
 
356
356
  # Called after TestTrack.sign_up!
357
357
  #
358
358
  # @param visitor_id [String] TestTrack's unique visitor identification key
359
- # @param existing_id [String] Any existing identifier for the visitor(defaults to Mixpanel's UniqueId)
360
- def alias(visitor_id, existing_id)
359
+ def sign_up!(visitor_id)
360
+ ```
361
+
362
+ ### Using TestTrack with a new analytics tool
363
+
364
+ TestTrack manages its own visitor identifier which is different from the identifier of your analytics tool. We recommend using TestTrack's visitor identifier as your analytics identifier when possible. Within TestTrack Rails Client, assignment events will trigger a call to `TestTrack.analytics.track_assignment` with a TestTrack visitor identifier. To ensure that analytics events coming from within the browser have the right identifier, you must set the identifier when your analytics javascript library is loaded.
365
+
366
+ Here's an example for how to do it with Mixpanel:
367
+
368
+ ```javascript
369
+ mixpanel.init('YOUR MIXPANEL TOKEN', {
370
+ loaded: function(mixpanel) {
371
+ mixpanel.identify('<%= test_track_visitor.id %>');
372
+ }
373
+ });
374
+ ```
375
+
376
+ ### Using TestTrack with an existing analytics tool
377
+
378
+ In cases where you have already established identities with your analytics tool, you can use TestTrack's hooks to link TestTrack's visitor identifier to your analytics identifier.
379
+
380
+ Using Mixpanel as an example, you must call [`mixpanel.alias`](https://mixpanel.com/help/questions/articles/assigning-your-own-unique-ids-to-users) with the visitor's analytics identifier and their TestTrack visitor identifier. This will establish a link between those two identifiers within your analytics tool, allowing you to analyze your funnels. We recommend using a thread-local storage like [`RequestStore`](https://github.com/steveklabnik/request_store) to make your identifier available to the TestTrack analytics client.
381
+
382
+ In your controller, store the Mixpanel distinct ID in the RequestStore.
383
+
384
+ ```ruby
385
+ class ApplicationController < ActionController::Base
386
+ before_action :store_mixpanel_distinct_id
387
+
388
+ def store_mixpanel_distinct_id
389
+ RequestStore[:mixpanel_distinct_id] = cookies["mp_#{ENV['MIXPANEL_TOKEN']}_mixpanel"]
390
+ end
391
+ end
392
+ ```
393
+
394
+ Then in your custom analytics plugin, use that value for assignment events and aliasing.
395
+
396
+ ```ruby
397
+ def track_assignment!(visitor_id)
398
+ identifier = RequestStore[:mixpanel_distinct_id] || visitor_id
399
+ properties = {
400
+ SplitName: assignment.split_name,
401
+ SplitVariant: assignment.variant,
402
+ SplitContext: assignment.context
403
+ }
404
+
405
+ mixpanel.track(identifier, 'SplitAssigned', properties)
406
+ end
407
+
408
+ def sign_up!(visitor_id)
409
+ mixpanel.alias(visitor_id, RequestStore[:mixpanel_distinct_id])
410
+ end
361
411
  ```
362
412
 
363
413
  ## Upgrading
364
414
 
415
+ ### From 2.0 to 3.0
416
+
417
+ TestTrack Rails Client no longer manages your Mixpanel cookie. The analytics plugin now provides a callback on `sign_up!` that will allow you to implement this functionality within your application. Please see the [analytics documentation](#analytics) for more details.
418
+ The TestTrack.analytics client `#track_assignment` method no longer accepts a properties hash as an argument as `mixpanel_distinct_id` is no longer relevant.
419
+
365
420
  ### From 1.x to 1.3
366
421
 
367
422
  `TestTrack::Session#log_in!` and `TestTrack:Session#sign_up!` now take a `TestTrack::Identity` instance argument instead of an identity type and identity value.
data/Rakefile CHANGED
@@ -36,30 +36,34 @@ task :vendor_deps do
36
36
  FileUtils.module_eval do
37
37
  cd "vendor/gems" do
38
38
  rm_r Dir.glob('*')
39
- %w(ruby_spec_helpers her fakeable_her publicsuffix-ruby).each do |repo|
39
+ %w(her fakeable_her).each do |repo|
40
40
  `git clone --depth=1 git@github.com:Betterment/#{repo}.git && rm -rf #{repo}/.git`
41
41
  end
42
42
  end
43
43
 
44
- cd "vendor/gems/ruby_spec_helpers" do
44
+ cd "vendor/gems/her" do
45
45
  rm_r(Dir.glob('.*') - %w(. ..))
46
46
  rm_r Dir.glob('*.md')
47
47
  rm_r %w(
48
+ Appraisals
48
49
  Gemfile
49
50
  Gemfile.lock
51
+ Rakefile
52
+ gemfiles
50
53
  spec
51
54
  ), force: true
52
- `sed -E -i '' '/license/d' ruby_spec_helpers.gemspec`
53
55
  end
54
56
 
55
57
  cd "vendor/gems/fakeable_her" do
56
58
  rm_r(Dir.glob('.*') - %w(. ..))
57
59
  rm_r Dir.glob('*.md')
58
60
  rm_r %w(
61
+ Appraisals
59
62
  Gemfile
60
63
  Gemfile.lock
61
64
  Rakefile
62
65
  bin
66
+ gemfiles
63
67
  spec
64
68
  ), force: true
65
69
  `sed -E -i '' '/license/d' fakeable_her.gemspec`
@@ -70,7 +74,7 @@ end
70
74
 
71
75
  task(:default).clear
72
76
  if ENV['APPRAISAL_INITIALIZED'] || ENV['TRAVIS']
73
- task default: [:rubocop, :spec]
77
+ task default: %i(rubocop spec)
74
78
  else
75
79
  require 'appraisal'
76
80
  Appraisal::Task.new
@@ -1,10 +1,7 @@
1
1
  module TestTrack::Analytics
2
2
  class MixpanelClient
3
- delegate :alias, to: :mixpanel
4
-
5
- def track_assignment(visitor_id, assignment, params = {})
6
- distinct_id = params.delete(:mixpanel_distinct_id) || visitor_id
7
- mixpanel.track(distinct_id, 'SplitAssigned', split_properties(assignment).merge(TTVisitorID: visitor_id))
3
+ def track_assignment(visitor_id, assignment)
4
+ mixpanel.track(visitor_id, 'SplitAssigned', split_properties(assignment).merge(TTVisitorID: visitor_id))
8
5
  end
9
6
 
10
7
  private
@@ -12,12 +12,12 @@ module TestTrack::Analytics
12
12
  @error_handler = handler
13
13
  end
14
14
 
15
- def track_assignment(visitor_id, assignment, params = {})
16
- safe_action { underlying.track_assignment(visitor_id, assignment, params) }
15
+ def track_assignment(visitor_id, assignment)
16
+ safe_action { underlying.track_assignment(visitor_id, assignment) }
17
17
  end
18
18
 
19
- def alias(visitor_id, existing_id)
20
- safe_action { underlying.alias(visitor_id, existing_id) }
19
+ def sign_up!(visitor_id)
20
+ safe_action { underlying.sign_up!(visitor_id) } if underlying.respond_to?(:sign_up!)
21
21
  end
22
22
 
23
23
  private
@@ -1,5 +1,5 @@
1
1
  class TestTrack::ConfigUpdater
2
- def initialize(schema_file_path = "#{Rails.root}/db/test_track_schema.yml")
2
+ def initialize(schema_file_path = Rails.root.join('db', 'test_track_schema.yml'))
3
3
  @schema_file_path = schema_file_path
4
4
  end
5
5
 
@@ -86,7 +86,7 @@ class TestTrack::ConfigUpdater
86
86
  end
87
87
 
88
88
  def schema_file_hash
89
- @schema_hash ||= YAML.load(schema_file_contents) || {}
89
+ @schema_hash ||= YAML.safe_load(schema_file_contents) || {}
90
90
  end
91
91
 
92
92
  def schema_file_contents
@@ -39,7 +39,7 @@ class TestTrack::Fake::SplitRegistry
39
39
  end
40
40
 
41
41
  def test_track_schema_yml_path
42
- ENV["TEST_TRACK_SCHEMA_FILE_PATH"] || "#{Rails.root}/db/test_track_schema.yml"
42
+ ENV["TEST_TRACK_SCHEMA_FILE_PATH"] || Rails.root.join('db', 'test_track_schema.yml')
43
43
  end
44
44
 
45
45
  def splits_with_deterministic_weights
@@ -47,7 +47,7 @@ class TestTrack::Fake::SplitRegistry
47
47
  default_variant = weighting_registry.keys.sort.first
48
48
 
49
49
  adjusted_weights = { default_variant => 100 }
50
- weighting_registry.except(default_variant).keys.each do |variant|
50
+ weighting_registry.except(default_variant).each_key do |variant|
51
51
  adjusted_weights[variant] = 0
52
52
  end
53
53
 
@@ -1,13 +1,12 @@
1
1
  class TestTrack::NotifyAssignmentJob
2
- attr_reader :mixpanel_distinct_id, :visitor_id, :assignment
2
+ attr_reader :visitor_id, :assignment
3
3
 
4
4
  def initialize(opts)
5
5
  @visitor_id = opts.delete(:visitor_id)
6
- @mixpanel_distinct_id = opts.delete(:mixpanel_distinct_id)
7
6
  @assignment = opts.delete(:assignment)
8
7
 
9
8
  %w(visitor_id assignment).each do |param_name|
10
- raise "#{param_name} must be present" unless send(param_name).present?
9
+ raise "#{param_name} must be present" if send(param_name).blank?
11
10
  end
12
11
  raise "unknown opts: #{opts.keys.to_sentence}" if opts.present?
13
12
  end
@@ -25,7 +24,7 @@ class TestTrack::NotifyAssignmentJob
25
24
 
26
25
  def track
27
26
  return "failure" unless TestTrack.enabled?
28
- result = TestTrack.analytics.track_assignment(visitor_id, assignment, mixpanel_distinct_id: mixpanel_distinct_id)
27
+ result = TestTrack.analytics.track_assignment(visitor_id, assignment)
29
28
  result ? "success" : "failure"
30
29
  end
31
30
  end
@@ -45,9 +45,11 @@ class TestTrack::OfflineSession
45
45
  end
46
46
 
47
47
  def notify_unsynced_assignments!
48
- TestTrack::UnsyncedAssignmentsNotifier.new(
49
- visitor_id: visitor.id,
50
- assignments: visitor.unsynced_assignments
51
- ).notify if unsynced_assignments?
48
+ if unsynced_assignments?
49
+ TestTrack::UnsyncedAssignmentsNotifier.new(
50
+ visitor_id: visitor.id,
51
+ assignments: visitor.unsynced_assignments
52
+ ).notify
53
+ end
52
54
  end
53
55
  end
@@ -26,9 +26,9 @@ class TestTrack::Remote::SplitRegistry
26
26
  if faked?
27
27
  instance.attributes.freeze
28
28
  else
29
- Rails.cache.fetch(CACHE_KEY, expires_in: 5.seconds) do
29
+ Rails.cache.fetch(CACHE_KEY, expires_in: 5.seconds) {
30
30
  instance.attributes
31
- end.freeze
31
+ }.freeze
32
32
  end
33
33
  rescue *TestTrack::SERVER_ERRORS => e
34
34
  Rails.logger.error "TestTrack failed to load split registry. #{e}"
@@ -6,8 +6,8 @@ class TestTrack::Remote::Visitor
6
6
  has_many :assignments
7
7
 
8
8
  def self.from_identifier(identifier_type, identifier_value)
9
- raise "must provide an identifier_type" unless identifier_type.present?
10
- raise "must provide an identifier_value" unless identifier_value.present?
9
+ raise "must provide an identifier_type" if identifier_type.blank?
10
+ raise "must provide an identifier_value" if identifier_value.blank?
11
11
 
12
12
  # TODO: FakeableHer needs to make this faking a feature of `get`
13
13
  if faked?
@@ -14,7 +14,6 @@ class TestTrack::Session
14
14
  manage_cookies!
15
15
  manage_response_headers!
16
16
  notify_unsynced_assignments! if sync_assignments?
17
- create_alias! if signed_up?
18
17
  end
19
18
 
20
19
  def visitor_dsl
@@ -31,42 +30,27 @@ class TestTrack::Session
31
30
  }
32
31
  end
33
32
 
34
- def log_in!(*args) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
35
- opts = args[-1].is_a?(Hash) ? args.pop : {}
33
+ def log_in!(identity, forget_current_visitor: nil)
34
+ identifier_type = identity.test_track_identifier_type
35
+ identifier_value = identity.test_track_identifier_value
36
36
 
37
- if args[0].is_a?(TestTrack::Identity)
38
- identity = args[0]
39
- identifier_type = identity.test_track_identifier_type
40
- identifier_value = identity.test_track_identifier_value
41
- else
42
- identifier_type = args[0]
43
- identifier_value = args[1]
44
- warn "#log_in! with two args is deprecated. Please provide a TestTrack::Identity"
45
- end
46
-
47
- @visitor = TestTrack::Visitor.new if opts[:forget_current_visitor]
37
+ @visitor = TestTrack::Visitor.new if forget_current_visitor
48
38
  visitor.link_identifier!(identifier_type, identifier_value)
49
39
 
50
40
  identities << identity if identity.present?
51
- self.mixpanel_distinct_id = visitor.id
52
41
  true
53
42
  end
54
43
 
55
- def sign_up!(*args) # rubocop:disable Metrics/MethodLength
56
- if args[0].is_a?(TestTrack::Identity)
57
- identity = args[0]
58
- identifier_type = identity.test_track_identifier_type
59
- identifier_value = identity.test_track_identifier_value
60
- else
61
- identifier_type = args[0]
62
- identifier_value = args[1]
63
- warn "#sign_up! with two args is deprecated. Please provide a TestTrack::Identity"
64
- end
44
+ def sign_up!(identity)
45
+ identifier_type = identity.test_track_identifier_type
46
+ identifier_value = identity.test_track_identifier_value
65
47
 
66
48
  visitor.link_identifier!(identifier_type, identifier_value)
67
-
68
49
  identities << identity if identity.present?
69
- @signed_up = true
50
+
51
+ TestTrack.analytics.sign_up!(visitor.id)
52
+
53
+ true
70
54
  end
71
55
 
72
56
  def has_matching_identity?(identity)
@@ -75,8 +59,7 @@ class TestTrack::Session
75
59
 
76
60
  private
77
61
 
78
- attr_reader :controller, :signed_up
79
- alias signed_up? signed_up
62
+ attr_reader :controller
80
63
 
81
64
  def visitor
82
65
  @visitor ||= TestTrack::Visitor.new(id: visitor_id)
@@ -127,7 +110,6 @@ class TestTrack::Session
127
110
  end
128
111
 
129
112
  def manage_cookies!
130
- set_cookie(mixpanel_cookie_name, mixpanel_cookie.to_json)
131
113
  set_cookie(visitor_cookie_name, visitor.id)
132
114
  end
133
115
 
@@ -157,7 +139,6 @@ class TestTrack::Session
157
139
 
158
140
  def notify_unsynced_assignments!
159
141
  payload = {
160
- mixpanel_distinct_id: mixpanel_distinct_id,
161
142
  visitor_id: visitor.id,
162
143
  assignments: visitor.unsynced_assignments
163
144
  }
@@ -171,52 +152,10 @@ class TestTrack::Session
171
152
  end
172
153
  end
173
154
 
174
- def create_alias!
175
- create_alias_job = TestTrack::CreateAliasJob.new(
176
- existing_id: mixpanel_distinct_id,
177
- alias_id: visitor.id
178
- )
179
- Delayed::Job.enqueue(create_alias_job)
180
- end
181
-
182
155
  def sync_assignments?
183
156
  visitor.loaded? && visitor.unsynced_assignments.present?
184
157
  end
185
158
 
186
- def mixpanel_distinct_id
187
- mixpanel_cookie['distinct_id']
188
- end
189
-
190
- def mixpanel_distinct_id=(value)
191
- mixpanel_cookie['distinct_id'] = value
192
- end
193
-
194
- def mixpanel_cookie
195
- @mixpanel_cookie ||= read_mixpanel_cookie || generate_mixpanel_cookie
196
- end
197
-
198
- def read_mixpanel_cookie
199
- mixpanel_cookie = cookies[mixpanel_cookie_name]
200
- begin
201
- JSON.parse(mixpanel_cookie) if mixpanel_cookie
202
- rescue JSON::ParserError
203
- Rails.logger.error("malformed mixpanel JSON from cookie #{URI.unescape(mixpanel_cookie)}")
204
- nil
205
- end
206
- end
207
-
208
- def generate_mixpanel_cookie
209
- { 'distinct_id' => visitor.id }
210
- end
211
-
212
- def mixpanel_token
213
- ENV['MIXPANEL_TOKEN'] || raise("ENV['MIXPANEL_TOKEN'] must be set")
214
- end
215
-
216
- def mixpanel_cookie_name
217
- "mp_#{mixpanel_token}_mixpanel"
218
- end
219
-
220
159
  def visitor_cookie_name
221
160
  ENV['TEST_TRACK_VISITOR_COOKIE_NAME'] || 'tt_visitor_id'
222
161
  end
@@ -1,13 +1,12 @@
1
1
  class TestTrack::UnsyncedAssignmentsNotifier
2
- attr_reader :mixpanel_distinct_id, :visitor_id, :assignments
2
+ attr_reader :visitor_id, :assignments
3
3
 
4
4
  def initialize(opts)
5
5
  @visitor_id = opts.delete(:visitor_id)
6
- @mixpanel_distinct_id = opts.delete(:mixpanel_distinct_id) || visitor_id
7
6
  @assignments = opts.delete(:assignments)
8
7
 
9
8
  %w(visitor_id assignments).each do |param_name|
10
- raise "#{param_name} must be present" unless send(param_name).present?
9
+ raise "#{param_name} must be present" if send(param_name).blank?
11
10
  end
12
11
  raise "unknown opts: #{opts.keys.to_sentence}" if opts.present?
13
12
  end
@@ -29,7 +28,6 @@ class TestTrack::UnsyncedAssignmentsNotifier
29
28
 
30
29
  def build_notify_assignment_job(assignment)
31
30
  TestTrack::NotifyAssignmentJob.new(
32
- mixpanel_distinct_id: mixpanel_distinct_id,
33
31
  visitor_id: visitor_id,
34
32
  assignment: assignment
35
33
  )
@@ -17,7 +17,7 @@ class TestTrack::VaryDSL
17
17
  end
18
18
 
19
19
  def when(*variants, &block)
20
- raise ArgumentError, "must provide at least one variant" unless variants.present?
20
+ raise ArgumentError, "must provide at least one variant" if variants.blank?
21
21
  variants.each do |variant|
22
22
  assign_behavior_to_variant(variant, block)
23
23
  end
@@ -57,6 +57,10 @@ class TestTrack::VaryDSL
57
57
  variant = variant.to_s
58
58
 
59
59
  raise ArgumentError, "must provide block for #{variant}" unless behavior_proc
60
+ notify_because_vary(<<-MESSAGE) if variant_behaviors.include?(variant)
61
+ configures variant "#{variant}" more than once.
62
+ This will raise an error in the next version of test_track_rails_client.
63
+ MESSAGE
60
64
  notify_because_vary "configures unknown variant \"#{variant}\"" unless variant_acceptable?(variant)
61
65
 
62
66
  variant_behaviors[variant] = behavior_proc
@@ -79,17 +79,6 @@ class TestTrack::Visitor
79
79
  end
80
80
  end
81
81
 
82
- def self.backfill_identity(opts)
83
- remote_identifier_visitor = TestTrack::Remote::Visitor.from_identifier(opts[:identifier_type], opts[:identifier_value])
84
- visitor = new(
85
- id: remote_identifier_visitor.id,
86
- assignments: remote_identifier_visitor.assignments
87
- )
88
-
89
- TestTrack::CreateAliasJob.new(existing_id: opts[:existing_id], alias_id: visitor.id).perform
90
- visitor
91
- end
92
-
93
82
  def offline?
94
83
  @tt_offline
95
84
  end
@@ -1,3 +1,3 @@
1
1
  module TestTrackRailsClient
2
- VERSION = "2.0.0" # rubocop:disable Style/MutableConstant
2
+ VERSION = "3.0.0" # rubocop:disable Style/MutableConstant
3
3
  end
@@ -1,4 +1,3 @@
1
- # coding: utf-8
2
1
  lib = File.expand_path('../lib', __FILE__)
3
2
  $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
3
  require 'fakeable_her/version'
@@ -16,7 +15,7 @@ Gem::Specification.new do |spec|
16
15
  spec.require_paths = ["lib"]
17
16
 
18
17
  spec.add_dependency 'her'
19
- spec.add_dependency 'rails', '~> 4.1'
18
+ spec.add_dependency 'rails', '>= 4.1', '< 5.2'
20
19
 
21
- spec.add_development_dependency 'rubocop', '>= 0.36'
20
+ spec.add_development_dependency 'appraisal', '~> 2.2.0'
22
21
  end
@@ -18,14 +18,13 @@ Gem::Specification.new do |s|
18
18
  s.require_paths = ["lib"]
19
19
 
20
20
  s.add_development_dependency "rake", "~> 10.0"
21
- s.add_development_dependency "rspec", "~> 2.13"
22
- s.add_development_dependency "rspec-its", "~> 1.0"
23
- s.add_development_dependency "fivemat", "~> 1.2"
21
+ s.add_development_dependency "rspec", "~> 3.5"
24
22
  s.add_development_dependency "json", "~> 1.8"
25
23
  s.add_development_dependency "pry"
24
+ s.add_development_dependency 'appraisal', '~> 2.2.0'
26
25
 
27
- s.add_runtime_dependency "activemodel", ">= 3.0.0", "<= 4.3.0"
28
- s.add_runtime_dependency "activesupport", ">= 3.0.0", "<= 4.3.0"
26
+ s.add_runtime_dependency "activemodel", ">= 3.0.0", "<= 6.0.0"
27
+ s.add_runtime_dependency "activesupport", ">= 3.0.0", "<= 6.0.0"
29
28
  s.add_runtime_dependency "faraday", ">= 0.8", "< 1.0"
30
29
  s.add_runtime_dependency "multi_json", "~> 1.7"
31
30
  end
@@ -6,7 +6,7 @@ module Her
6
6
  attr_reader :connection, :options
7
7
 
8
8
  # Constants
9
- FARADAY_OPTIONS = [:request, :proxy, :ssl, :builder, :url, :parallel_manager, :params, :headers, :builder_class].freeze
9
+ FARADAY_OPTIONS = [:request, :proxy, :ssl, :builder, :url, :parallel_manager, :params, :headers, :builder_class, :timeout, :open_timeout].freeze
10
10
 
11
11
  # Setup a default API connection. Accepted arguments and options are the same as {API#setup}.
12
12
  def self.setup(opts={}, &block)
@@ -33,8 +33,7 @@ module Her
33
33
  end
34
34
 
35
35
  # create a proxy to the fetched object's method
36
- metaclass = (class << self; self; end)
37
- metaclass.install_proxy_methods 'association.fetch', name
36
+ AssociationProxy.install_proxy_methods 'association.fetch', name
38
37
 
39
38
  # resend message to fetched object
40
39
  __send__(name, *args, &block)