test_track_rails_client 4.0.1 → 5.0.1

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
  SHA256:
3
- metadata.gz: 3a4e66371e5bfdda4c10e9f0e7ee91fb458bb67e58e624bb2c9349f6d7bfd6a7
4
- data.tar.gz: e07a71f4d00429b0ccbb7722c2f247ab23f87e622b04011d4c80c2812a1a5d6e
3
+ metadata.gz: 1362a616d6ae5b12bf8a7d3a1af3180f069453ffeb87b65863b6833fd544bbfa
4
+ data.tar.gz: 53a48cb3d727a1b288f0bf49d27438529a6c0a04745096fe89e01e917e847f7d
5
5
  SHA512:
6
- metadata.gz: ce33a99b61265af0eb5fbc2a8b978d5e383c28e00f294cf2331759690bd6eec296d10d96b6b4e61e51f89488ffebf103eceb67cb4334b840478903bdb8d8f4b0
7
- data.tar.gz: 97dc832aa1656acfd345223dfae3f43208e0a6eeb42ef440fe616cdfd631b4c5dd03b627452fe243fce794bae6c210dea32045bdcc67487a6216acadd1b7922f
6
+ metadata.gz: 100b8fd232c2e51a0bdf7879a7a797852cfa94ebb0ab6236f2eb62fc0c2a15946717f1cb981c25ac278c5173a4da2fba81c52f0c24d2f76f32dd1ef10ea13b2d
7
+ data.tar.gz: 8719fbe5e2034c70a4b0b4aea2be8fdd251c7e0b0313fac7c5f184ed5797e3fce517434e447e09f06bb1081b476826e788d9408f61f593c3ecef685e5260ba68
data/README.md CHANGED
@@ -48,6 +48,7 @@ Set up ENV vars in every environment:
48
48
 
49
49
  * `MIXPANEL_TOKEN` - By default, TestTrack reports to Mixpanel. If you're using a [custom analytics provider](#analytics) you can omit this.
50
50
  * `TEST_TRACK_API_URL` - Set this to the URL of your TestTrack instance with your app credentials, e.g. `http://[myapp]:[your new app password]@[your-app-domain]/`
51
+ * `TEST_TRACK_PUBLIC_API_URL` - (optional) If public traffic to TestTrack should use a different host name, set this variable. By default this will use `TEST_TRACK_API_URL` without any credentials
51
52
 
52
53
  [your-app-domain] can be
53
54
  * `testtrack.test`
@@ -0,0 +1,4 @@
1
+ module TestTrack
2
+ class ApplicationJob < TestTrack.job_base_class_name.constantize
3
+ end
4
+ end
@@ -0,0 +1,71 @@
1
+ module TestTrack
2
+ class AssignmentEventJob < ApplicationJob
3
+ attr_reader :visitor_id, :assignment
4
+
5
+ def perform(visitor_id:, split_name:, variant:, context:)
6
+ raise "visitor_id must be present" if visitor_id.blank?
7
+ raise "split_name must be present" if visitor_id.blank?
8
+
9
+ @visitor_id = visitor_id
10
+ @assignment = build_assignment(visitor_id, split_name, variant, context)
11
+
12
+ create_assignment_event!
13
+ end
14
+
15
+ private
16
+
17
+ def build_assignment(visitor_id, split_name, variant, context)
18
+ assignment = Assignment.new(
19
+ visitor: Visitor.new(id: visitor_id),
20
+ split_name: split_name
21
+ )
22
+ assignment.variant = variant
23
+ assignment.context = context
24
+ assignment
25
+ end
26
+
27
+ def create_assignment_event!
28
+ tracking_result = maybe_track
29
+ unless assignment.feature_gate?
30
+ Remote::AssignmentEvent.create!(
31
+ visitor_id: visitor_id,
32
+ split_name: assignment.split_name,
33
+ context: assignment.context,
34
+ mixpanel_result: tracking_result
35
+ )
36
+ end
37
+ end
38
+
39
+ def maybe_track
40
+ return "failure" unless TestTrack.enabled?
41
+ return "success" if skip_analytics_event?
42
+
43
+ result = TestTrack.analytics.track(AnalyticsEvent.new(visitor_id, assignment))
44
+ result ? "success" : "failure"
45
+ end
46
+
47
+ def skip_analytics_event?
48
+ assignment.feature_gate? && skip_experience_event?
49
+ end
50
+
51
+ def skip_experience_event?
52
+ skip_all_experience_events? || !sample_event?
53
+ end
54
+
55
+ def skip_all_experience_events?
56
+ experience_sampling_weight.zero?
57
+ end
58
+
59
+ def sample_event?
60
+ Kernel.rand(experience_sampling_weight).zero?
61
+ end
62
+
63
+ def experience_sampling_weight
64
+ @experience_sampling_weight ||= split_registry.experience_sampling_weight
65
+ end
66
+
67
+ def split_registry
68
+ @split_registry ||= SplitRegistry.from_remote
69
+ end
70
+ end
71
+ end
@@ -0,0 +1,11 @@
1
+ module TestTrack
2
+ class IdentifierCreationJob < ApplicationJob
3
+ def perform(identifier_type:, visitor_id:, value:)
4
+ Remote::Identifier.create!(
5
+ identifier_type: identifier_type,
6
+ visitor_id: visitor_id,
7
+ value: value
8
+ )
9
+ end
10
+ end
11
+ end
@@ -13,21 +13,21 @@ class TestTrack::UnsyncedAssignmentsNotifier
13
13
 
14
14
  def notify
15
15
  assignments.each do |assignment|
16
- build_notify_assignment_job(assignment).tap do |job|
17
- job.perform
18
- rescue *TestTrack::SERVER_ERRORS => e
19
- Rails.logger.error "TestTrack failed to notify unsynced assignments, retrying. #{e}"
20
- Delayed::Job.enqueue(build_notify_assignment_job(assignment))
21
- end
16
+ TestTrack::AssignmentEventJob.perform_now assignment_job_args(assignment)
17
+ rescue *TestTrack::SERVER_ERRORS => e
18
+ Rails.logger.error "TestTrack failed to notify unsynced assignments, retrying. #{e}"
19
+ TestTrack::AssignmentEventJob.perform_later assignment_job_args(assignment)
22
20
  end
23
21
  end
24
22
 
25
23
  private
26
24
 
27
- def build_notify_assignment_job(assignment)
28
- TestTrack::NotifyAssignmentJob.new(
25
+ def assignment_job_args(assignment)
26
+ {
29
27
  visitor_id: visitor_id,
30
- assignment: assignment
31
- )
28
+ context: assignment.context,
29
+ split_name: assignment.split_name,
30
+ variant: assignment.variant
31
+ }
32
32
  end
33
33
  end
@@ -78,7 +78,7 @@ class TestTrack::Visitor
78
78
 
79
79
  # If at first you don't succeed, async it - we may not display 100% consistent UX this time,
80
80
  # but subsequent requests will be better off
81
- TestTrack::Remote::Identifier.delay.create!(opts)
81
+ TestTrack::IdentifierCreationJob.perform_later(opts)
82
82
  end
83
83
  end
84
84
 
@@ -25,7 +25,7 @@ class TestTrack::WebSession
25
25
 
26
26
  def state_hash
27
27
  {
28
- url: TestTrack.url,
28
+ url: TestTrack.public_url,
29
29
  cookieDomain: cookie_domain,
30
30
  cookieName: visitor_cookie_name,
31
31
  splits: current_visitor.split_registry.to_hash,
data/lib/test_track.rb CHANGED
@@ -20,6 +20,7 @@ module TestTrack
20
20
  BUILD_TIMESTAMP_REGEX = /\A\d{4}-[01]\d-[0-3]\dT[0-2]\d:[0-5]\d:[0-5]\d(.\d+)?([+-][0-2]\d:[0-5]\d|Z)\z/.freeze
21
21
 
22
22
  mattr_accessor :enabled_override, :app_name
23
+ mattr_accessor(:job_base_class_name) { 'ActiveJob::Base' }
23
24
 
24
25
  class << self
25
26
  def analytics
@@ -115,7 +116,15 @@ module TestTrack
115
116
  yield(ConfigUpdater.new)
116
117
  end
117
118
 
118
- def url
119
+ def public_url
120
+ ENV['TEST_TRACK_PUBLIC_API_URL'] || _uncredentialed_private_url
121
+ end
122
+
123
+ def private_url
124
+ ENV['TEST_TRACK_API_URL']
125
+ end
126
+
127
+ def _uncredentialed_private_url
119
128
  return nil unless private_url
120
129
 
121
130
  full_uri = URI.parse(private_url)
@@ -124,10 +133,6 @@ module TestTrack
124
133
  full_uri.to_s
125
134
  end
126
135
 
127
- def private_url
128
- ENV['TEST_TRACK_API_URL']
129
- end
130
-
131
136
  def _build_timestamp
132
137
  File.read(BUILD_TIMESTAMP_FILE_PATH).chomp.presence if File.exist?(BUILD_TIMESTAMP_FILE_PATH)
133
138
  end
@@ -1,19 +1,5 @@
1
- require 'delayed_job'
2
-
3
- begin
4
- require 'airbrake'
5
- rescue LoadError
6
- # no-op
7
- end
8
-
9
- unless defined?(Delayed::Plugins::Airbrake) && Delayed::Worker.plugins.include?(Delayed::Plugins::Airbrake)
10
- begin
11
- require 'delayed-plugins-airbrake'
12
- rescue LoadError
13
- # no-op
14
- end
15
- end
16
-
1
+ require 'active_job'
2
+ require 'active_model'
17
3
  require 'test_track'
18
4
 
19
5
  module TestTrackRailsClient
@@ -1,3 +1,3 @@
1
1
  module TestTrackRailsClient
2
- VERSION = "4.0.1" # rubocop:disable Style/MutableConstant
2
+ VERSION = "5.0.1" # rubocop:disable Style/MutableConstant
3
3
  end
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
15
15
  spec.require_paths = ["lib"]
16
16
 
17
17
  spec.add_dependency 'her'
18
- spec.add_dependency 'rails', '>= 4.1', '< 5.2'
18
+ spec.add_dependency 'activesupport'
19
19
 
20
20
  spec.add_development_dependency 'appraisal', '~> 2.2.0'
21
21
  end
@@ -1,6 +1,6 @@
1
1
  require 'her'
2
2
  require 'active_support/concern'
3
- require 'rails'
3
+ require 'active_support/callbacks'
4
4
 
5
5
  module FakeableHer
6
6
  module Model
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: 4.0.1
4
+ version: 5.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ryan O'Neill
@@ -13,36 +13,36 @@ authors:
13
13
  autorequire:
14
14
  bindir: bin
15
15
  cert_chain: []
16
- date: 2021-02-01 00:00:00.000000000 Z
16
+ date: 2022-05-11 00:00:00.000000000 Z
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
19
- name: delayed_job
19
+ name: activejob
20
20
  requirement: !ruby/object:Gem::Requirement
21
21
  requirements:
22
- - - "~>"
22
+ - - ">="
23
23
  - !ruby/object:Gem::Version
24
- version: '4.0'
24
+ version: '5.1'
25
25
  type: :runtime
26
26
  prerelease: false
27
27
  version_requirements: !ruby/object:Gem::Requirement
28
28
  requirements:
29
- - - "~>"
29
+ - - ">="
30
30
  - !ruby/object:Gem::Version
31
- version: '4.0'
31
+ version: '5.1'
32
32
  - !ruby/object:Gem::Dependency
33
- name: delayed_job_active_record
33
+ name: activemodel
34
34
  requirement: !ruby/object:Gem::Requirement
35
35
  requirements:
36
36
  - - ">="
37
37
  - !ruby/object:Gem::Version
38
- version: '0'
38
+ version: '5.1'
39
39
  type: :runtime
40
40
  prerelease: false
41
41
  version_requirements: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: '5.1'
46
46
  - !ruby/object:Gem::Dependency
47
47
  name: faraday
48
48
  requirement: !ruby/object:Gem::Requirement
@@ -106,9 +106,6 @@ dependencies:
106
106
  - - ">="
107
107
  - !ruby/object:Gem::Version
108
108
  version: 2.0.0
109
- - - "<="
110
- - !ruby/object:Gem::Version
111
- version: 3.0.0
112
109
  type: :runtime
113
110
  prerelease: false
114
111
  version_requirements: !ruby/object:Gem::Requirement
@@ -116,29 +113,20 @@ dependencies:
116
113
  - - ">="
117
114
  - !ruby/object:Gem::Version
118
115
  version: 2.0.0
119
- - - "<="
120
- - !ruby/object:Gem::Version
121
- version: 3.0.0
122
116
  - !ruby/object:Gem::Dependency
123
- name: rails
117
+ name: railties
124
118
  requirement: !ruby/object:Gem::Requirement
125
119
  requirements:
126
120
  - - ">="
127
121
  - !ruby/object:Gem::Version
128
- version: '4.1'
129
- - - "<"
130
- - !ruby/object:Gem::Version
131
- version: '7.0'
122
+ version: '5.1'
132
123
  type: :runtime
133
124
  prerelease: false
134
125
  version_requirements: !ruby/object:Gem::Requirement
135
126
  requirements:
136
127
  - - ">="
137
128
  - !ruby/object:Gem::Version
138
- version: '4.1'
139
- - - "<"
140
- - !ruby/object:Gem::Version
141
- version: '7.0'
129
+ version: '5.1'
142
130
  - !ruby/object:Gem::Dependency
143
131
  name: request_store
144
132
  requirement: !ruby/object:Gem::Requirement
@@ -153,6 +141,20 @@ dependencies:
153
141
  - - "~>"
154
142
  - !ruby/object:Gem::Version
155
143
  version: '1.3'
144
+ - !ruby/object:Gem::Dependency
145
+ name: sprockets-rails
146
+ requirement: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - ">="
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ type: :runtime
152
+ prerelease: false
153
+ version_requirements: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
156
158
  - !ruby/object:Gem::Dependency
157
159
  name: appraisal
158
160
  requirement: !ruby/object:Gem::Requirement
@@ -279,20 +281,6 @@ dependencies:
279
281
  - - ">="
280
282
  - !ruby/object:Gem::Version
281
283
  version: '0'
282
- - !ruby/object:Gem::Dependency
283
- name: sqlite3
284
- requirement: !ruby/object:Gem::Requirement
285
- requirements:
286
- - - ">="
287
- - !ruby/object:Gem::Version
288
- version: '0'
289
- type: :development
290
- prerelease: false
291
- version_requirements: !ruby/object:Gem::Requirement
292
- requirements:
293
- - - ">="
294
- - !ruby/object:Gem::Version
295
- version: '0'
296
284
  - !ruby/object:Gem::Dependency
297
285
  name: timecop
298
286
  requirement: !ruby/object:Gem::Requirement
@@ -344,6 +332,9 @@ files:
344
332
  - app/controllers/tt/api/v1/visitor_details_controller.rb
345
333
  - app/controllers/tt/api/v1/visitors_controller.rb
346
334
  - app/helpers/test_track/application_helper.rb
335
+ - app/jobs/test_track/application_job.rb
336
+ - app/jobs/test_track/assignment_event_job.rb
337
+ - app/jobs/test_track/identifier_creation_job.rb
347
338
  - app/models/concerns/test_track/identity.rb
348
339
  - app/models/concerns/test_track/remote_model.rb
349
340
  - app/models/concerns/test_track/required_options.rb
@@ -463,7 +454,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
463
454
  - !ruby/object:Gem::Version
464
455
  version: '0'
465
456
  requirements: []
466
- rubygems_version: 3.2.5
457
+ rubygems_version: 3.3.7
467
458
  signing_key:
468
459
  specification_version: 4
469
460
  summary: Rails client for TestTrack