Skip to content

Commit d35161b

Browse files
update: Enhance send_impression method to include CMAB UUID and add tests for CMAB experiments
1 parent 9c31bb8 commit d35161b

File tree

2 files changed

+100
-2
lines changed

2 files changed

+100
-2
lines changed

lib/optimizely.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -219,7 +219,7 @@ def create_optimizely_decision(user_context, flag_key, decision, reasons, decide
219219
end
220220

221221
if !decide_options.include?(OptimizelyDecideOption::DISABLE_DECISION_EVENT) && (decision_source == Optimizely::DecisionService::DECISION_SOURCES['FEATURE_TEST'] || config.send_flag_decisions)
222-
send_impression(config, experiment, variation_key || '', flag_key, rule_key || '', feature_enabled, decision_source, user_id, attributes)
222+
send_impression(config, experiment, variation_key || '', flag_key, rule_key || '', feature_enabled, decision_source, user_id, attributes, decision&.cmab_uuid)
223223
decision_event_dispatched = true
224224
end
225225

@@ -1244,7 +1244,7 @@ def validate_instantiation_options
12441244
raise InvalidInputError, 'event_dispatcher'
12451245
end
12461246

1247-
def send_impression(config, experiment, variation_key, flag_key, rule_key, enabled, rule_type, user_id, attributes = nil)
1247+
def send_impression(config, experiment, variation_key, flag_key, rule_key, enabled, rule_type, user_id, attributes = nil, cmab_uuid = nil)
12481248
if experiment.nil?
12491249
experiment = {
12501250
'id' => '',
@@ -1276,6 +1276,7 @@ def send_impression(config, experiment, variation_key, flag_key, rule_key, enabl
12761276
variation_key: variation_key,
12771277
enabled: enabled
12781278
}
1279+
metadata[:cmab_uuid] = cmab_uuid unless cmab_uuid.nil?
12791280

12801281
user_event = UserEventFactory.create_impression_event(config, experiment, variation_id, metadata, user_id, attributes)
12811282
@event_processor.process(user_event)

spec/project_spec.rb

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4308,6 +4308,103 @@ def callback(_args); end
43084308
expect(decision.reasons).to include('CMAB service failed to fetch decision')
43094309
end
43104310
end
4311+
describe 'CMAB experiments' do
4312+
it 'should include CMAB UUID in dispatched event when decision service returns CMAB result' do
4313+
# Use an existing feature flag from the test config
4314+
feature_flag_key = 'boolean_single_variable_feature'
4315+
4316+
# Get an existing experiment that actually exists in the datafile
4317+
# Looking at the test config, let's use experiment ID '122230' which exists
4318+
existing_experiment = project_config.get_experiment_from_id('122230')
4319+
4320+
# Modify the existing experiment to be a CMAB experiment
4321+
cmab_experiment = existing_experiment.dup
4322+
cmab_experiment['trafficAllocation'] = [] # Empty for CMAB
4323+
cmab_experiment['cmab'] = {'attributeIds' => %w[808797688 808797689], 'trafficAllocation' => 4000}
4324+
4325+
# Mock the config to return our modified CMAB experiment
4326+
allow(project_instance.config_manager.config).to receive(:get_experiment_from_id)
4327+
.with('122230')
4328+
.and_return(cmab_experiment)
4329+
4330+
allow(project_instance.config_manager.config).to receive(:experiment_running?)
4331+
.with(cmab_experiment)
4332+
.and_return(true)
4333+
4334+
# Get the feature flag and update it to reference our CMAB experiment
4335+
feature_flag = project_instance.config_manager.config.get_feature_flag_from_key(feature_flag_key)
4336+
feature_flag['experimentIds'] = ['122230']
4337+
4338+
# Use existing variations from the original experiment
4339+
variation_to_use = existing_experiment['variations'][0]
4340+
4341+
# Create a decision with CMAB UUID
4342+
expected_cmab_uuid = 'uuid-cmab'
4343+
decision_with_cmab = Optimizely::DecisionService::Decision.new(
4344+
cmab_experiment,
4345+
variation_to_use,
4346+
Optimizely::DecisionService::DECISION_SOURCES['FEATURE_TEST'],
4347+
expected_cmab_uuid
4348+
)
4349+
4350+
decision_result_with_cmab = Optimizely::DecisionService::DecisionResult.new(
4351+
decision_with_cmab,
4352+
false,
4353+
[]
4354+
)
4355+
4356+
# Mock get_variations_for_feature_list to return CMAB result
4357+
allow(project_instance.decision_service).to receive(:get_variations_for_feature_list)
4358+
.and_return([decision_result_with_cmab])
4359+
4360+
# Set up time and UUID mocks for consistent event data
4361+
allow(Time).to receive(:now).and_return(time_now)
4362+
allow(SecureRandom).to receive(:uuid).and_return('a68cf1ad-0393-4e18-af87-efe8f01a7c9c')
4363+
4364+
# Create array to capture dispatched events
4365+
dispatched_events = []
4366+
allow(project_instance.event_dispatcher).to receive(:dispatch_event) do |event|
4367+
dispatched_events << event
4368+
end
4369+
4370+
user_context = project_instance.create_user_context('test_user')
4371+
decision = user_context.decide(feature_flag_key)
4372+
4373+
# Wait for batch processing thread to send event
4374+
sleep 0.1 until project_instance.event_processor.event_queue.empty?
4375+
4376+
# Verify the decision contains expected information
4377+
expect(decision.enabled).to eq(true)
4378+
expect(decision.variation_key).to eq(variation_to_use['key'])
4379+
expect(decision.rule_key).to eq(existing_experiment['key'])
4380+
expect(decision.flag_key).to eq(feature_flag_key)
4381+
4382+
# Verify an event was dispatched
4383+
expect(dispatched_events.length).to eq(1)
4384+
4385+
dispatched_event = dispatched_events[0]
4386+
4387+
# Remove the puts statement and verify the event structure and CMAB UUID
4388+
expect(dispatched_event.params).to have_key(:visitors)
4389+
expect(dispatched_event.params[:visitors].length).to be > 0
4390+
expect(dispatched_event.params[:visitors][0]).to have_key(:snapshots)
4391+
expect(dispatched_event.params[:visitors][0][:snapshots].length).to be > 0
4392+
expect(dispatched_event.params[:visitors][0][:snapshots][0]).to have_key(:decisions)
4393+
expect(dispatched_event.params[:visitors][0][:snapshots][0][:decisions].length).to be > 0
4394+
4395+
# Get the metadata and assert CMAB UUID
4396+
metadata = dispatched_event.params[:visitors][0][:snapshots][0][:decisions][0][:metadata]
4397+
expect(metadata).to have_key(:cmab_uuid)
4398+
expect(metadata[:cmab_uuid]).to eq(expected_cmab_uuid)
4399+
4400+
# Also verify other expected metadata fields
4401+
expect(metadata[:flag_key]).to eq(feature_flag_key)
4402+
expect(metadata[:rule_key]).to eq('test_experiment_multivariate')
4403+
expect(metadata[:rule_type]).to eq('feature-test')
4404+
expect(metadata[:variation_key]).to eq('Fred')
4405+
expect(metadata[:enabled]).to eq(true)
4406+
end
4407+
end
43114408
end
43124409

43134410
describe '#decide_all' do

0 commit comments

Comments
 (0)