test_track_rails_client 1.2.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2e89607653cb61940fedd99d80d61957a0bf57a1
4
- data.tar.gz: dd88c45263723f36ac874a066dce626d24b85cc8
3
+ metadata.gz: 30685a58f06262e141d5deb48bce124da381861e
4
+ data.tar.gz: 22c790111f624535e1165bba5ad83b68b765944b
5
5
  SHA512:
6
- metadata.gz: a49693c2afd28427caacc2398673a8dc6442eabfa57bbc00a8d999343b7bf9220c0fd8a0c6dfba72bfb28e1a91009e67d97e7d77e229aee611190b7caa9a20bb
7
- data.tar.gz: ea250b67d413d2e3e6acd8b854d5bb9799cce2d2b6105570af3c192813cfcaff655d8e50cfb19218a35007003225005a95f4025bed779d541f9b6bcd91c0325c
6
+ metadata.gz: 7452da90b5d34c19107e6a446908fd48034e094997b0c40f612b9fdf4c3c10b0c7f80779eed9981294184c7982f39919a83b5086671b47bf42970dc2adca3106
7
+ data.tar.gz: 805507d3629c7cd387a0f90604a9e0725fa234360bd4d575a84a7f756c698440a39d088f29cc0dd642ff2bb9da947b581600d1584f6432a6cef07820a75634f6
data/README.md CHANGED
@@ -8,6 +8,17 @@ It provides server-side split-testing and feature-toggling through a simple API.
8
8
 
9
9
  If you're looking to do client-side assignment, then check out our [JS client](https://github.com/Betterment/test_track_js_client).
10
10
 
11
+ * [Installation](#installation)
12
+ * [Concepts](#concepts)
13
+ * [Configuring the TestTrack server from your app](#configuring-the-testtrack-server-from-your-app)
14
+ * [Varying app behavior based on assigned variant](#varying-app-behavior-based-on-assigned-variant)
15
+ * [Tracking visitor logins](#tracking-visitor-logins)
16
+ * [Tracking signups](#tracking-signups)
17
+ * [Testing splits](#testing-splits)
18
+ * [Custom Analytics](#custom-analytics)
19
+ * [Upgrading](#upgrading)
20
+ * [How to Contribute](#how-to-contribute)
21
+
11
22
  ## Installation
12
23
 
13
24
  Install the gem:
@@ -349,6 +360,12 @@ def track_assignment(visitor_id, assignment, properties)
349
360
  def alias(visitor_id, existing_id)
350
361
  ```
351
362
 
363
+ ## Upgrading
364
+
365
+ ### From 1.x to 1.3
366
+
367
+ `TestTrack::Session#log_in!` and `TestTrack:Session#sign_up!` now take a `TestTrack::Identity` instance argument instead of an identity type and identity value.
368
+
352
369
  ## How to Contribute
353
370
 
354
371
  We would love for you to contribute! Anything that benefits the majority of `test_track` users—from a documentation fix to an entirely new feature—is encouraged.
@@ -18,7 +18,7 @@ module TestTrack::Controller
18
18
  end
19
19
 
20
20
  def manage_test_track_session
21
- RequestStore[:test_track_controller] = self
21
+ RequestStore[:test_track_session] = test_track_session
22
22
  test_track_session.manage do
23
23
  yield
24
24
  end
@@ -2,74 +2,54 @@ module TestTrack::Identity
2
2
  extend ActiveSupport::Concern
3
3
 
4
4
  module ClassMethods
5
- # rubocop:disable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
6
- def test_track_identifier(identifier_type, identifier_value_method)
5
+ def test_track_identifier(identifier_type, identifier_value_method) # rubocop:disable Metrics/MethodLength, Metrics/AbcSize
7
6
  instance_methods = Module.new
8
7
  include instance_methods
9
8
 
10
9
  instance_methods.module_eval do
10
+ define_method :test_track_identifier_type do
11
+ identifier_type
12
+ end
13
+
14
+ define_method :test_track_identifier_value do
15
+ send(identifier_value_method)
16
+ end
17
+
11
18
  define_method :test_track_ab do |*args|
12
19
  discriminator = TestTrack::IdentitySessionDiscriminator.new(self)
13
-
14
- if discriminator.authenticated_resource_matches_identity?
15
- discriminator.controller.send(:test_track_visitor).ab(*args)
16
- else
17
- identifier_value = send(identifier_value_method)
18
- TestTrack::OfflineSession.with_visitor_for(identifier_type, identifier_value) do |v|
19
- v.ab(*args)
20
- end
20
+ discriminator.with_visitor do |v|
21
+ v.ab(*args)
21
22
  end
22
23
  end
23
24
 
24
25
  define_method :test_track_vary do |*args, &block|
25
26
  discriminator = TestTrack::IdentitySessionDiscriminator.new(self)
26
-
27
- if discriminator.authenticated_resource_matches_identity?
28
- discriminator.controller.send(:test_track_visitor).vary(*args, &block)
29
- else
30
- identifier_value = send(identifier_value_method)
31
- TestTrack::OfflineSession.with_visitor_for(identifier_type, identifier_value) do |v|
32
- v.vary(*args, &block)
33
- end
27
+ discriminator.with_visitor do |v|
28
+ v.vary(*args, &block)
34
29
  end
35
30
  end
36
31
 
37
32
  define_method :test_track_visitor_id do
38
33
  discriminator = TestTrack::IdentitySessionDiscriminator.new(self)
39
-
40
- if discriminator.authenticated_resource_matches_identity?
41
- discriminator.controller.send(:test_track_visitor).id
42
- else
43
- identifier_value = send(identifier_value_method)
44
- TestTrack::OfflineSession.with_visitor_for(identifier_type, identifier_value) do |v|
45
- v.id
46
- end
34
+ discriminator.with_visitor do |v|
35
+ v.id
47
36
  end
48
37
  end
49
38
 
50
39
  define_method :test_track_sign_up! do
51
40
  discriminator = TestTrack::IdentitySessionDiscriminator.new(self)
52
-
53
- if discriminator.web_context?
54
- identifier_value = send(identifier_value_method)
55
- discriminator.controller.send(:test_track_session).sign_up! identifier_type, identifier_value
56
- else
57
- raise "test_track_sign_up! called outside of a web context"
41
+ discriminator.with_session do |session|
42
+ session.sign_up! self
58
43
  end
59
44
  end
60
45
 
61
46
  define_method :test_track_log_in! do |opts = {}|
62
47
  discriminator = TestTrack::IdentitySessionDiscriminator.new(self)
63
-
64
- if discriminator.web_context?
65
- identifier_value = send(identifier_value_method)
66
- discriminator.controller.send(:test_track_session).log_in! identifier_type, identifier_value, opts
67
- else
68
- raise "test_track_log_in! called outside of a web context"
48
+ discriminator.with_session do |session|
49
+ session.log_in! self, opts
69
50
  end
70
51
  end
71
52
  end
72
53
  end
73
- # rubocop:enable Metrics/MethodLength, Metrics/AbcSize, Metrics/PerceivedComplexity
74
54
  end
75
55
  end
@@ -5,26 +5,39 @@ class TestTrack::IdentitySessionDiscriminator
5
5
  @identity = identity
6
6
  end
7
7
 
8
- def controller
9
- @controller ||= RequestStore[:test_track_controller]
10
- end
8
+ def with_visitor
9
+ raise ArgumentError, "must provide block to `with_visitor`" unless block_given?
11
10
 
12
- def authenticated_resource_matches_identity?
13
- controller_has_authenticated_resource? && controller.send(authenticated_resource_method_name) == identity
11
+ if matching_identity?
12
+ yield session.visitor_dsl
13
+ else
14
+ TestTrack::OfflineSession.with_visitor_for(identity.test_track_identifier_type, identity.test_track_identifier_value) do |v|
15
+ yield v
16
+ end
17
+ end
14
18
  end
15
19
 
16
- def web_context?
17
- controller.present?
20
+ def with_session
21
+ raise ArgumentError, "must provide block to `with_session`" unless block_given?
22
+
23
+ if web_context?
24
+ yield session
25
+ else
26
+ raise "#with_session called outside of web context"
27
+ end
18
28
  end
19
29
 
20
30
  private
21
31
 
22
- def controller_has_authenticated_resource?
23
- # pass true to `respond_to?` to include private methods
24
- web_context? && controller.respond_to?(authenticated_resource_method_name, true)
32
+ def matching_identity?
33
+ session.present? && session.has_matching_identity?(identity)
34
+ end
35
+
36
+ def web_context?
37
+ session.present?
25
38
  end
26
39
 
27
- def authenticated_resource_method_name
28
- @authenticated_resource_method_name ||= "current_#{identity.class.model_name.element}"
40
+ def session
41
+ @session ||= RequestStore[:test_track_session]
29
42
  end
30
43
  end
@@ -31,18 +31,48 @@ class TestTrack::Session
31
31
  }
32
32
  end
33
33
 
34
- def log_in!(identifier_type, identifier_value, opts = {})
34
+ def log_in!(*args) # rubocop:disable Metrics/AbcSize, Metrics/MethodLength
35
+ opts = args[-1].is_a?(Hash) ? args.pop : {}
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
+
35
47
  @visitor = TestTrack::Visitor.new if opts[:forget_current_visitor]
36
48
  visitor.link_identifier!(identifier_type, identifier_value)
49
+
50
+ identities << identity if identity.present?
37
51
  self.mixpanel_distinct_id = visitor.id
38
52
  true
39
53
  end
40
54
 
41
- def sign_up!(identifier_type, identifier_value)
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
65
+
42
66
  visitor.link_identifier!(identifier_type, identifier_value)
67
+
68
+ identities << identity if identity.present?
43
69
  @signed_up = true
44
70
  end
45
71
 
72
+ def has_matching_identity?(identity)
73
+ identities.include?(identity)
74
+ end
75
+
46
76
  private
47
77
 
48
78
  attr_reader :controller, :signed_up
@@ -215,4 +245,8 @@ class TestTrack::Session
215
245
  end
216
246
  end
217
247
  end
248
+
249
+ def identities
250
+ @identities ||= TestTrack::SessionIdentityCollection.new(controller)
251
+ end
218
252
  end
@@ -0,0 +1,29 @@
1
+ class TestTrack::SessionIdentityCollection
2
+ def initialize(controller)
3
+ @controller = controller
4
+ end
5
+
6
+ def include?(identity)
7
+ found_identity = identities[identity.test_track_identifier_type] || authenticated_resource_for_identity(identity)
8
+ found_identity.present? && found_identity == identity
9
+ end
10
+
11
+ def <<(identity)
12
+ identities[identity.test_track_identifier_type] = identity
13
+ end
14
+
15
+ private
16
+
17
+ attr_reader :controller
18
+
19
+ def identities
20
+ @identities ||= {}
21
+ end
22
+
23
+ def authenticated_resource_for_identity(identity)
24
+ authenticated_resource_method_name = "current_#{identity.class.model_name.element}"
25
+
26
+ # pass true to `respond_to?` to include private methods
27
+ controller.respond_to?(authenticated_resource_method_name, true) && controller.send(authenticated_resource_method_name)
28
+ end
29
+ end
@@ -1,3 +1,3 @@
1
1
  module TestTrackRailsClient
2
- VERSION = "1.2.0" # rubocop:disable Style/MutableConstant
2
+ VERSION = "1.3.0" # rubocop:disable Style/MutableConstant
3
3
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: test_track_rails_client
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.2.0
4
+ version: 1.3.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan O'Neill
@@ -13,7 +13,7 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2017-08-01 00:00:00.000000000 Z
16
+ date: 2017-10-02 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
19
  name: rails
@@ -291,6 +291,7 @@ files:
291
291
  - app/models/test_track/remote/visitor.rb
292
292
  - app/models/test_track/remote/visitor_detail.rb
293
293
  - app/models/test_track/session.rb
294
+ - app/models/test_track/session_identity_collection.rb
294
295
  - app/models/test_track/unsynced_assignments_notifier.rb
295
296
  - app/models/test_track/variant_calculator.rb
296
297
  - app/models/test_track/vary_dsl.rb
@@ -441,7 +442,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
441
442
  version: '0'
442
443
  requirements: []
443
444
  rubyforge_project:
444
- rubygems_version: 2.5.1
445
+ rubygems_version: 2.6.13
445
446
  signing_key:
446
447
  specification_version: 4
447
448
  summary: Rails client for TestTrack