Skip to content

Commit 2604b6a

Browse files
test: Unittest for event (#18)
###Summary inline doc for event module unit test for event module ###Checklist * [x]Does your PR title have the correct title format? * Does your PR have a breaking change?: no
1 parent e5c0f24 commit 2604b6a

11 files changed

+911
-38
lines changed

.github/pull_request_template.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!---
2-
Thanks for contributing to the Amplitude Java SDK! 🎉
2+
Thanks for contributing to the Amplitude Python SDK! 🐍
33
44
Please fill out the following sections to help us quickly review your pull request.
55
--->

src/amplitude/__init__.py

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1+
"""The official Amplitude Python SDK"""
2+
3+
14
from amplitude.client import Amplitude
2-
from amplitude.event import BaseEvent, EventOptions, Identify, Revenue, IdentifyEvent, GroupIdentifyEvent, RevenueEvent
5+
from amplitude.event import BaseEvent, EventOptions, Identify, Revenue, IdentifyEvent, \
6+
GroupIdentifyEvent, RevenueEvent, Plan
37
from amplitude.config import Config
48
from amplitude.constants import PluginType
59
from amplitude.plugin import EventPlugin, DestinationPlugin

src/amplitude/client.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ class Amplitude:
2323
Attributes:
2424
configuration (amplitude.config.Config): the configuration of client instance
2525
26-
Methods
26+
Methods:
2727
track(event): Process and send event
2828
identify(identify_obj, event_properties, event_options): Send an identify event to update user properties
2929
group_identify(group_type, group_name, identify_obj, event_options, event_properties, user_properties): Send
@@ -110,7 +110,7 @@ def revenue(self, revenue_obj: Revenue, event_options: EventOptions):
110110
like user_id.
111111
"""
112112
if not revenue_obj.is_valid():
113-
self.configuration.logger.error("Missing price for revenue event")
113+
self.configuration.logger.error("Invalid price for revenue event")
114114
else:
115115
event = revenue_obj.to_revenue_event()
116116
event.load_event_options(event_options)

src/amplitude/config.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ def __init__(self, api_key: str = None,
1212
flush_queue_size: int = constants.FLUSH_QUEUE_SIZE,
1313
flush_interval_millis: int = constants.FLUSH_INTERVAL_MILLIS,
1414
flush_max_retries: int = constants.FLUSH_MAX_RETRIES,
15-
logger=logging.getLogger(__name__),
15+
logger=logging.getLogger(constants.LOGGER_NAME),
1616
min_id_length: Optional[int] = None,
1717
callback: Optional[Callable[[BaseEvent, int, Optional[str]], None]] = None,
1818
server_zone: str = constants.DEFAULT_ZONE,

src/amplitude/constants.py

+1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
HTTP_V2: "https://api2.amplitude.com/2/httpapi"
1818
}
1919
}
20+
LOGGER_NAME = "amplitude"
2021

2122
IDENTIFY_EVENT = "$identify"
2223
GROUP_IDENTIFY_EVENT = "$groupidentify"

src/amplitude/event.py

+493-11
Large diffs are not rendered by default.

src/amplitude/timeline.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44

55
from amplitude.constants import PluginType
66
from amplitude.exception import InvalidEventError
7+
from amplitude.constants import LOGGER_NAME
78

89

910
class Timeline:
@@ -25,7 +26,7 @@ def __init__(self, configuration=None):
2526
def logger(self):
2627
if self.configuration:
2728
return self.configuration.logger
28-
return logging.getLogger(__name__)
29+
return logging.getLogger(LOGGER_NAME)
2930

3031
def setup(self, client):
3132
self.configuration = client.configuration

src/amplitude/utils.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
from amplitude import constants
55

6-
logger = logging.getLogger(__name__)
6+
logger = logging.getLogger(constants.LOGGER_NAME)
77

88

99
def current_milliseconds() -> int:
@@ -15,7 +15,7 @@ def truncate(obj):
1515
if not obj:
1616
return {}
1717
if len(obj) > constants.MAX_PROPERTY_KEYS:
18-
logger.error(f"Too many properties: {obj}")
18+
logger.error(f"Too many properties. {constants.MAX_PROPERTY_KEYS} maximum.")
1919
return {}
2020
for key, value in obj.items():
2121
obj[key] = truncate(value)

src/test/event.py

-10
This file was deleted.

src/test/test_client.py

+48-9
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ def setUp(self) -> None:
1717
def tearDown(self) -> None:
1818
self.client.shutdown()
1919

20-
def test_track_success(self):
20+
def test_amplitude_client_track_success(self):
2121
post_method = MagicMock()
2222
HttpClient.post = post_method
2323
res = Response(HttpStatus.SUCCESS)
@@ -40,7 +40,7 @@ def callback_func(event, code, message=None):
4040
self.assertEqual(25, len(events))
4141
post_method.assert_called()
4242

43-
def test_track_invalid_api_key(self):
43+
def test_amplitude_client_track_invalid_api_key_log_error(self):
4444
post_method = MagicMock()
4545
HttpClient.post = post_method
4646
res = Response(HttpStatus.INVALID_REQUEST)
@@ -57,7 +57,7 @@ def test_track_invalid_api_key(self):
5757
post_method.assert_called_once()
5858
self.assertEqual(["ERROR:test:Invalid API Key"], cm.output)
5959

60-
def test_track_invalid(self):
60+
def test_amplitude_client_track_invalid_response_then_success_response(self):
6161
post_method = MagicMock()
6262
HttpClient.post = post_method
6363
invalid_res = Response(HttpStatus.INVALID_REQUEST)
@@ -97,7 +97,7 @@ def callback_func(event, code, message=None):
9797
self.assertEqual([(1, 0), (2, 0), (5, 0), (6, 0), (8, 0),
9898
(0, 1), (3, 1), (4, 1), (7, 1), (9, 1)], events)
9999

100-
def test_identify(self):
100+
def test_amplitude_client_identify_invalid_log_error_then_success(self):
101101
post_method = MagicMock()
102102
HttpClient.post = post_method
103103
res = Response(HttpStatus.SUCCESS)
@@ -118,14 +118,19 @@ def callback_func(event, code, message=None):
118118
self.client.configuration.use_batch = use_batch
119119
identify_obj = Identify()
120120
self.assertFalse(identify_obj.is_valid())
121+
with self.assertLogs("test", "ERROR") as cm:
122+
self.client.configuration.logger = logging.getLogger("test")
123+
self.client.identify(identify_obj,
124+
EventOptions(user_id="test_user_id", device_id="test_device_id"))
125+
self.assertEqual(["ERROR:test:Empty identify properties"], cm.output)
121126
identify_obj.set("birth_date", "4-1-2022")
122127
self.assertTrue(identify_obj.is_valid())
123128
self.assertEqual({"$set": {"birth_date": "4-1-2022"}}, identify_obj.user_properties)
124129
self.client.identify(identify_obj, EventOptions(user_id="test_user_id", device_id="test_device_id"))
125130
self.client.flush()
126131
post_method.assert_called_once()
127132

128-
def test_group_identify(self):
133+
def test_amplitude_client_group_identify_invalid_log_error_then_success(self):
129134
post_method = MagicMock()
130135
HttpClient.post = post_method
131136
res = Response(HttpStatus.SUCCESS)
@@ -147,6 +152,11 @@ def callback_func(event, code, message=None):
147152
self.client.configuration.use_batch = use_batch
148153
identify_obj = Identify()
149154
self.assertFalse(identify_obj.is_valid())
155+
with self.assertLogs("test", "ERROR") as cm:
156+
self.client.configuration.logger = logging.getLogger("test")
157+
self.client.group_identify("Sports", "Football", identify_obj,
158+
EventOptions(user_id="test_user_id", device_id="test_device_id"))
159+
self.assertEqual(["ERROR:test:Empty group identify properties"], cm.output)
150160
identify_obj.set("team_name", "Super Power")
151161
self.assertTrue(identify_obj.is_valid())
152162
self.assertEqual({"$set": {"team_name": "Super Power"}}, identify_obj.user_properties)
@@ -155,7 +165,32 @@ def callback_func(event, code, message=None):
155165
self.client.flush()
156166
post_method.assert_called_once()
157167

158-
def test_revenue(self):
168+
def test_amplitude_set_group_success(self):
169+
post_method = MagicMock()
170+
HttpClient.post = post_method
171+
res = Response(HttpStatus.SUCCESS)
172+
post_method.return_value = res
173+
174+
def callback_func(event, code, message=None):
175+
self.assertEqual(200, code)
176+
self.assertTrue(isinstance(event, IdentifyEvent))
177+
self.assertTrue("user_properties" in event)
178+
self.assertEqual("$identify", event["event_type"])
179+
self.assertEqual("test_user_id", event["user_id"])
180+
self.assertEqual("test_device_id", event["device_id"])
181+
self.assertEqual({"$set": {"type": ["test_group", "test_group_2"]}}, event.user_properties)
182+
183+
self.client.configuration.callback = callback_func
184+
for use_batch in (True, False):
185+
with self.subTest(use_batch=use_batch):
186+
post_method.reset_mock()
187+
self.client.configuration.use_batch = use_batch
188+
self.client.set_group("type", ["test_group", "test_group_2"],
189+
EventOptions(user_id="test_user_id", device_id="test_device_id"))
190+
self.client.flush()
191+
post_method.assert_called_once()
192+
193+
def test_amplitude_client_revenue_invalid_log_error_then_success(self):
159194
post_method = MagicMock()
160195
HttpClient.post = post_method
161196
res = Response(HttpStatus.SUCCESS)
@@ -169,7 +204,7 @@ def callback_func(event, code, message=None):
169204
self.assertEqual("test_user_id", event["user_id"])
170205
self.assertEqual("test_device_id", event["device_id"])
171206
self.assertEqual({'$price': 60.2, '$productId': 'P63', '$quantity': 3, '$receipt': 'A0001',
172-
'$receiptSig': '0001A', '$revenue': None, '$revenueType': None, 'other_property': 'test'},
207+
'$receiptSig': '0001A', 'other_property': 'test'},
173208
event["event_properties"])
174209

175210
self.client.configuration.callback = callback_func
@@ -179,14 +214,18 @@ def callback_func(event, code, message=None):
179214
self.client.configuration.use_batch = use_batch
180215
revenue_obj = Revenue(price="abc", quantity=3, product_id="P63", properties={"other_property": "test"})
181216
self.assertFalse(revenue_obj.is_valid())
217+
with self.assertLogs("test", "ERROR") as cm:
218+
self.client.configuration.logger = logging.getLogger("test")
219+
self.client.revenue(revenue_obj, EventOptions(user_id="test_user_id", device_id="test_device_id"))
220+
self.assertEqual(["ERROR:test:Invalid price for revenue event"], cm.output)
182221
revenue_obj.price = 60.2
183222
self.assertTrue(revenue_obj.is_valid())
184223
revenue_obj.set_receipt("A0001", "0001A")
185224
self.client.revenue(revenue_obj, EventOptions(user_id="test_user_id", device_id="test_device_id"))
186225
self.client.flush()
187226
post_method.assert_called_once()
188227

189-
def test_flush(self):
228+
def test_amplitude_client_flush_success(self):
190229
post_method = MagicMock()
191230
HttpClient.post = post_method
192231
res = Response(HttpStatus.SUCCESS)
@@ -210,7 +249,7 @@ def callback_func(event, code, message=None):
210249
self.client.flush()
211250
post_method.assert_called_once()
212251

213-
def test_add_remove(self):
252+
def test_amplitude_add_remove_plugins_success(self):
214253
timeline = self.client._Amplitude__timeline
215254
before_plugin = EventPlugin(PluginType.BEFORE)
216255
enrich_plugin = EventPlugin(plugin_type=PluginType.ENRICHMENT)

0 commit comments

Comments
 (0)