Skip to content

Commit b987ccc

Browse files
committed
[AI-FSSDK] [FSSDK-12670] Block ODP identify event for single identifier
1 parent c44cf9c commit b987ccc

6 files changed

Lines changed: 66 additions & 14 deletions

File tree

lib/optimizely.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1018,13 +1018,13 @@ def send_odp_event(action:, identifiers:, type: Helpers::Constants::ODP_MANAGER_
10181018
@odp_manager.send_event(type: type, action: action, identifiers: identifiers, data: data)
10191019
end
10201020

1021-
def identify_user(user_id:)
1021+
def identify_user(identifiers:)
10221022
unless is_valid
10231023
@logger.log(Logger::ERROR, InvalidProjectConfigError.new('identify_user').message)
10241024
return
10251025
end
10261026

1027-
@odp_manager.identify_user(user_id: user_id)
1027+
@odp_manager.identify_user(identifiers: identifiers)
10281028
end
10291029

10301030
def fetch_qualified_segments(user_id:, options: [])

lib/optimizely/odp/odp_manager.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def fetch_qualified_segments(user_id:, options:)
8787
@segment_manager.fetch_qualified_segments(ODP_MANAGER_CONFIG[:KEY_FOR_USER_ID], user_id, options)
8888
end
8989

90-
def identify_user(user_id:)
90+
def identify_user(identifiers:)
9191
unless @enabled
9292
@logger.log(Logger::DEBUG, 'ODP identify event is not dispatched (ODP disabled).')
9393
return
@@ -102,10 +102,16 @@ def identify_user(user_id:)
102102
return
103103
end
104104

105+
valid_identifiers = identifiers.select { |_k, v| v && !v.to_s.empty? }
106+
if valid_identifiers.length < 2
107+
@logger.log(Logger::DEBUG, 'ODP identify event is not dispatched (only one identifier provided).')
108+
return
109+
end
110+
105111
@event_manager.send_event(
106112
type: ODP_MANAGER_CONFIG[:EVENT_TYPE],
107113
action: 'identified',
108-
identifiers: {ODP_MANAGER_CONFIG[:KEY_FOR_USER_ID] => user_id},
114+
identifiers: valid_identifiers,
109115
data: {}
110116
)
111117
end

lib/optimizely/optimizely_user_context.rb

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#
1818

1919
require 'json'
20+
require_relative 'helpers/constants'
2021

2122
module Optimizely
2223
class OptimizelyUserContext
@@ -36,7 +37,10 @@ def initialize(optimizely_client, user_id, user_attributes, identify: true)
3637
@forced_decisions = {}
3738
@qualified_segments = nil
3839

39-
@optimizely_client&.identify_user(user_id: user_id) if identify
40+
if identify
41+
identifiers = {Optimizely::Helpers::Constants::ODP_MANAGER_CONFIG[:KEY_FOR_USER_ID] => user_id}
42+
@optimizely_client&.identify_user(identifiers: identifiers)
43+
end
4044
end
4145

4246
def clone

spec/odp/odp_manager_spec.rb

Lines changed: 48 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -218,10 +218,52 @@
218218
end
219219

220220
describe '#identify_user' do
221-
it 'should send event' do
221+
it 'should send event when multiple identifiers provided' do
222+
allow(SecureRandom).to receive(:uuid).and_return(test_uuid)
223+
event_manager = Optimizely::OdpEventManager.new
224+
identifiers = {user_key => user_value, 'email' => 'test@example.com'}
225+
event = Optimizely::OdpEvent.new(type: 'fullstack', action: 'identified', identifiers: identifiers, data: {})
226+
expect(spy_logger).not_to receive(:log).with(Logger::ERROR, anything)
227+
228+
expect(event_manager.api_manager)
229+
.to receive(:send_odp_events)
230+
.once
231+
.with(api_key, api_host, [event])
232+
.and_return(false)
233+
234+
manager = Optimizely::OdpManager.new(disable: false, event_manager: event_manager, logger: spy_logger)
235+
manager.update_odp_config(api_key, api_host, segments_to_check)
236+
237+
manager.identify_user(identifiers: identifiers)
238+
239+
manager.stop!
240+
end
241+
242+
it 'should not send event when only one identifier provided' do
243+
expect(spy_logger).to receive(:log).with(Logger::DEBUG, 'ODP identify event is not dispatched (only one identifier provided).')
244+
245+
manager = Optimizely::OdpManager.new(disable: false, logger: spy_logger)
246+
manager.update_odp_config(api_key, api_host, segments_to_check)
247+
manager.identify_user(identifiers: {user_key => user_value})
248+
249+
manager.stop!
250+
end
251+
252+
it 'should not count empty or nil identifier values' do
253+
expect(spy_logger).to receive(:log).with(Logger::DEBUG, 'ODP identify event is not dispatched (only one identifier provided).')
254+
255+
manager = Optimizely::OdpManager.new(disable: false, logger: spy_logger)
256+
manager.update_odp_config(api_key, api_host, segments_to_check)
257+
manager.identify_user(identifiers: {user_key => user_value, 'email' => '', 'phone' => nil})
258+
259+
manager.stop!
260+
end
261+
262+
it 'should send event with all valid identifiers when some are empty' do
222263
allow(SecureRandom).to receive(:uuid).and_return(test_uuid)
223264
event_manager = Optimizely::OdpEventManager.new
224-
event = Optimizely::OdpEvent.new(type: 'fullstack', action: 'identified', identifiers: {user_key => user_value}, data: {})
265+
valid_identifiers = {user_key => user_value, 'email' => 'test@example.com'}
266+
event = Optimizely::OdpEvent.new(type: 'fullstack', action: 'identified', identifiers: valid_identifiers, data: {})
225267
expect(spy_logger).not_to receive(:log).with(Logger::ERROR, anything)
226268

227269
expect(event_manager.api_manager)
@@ -233,7 +275,7 @@
233275
manager = Optimizely::OdpManager.new(disable: false, event_manager: event_manager, logger: spy_logger)
234276
manager.update_odp_config(api_key, api_host, segments_to_check)
235277

236-
manager.identify_user(user_id: user_value)
278+
manager.identify_user(identifiers: {user_key => user_value, 'email' => 'test@example.com', 'phone' => ''})
237279

238280
manager.stop!
239281
end
@@ -243,7 +285,7 @@
243285
expect(spy_logger).to receive(:log).with(Logger::DEBUG, 'ODP identify event is not dispatched (ODP disabled).')
244286

245287
manager = Optimizely::OdpManager.new(disable: true, logger: spy_logger)
246-
manager.identify_user(user_id: user_value)
288+
manager.identify_user(identifiers: {user_key => user_value, 'email' => 'test@example.com'})
247289

248290
manager.stop!
249291
end
@@ -253,7 +295,7 @@
253295
expect(spy_logger).to receive(:log).with(Logger::DEBUG, 'ODP identify event is not dispatched (ODP not integrated).')
254296
manager = Optimizely::OdpManager.new(disable: false, logger: spy_logger)
255297
manager.update_odp_config(nil, nil, [])
256-
manager.identify_user(user_id: user_value)
298+
manager.identify_user(identifiers: {user_key => user_value, 'email' => 'test@example.com'})
257299

258300
manager.stop!
259301
end
@@ -263,7 +305,7 @@
263305
expect(spy_logger).to receive(:log).with(Logger::DEBUG, 'ODP identify event is not dispatched (datafile not ready).')
264306

265307
manager = Optimizely::OdpManager.new(disable: false, logger: spy_logger)
266-
manager.identify_user(user_id: user_value)
308+
manager.identify_user(identifiers: {user_key => user_value, 'email' => 'test@example.com'})
267309

268310
manager.stop!
269311
end

spec/optimizely_user_context_spec.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -907,15 +907,15 @@
907907
it 'should send identify event when user context created' do
908908
stub_request(:post, 'https://api.zaius.com/v3/graphql').to_return(status: 200, body: good_response_data.to_json)
909909
stub_request(:post, 'https://api.zaius.com/v3/events').to_return(status: 200)
910-
expect(integration_project_instance.odp_manager).to receive(:identify_user).with({user_id: 'tester'})
910+
expect(integration_project_instance.odp_manager).to receive(:identify_user).with({identifiers: {'fs_user_id' => 'tester'}})
911911
Optimizely::OptimizelyUserContext.new(integration_project_instance, 'tester', {})
912912

913913
integration_project_instance.close
914914
end
915915

916916
it 'should skip identify with decisions' do
917917
stub_request(:post, impression_log_url)
918-
expect(integration_project_instance.odp_manager).to receive(:identify_user).with({user_id: 'tester'})
918+
expect(integration_project_instance.odp_manager).to receive(:identify_user).with({identifiers: {'fs_user_id' => 'tester'}})
919919
expect(spy_logger).not_to receive(:log).with(Logger::ERROR, anything)
920920

921921
user_context = Optimizely::OptimizelyUserContext.new(integration_project_instance, 'tester', {})

spec/project_spec.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,7 @@ class InvalidErrorHandler; end # rubocop:disable Lint/ConstantDefinitionInBlock
226226

227227
it 'should send identify event when called with odp enabled' do
228228
project = Optimizely::Project.new(datafile: config_body_integrations_JSON, logger: spy_logger)
229-
expect(project.odp_manager).to receive(:identify_user).with({user_id: 'tester'})
229+
expect(project.odp_manager).to receive(:identify_user).with({identifiers: {'fs_user_id' => 'tester'}})
230230
project.create_user_context('tester')
231231

232232
project.close

0 commit comments

Comments
 (0)