From cf66169c1fb03d9d5ec73335a179e62647dfcb86 Mon Sep 17 00:00:00 2001 From: Gagan Trivedi Date: Mon, 9 Nov 2026 13:29:36 +0530 Subject: [PATCH] fix: Serve multivariate segment overrides their variant under local evaluation Segment overrides were mapped without their multivariate values, so every identity in the segment got the override's control value. Map them the same way as environment features. --- lib/flagsmith/engine/mappers/segments.rb | 20 ++------------- .../unit/evaluation_context_mappers_spec.rb | 25 +++++++++++++++++++ 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/lib/flagsmith/engine/mappers/segments.rb b/lib/flagsmith/engine/mappers/segments.rb index f842e6f..4c687fc 100644 --- a/lib/flagsmith/engine/mappers/segments.rb +++ b/lib/flagsmith/engine/mappers/segments.rb @@ -26,24 +26,8 @@ def self.build_segment_hash(segment) } end - def self.build_overrides(feature_states) # rubocop:disable Metrics/MethodLength - feature_states.map do |feature_state| - override_hash = { - key: feature_state.django_id&.to_s || feature_state.uuid, - name: feature_state.feature.name, - enabled: feature_state.enabled, - value: feature_state.get_value, - metadata: { id: feature_state.feature.id } - } - add_priority_to_override(override_hash, feature_state) - override_hash - end - end - - def self.add_priority_to_override(override_hash, feature_state) - return unless feature_state.feature_segment&.priority - - override_hash[:priority] = feature_state.feature_segment.priority + def self.build_overrides(feature_states) + feature_states.map { |feature_state| Environment.build_feature_hash(feature_state) } end def self.map_rule(rule) diff --git a/spec/engine/unit/evaluation_context_mappers_spec.rb b/spec/engine/unit/evaluation_context_mappers_spec.rb index 2c92dca..d62ea65 100644 --- a/spec/engine/unit/evaluation_context_mappers_spec.rb +++ b/spec/engine/unit/evaluation_context_mappers_spec.rb @@ -207,6 +207,31 @@ expect(feature_context[:variants][0][:priority]).not_to eq(feature_context[:variants][1][:priority]) end + it 'serves a multivariate segment override its variant' do + # Given + segment_override = environment_json[:project][:segments][0][:feature_states][0] + segment_override[:multivariate_feature_state_values] = [{ + id: 7, + percentage_allocation: 100, + multivariate_feature_option: { id: 7, value: 'segment_variant' } + }] + identity = Flagsmith::Engine::Identity.new( + identifier: 'test_user', + environment_api_key: 'B62qaMZNwfiqT76p38ggrQ', + identity_traits: [Flagsmith::Engine::Identities::Trait.new(trait_key: 'age', trait_value: 25)] + ) + + # When + context = described_class.get_evaluation_context(environment, identity) + result = Flagsmith::Engine.get_evaluation_result(context) + + # Then + expect(context[:segments]['1'][:overrides][0][:variants]).to eq( + [{ value: 'segment_variant', weight: 100, priority: 7 }] + ) + expect(result[:flags][:some_feature][:value]).to eq('segment_variant') + end + it 'handles environment with no features' do # Given empty_env = Flagsmith::Engine::Environment.new(