vwo-sdk 1.6.0 → 1.14.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.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -142,6 +142,113 @@ class VWO
142
142
  campaign['key'] == campaign_key
143
143
  end
144
144
  end
145
+
146
+ # fetch campaigns from settings
147
+ #
148
+ # [string|array|nil] :campaign_key
149
+ # [Hash] :settings_file
150
+ # [string] :goal_identifier
151
+ # [string] :goal_type_to_track
152
+ # @return[Hash]
153
+ def get_campaigns(settings_file, campaign_key, goal_identifier, goal_type_to_track = 'ALL')
154
+ campaigns = []
155
+ if campaign_key.nil?
156
+ campaigns = get_campaigns_for_goal(settings_file, goal_identifier, goal_type_to_track)
157
+ elsif campaign_key.is_a?(Array)
158
+ campaigns = get_campaigns_from_campaign_keys(campaign_key, settings_file, goal_identifier, goal_type_to_track)
159
+ elsif campaign_key.is_a?(String)
160
+ campaign = get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
161
+ if campaign
162
+ campaigns = [campaign]
163
+ end
164
+ end
165
+ if campaigns.length() == 0
166
+ VWO::Logger.get_instance.log(
167
+ LogLevelEnum::ERROR,
168
+ format(
169
+ LogMessageEnum::ErrorMessages::NO_CAMPAIGN_FOUND,
170
+ file: FileNameEnum::CampaignUtil,
171
+ goal_identifier: goal_identifier
172
+ )
173
+ )
174
+ end
175
+ return campaigns
176
+ end
177
+
178
+ # fetch all running campaigns (having goal identifier goal_type_to_track and goal type CUSTOM|REVENUE|ALL) from settings
179
+ #
180
+ # [Hash] :settings_file
181
+ # [string] :goal_identifier
182
+ # [string] :goal_type_to_track
183
+ # @return[Hash]
184
+ def get_campaigns_for_goal(settings_file, goal_identifier, goal_type_to_track = 'ALL')
185
+ campaigns = []
186
+ if settings_file
187
+ settings_file['campaigns'].each do |campaign|
188
+ if campaign.key?(:status) && campaign[:status] != 'RUNNING'
189
+ next
190
+ end
191
+ goal = get_campaign_goal(campaign, goal_identifier)
192
+ if validate_goal(goal, goal_type_to_track)
193
+ campaigns.append(campaign)
194
+ end
195
+ end
196
+ end
197
+ campaigns
198
+ end
199
+
200
+ def validate_goal(goal, goal_type_to_track)
201
+ result = goal && (
202
+ goal_type_to_track == 'ALL' ||
203
+ (
204
+ GOAL_TYPES.has_value?(goal['type']) &&
205
+ (GOAL_TYPES.key? goal_type_to_track) &&
206
+ goal['type'] == GOAL_TYPES[goal_type_to_track]
207
+ )
208
+ )
209
+ return result
210
+ end
211
+
212
+ def get_campaigns_from_campaign_keys(campaign_keys, settings_file, goal_identifier, goal_type_to_track = 'ALL')
213
+ campaigns = []
214
+ campaign_keys.each do |campaign_key|
215
+
216
+ campaign = get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
217
+ if campaign
218
+ campaigns.append(campaign)
219
+ end
220
+ end
221
+ campaigns
222
+ end
223
+
224
+ def get_campaign_for_campaign_key_and_goal(campaign_key, settings_file, goal_identifier, goal_type_to_track)
225
+ campaign = get_running_campaign(campaign_key, settings_file)
226
+ if campaign
227
+ goal = get_campaign_goal(campaign, goal_identifier)
228
+ if validate_goal(goal, goal_type_to_track)
229
+ return campaign
230
+ end
231
+ end
232
+ nil
233
+ end
234
+
235
+ def get_running_campaign(campaign_key, settings_file)
236
+ campaign = get_campaign(settings_file, campaign_key)
237
+ if campaign.nil? || (campaign['status'] != 'RUNNING')
238
+ @logger.log(
239
+ LogLevelEnum::ERROR,
240
+ format(
241
+ LogMessageEnum::ErrorMessages::CAMPAIGN_NOT_RUNNING,
242
+ file: FILE,
243
+ campaign_key: campaign_key,
244
+ api_name: ApiMethods::TRACK
245
+ )
246
+ )
247
+ nil
248
+ end
249
+ return campaign
250
+ end
251
+
145
252
  end
146
253
  end
147
254
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -26,13 +26,36 @@ class VWO
26
26
  include VWO::Enums
27
27
  include VWO::Utils::Impression
28
28
 
29
- def get_url_params(settings_file, tag_key, tag_value, user_id)
29
+ def get_url_params(settings_file, tag_key, tag_value, user_id, sdk_key)
30
30
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL + ENDPOINTS::PUSH
31
31
  tag = { 'u' => {} }
32
32
  tag['u'][tag_key] = tag_value
33
33
 
34
34
  params = get_common_properties(user_id, settings_file)
35
- params.merge!('url' => url, 'tags' => JSON.generate(tag))
35
+ params.merge!('url' => url, 'tags' => JSON.generate(tag), 'env' => sdk_key)
36
+
37
+ VWO::Logger.get_instance.log(
38
+ LogLevelEnum::DEBUG,
39
+ format(
40
+ LogMessageEnum::DebugMessages::PARAMS_FOR_PUSH_CALL,
41
+ file: FileNameEnum::CustomDimensionsUtil,
42
+ properties: JSON.generate(params)
43
+ )
44
+ )
45
+ params
46
+ end
47
+
48
+ def get_batch_event_url_params(settings_file, tag_key, tag_value, user_id)
49
+ tag = { 'u' => {} }
50
+ tag['u'][tag_key] = tag_value
51
+
52
+ account_id = settings_file['accountId']
53
+ params = {
54
+ 'eT' => 3,
55
+ 't' => JSON.generate(tag),
56
+ 'u' => generator_for(user_id, account_id),
57
+ 'sId' => get_current_unix_timestamp
58
+ }
36
59
 
37
60
  VWO::Logger.get_instance.log(
38
61
  LogLevelEnum::DEBUG,
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -31,16 +31,17 @@ class VWO
31
31
 
32
32
  # Creates the impression from the arguments passed
33
33
  #
34
- # @param[Hash] :settings_file Settings file object
34
+ # @param[Hash] :settings_file Settings file object
35
35
  # @param[String] :campaign_id Campaign identifier
36
36
  # @param[String] :variation_id Variation identifier
37
37
  # @param[String] :user_id User identifier
38
+ # @param[String] :sdk_key SDK Key
38
39
  # @param[String] :goal_id Goal identifier, if building track impression
39
40
  # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
40
41
  #
41
42
  # @return[nil|Hash] None if campaign ID or variation ID is invalid,
42
43
  # Else Properties(dict)
43
- def create_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
44
+ def create_impression(settings_file, campaign_id, variation_id, user_id, sdk_key, goal_id = nil, revenue = nil, usage_stats = {})
44
45
  return unless valid_number?(campaign_id) && valid_string?(user_id)
45
46
 
46
47
  is_track_user_api = true
@@ -51,17 +52,19 @@ class VWO
51
52
  account_id: account_id,
52
53
  experiment_id: campaign_id,
53
54
  ap: PLATFORM,
54
- uId: CGI.escape(user_id.encode('utf-8')),
55
55
  combination: variation_id,
56
56
  random: get_random_number,
57
57
  sId: get_current_unix_timestamp,
58
- u: generator_for(user_id, account_id)
58
+ u: generator_for(user_id, account_id),
59
+ env: sdk_key
59
60
  }
60
61
  # Version and SDK constants
61
62
  sdk_version = Gem.loaded_specs['vwo_sdk'] ? Gem.loaded_specs['vwo_sdk'].version : VWO::SDK_VERSION
62
63
  impression['sdk'] = 'ruby'
63
64
  impression['sdk-v'] = sdk_version
64
65
 
66
+ impression = usage_stats.merge(impression)
67
+
65
68
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL
66
69
  logger = VWO::Logger.get_instance
67
70
 
@@ -107,9 +110,57 @@ class VWO
107
110
  'ap' => PLATFORM,
108
111
  'sId' => get_current_unix_timestamp,
109
112
  'u' => generator_for(user_id, account_id),
110
- 'account_id' => account_id,
111
- 'uId' => CGI.escape(user_id.encode('utf-8'))
113
+ 'account_id' => account_id
114
+ }
115
+ end
116
+
117
+ # Creates properties for the bulk impression event
118
+ #
119
+ # @param[Hash] :settings_file Settings file object
120
+ # @param[String] :campaign_id Campaign identifier
121
+ # @param[String] :variation_id Variation identifier
122
+ # @param[String] :user_id User identifier
123
+ # @param[String] :sdk_key SDK Key
124
+ # @param[String] :goal_id Goal identifier, if building track impression
125
+ # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
126
+ #
127
+ # @return[nil|Hash] None if campaign ID or variation ID is invalid,
128
+ # Else Properties(dict)
129
+ def create_bulk_event_impression(settings_file, campaign_id, variation_id, user_id, goal_id = nil, revenue = nil)
130
+ return unless valid_number?(campaign_id) && valid_string?(user_id)
131
+ is_track_user_api = true
132
+ is_track_user_api = false unless goal_id.nil?
133
+ account_id = settings_file['accountId']
134
+ impression = {
135
+ eT: is_track_user_api ? 1 : 2,
136
+ e: campaign_id,
137
+ c: variation_id,
138
+ u: generator_for(user_id, account_id),
139
+ sId: get_current_unix_timestamp
112
140
  }
141
+ logger = VWO::Logger.get_instance
142
+ if is_track_user_api
143
+ logger.log(
144
+ LogLevelEnum::DEBUG,
145
+ format(
146
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_USER,
147
+ file: FileNameEnum::ImpressionUtil,
148
+ properties: JSON.generate(impression)
149
+ )
150
+ )
151
+ else
152
+ impression['g'] = goal_id
153
+ impression['r'] = revenue if revenue
154
+ logger.log(
155
+ LogLevelEnum::DEBUG,
156
+ format(
157
+ LogMessageEnum::DebugMessages::IMPRESSION_FOR_TRACK_GOAL,
158
+ file: FileNameEnum::ImpressionUtil,
159
+ properties: JSON.generate(impression)
160
+ )
161
+ )
162
+ end
163
+ impression
113
164
  end
114
165
  end
115
166
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -24,6 +24,20 @@ class VWO
24
24
  uri.query = URI.encode_www_form(params)
25
25
  Net::HTTP.get_response(uri)
26
26
  end
27
+
28
+ def self.post(url, params, post_data)
29
+ uri = URI.parse(url)
30
+ http = Net::HTTP.new(uri.host, uri.port)
31
+ http.use_ssl = true
32
+ uri.query = URI.encode_www_form(params)
33
+ headers = {
34
+ 'Authorization'=>params[:env],
35
+ 'Content-Type' =>'application/json',
36
+ 'Accept'=>'application/json'
37
+ }
38
+ response = http.post(uri, post_data.to_json, headers)
39
+ response
40
+ end
27
41
  end
28
42
  end
29
43
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -1,4 +1,4 @@
1
- # Copyright 2019-2020 Wingify Software Pvt. Ltd.
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
2
  #
3
3
  # Licensed under the Apache License, Version 2.0 (the "License");
4
4
  # you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
15
15
  require 'json'
16
16
  require 'json-schema'
17
17
  require_relative '../schemas/settings_file'
18
+ require_relative '../logger'
19
+ require_relative '../enums'
20
+ require_relative '../constants'
18
21
 
19
22
  class VWO
20
23
  module Utils
@@ -59,6 +62,87 @@ class VWO
59
62
  def valid_basic_data_type?(val)
60
63
  valid_number?(val) || valid_string?(val) || valid_boolean?(val)
61
64
  end
65
+
66
+ # Validates if the value passed batch_events has correct data type and values or not.
67
+ #
68
+ # Args: batch_events [Hash]: value to be tested
69
+ #
70
+ # @return: [Boolean]: True if all conditions are passed else False
71
+ def is_valid_batch_event_settings(batch_events)
72
+ logger = VWO::Logger.get_instance
73
+ events_per_request = batch_events[:events_per_request]
74
+ request_time_interval = batch_events[:request_time_interval]
75
+
76
+ unless events_per_request || request_time_interval
77
+ logger.log(
78
+ VWO::LogLevelEnum::ERROR,
79
+ format(
80
+ VWO::LogMessageEnum::ErrorMessages::EVENT_BATCHING_INSUFFICIENT,
81
+ file: VWO::FileNameEnum::ValidateUtil
82
+ )
83
+ )
84
+ return false
85
+ end
86
+
87
+ if (request_time_interval && !valid_number?(request_time_interval))
88
+ logger.log(
89
+ VWO::LogLevelEnum::ERROR,
90
+ format(
91
+ VWO::LogMessageEnum::ErrorMessages::REQUEST_TIME_INTERVAL_INVALID,
92
+ file: VWO::FileNameEnum::ValidateUtil
93
+ )
94
+ )
95
+ return false
96
+ end
97
+
98
+ if (events_per_request && !valid_number?(events_per_request))
99
+ logger.log(
100
+ VWO::LogLevelEnum::ERROR,
101
+ format(
102
+ VWO::LogMessageEnum::ErrorMessages::EVENTS_PER_REQUEST_INVALID,
103
+ file: VWO::FileNameEnum::ValidateUtil
104
+ )
105
+ )
106
+ return false
107
+ end
108
+
109
+ if events_per_request && (events_per_request < VWO::MIN_EVENTS_PER_REQUEST || events_per_request > VWO::MAX_EVENTS_PER_REQUEST)
110
+ logger.log(
111
+ VWO::LogLevelEnum::ERROR,
112
+ format(
113
+ VWO::LogMessageEnum::ErrorMessages::EVENTS_PER_REQUEST_OUT_OF_BOUNDS,
114
+ file: VWO::FileNameEnum::ValidateUtil,
115
+ min_value: VWO::MIN_EVENTS_PER_REQUEST,
116
+ max_value: VWO::MAX_EVENTS_PER_REQUEST
117
+ )
118
+ )
119
+ return false
120
+ end
121
+
122
+ if request_time_interval && request_time_interval < VWO::MIN_REQUEST_TIME_INTERVAL
123
+ logger.log(
124
+ VWO::LogLevelEnum::ERROR,
125
+ format(
126
+ VWO::LogMessageEnum::ErrorMessages::REQUEST_TIME_INTERVAL_OUT_OF_BOUNDS,
127
+ file: VWO::FileNameEnum::ValidateUtil,
128
+ min_value: VWO::MIN_REQUEST_TIME_INTERVAL
129
+ )
130
+ )
131
+ return false
132
+ end
133
+
134
+ if batch_events.key?(:flushCallback) && !batch_events[:flushCallback].is_a?(Method)
135
+ logger.log(
136
+ VWO::LogLevelEnum::ERROR,
137
+ format(
138
+ VWO::LogMessageEnum::ErrorMessages::FLUSH_CALLBACK_INVALID,
139
+ file: VWO::FileNameEnum::ValidateUtil
140
+ )
141
+ )
142
+ return false
143
+ end
144
+ true
145
+ end
62
146
  end
63
147
  end
64
148
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: vwo-sdk
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.6.0
4
+ version: 1.14.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - VWO
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-06 00:00:00.000000000 Z
11
+ date: 2021-07-07 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: coveralls
@@ -80,11 +80,15 @@ files:
80
80
  - lib/vwo/enums.rb
81
81
  - lib/vwo/logger.rb
82
82
  - lib/vwo/schemas/settings_file.rb
83
+ - lib/vwo/services/batch_events_dispatcher.rb
84
+ - lib/vwo/services/batch_events_queue.rb
83
85
  - lib/vwo/services/event_dispatcher.rb
86
+ - lib/vwo/services/hooks_manager.rb
84
87
  - lib/vwo/services/operand_evaluator.rb
85
88
  - lib/vwo/services/segment_evaluator.rb
86
89
  - lib/vwo/services/settings_file_manager.rb
87
90
  - lib/vwo/services/settings_file_processor.rb
91
+ - lib/vwo/services/usage_stats.rb
88
92
  - lib/vwo/user_storage.rb
89
93
  - lib/vwo/utils/campaign.rb
90
94
  - lib/vwo/utils/custom_dimensions.rb
@@ -99,7 +103,7 @@ homepage: https://vwo.com/fullstack/server-side-testing/
99
103
  licenses:
100
104
  - Apache-2.0
101
105
  metadata: {}
102
- post_install_message:
106
+ post_install_message:
103
107
  rdoc_options: []
104
108
  require_paths:
105
109
  - lib
@@ -115,7 +119,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
115
119
  version: '0'
116
120
  requirements: []
117
121
  rubygems_version: 3.0.6
118
- signing_key:
122
+ signing_key:
119
123
  specification_version: 4
120
124
  summary: Ruby SDK for VWO full-stack testing
121
125
  test_files: []