vwo-sdk 1.5.0 → 1.6.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 +4 -4
- data/lib/vwo.rb +22 -11
- data/lib/vwo/constants.rb +1 -1
- data/lib/vwo/core/bucketer.rb +3 -5
- data/lib/vwo/core/variation_decider.rb +180 -6
- data/lib/vwo/enums.rb +19 -4
- data/lib/vwo/services/operand_evaluator.rb +9 -1
- data/lib/vwo/services/segment_evaluator.rb +4 -25
- metadata +3 -3
    
        checksums.yaml
    CHANGED
    
    | @@ -1,7 +1,7 @@ | |
| 1 1 | 
             
            ---
         | 
| 2 2 | 
             
            SHA256:
         | 
| 3 | 
            -
              metadata.gz:  | 
| 4 | 
            -
              data.tar.gz:  | 
| 3 | 
            +
              metadata.gz: 88beb4ef415731a07ac86d4d3ce19b9e3ea077d79d00e3e35e84f2b669c802eb
         | 
| 4 | 
            +
              data.tar.gz: 2748de038b879ca5c27e237455bcbd6a62178101eae5c9fe1b2c87f64d5b25d7
         | 
| 5 5 | 
             
            SHA512:
         | 
| 6 | 
            -
              metadata.gz:  | 
| 7 | 
            -
              data.tar.gz:  | 
| 6 | 
            +
              metadata.gz: 38889e01c758f1336042deda0c39e2a678860eff7431bb465885bf72e9032f2277f0ef52ed5837593fd49b9b76ca1d74a673eb7774ee970422f9588b3698e0c6
         | 
| 7 | 
            +
              data.tar.gz: 481f64eb7ff87622f12ff3122dcb57618d56add48ebe99524a8557930dd4e2bea85ee7c875024a45134d4948be47fa5da54e8c6e64463dae4f11d732fd00e2dd
         | 
    
        data/lib/vwo.rb
    CHANGED
    
    | @@ -143,9 +143,11 @@ class VWO | |
| 143 143 | 
             
              def activate(campaign_key, user_id, options = {})
         | 
| 144 144 | 
             
                # Retrieve custom variables
         | 
| 145 145 | 
             
                custom_variables = options['custom_variables'] || options[:custom_variables]
         | 
| 146 | 
            +
                variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
         | 
| 146 147 |  | 
| 147 148 | 
             
                # Validate input parameters
         | 
| 148 | 
            -
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables))
         | 
| 149 | 
            +
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
         | 
| 150 | 
            +
                       (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
         | 
| 149 151 | 
             
                  @logger.log(
         | 
| 150 152 | 
             
                    LogLevelEnum::ERROR,
         | 
| 151 153 | 
             
                    format(
         | 
| @@ -208,11 +210,14 @@ class VWO | |
| 208 210 |  | 
| 209 211 | 
             
                # Once the matching RUNNING campaign is found, assign the
         | 
| 210 212 | 
             
                # deterministic variation to the user_id provided
         | 
| 213 | 
            +
             | 
| 211 214 | 
             
                variation = @variation_decider.get_variation(
         | 
| 212 215 | 
             
                  user_id,
         | 
| 213 216 | 
             
                  campaign,
         | 
| 217 | 
            +
                  ApiMethods::ACTIVATE,
         | 
| 214 218 | 
             
                  campaign_key,
         | 
| 215 | 
            -
                  custom_variables
         | 
| 219 | 
            +
                  custom_variables,
         | 
| 220 | 
            +
                  variation_targeting_variables
         | 
| 216 221 | 
             
                )
         | 
| 217 222 |  | 
| 218 223 | 
             
                # Check if variation_name has been assigned
         | 
| @@ -271,9 +276,11 @@ class VWO | |
| 271 276 | 
             
              def get_variation_name(campaign_key, user_id, options = {})
         | 
| 272 277 | 
             
                # Retrieve custom variables
         | 
| 273 278 | 
             
                custom_variables = options['custom_variables'] || options[:custom_variables]
         | 
| 279 | 
            +
                variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
         | 
| 274 280 |  | 
| 275 281 | 
             
                # Validate input parameters
         | 
| 276 | 
            -
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables))
         | 
| 282 | 
            +
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
         | 
| 283 | 
            +
                       (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
         | 
| 277 284 | 
             
                  @logger.log(
         | 
| 278 285 | 
             
                    LogLevelEnum::ERROR,
         | 
| 279 286 | 
             
                    format(
         | 
| @@ -330,7 +337,7 @@ class VWO | |
| 330 337 | 
             
                  return
         | 
| 331 338 | 
             
                end
         | 
| 332 339 |  | 
| 333 | 
            -
                variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
         | 
| 340 | 
            +
                variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::GET_VARIATION_NAME, campaign_key, custom_variables, variation_targeting_variables)
         | 
| 334 341 |  | 
| 335 342 | 
             
                # Check if variation_name has been assigned
         | 
| 336 343 | 
             
                unless valid_value?(variation)
         | 
| @@ -379,14 +386,15 @@ class VWO | |
| 379 386 | 
             
                if args[0].is_a?(Hash)
         | 
| 380 387 | 
             
                  revenue_value = args[0]['revenue_value'] || args[0][:revenue_value]
         | 
| 381 388 | 
             
                  custom_variables = args[0]['custom_variables'] || args[0][:custom_variables]
         | 
| 389 | 
            +
                  variation_targeting_variables = args[0]['variation_targeting_variables'] || args[0][:variation_targeting_variables]
         | 
| 382 390 | 
             
                elsif args.is_a?(Array)
         | 
| 383 391 | 
             
                  revenue_value = args[0]
         | 
| 384 392 | 
             
                  custom_variables = nil
         | 
| 385 393 | 
             
                end
         | 
| 386 394 |  | 
| 387 395 | 
             
                # Check for valid args
         | 
| 388 | 
            -
                unless valid_string?(campaign_key) && valid_string?(user_id) &&  | 
| 389 | 
            -
                       ( | 
| 396 | 
            +
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
         | 
| 397 | 
            +
                       (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
         | 
| 390 398 | 
             
                  # log invalid params
         | 
| 391 399 | 
             
                  @logger.log(
         | 
| 392 400 | 
             
                    LogLevelEnum::ERROR,
         | 
| @@ -446,7 +454,7 @@ class VWO | |
| 446 454 | 
             
                  return false
         | 
| 447 455 | 
             
                end
         | 
| 448 456 |  | 
| 449 | 
            -
                variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
         | 
| 457 | 
            +
                variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::TRACK, campaign_key, custom_variables, variation_targeting_variables)
         | 
| 450 458 |  | 
| 451 459 | 
             
                if variation
         | 
| 452 460 | 
             
                  goal = get_campaign_goal(campaign, goal_identifier)
         | 
| @@ -532,9 +540,11 @@ class VWO | |
| 532 540 | 
             
              def feature_enabled?(campaign_key, user_id, options = {})
         | 
| 533 541 | 
             
                # Retrieve custom variables
         | 
| 534 542 | 
             
                custom_variables = options['custom_variables'] || options[:custom_variables]
         | 
| 543 | 
            +
                variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
         | 
| 535 544 |  | 
| 536 545 | 
             
                # Validate input parameters
         | 
| 537 | 
            -
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables))
         | 
| 546 | 
            +
                unless valid_string?(campaign_key) && valid_string?(user_id) && (custom_variables.nil? || valid_hash?(custom_variables)) &&
         | 
| 547 | 
            +
                       (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
         | 
| 538 548 | 
             
                  @logger.log(
         | 
| 539 549 | 
             
                    LogLevelEnum::ERROR,
         | 
| 540 550 | 
             
                    format(
         | 
| @@ -594,7 +604,7 @@ class VWO | |
| 594 604 | 
             
                end
         | 
| 595 605 |  | 
| 596 606 | 
             
                # Get variation
         | 
| 597 | 
            -
                variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
         | 
| 607 | 
            +
                variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::IS_FEATURE_ENABLED, campaign_key, custom_variables, variation_targeting_variables)
         | 
| 598 608 |  | 
| 599 609 | 
             
                # If no variation, did not become part of feature_test/rollout
         | 
| 600 610 | 
             
                return false unless variation
         | 
| @@ -682,9 +692,10 @@ class VWO | |
| 682 692 | 
             
              def get_feature_variable_value(campaign_key, variable_key, user_id, options = {})
         | 
| 683 693 | 
             
                # Retrieve custom variables
         | 
| 684 694 | 
             
                custom_variables = options['custom_variables'] || options[:custom_variables]
         | 
| 695 | 
            +
                variation_targeting_variables = options['variation_targeting_variables'] || options[:variation_targeting_variables]
         | 
| 685 696 |  | 
| 686 697 | 
             
                unless valid_string?(campaign_key) && valid_string?(variable_key) && valid_string?(user_id) &&
         | 
| 687 | 
            -
                       (custom_variables.nil? || valid_hash?(custom_variables))
         | 
| 698 | 
            +
                       (custom_variables.nil? || valid_hash?(custom_variables)) && (variation_targeting_variables.nil? || valid_hash?(variation_targeting_variables))
         | 
| 688 699 | 
             
                  @logger.log(
         | 
| 689 700 | 
             
                    LogLevelEnum::ERROR,
         | 
| 690 701 | 
             
                    format(
         | 
| @@ -743,7 +754,7 @@ class VWO | |
| 743 754 | 
             
                  return
         | 
| 744 755 | 
             
                end
         | 
| 745 756 |  | 
| 746 | 
            -
                variation = @variation_decider.get_variation(user_id, campaign, campaign_key, custom_variables)
         | 
| 757 | 
            +
                variation = @variation_decider.get_variation(user_id, campaign, ApiMethods::GET_FEATURE_VARIABLE_VALUE, campaign_key, custom_variables, variation_targeting_variables)
         | 
| 747 758 |  | 
| 748 759 | 
             
                # Check if variation has been assigned to user
         | 
| 749 760 | 
             
                return unless variation
         | 
    
        data/lib/vwo/constants.rb
    CHANGED
    
    
    
        data/lib/vwo/core/bucketer.rb
    CHANGED
    
    | @@ -116,11 +116,9 @@ class VWO | |
| 116 116 | 
             
                      )
         | 
| 117 117 | 
             
                    )
         | 
| 118 118 |  | 
| 119 | 
            -
                    get_variation(campaign, bucket_value)
         | 
| 119 | 
            +
                    get_variation(campaign['variations'], bucket_value)
         | 
| 120 120 | 
             
                  end
         | 
| 121 121 |  | 
| 122 | 
            -
                  private
         | 
| 123 | 
            -
             | 
| 124 122 | 
             
                  # Returns the Variation by checking the Start and End
         | 
| 125 123 | 
             
                  # Bucket Allocations of each Variation
         | 
| 126 124 | 
             
                  #
         | 
| @@ -128,8 +126,8 @@ class VWO | |
| 128 126 | 
             
                  # @param[Integer]     :bucket_value   The bucket Value of the user
         | 
| 129 127 | 
             
                  # @return[Hash|nil]                   Variation data allotted to the user or None if not
         | 
| 130 128 | 
             
                  #
         | 
| 131 | 
            -
                  def get_variation( | 
| 132 | 
            -
                     | 
| 129 | 
            +
                  def get_variation(variations, bucket_value)
         | 
| 130 | 
            +
                    variations.find do |variation|
         | 
| 133 131 | 
             
                      (variation['start_variation_allocation']..variation['end_variation_allocation']).cover?(bucket_value)
         | 
| 134 132 | 
             
                    end
         | 
| 135 133 | 
             
                  end
         | 
| @@ -43,6 +43,7 @@ class VWO | |
| 43 43 | 
             
                  end
         | 
| 44 44 |  | 
| 45 45 | 
             
                  # Returns variation for the user for the passed campaign-key
         | 
| 46 | 
            +
                  # Check if Whitelisting is applicable, evaluate it, if any eligible variation is found,return, otherwise skip it
         | 
| 46 47 | 
             
                  # Check in User Storage, if user found, validate variation and return
         | 
| 47 48 | 
             
                  # Otherwise, proceed with variation assignment logic
         | 
| 48 49 | 
             
                  #
         | 
| @@ -53,9 +54,54 @@ class VWO | |
| 53 54 | 
             
                  # @return[String,String]                       ({variation_id, variation_name}|Nil): Tuple of
         | 
| 54 55 | 
             
                  #                                              variation_id and variation_name if variation allotted, else nil
         | 
| 55 56 |  | 
| 56 | 
            -
                  def get_variation(user_id, campaign, campaign_key, custom_variables = {})
         | 
| 57 | 
            +
                  def get_variation(user_id, campaign, api_name, campaign_key, custom_variables = {}, variation_targeting_variables = {})
         | 
| 57 58 | 
             
                    campaign_key ||= campaign['key']
         | 
| 58 59 |  | 
| 60 | 
            +
                    return unless campaign
         | 
| 61 | 
            +
             | 
| 62 | 
            +
                    if campaign['isForcedVariationEnabled']
         | 
| 63 | 
            +
                      variation = evaluate_whitelisting(
         | 
| 64 | 
            +
                        user_id,
         | 
| 65 | 
            +
                        campaign,
         | 
| 66 | 
            +
                        api_name,
         | 
| 67 | 
            +
                        campaign_key,
         | 
| 68 | 
            +
                        variation_targeting_variables
         | 
| 69 | 
            +
                      )
         | 
| 70 | 
            +
                      status = if variation
         | 
| 71 | 
            +
                                 StatusEnum::PASSED
         | 
| 72 | 
            +
                               else
         | 
| 73 | 
            +
                                 StatusEnum::FAILED
         | 
| 74 | 
            +
                               end
         | 
| 75 | 
            +
             | 
| 76 | 
            +
                      @logger.log(
         | 
| 77 | 
            +
                        LogLevelEnum::INFO,
         | 
| 78 | 
            +
                        format(
         | 
| 79 | 
            +
                          LogMessageEnum::InfoMessages::SEGMENTATION_STATUS,
         | 
| 80 | 
            +
                          file: FILE,
         | 
| 81 | 
            +
                          campaign_key: campaign_key,
         | 
| 82 | 
            +
                          user_id: user_id,
         | 
| 83 | 
            +
                          status: status,
         | 
| 84 | 
            +
                          custom_variables: variation_targeting_variables,
         | 
| 85 | 
            +
                          variation_name: status == StatusEnum::PASSED ? "and #{variation['name']} is Assigned" : ' ',
         | 
| 86 | 
            +
                          segmentation_type: SegmentationTypeEnum::WHITELISTING,
         | 
| 87 | 
            +
                          api_name: api_name
         | 
| 88 | 
            +
                        )
         | 
| 89 | 
            +
                      )
         | 
| 90 | 
            +
             | 
| 91 | 
            +
                      return variation if variation && variation['name']
         | 
| 92 | 
            +
                    else
         | 
| 93 | 
            +
                      @logger.log(
         | 
| 94 | 
            +
                        LogLevelEnum::INFO,
         | 
| 95 | 
            +
                        format(
         | 
| 96 | 
            +
                          LogMessageEnum::InfoMessages::WHITELISTING_SKIPPED,
         | 
| 97 | 
            +
                          file: FILE,
         | 
| 98 | 
            +
                          campaign_key: campaign_key,
         | 
| 99 | 
            +
                          user_id: user_id,
         | 
| 100 | 
            +
                          api_name: api_name
         | 
| 101 | 
            +
                        )
         | 
| 102 | 
            +
                      )
         | 
| 103 | 
            +
                    end
         | 
| 104 | 
            +
             | 
| 59 105 | 
             
                    user_campaign_map = get_user_storage(user_id, campaign_key)
         | 
| 60 106 | 
             
                    variation = get_stored_variation(user_id, campaign_key, user_campaign_map) if valid_hash?(user_campaign_map)
         | 
| 61 107 |  | 
| @@ -74,7 +120,6 @@ class VWO | |
| 74 120 | 
             
                    end
         | 
| 75 121 |  | 
| 76 122 | 
             
                    # Pre-segmentation
         | 
| 77 | 
            -
                    return unless campaign
         | 
| 78 123 |  | 
| 79 124 | 
             
                    segments = get_segments(campaign)
         | 
| 80 125 | 
             
                    is_valid_segments = valid_value?(segments)
         | 
| @@ -88,21 +133,44 @@ class VWO | |
| 88 133 | 
             
                            file: FILE,
         | 
| 89 134 | 
             
                            campaign_key: campaign_key,
         | 
| 90 135 | 
             
                            user_id: user_id,
         | 
| 91 | 
            -
                            api_name:  | 
| 136 | 
            +
                            api_name: api_name
         | 
| 92 137 | 
             
                          )
         | 
| 93 138 | 
             
                        )
         | 
| 94 139 | 
             
                        custom_variables = {}
         | 
| 95 140 | 
             
                      end
         | 
| 96 | 
            -
                       | 
| 141 | 
            +
                      unless @segment_evaluator.evaluate(campaign_key, user_id, segments, custom_variables)
         | 
| 142 | 
            +
                        @logger.log(
         | 
| 143 | 
            +
                          LogLevelEnum::INFO,
         | 
| 144 | 
            +
                          format(
         | 
| 145 | 
            +
                            LogMessageEnum::InfoMessages::USER_FAILED_SEGMENTATION,
         | 
| 146 | 
            +
                            file: FileNameEnum::SegmentEvaluator,
         | 
| 147 | 
            +
                            user_id: user_id,
         | 
| 148 | 
            +
                            campaign_key: campaign_key,
         | 
| 149 | 
            +
                            custom_variables: custom_variables
         | 
| 150 | 
            +
                          )
         | 
| 151 | 
            +
                        )
         | 
| 152 | 
            +
                        return
         | 
| 153 | 
            +
                      end
         | 
| 154 | 
            +
                      @logger.log(
         | 
| 155 | 
            +
                        LogLevelEnum::INFO,
         | 
| 156 | 
            +
                        format(
         | 
| 157 | 
            +
                          LogMessageEnum::InfoMessages::USER_PASSED_SEGMENTATION,
         | 
| 158 | 
            +
                          file: FileNameEnum::SegmentEvaluator,
         | 
| 159 | 
            +
                          user_id: user_id,
         | 
| 160 | 
            +
                          campaign_key: campaign_key,
         | 
| 161 | 
            +
                          custom_variables: custom_variables
         | 
| 162 | 
            +
                        )
         | 
| 163 | 
            +
                      )
         | 
| 97 164 | 
             
                    else
         | 
| 98 165 | 
             
                      @logger.log(
         | 
| 99 166 | 
             
                        LogLevelEnum::INFO,
         | 
| 100 167 | 
             
                        format(
         | 
| 101 | 
            -
                          LogMessageEnum::InfoMessages:: | 
| 168 | 
            +
                          LogMessageEnum::InfoMessages::SKIPPING_SEGMENTATION,
         | 
| 102 169 | 
             
                          file: FILE,
         | 
| 103 170 | 
             
                          campaign_key: campaign_key,
         | 
| 104 171 | 
             
                          user_id: user_id,
         | 
| 105 | 
            -
                          api_name:  | 
| 172 | 
            +
                          api_name: api_name,
         | 
| 173 | 
            +
                          variation: ''
         | 
| 106 174 | 
             
                        )
         | 
| 107 175 | 
             
                      )
         | 
| 108 176 | 
             
                    end
         | 
| @@ -183,6 +251,7 @@ class VWO | |
| 183 251 | 
             
                  # @param[String]              :user_id      The unique ID assigned to a user
         | 
| 184 252 | 
             
                  # @param[Hash]                :campaign     The Campaign of which user is to be made a part of
         | 
| 185 253 | 
             
                  # @return[Hash]                         Variation allotted to User
         | 
| 254 | 
            +
             | 
| 186 255 | 
             
                  def get_variation_of_campaign_for_user(user_id, campaign)
         | 
| 187 256 | 
             
                    unless campaign
         | 
| 188 257 | 
             
                      @logger.log(
         | 
| @@ -226,6 +295,111 @@ class VWO | |
| 226 295 |  | 
| 227 296 | 
             
                  private
         | 
| 228 297 |  | 
| 298 | 
            +
                  # Evaluate all the variations in the campaign to find
         | 
| 299 | 
            +
                  #
         | 
| 300 | 
            +
                  # @param[String]  :user_id                            The unique key assigned to User
         | 
| 301 | 
            +
                  # @param[Hash]    :campaign                           Campaign hash for Unique campaign key
         | 
| 302 | 
            +
                  # @param[String]  :api_name                           The key Passed to identify the calling API
         | 
| 303 | 
            +
                  # @param[String]  :campaign_key                       Unique campaign key
         | 
| 304 | 
            +
                  # @param[Hash]    :variation_targeting_variables      Key/value pair of Whitelisting Custom Attributes
         | 
| 305 | 
            +
                  #
         | 
| 306 | 
            +
                  # @return[Hash]
         | 
| 307 | 
            +
             | 
| 308 | 
            +
                  def evaluate_whitelisting(user_id, campaign, api_name, campaign_key, variation_targeting_variables = {})
         | 
| 309 | 
            +
                    if variation_targeting_variables.nil?
         | 
| 310 | 
            +
                      variation_targeting_variables = { '_vwo_user_id' => user_id }
         | 
| 311 | 
            +
                    else
         | 
| 312 | 
            +
                      variation_targeting_variables['_vwo_user_id'] = user_id
         | 
| 313 | 
            +
                    end
         | 
| 314 | 
            +
                    targeted_variations = []
         | 
| 315 | 
            +
             | 
| 316 | 
            +
                    campaign['variations'].each do |variation|
         | 
| 317 | 
            +
                      segments = get_segments(variation)
         | 
| 318 | 
            +
                      is_valid_segments = valid_value?(segments)
         | 
| 319 | 
            +
                      if is_valid_segments
         | 
| 320 | 
            +
                        if @segment_evaluator.evaluate(campaign_key, user_id, segments, variation_targeting_variables)
         | 
| 321 | 
            +
                          targeted_variations.push(variation)
         | 
| 322 | 
            +
                          status = StatusEnum::PASSED
         | 
| 323 | 
            +
                        else
         | 
| 324 | 
            +
                          status = StatusEnum::FAILED
         | 
| 325 | 
            +
                        end
         | 
| 326 | 
            +
                        @logger.log(
         | 
| 327 | 
            +
                          LogLevelEnum::DEBUG,
         | 
| 328 | 
            +
                          format(
         | 
| 329 | 
            +
                            LogMessageEnum::DebugMessages::SEGMENTATION_STATUS,
         | 
| 330 | 
            +
                            file: FILE,
         | 
| 331 | 
            +
                            campaign_key: campaign_key,
         | 
| 332 | 
            +
                            user_id: user_id,
         | 
| 333 | 
            +
                            status: status,
         | 
| 334 | 
            +
                            custom_variables: variation_targeting_variables,
         | 
| 335 | 
            +
                            variation_name: variation['name'],
         | 
| 336 | 
            +
                            segmentation_type: SegmentationTypeEnum::WHITELISTING,
         | 
| 337 | 
            +
                            api_name: api_name
         | 
| 338 | 
            +
                          )
         | 
| 339 | 
            +
                        )
         | 
| 340 | 
            +
                      else
         | 
| 341 | 
            +
                        @logger.log(
         | 
| 342 | 
            +
                          LogLevelEnum::DEBUG,
         | 
| 343 | 
            +
                          format(
         | 
| 344 | 
            +
                            LogMessageEnum::InfoMessages::SKIPPING_SEGMENTATION,
         | 
| 345 | 
            +
                            file: FILE,
         | 
| 346 | 
            +
                            campaign_key: campaign_key,
         | 
| 347 | 
            +
                            user_id: user_id,
         | 
| 348 | 
            +
                            api_name: api_name,
         | 
| 349 | 
            +
                            variation: variation['name']
         | 
| 350 | 
            +
                          )
         | 
| 351 | 
            +
                        )
         | 
| 352 | 
            +
                      end
         | 
| 353 | 
            +
                    end
         | 
| 354 | 
            +
             | 
| 355 | 
            +
                    if targeted_variations.length > 1
         | 
| 356 | 
            +
                      targeted_variations_deep_clone = Marshal.load(Marshal.dump(targeted_variations))
         | 
| 357 | 
            +
                      scale_variation_weights(targeted_variations_deep_clone)
         | 
| 358 | 
            +
                      current_allocation = 0
         | 
| 359 | 
            +
                      targeted_variations_deep_clone.each do |variation|
         | 
| 360 | 
            +
                        step_factor = get_variation_bucketing_range(variation['weight'])
         | 
| 361 | 
            +
                        if step_factor > 0
         | 
| 362 | 
            +
                          start_range = current_allocation + 1
         | 
| 363 | 
            +
                          end_range = current_allocation + step_factor
         | 
| 364 | 
            +
                          variation['start_variation_allocation'] = start_range
         | 
| 365 | 
            +
                          variation['end_variation_allocation'] = end_range
         | 
| 366 | 
            +
                          current_allocation += step_factor
         | 
| 367 | 
            +
                        else
         | 
| 368 | 
            +
                          variation['start_variation_allocation'] = -1
         | 
| 369 | 
            +
                          variation['end_variation_allocation'] = -1
         | 
| 370 | 
            +
                        end
         | 
| 371 | 
            +
                      end
         | 
| 372 | 
            +
                      whitelisted_variation = @bucketer.get_variation(
         | 
| 373 | 
            +
                        targeted_variations_deep_clone,
         | 
| 374 | 
            +
                        @bucketer.get_bucket_value_for_user(
         | 
| 375 | 
            +
                          user_id
         | 
| 376 | 
            +
                        )
         | 
| 377 | 
            +
                      )
         | 
| 378 | 
            +
                    else
         | 
| 379 | 
            +
                      whitelisted_variation = targeted_variations[0]
         | 
| 380 | 
            +
                    end
         | 
| 381 | 
            +
                    whitelisted_variation
         | 
| 382 | 
            +
                  end
         | 
| 383 | 
            +
             | 
| 384 | 
            +
                  # It extracts the weights from all the variations inside the campaign
         | 
| 385 | 
            +
                  # and scales them so that the total sum of eligible variations' weights become 100%
         | 
| 386 | 
            +
                  #
         | 
| 387 | 
            +
                  # 1. variations
         | 
| 388 | 
            +
             | 
| 389 | 
            +
                  def scale_variation_weights(variations)
         | 
| 390 | 
            +
                    total_weight = variations.reduce(0) { |final_weight, variation| final_weight + variation['weight'].to_f }
         | 
| 391 | 
            +
                    if total_weight == 0
         | 
| 392 | 
            +
                      weight = 100 / variations.length
         | 
| 393 | 
            +
                      variations.each do |variation|
         | 
| 394 | 
            +
                        variation['weight'] = weight
         | 
| 395 | 
            +
                      end
         | 
| 396 | 
            +
                    else
         | 
| 397 | 
            +
                      variations.each do |variation|
         | 
| 398 | 
            +
                        variation['weight'] = (variation['weight'] / total_weight) * 100
         | 
| 399 | 
            +
                      end
         | 
| 400 | 
            +
                    end
         | 
| 401 | 
            +
                  end
         | 
| 402 | 
            +
             | 
| 229 403 | 
             
                  # Get the UserStorageData after looking up into get method
         | 
| 230 404 | 
             
                  # Being provided via UserStorageService
         | 
| 231 405 | 
             
                  #
         | 
    
        data/lib/vwo/enums.rb
    CHANGED
    
    | @@ -42,6 +42,7 @@ class VWO | |
| 42 42 |  | 
| 43 43 | 
             
                module OperandTypes
         | 
| 44 44 | 
             
                  CUSTOM_VARIABLE = 'custom_variable'
         | 
| 45 | 
            +
                  USER = 'user'
         | 
| 45 46 | 
             
                end
         | 
| 46 47 |  | 
| 47 48 | 
             
                module OperandValuesBooleanTypes
         | 
| @@ -49,6 +50,16 @@ class VWO | |
| 49 50 | 
             
                  FALSE = 'false'
         | 
| 50 51 | 
             
                end
         | 
| 51 52 |  | 
| 53 | 
            +
                module StatusEnum
         | 
| 54 | 
            +
                  PASSED = 'passed'
         | 
| 55 | 
            +
                  FAILED = 'failed'
         | 
| 56 | 
            +
                end
         | 
| 57 | 
            +
             | 
| 58 | 
            +
                module SegmentationTypeEnum
         | 
| 59 | 
            +
                  WHITELISTING = 'whitelisting'
         | 
| 60 | 
            +
                  PRE_SEGMENTATION = 'pre-segmentation'
         | 
| 61 | 
            +
                end
         | 
| 62 | 
            +
             | 
| 52 63 | 
             
                module FileNameEnum
         | 
| 53 64 | 
             
                  VWO_PATH = 'vwo'
         | 
| 54 65 | 
             
                  UTIL_PATH = 'vwo/utils'
         | 
| @@ -93,6 +104,7 @@ class VWO | |
| 93 104 | 
             
                    IMPRESSION_FOR_TRACK_USER = '(%<file>s): Impression built for track-user - %<properties>s'
         | 
| 94 105 | 
             
                    IMPRESSION_FOR_TRACK_GOAL = '(%<file>s): Impression built for track-goal - %<properties>s'
         | 
| 95 106 | 
             
                    GOT_VARIATION_FOR_USER = '(%<file>s): userId:%<user_id>s for campaign:%<campaign_key>s got variationName:%<variation_name>s'
         | 
| 107 | 
            +
                    SEGMENTATION_STATUS = '(%<file>s): In API: %<api_name>s, for UserId:%<user_id>s of campaign:%<campaign_key>s  with variables:%<custom_variables>s %<status>s %<segmentation_type>s for %<variation_name>s'
         | 
| 96 108 | 
             
                    PARAMS_FOR_PUSH_CALL = '(%<file>s): Params for push call - %<properties>s'
         | 
| 97 109 | 
             
                  end
         | 
| 98 110 |  | 
| @@ -120,11 +132,14 @@ class VWO | |
| 120 132 |  | 
| 121 133 | 
             
                    VARIABLE_FOUND = '(%<file>s): In API: %<api_name>s Value for variable:%<variable_key>s of campaign:%<campaign_key>s and campaign type: %<campaign_type>s is:%<variable_value>s for user:%<user_id>s'
         | 
| 122 134 |  | 
| 123 | 
            -
                     | 
| 124 | 
            -
                     | 
| 135 | 
            +
                    USER_PASSED_SEGMENTATION = '(%<file>s): UserId:%<user_id>s of campaign:%<campaign_key>s with custom_variables:%<custom_variables>s passed segmentation'
         | 
| 136 | 
            +
                    USER_FAILED_SEGMENTATION = '(%<file>s): UserId:%<user_id>s of campaign:%<campaign_key>s with custom_variables:%<custom_variables>s failed segmentation'
         | 
| 125 137 |  | 
| 126 138 | 
             
                    NO_CUSTOM_VARIABLES = '(%<file>s): In API: %<api_name>s, for UserId:%<user_id>s preSegments/customVariables are not passed for campaign:%<campaign_key>s and campaign has pre-segmentation'
         | 
| 127 | 
            -
                     | 
| 139 | 
            +
                    SKIPPING_SEGMENTATION = '(%<file>s): In API: %<api_name>s, Skipping segmentation:%<variation>s for UserId:%<user_id>s as no valid segments found in campaign:%<campaign_key>s'
         | 
| 140 | 
            +
             | 
| 141 | 
            +
                    SEGMENTATION_STATUS = '(%<file>s): In API: %<api_name>s, for UserId:%<user_id>s of campaign:%<campaign_key>s  with variables:%<custom_variables>s %<status>s %<segmentation_type>s %<variation_name>s'
         | 
| 142 | 
            +
                    WHITELISTING_SKIPPED = '(%<file>s): In API: %<api_name>s, Skipping whitelisting for UserId:%<user_id>s of campaign:%<campaign_key>s'
         | 
| 128 143 | 
             
                  end
         | 
| 129 144 |  | 
| 130 145 | 
             
                  # Warning Messages
         | 
| @@ -159,7 +174,7 @@ class VWO | |
| 159 174 | 
             
                    USER_NOT_IN_CAMPAIGN = '(%<file>s): userId:%<user_id>s did not become part of campaign:%<campaign_key>s and campaign type:%<campaign_type>s'
         | 
| 160 175 | 
             
                    API_NOT_WORKING = '(%<file>s): API: %<api_name>s not working, exception caught: %<exception>s. Please contact VWO Support for help.'
         | 
| 161 176 |  | 
| 162 | 
            -
                     | 
| 177 | 
            +
                    SEGMENTATION_ERROR = '(%<file>s): Error while segmenting the UserId:%<user_id>s of campaign:%<campaign_key>s with custom_variables:%<custom_variables>s. Error message: %<error_message>s'
         | 
| 163 178 |  | 
| 164 179 | 
             
                    PUSH_API_INVALID_PARAMS = '(%<file>s): %<api_name>s API got bad parameters. It expects tag_key(String) as first and tag_value(String) as second argument and user_id(String) as third argument'
         | 
| 165 180 | 
             
                    TAG_VALUE_LENGTH_EXCEEDED = '(%<file>s): In API: %<api_name>s, the length of tag_value:%<tag_value>s and userID: %<user_id>s can not be greater than 255'
         | 
| @@ -89,7 +89,7 @@ class VWO | |
| 89 89 | 
             
                  # @param [String] :custom_variables_value   Value from the custom_variables
         | 
| 90 90 | 
             
                  #
         | 
| 91 91 | 
             
                  # @return [Boolean]
         | 
| 92 | 
            -
                  def  | 
| 92 | 
            +
                  def evaluate_custom_variable?(operand, custom_variables)
         | 
| 93 93 | 
             
                    # Extract custom_variable_key and custom_variables_value from operand
         | 
| 94 94 |  | 
| 95 95 | 
             
                    operand_key, operand = get_key_value(operand)
         | 
| @@ -109,6 +109,14 @@ class VWO | |
| 109 109 | 
             
                    # Call the self method corresponding to operand_type to evaluate the result
         | 
| 110 110 | 
             
                    public_send("#{operand_type}?", operand_value, custom_variables_value)
         | 
| 111 111 | 
             
                  end
         | 
| 112 | 
            +
             | 
| 113 | 
            +
                  def evaluate_user?(operand, custom_variables)
         | 
| 114 | 
            +
                    users = operand.split(',')
         | 
| 115 | 
            +
                    users.each do |user|
         | 
| 116 | 
            +
                      return true if user.strip == custom_variables['_vwo_user_id']
         | 
| 117 | 
            +
                    end
         | 
| 118 | 
            +
                    false
         | 
| 119 | 
            +
                  end
         | 
| 112 120 | 
             
                end
         | 
| 113 121 | 
             
              end
         | 
| 114 122 | 
             
            end
         | 
| @@ -50,7 +50,9 @@ class VWO | |
| 50 50 | 
             
                    elsif operator == OperatorTypes::OR
         | 
| 51 51 | 
             
                      sub_dsl.any? { |y| evaluate_util(y, custom_variables) }
         | 
| 52 52 | 
             
                    elsif operator == OperandTypes::CUSTOM_VARIABLE
         | 
| 53 | 
            -
                      @operand_evaluator. | 
| 53 | 
            +
                      @operand_evaluator.evaluate_custom_variable?(sub_dsl, custom_variables)
         | 
| 54 | 
            +
                    elsif operator == OperandTypes::USER
         | 
| 55 | 
            +
                      @operand_evaluator.evaluate_user?(sub_dsl, custom_variables)
         | 
| 54 56 | 
             
                    end
         | 
| 55 57 | 
             
                  end
         | 
| 56 58 |  | 
| @@ -66,35 +68,12 @@ class VWO | |
| 66 68 | 
             
                  #
         | 
| 67 69 | 
             
                  def evaluate(campaign_key, user_id, dsl, custom_variables)
         | 
| 68 70 | 
             
                    result = evaluate_util(dsl, custom_variables) if valid_value?(dsl)
         | 
| 69 | 
            -
                    if result
         | 
| 70 | 
            -
                      @logger.log(
         | 
| 71 | 
            -
                        LogLevelEnum::INFO,
         | 
| 72 | 
            -
                        format(
         | 
| 73 | 
            -
                          LogMessageEnum::InfoMessages::USER_PASSED_PRE_SEGMENTATION,
         | 
| 74 | 
            -
                          file: FileNameEnum::SegmentEvaluator,
         | 
| 75 | 
            -
                          user_id: user_id,
         | 
| 76 | 
            -
                          campaign_key: campaign_key,
         | 
| 77 | 
            -
                          custom_variables: custom_variables
         | 
| 78 | 
            -
                        )
         | 
| 79 | 
            -
                      )
         | 
| 80 | 
            -
                    else
         | 
| 81 | 
            -
                      @logger.log(
         | 
| 82 | 
            -
                        LogLevelEnum::INFO,
         | 
| 83 | 
            -
                        format(
         | 
| 84 | 
            -
                          LogMessageEnum::InfoMessages::USER_FAILED_PRE_SEGMENTATION,
         | 
| 85 | 
            -
                          file: FileNameEnum::SegmentEvaluator,
         | 
| 86 | 
            -
                          user_id: user_id,
         | 
| 87 | 
            -
                          campaign_key: campaign_key,
         | 
| 88 | 
            -
                          custom_variables: custom_variables
         | 
| 89 | 
            -
                        )
         | 
| 90 | 
            -
                      )
         | 
| 91 | 
            -
                    end
         | 
| 92 71 | 
             
                    result
         | 
| 93 72 | 
             
                  rescue StandardError => e
         | 
| 94 73 | 
             
                    @logger.log(
         | 
| 95 74 | 
             
                      LogLevelEnum::ERROR,
         | 
| 96 75 | 
             
                      format(
         | 
| 97 | 
            -
                        LogMessageEnum::ErrorMessages:: | 
| 76 | 
            +
                        LogMessageEnum::ErrorMessages::SEGMENTATION_ERROR,
         | 
| 98 77 | 
             
                        file: FileNameEnum::SegmentEvaluator,
         | 
| 99 78 | 
             
                        user_id: user_id,
         | 
| 100 79 | 
             
                        campaign_key: campaign_key,
         | 
    
        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. | 
| 4 | 
            +
              version: 1.6.0
         | 
| 5 5 | 
             
            platform: ruby
         | 
| 6 6 | 
             
            authors:
         | 
| 7 7 | 
             
            - VWO
         | 
| 8 8 | 
             
            autorequire: 
         | 
| 9 9 | 
             
            bindir: bin
         | 
| 10 10 | 
             
            cert_chain: []
         | 
| 11 | 
            -
            date: 2020- | 
| 11 | 
            +
            date: 2020-05-06 00:00:00.000000000 Z
         | 
| 12 12 | 
             
            dependencies:
         | 
| 13 13 | 
             
            - !ruby/object:Gem::Dependency
         | 
| 14 14 | 
             
              name: coveralls
         | 
| @@ -97,7 +97,7 @@ files: | |
| 97 97 | 
             
            - lib/vwo/utils/validations.rb
         | 
| 98 98 | 
             
            homepage: https://vwo.com/fullstack/server-side-testing/
         | 
| 99 99 | 
             
            licenses:
         | 
| 100 | 
            -
            - Apache | 
| 100 | 
            +
            - Apache-2.0
         | 
| 101 101 | 
             
            metadata: {}
         | 
| 102 102 | 
             
            post_install_message: 
         | 
| 103 103 | 
             
            rdoc_options: []
         |