vwo-sdk 1.3.0 → 1.14.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.
@@ -0,0 +1,72 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require 'json'
16
+ require_relative '../logger'
17
+ require_relative '../enums'
18
+ require_relative '../constants'
19
+ require_relative './impression'
20
+
21
+ # Utility module for helper math and random functions
22
+ class VWO
23
+ module Utils
24
+ module CustomDimensions
25
+ include VWO::CONSTANTS
26
+ include VWO::Enums
27
+ include VWO::Utils::Impression
28
+
29
+ def get_url_params(settings_file, tag_key, tag_value, user_id, sdk_key)
30
+ url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL + ENDPOINTS::PUSH
31
+ tag = { 'u' => {} }
32
+ tag['u'][tag_key] = tag_value
33
+
34
+ params = get_common_properties(user_id, settings_file)
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
+ }
59
+
60
+ VWO::Logger.get_instance.log(
61
+ LogLevelEnum::DEBUG,
62
+ format(
63
+ LogMessageEnum::DebugMessages::PARAMS_FOR_PUSH_CALL,
64
+ file: FileNameEnum::CustomDimensionsUtil,
65
+ properties: JSON.generate(params)
66
+ )
67
+ )
68
+ params
69
+ end
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,56 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../logger'
16
+ require_relative '../enums'
17
+ require_relative '../constants'
18
+
19
+ # Utility module for helper math and random functions
20
+ class VWO
21
+ module Utils
22
+ module Feature
23
+ include VWO::CONSTANTS
24
+ include VWO::Enums
25
+
26
+ # Returns type casted value to given value type if possible.
27
+ # @param[Number|String|Boolean] :value Value to type cast
28
+ # @param[Type] :variable_type Type to which value needs to be casted
29
+ # @return[any] Type casted value if value can be type-casted
30
+ def get_type_casted_feature_value(value, variable_type)
31
+ # Check if type(value) is already equal to required variable_type
32
+ return value if RUBY_VARIABLE_TYPES[variable_type].include?(value.class)
33
+
34
+ return value.to_s if variable_type == VariableTypes::STRING
35
+
36
+ return value.to_i if variable_type == VariableTypes::INTEGER
37
+
38
+ return value.to_f if variable_type == VariableTypes::DOUBLE
39
+
40
+ return !value || value == 0 ? false : true if variable_type == VariableTypes.BOOLEAN
41
+ rescue StandardError => _e
42
+ VWO::Logger.get_instance.log(
43
+ LogLevelEnum::ERROR,
44
+ format(
45
+ LogMessageEnum::ErrorMessages::UNABLE_TO_TYPE_CAST,
46
+ file: FileNameEnum::FeatureUtil,
47
+ value: value,
48
+ variable_type: variable_type,
49
+ of_type: value.class.name
50
+ )
51
+ )
52
+ nil
53
+ end
54
+ end
55
+ end
56
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 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.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require_relative '../logger'
18
16
  require_relative '../enums'
19
17
  require_relative '../constants'
@@ -34,6 +32,11 @@ class VWO
34
32
  def get_current_unix_timestamp
35
33
  Time.now.to_i
36
34
  end
35
+
36
+ # @return[any, any]
37
+ def get_key_value(obj)
38
+ [obj.keys[0], obj.values[0]]
39
+ end
37
40
  end
38
41
  end
39
42
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 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.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'json'
18
16
  require 'cgi'
19
17
  require_relative '../logger'
@@ -33,16 +31,17 @@ class VWO
33
31
 
34
32
  # Creates the impression from the arguments passed
35
33
  #
36
- # @param[Hash] :settings_file Settings file object
34
+ # @param[Hash] :settings_file Settings file object
37
35
  # @param[String] :campaign_id Campaign identifier
38
36
  # @param[String] :variation_id Variation identifier
39
37
  # @param[String] :user_id User identifier
38
+ # @param[String] :sdk_key SDK Key
40
39
  # @param[String] :goal_id Goal identifier, if building track impression
41
40
  # @param[String|Float|Integer|nil) :revenue Number value, in any representation, if building track impression
42
41
  #
43
42
  # @return[nil|Hash] None if campaign ID or variation ID is invalid,
44
43
  # Else Properties(dict)
45
- 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 = {})
46
45
  return unless valid_number?(campaign_id) && valid_string?(user_id)
47
46
 
48
47
  is_track_user_api = true
@@ -53,17 +52,19 @@ class VWO
53
52
  account_id: account_id,
54
53
  experiment_id: campaign_id,
55
54
  ap: PLATFORM,
56
- uId: CGI.escape(user_id.encode('utf-8')),
57
55
  combination: variation_id,
58
56
  random: get_random_number,
59
57
  sId: get_current_unix_timestamp,
60
- u: generator_for(user_id, account_id)
58
+ u: generator_for(user_id, account_id),
59
+ env: sdk_key
61
60
  }
62
61
  # Version and SDK constants
63
62
  sdk_version = Gem.loaded_specs['vwo_sdk'] ? Gem.loaded_specs['vwo_sdk'].version : VWO::SDK_VERSION
64
63
  impression['sdk'] = 'ruby'
65
64
  impression['sdk-v'] = sdk_version
66
65
 
66
+ impression = usage_stats.merge(impression)
67
+
67
68
  url = HTTPS_PROTOCOL + ENDPOINTS::BASE_URL
68
69
  logger = VWO::Logger.get_instance
69
70
 
@@ -93,6 +94,74 @@ class VWO
93
94
  end
94
95
  impression
95
96
  end
97
+
98
+ # Returns commonly used params for making requests to our servers.
99
+ #
100
+ # @param[String] :user_id Unique identification of user
101
+ # @param[String] :settings_file Settings file containing campaign data for extracting account_id
102
+ # @return[Hash] Commonly used params for making call to our servers
103
+ #
104
+ def get_common_properties(user_id, settings_file)
105
+ account_id = settings_file['accountId']
106
+ {
107
+ 'random' => get_random_number,
108
+ 'sdk' => SDK_NAME,
109
+ 'sdk-v' => SDK_VERSION,
110
+ 'ap' => PLATFORM,
111
+ 'sId' => get_current_unix_timestamp,
112
+ 'u' => generator_for(user_id, account_id),
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
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
164
+ end
96
165
  end
97
166
  end
98
167
  end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 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.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'net/http'
18
16
 
19
17
  class VWO
@@ -26,6 +24,20 @@ class VWO
26
24
  uri.query = URI.encode_www_form(params)
27
25
  Net::HTTP.get_response(uri)
28
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
29
41
  end
30
42
  end
31
43
  end
@@ -0,0 +1,116 @@
1
+ # Copyright 2019-2021 Wingify Software Pvt. Ltd.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ require_relative '../enums'
16
+
17
+ # Utility module for helper math and random functions
18
+ class VWO
19
+ module Utils
20
+ module Segment
21
+ GROUPING_PATTERN = /^(.+?)\((.*)\)/
22
+ WILDCARD_PATTERN = /(^\*|^)(.+?)(\*$|$)/
23
+ include VWO::Enums
24
+
25
+ # Extracts true values represented in the args, and returns stringified value of it
26
+ #
27
+ # @param [String] :operator_value operand/dsl leaf value
28
+ # @param [String|Number] :custom_variables_value custom_variables value
29
+ # @return [[String, String]] tuple of str value of operator_value, custom_variables_value converted
30
+ # into their true types
31
+ def convert_to_true_types(operator_value, custom_variables_value)
32
+ # This is atomic, either both values will be processed or none
33
+ begin
34
+ true_type_operator_value = Kernel::Float(operator_value)
35
+ true_type_custom_variables_value = Kernel::Float(custom_variables_value)
36
+ rescue StandardError => _e
37
+ return operator_value, custom_variables_value
38
+ end
39
+ # Now both are float, So, convert them independently to int type if they are int rather than floats
40
+ true_type_operator_value = true_type_operator_value.to_i if true_type_operator_value == true_type_operator_value.floor
41
+
42
+ true_type_custom_variables_value = true_type_custom_variables_value.to_i if true_type_custom_variables_value == true_type_custom_variables_value.floor
43
+
44
+ # Convert them back to string and return
45
+ [true_type_operator_value.to_s, true_type_custom_variables_value.to_s]
46
+ end
47
+
48
+ # Extract the operand_type, ie. lower, wildcard, regex or equals
49
+ #
50
+ # @param[String] :operand string value from leaf_node of dsl
51
+ # @return [[String, String]] tuple of operand value and operand type
52
+ #
53
+ def separate_operand(operand)
54
+ groups = GROUPING_PATTERN.match(operand)
55
+ return groups[1..2] if groups
56
+
57
+ [OperandValueTypesName::EQUALS, operand]
58
+ end
59
+
60
+ # Processes the value from the custom_variables_variables
61
+ # @param[String|Number|Boolean|nil] :custom_variables_value the custom_variables_value provided inside custom_variables
62
+ #
63
+ # @return [String] stringified value of processed custom_variables_value
64
+ #
65
+ def process_custom_variables_value(custom_variables_value)
66
+ return '' if custom_variables_value.nil?
67
+
68
+ if custom_variables_value.is_a?(TrueClass) || custom_variables_value.is_a?(FalseClass)
69
+ custom_variables_value = custom_variables_value ? OperandValuesBooleanTypes::TRUE : OperandValuesBooleanTypes::FALSE
70
+ end
71
+ custom_variables_value.to_s
72
+ end
73
+
74
+ # Extracts operand_type and operand_value from the leaf_node/operand
75
+ # @param[String] :operand String value from the leaf_node
76
+ # @return[[String, String]] Tuple of defined operand_types and operand_value
77
+ #
78
+ def process_operand_value(operand)
79
+ # Separate the operand type and value inside the bracket
80
+
81
+ operand_type_name, operand_value = separate_operand(operand)
82
+
83
+ # Enum the operand type, here lower, regex, and equals will be identified
84
+ operand_type =
85
+ begin
86
+ VWO::Enums::OperandValueTypesName.const_get(operand_type_name.upcase)
87
+ rescue StandardError => _e
88
+ nil
89
+ end
90
+
91
+ # In case of wildcard, the operand type is further divided into contains, startswith and endswith
92
+ if operand_type_name == OperandValueTypesName::WILDCARD
93
+ starting_star, operand_value, ending_star = WILDCARD_PATTERN.match(operand_value)[1..3]
94
+ operand_type =
95
+ if starting_star.to_s.length > 0 && ending_star.to_s.length > 0
96
+ OperandValueTypes::CONTAINS
97
+ elsif starting_star.to_s.length > 0
98
+ OperandValueTypes::STARTS_WITH
99
+ elsif ending_star.to_s.length > 0
100
+ OperandValueTypes::ENDS_WITH
101
+ else
102
+ OperandValueTypes::EQUALS
103
+ end
104
+ end
105
+
106
+ # In case there is an abnormal patter, it would have passed all the above if cases, which means it
107
+ # should be equals, so set the whole operand as operand value and operand type as equals
108
+ if operand_type.nil?
109
+ operand_type = OperandValueTypes::EQUALS
110
+ operand_value = operand
111
+ end
112
+ [operand_type, operand_value]
113
+ end
114
+ end
115
+ end
116
+ end
@@ -1,4 +1,4 @@
1
- # Copyright 2019 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.
@@ -12,8 +12,6 @@
12
12
  # See the License for the specific language governing permissions and
13
13
  # limitations under the License.
14
14
 
15
- # frozen_string_literal: true
16
-
17
15
  require 'digest'
18
16
  require_relative '../logger'
19
17
  require_relative '../enums'
@@ -44,9 +42,9 @@ class VWO
44
42
  ary = hash.digest.unpack('NnnnnN')
45
43
  ary[2] = (ary[2] & 0x0FFF) | (version << 12)
46
44
  ary[3] = (ary[3] & 0x3FFF) | 0x8000
47
- # rubocop:disable Lint/FormatString
45
+ # rubocop:disable Lint/FormatStringToken,Style/FormatString
48
46
  '%08x-%04x-%04x-%04x-%04x%08x' % ary
49
- # rubocop:enable Lint/FormatString
47
+ # rubocop:enable Lint/FormatStringToken,Style/FormatString
50
48
  end
51
49
 
52
50
  VWO_NAMESPACE = uuid_v5(URL_NAMESPACE, 'https://vwo.com')