diff --git a/CHANGES.txt b/CHANGES.txt index a9e4fc42..7dc8f06f 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,7 +1,10 @@ CHANGES +8.10.1 (Jan 21, 2025) +- Fixed rule-based segment matcher. + 8.10.0 (Nov 28, 2025) -- Replaced socketry gem used in streaming feature with built-in socket lib. +- Updated socketry gem used in streaming feature with built-in socket lib. 8.9.0 (Oct 8, 2025) - Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs. diff --git a/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb b/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb index a5463d0a..2443e258 100644 --- a/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb +++ b/lib/splitclient-rb/engine/matchers/rule_based_segment_matcher.rb @@ -30,15 +30,18 @@ def match?(args) return false unless check_excluded_segments(rule_based_segment, key, args) - matches = false + matched = false rule_based_segment[:conditions].each do |c| condition = SplitIoClient::Condition.new(c, @config) next if condition.empty? - matches = Helpers::EvaluatorHelper.matcher_type(condition, @segments_repository, @rule_based_segments_repository).match?(args) + matched = Helpers::EvaluatorHelper.matcher_type(condition, @segments_repository, @rule_based_segments_repository).match?(args) + + break if matched end - @logger.debug("[InRuleSegmentMatcher] #{@segment_name} is in rule based segment -> #{matches}") - matches + + @logger.debug("[InRuleSegmentMatcher] #{@segment_name} is in rule based segment -> #{matched}") + matched end private diff --git a/lib/splitclient-rb/version.rb b/lib/splitclient-rb/version.rb index adf700f9..6a908fc6 100644 --- a/lib/splitclient-rb/version.rb +++ b/lib/splitclient-rb/version.rb @@ -1,3 +1,3 @@ module SplitIoClient - VERSION = '8.10.1-rc1' + VERSION = '8.10.1-rc.2' end diff --git a/spec/engine/matchers/rule_based_segment_matcher_spec.rb b/spec/engine/matchers/rule_based_segment_matcher_spec.rb index 4f7786e4..6034dfc3 100644 --- a/spec/engine/matchers/rule_based_segment_matcher_spec.rb +++ b/spec/engine/matchers/rule_based_segment_matcher_spec.rb @@ -177,6 +177,61 @@ matcher = described_class.new(segments_repository, rbs_repositoy, 'sample_rule_based_segment', config) expect(matcher.match?(value: 'bilal@split.io', attributes: {'email': 'bilal@split.io'})).to be true expect(matcher.match?(value: 'bilal', attributes: {'email': 'bilal'})).to be false - end + end + + it 'return true if has multiple conditions' do + rbs_repositoy = SplitIoClient::Cache::Repositories::RuleBasedSegmentsRepository.new(config) + rbs = { + :name => 'sample_rule_based_segment', + :trafficTypeName => 'tt_name_1', + :conditions => [ + { + :matcherGroup => { + :combiner => "AND", + :matchers => [ + { + :matcherType => "WHITELIST", + :negate => false, + :userDefinedSegmentMatcherData => nil, + :whitelistMatcherData => { + :whitelist => [ + "bilal" + ] + }, + :unaryNumericMatcherData => nil, + :betweenMatcherData => nil + } + ] + } + }, + { + :matcherGroup => { + :combiner => "AND", + :matchers => [ + { + :matcherType => "WHITELIST", + :negate => false, + :userDefinedSegmentMatcherData => nil, + :whitelistMatcherData => { + :whitelist => [ + "mauro" + ] + }, + :unaryNumericMatcherData => nil, + :betweenMatcherData => nil + } + ] + } + } + ], + :excluded => {:keys => [], :segments => []} + } + + rbs_repositoy.update([rbs], [], -1) + matcher = described_class.new(segments_repository, rbs_repositoy, 'sample_rule_based_segment', config) + expect(matcher.match?(value: 'mauro', attributes: {})).to be true + expect(matcher.match?(value: 'bilal', attributes: {})).to be true + expect(matcher.match?(value: 'nicolas', attributes: {})).to be false + end end end \ No newline at end of file diff --git a/spec/integrations/in_memory_client_spec.rb b/spec/integrations/in_memory_client_spec.rb index 6802710d..b65a8fd5 100644 --- a/spec/integrations/in_memory_client_spec.rb +++ b/spec/integrations/in_memory_client_spec.rb @@ -1401,8 +1401,8 @@ client_rbs = factory_rbs.client client_rbs.block_until_ready - expect(client_rbs.get_treatment('bilal@split.io', 'rbs_feature_flag', {:email => 'bilal@split.io'})).to eq('on') - expect(client_rbs.get_treatment('mauro@split.io', 'rbs_feature_flag', {:email => 'mauro@split.io'})).to eq('off') + expect(client_rbs.get_treatment('bilal', 'rbs_feature_flag', {:email => 'bilal@split.io'})).to eq('on') + expect(client_rbs.get_treatment('mauro', 'rbs_feature_flag', {:email => 'mauro@split.io'})).to eq('off') end end diff --git a/spec/test_data/rule_based_segments/rule_base_segments.json b/spec/test_data/rule_based_segments/rule_base_segments.json index deafbdc2..6a9b4bd4 100644 --- a/spec/test_data/rule_based_segments/rule_base_segments.json +++ b/spec/test_data/rule_based_segments/rule_base_segments.json @@ -78,7 +78,7 @@ "name": "dependent_rbs", "status": "ACTIVE", "trafficTypeName": "user", - "excluded":{"keys":["mauro@split.io","gaston@split.io"],"segments":[]}, + "excluded":{"keys":["mauro","gaston@split.io"],"segments":[]}, "conditions": [ { "conditionType": "WHITELIST", @@ -100,6 +100,27 @@ } ] } + }, + { + "conditionType": "WHITELIST", + "matcherGroup": { + "combiner": "AND", + "matchers": [ + { + "keySelector": { + "trafficType": "user", + "attribute": "email" + }, + "matcherType": "ENDS_WITH", + "negate": false, + "whitelistMatcherData": { + "whitelist": [ + "@harness.io" + ] + } + } + ] + } } ]}, {