diff --git a/optimizely/event/event_factory.py b/optimizely/event/event_factory.py index 8a4bb0cf..b92c86a1 100644 --- a/optimizely/event/event_factory.py +++ b/optimizely/event/event_factory.py @@ -42,7 +42,10 @@ class EventFactory: to record the events via the Optimizely Events API ("https://developers.optimizely.com/x/events/api/index.html") """ - EVENT_ENDPOINT: Final = 'https://logx.optimizely.com/v1/events' + EVENT_ENDPOINTS: Final = { + 'US': 'https://logx.optimizely.com/v1/events', + 'EU': 'https://eu.logx.optimizely.com/v1/events' + } HTTP_VERB: Final = 'POST' HTTP_HEADERS: Final = {'Content-Type': 'application/json'} ACTIVATE_EVENT_KEY: Final = 'campaign_activated' @@ -97,7 +100,18 @@ def create_log_event( event_params = event_batch.get_event_params() - return log_event.LogEvent(cls.EVENT_ENDPOINT, event_params, cls.HTTP_VERB, cls.HTTP_HEADERS) + region = user_context.region + if hasattr(region, 'value'): + region_str = region.value + elif region is None: + region_str = 'US' # Default to US + else: + region_str = str(region) + + region_key = region_str.upper() + endpoint = cls.EVENT_ENDPOINTS.get(region_key, cls.EVENT_ENDPOINTS['US']) + + return log_event.LogEvent(endpoint, event_params, cls.HTTP_VERB, cls.HTTP_HEADERS) @classmethod def _create_visitor(cls, event: Optional[user_event.UserEvent], logger: Logger) -> Optional[payload.Visitor]: diff --git a/optimizely/event/user_event.py b/optimizely/event/user_event.py index 9cdb623a..243234d3 100644 --- a/optimizely/event/user_event.py +++ b/optimizely/event/user_event.py @@ -17,6 +17,7 @@ from sys import version_info from optimizely import version +from optimizely.project_config import Region if version_info < (3, 8): @@ -97,10 +98,11 @@ def __init__( class EventContext: """ Class respresenting User Event Context. """ - def __init__(self, account_id: str, project_id: str, revision: str, anonymize_ip: bool): + def __init__(self, account_id: str, project_id: str, revision: str, anonymize_ip: bool, region: Region): self.account_id = account_id self.project_id = project_id self.revision = revision self.client_name = CLIENT_NAME self.client_version = version.__version__ self.anonymize_ip = anonymize_ip + self.region = region or 'US' diff --git a/optimizely/event/user_event_factory.py b/optimizely/event/user_event_factory.py index ef07d06b..a15d8f57 100644 --- a/optimizely/event/user_event_factory.py +++ b/optimizely/event/user_event_factory.py @@ -76,7 +76,11 @@ def create_impression_event( variation = project_config.get_variation_from_id_by_experiment_id(experiment_id, variation_id) event_context = user_event.EventContext( - project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, + project_config.account_id, + project_config.project_id, + project_config.revision, + project_config.anonymize_ip, + project_config.region ) return user_event.ImpressionEvent( @@ -115,7 +119,11 @@ def create_conversion_event( """ event_context = user_event.EventContext( - project_config.account_id, project_config.project_id, project_config.revision, project_config.anonymize_ip, + project_config.account_id, + project_config.project_id, + project_config.revision, + project_config.anonymize_ip, + project_config.region ) return user_event.ConversionEvent( diff --git a/optimizely/event_builder.py b/optimizely/event_builder.py index ecabf14c..1416a8f5 100644 --- a/optimizely/event_builder.py +++ b/optimizely/event_builder.py @@ -54,7 +54,10 @@ class EventBuilder: """ Class which encapsulates methods to build events for tracking impressions and conversions using the new V3 event API (batch). """ - EVENTS_URL: Final = 'https://logx.optimizely.com/v1/events' + EVENTS_URLS: Final = { + 'US': 'https://logx.optimizely.com/v1/events', + 'EU': 'https://eu.logx.optimizely.com/v1/events' + } HTTP_VERB: Final = 'POST' HTTP_HEADERS: Final = {'Content-Type': 'application/json'} @@ -266,7 +269,10 @@ def create_impression_event( params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(impression_params) - return Event(self.EVENTS_URL, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) + region = project_config.region.value if hasattr(project_config.region, 'value') else 'US' + events_url = self.EVENTS_URLS.get(str(region), self.EVENTS_URLS['US']) + + return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) def create_conversion_event( self, project_config: ProjectConfig, event_key: str, @@ -289,4 +295,8 @@ def create_conversion_event( conversion_params = self._get_required_params_for_conversion(project_config, event_key, event_tags) params[self.EventParams.USERS][0][self.EventParams.SNAPSHOTS].append(conversion_params) - return Event(self.EVENTS_URL, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) + + region = project_config.region.value if hasattr(project_config.region, 'value') else 'US' + events_url = self.EVENTS_URLS.get(str(region), self.EVENTS_URLS['US']) + + return Event(events_url, params, http_verb=self.HTTP_VERB, headers=self.HTTP_HEADERS) diff --git a/optimizely/project_config.py b/optimizely/project_config.py index f774ff8a..bfbf7ca5 100644 --- a/optimizely/project_config.py +++ b/optimizely/project_config.py @@ -14,6 +14,7 @@ import json from typing import TYPE_CHECKING, Optional, Type, TypeVar, cast, Any, Iterable, List from sys import version_info +from enum import Enum from . import entities from . import exceptions @@ -42,6 +43,11 @@ EntityClass = TypeVar('EntityClass') +class Region(str, Enum): + US = 'US' + EU = 'EU' + + class ProjectConfig: """ Representation of the Optimizely project config. """ @@ -85,6 +91,13 @@ def __init__(self, datafile: str | bytes, logger: Logger, error_handler: Any): self.host_for_odp: Optional[str] = None self.all_segments: list[str] = [] + region_value = config.get('region') + self.region: Region + if region_value == Region.EU.value: + self.region = Region.EU + else: + self.region = Region.US + # Utility maps for quick lookup self.group_id_map: dict[str, entities.Group] = self._generate_key_map(self.groups, 'id', entities.Group) self.experiment_id_map: dict[str, entities.Experiment] = self._generate_key_map( diff --git a/tests/test_config.py b/tests/test_config.py index 9ec5c761..2d7fff5f 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -21,7 +21,7 @@ from optimizely import logger from optimizely import optimizely from optimizely.helpers import enums -from optimizely.project_config import ProjectConfig +from optimizely.project_config import ProjectConfig, Region from . import base @@ -154,6 +154,28 @@ def test_init(self): self.assertEqual(expected_variation_key_map, self.project_config.variation_key_map) self.assertEqual(expected_variation_id_map, self.project_config.variation_id_map) + def test_region_when_no_region(self): + """ Test that region defaults to 'US' when not specified in the config. """ + config_dict = copy.deepcopy(self.config_dict_with_multiple_experiments) + opt_obj = optimizely.Optimizely(json.dumps(config_dict)) + project_config = opt_obj.config_manager.get_config() + self.assertEqual(project_config.region, Region.US) + + def test_region_when_specified_in_datafile(self): + """ Test that region is set to 'US' when specified in the config. """ + config_dict_us = copy.deepcopy(self.config_dict_with_multiple_experiments) + config_dict_us['region'] = 'US' + opt_obj_us = optimizely.Optimizely(json.dumps(config_dict_us)) + project_config_us = opt_obj_us.config_manager.get_config() + self.assertEqual(project_config_us.region, Region.US) + + """ Test that region is set to 'EU' when specified in the config. """ + config_dict_eu = copy.deepcopy(self.config_dict_with_multiple_experiments) + config_dict_eu['region'] = 'EU' + opt_obj_eu = optimizely.Optimizely(json.dumps(config_dict_eu)) + project_config_eu = opt_obj_eu.config_manager.get_config() + self.assertEqual(project_config_eu.region, Region.EU) + def test_cmab_field_population(self): """ Test that the cmab field is populated correctly in experiments.""" diff --git a/tests/test_event_builder.py b/tests/test_event_builder.py index fb4d7a0d..0421e06e 100644 --- a/tests/test_event_builder.py +++ b/tests/test_event_builder.py @@ -17,6 +17,7 @@ from optimizely import event_builder from optimizely import version +from optimizely.project_config import Region from . import base @@ -100,7 +101,61 @@ def test_create_impression_event(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), + expected_params, + event_builder.EventBuilder.HTTP_VERB, + event_builder.EventBuilder.HTTP_HEADERS, + ) + + def test_create_impression_event_with_EU(self): + """ Test that create_impression_event creates Event object with right params and EU region. """ + + expected_params = { + 'account_id': '12001', + 'project_id': '111001', + 'visitors': [ + { + 'visitor_id': 'test_user', + 'attributes': [], + 'snapshots': [ + { + 'decisions': [ + {'variation_id': '111129', 'experiment_id': '111127', 'campaign_id': '111182'} + ], + 'events': [ + { + 'timestamp': 42123, + 'entity_id': '111182', + 'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c', + 'key': 'campaign_activated', + } + ], + } + ], + } + ], + 'client_name': 'python-sdk', + 'client_version': version.__version__, + 'enrich_decisions': True, + 'anonymize_ip': False, + 'revision': '42', + } + + with mock.patch.object(self.project_config, 'region', new=Region.EU), mock.patch( + 'time.time', return_value=42.123 + ), mock.patch( + 'optimizely.bucketer.Bucketer._generate_bucket_value', return_value=5042 + ), mock.patch('uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c'): + event_obj = self.event_builder.create_impression_event( + self.project_config, + self.project_config.get_experiment_from_key('test_experiment'), + '111129', + 'test_user', + None, + ) + self._validate_event_object( + event_obj, + event_builder.EventBuilder.EVENTS_URLS.get('EU'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -155,7 +210,7 @@ def test_create_impression_event__with_attributes(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -204,11 +259,11 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): self.project_config.get_experiment_from_key('test_experiment'), '111129', 'test_user', - {'do_you_know_me': 'test_value'}, + {'do_you_know_me': 'test_value'} ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -275,12 +330,12 @@ def side_effect(*args, **kwargs): self.project_config.get_experiment_from_key('test_experiment'), '111129', 'test_user', - attributes, + attributes ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -340,12 +395,12 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( self.project_config.get_experiment_from_key('test_experiment'), '111129', 'test_user', - {'$opt_user_agent': 'Edge'}, + {'$opt_user_agent': 'Edge'} ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -404,12 +459,12 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en self.project_config.get_experiment_from_key('test_experiment'), '111129', 'test_user', - None, + None ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -474,12 +529,12 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled self.project_config.get_experiment_from_key('test_experiment'), '111129', 'test_user', - {'$opt_user_agent': 'Chrome'}, + {'$opt_user_agent': 'Chrome'} ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -525,7 +580,55 @@ def test_create_conversion_event(self): ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), + expected_params, + event_builder.EventBuilder.HTTP_VERB, + event_builder.EventBuilder.HTTP_HEADERS, + ) + + def test_create_conversion_event_with_eu(self): + """ Test that create_conversion_event creates Event object + with right params when no attributes are provided. """ + + expected_params = { + 'account_id': '12001', + 'project_id': '111001', + 'visitors': [ + { + 'visitor_id': 'test_user', + 'attributes': [], + 'snapshots': [ + { + 'events': [ + { + 'timestamp': 42123, + 'entity_id': '111095', + 'uuid': 'a68cf1ad-0393-4e18-af87-efe8f01a7c9c', + 'key': 'test_event', + } + ] + } + ], + } + ], + 'client_name': 'python-sdk', + 'client_version': version.__version__, + 'enrich_decisions': True, + 'anonymize_ip': False, + 'revision': '42', + } + + with mock.patch.object(self.project_config, 'region', new=Region.EU), mock.patch( + 'time.time', return_value=42.123 + ), mock.patch( + 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' + ): + event_obj = self.event_builder.create_conversion_event( + self.project_config, 'test_event', 'test_user', None, None + ) + self._validate_event_object( + event_obj, + event_builder.EventBuilder.EVENTS_URLS.get('EU'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -569,11 +672,11 @@ def test_create_conversion_event__with_attributes(self): 'uuid.uuid4', return_value='a68cf1ad-0393-4e18-af87-efe8f01a7c9c' ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', {'test_attribute': 'test_value'}, None, + self.project_config, 'test_event', 'test_user', {'test_attribute': 'test_value'}, None ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -626,12 +729,12 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( 'optimizely.project_config.ProjectConfig.get_bot_filtering_value', return_value=True, ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Edge'}, None, + self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Edge'}, None ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -689,12 +792,12 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled 'optimizely.project_config.ProjectConfig.get_bot_filtering_value', return_value=False, ): event_obj = self.event_builder.create_conversion_event( - self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Chrome'}, None, + self.project_config, 'test_event', 'test_user', {'$opt_user_agent': 'Chrome'}, None ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -745,11 +848,11 @@ def test_create_conversion_event__with_event_tags(self): 'test_event', 'test_user', {'test_attribute': 'test_value'}, - {'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'}, + {'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'} ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -798,11 +901,11 @@ def test_create_conversion_event__with_invalid_event_tags(self): 'test_event', 'test_user', {'test_attribute': 'test_value'}, - {'revenue': '4200', 'value': True, 'non-revenue': 'abc'}, + {'revenue': '4200', 'value': True, 'non-revenue': 'abc'} ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, @@ -853,11 +956,11 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel 'test_event', 'test_user', {'test_attribute': 'test_value'}, - {'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'}, + {'revenue': 4200, 'value': 1.234, 'non-revenue': 'abc'} ) self._validate_event_object( event_obj, - event_builder.EventBuilder.EVENTS_URL, + event_builder.EventBuilder.EVENTS_URLS.get('US'), expected_params, event_builder.EventBuilder.HTTP_VERB, event_builder.EventBuilder.HTTP_HEADERS, diff --git a/tests/test_event_factory.py b/tests/test_event_factory.py index adbebd35..ccd53c49 100644 --- a/tests/test_event_factory.py +++ b/tests/test_event_factory.py @@ -118,7 +118,11 @@ def test_create_impression_event(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_attributes(self): @@ -182,7 +186,11 @@ def test_create_impression_event__with_attributes(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event_when_attribute_is_not_in_datafile(self): @@ -244,7 +252,11 @@ def test_create_impression_event_when_attribute_is_not_in_datafile(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event_calls_is_attribute_valid(self): @@ -399,7 +411,11 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_enabled( log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_enabled(self,): @@ -471,7 +487,11 @@ def test_create_impression_event__with_empty_attributes_when_bot_filtering_is_en log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled(self,): @@ -549,7 +569,11 @@ def test_create_impression_event__with_user_agent_when_bot_filtering_is_disabled log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event(self): @@ -594,7 +618,11 @@ def test_create_conversion_event(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_attributes(self): @@ -641,7 +669,11 @@ def test_create_conversion_event__with_attributes(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled(self,): @@ -697,7 +729,11 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_enabled( log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled(self,): @@ -758,7 +794,11 @@ def test_create_conversion_event__with_user_agent_when_bot_filtering_is_disabled log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_event_tags(self): @@ -812,7 +852,11 @@ def test_create_conversion_event__with_event_tags(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__with_invalid_event_tags(self): @@ -864,7 +908,11 @@ def test_create_conversion_event__with_invalid_event_tags(self): log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) def test_create_conversion_event__when_event_is_used_in_multiple_experiments(self): @@ -918,5 +966,9 @@ def test_create_conversion_event__when_event_is_used_in_multiple_experiments(sel log_event = EventFactory.create_log_event(event_obj, self.logger) self._validate_event_object( - log_event, EventFactory.EVENT_ENDPOINT, expected_params, EventFactory.HTTP_VERB, EventFactory.HTTP_HEADERS, + log_event, + EventFactory.EVENT_ENDPOINTS.get('US'), + expected_params, + EventFactory.HTTP_VERB, + EventFactory.HTTP_HEADERS, ) diff --git a/tests/test_event_processor.py b/tests/test_event_processor.py index 4e45e6fc..7b3ff240 100644 --- a/tests/test_event_processor.py +++ b/tests/test_event_processor.py @@ -576,7 +576,7 @@ def __init__(self, is_updated=False): self.is_updated = is_updated def dispatch_event(self, log_event): - if log_event.http_verb == 'POST' and log_event.url == EventFactory.EVENT_ENDPOINT: + if log_event.url in EventFactory.EVENT_ENDPOINTS.values(): self.is_updated = True return self.is_updated diff --git a/tests/test_user_event_factory.py b/tests/test_user_event_factory.py index 009ef05d..4e4d17d1 100644 --- a/tests/test_user_event_factory.py +++ b/tests/test_user_event_factory.py @@ -41,6 +41,21 @@ def test_impression_event(self): self.assertEqual(experiment, impression_event.experiment) self.assertEqual(variation, impression_event.variation) self.assertEqual(user_id, impression_event.user_id) + self.assertEqual(self.project_config.region, impression_event.event_context.region) + + def test_impression_event_with_region_eu(self): + project_config = self.project_config + experiment = self.project_config.get_experiment_from_key('test_experiment') + user_id = 'test_user' + + project_config.region = 'EU' + + impression_event = UserEventFactory.create_impression_event( + project_config, experiment, '111128', '', 'rule_key', 'rule_type', True, user_id, None + ) + + self.assertEqual(self.project_config.region, impression_event.event_context.region) + self.assertEqual('EU', impression_event.event_context.region) def test_impression_event__with_attributes(self): project_config = self.project_config @@ -66,6 +81,7 @@ def test_impression_event__with_attributes(self): self.assertEqual(experiment, impression_event.experiment) self.assertEqual(variation, impression_event.variation) self.assertEqual(user_id, impression_event.user_id) + self.assertEqual(self.project_config.region, impression_event.event_context.region) self.assertEqual( [x.__dict__ for x in expected_attrs], [x.__dict__ for x in impression_event.visitor_attributes], ) @@ -91,6 +107,7 @@ def test_conversion_event(self): self.assertEqual(self.project_config.bot_filtering, conversion_event.bot_filtering) self.assertEqual(self.project_config.get_event(event_key), conversion_event.event) self.assertEqual(user_id, conversion_event.user_id) + self.assertEqual(self.project_config.region, conversion_event.event_context.region) self.assertEqual( [x.__dict__ for x in expected_attrs], [x.__dict__ for x in conversion_event.visitor_attributes], ) @@ -117,6 +134,7 @@ def test_conversion_event__with_event_tags(self): self.assertEqual(self.project_config.bot_filtering, conversion_event.bot_filtering) self.assertEqual(self.project_config.get_event(event_key), conversion_event.event) self.assertEqual(user_id, conversion_event.user_id) + self.assertEqual(self.project_config.region, conversion_event.event_context.region) self.assertEqual( [x.__dict__ for x in expected_attrs], [x.__dict__ for x in conversion_event.visitor_attributes], )