Skip to content

Commit d53e8ee

Browse files
Fix falsy ID validation rejecting valid values like integer 0 (#129)
1 parent 4a98d69 commit d53e8ee

2 files changed

Lines changed: 65 additions & 15 deletions

File tree

customerio/track.py

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -86,14 +86,14 @@ def get_device_query_string(self, customer_id):
8686

8787
def identify(self, id, **kwargs):
8888
"""Identify a single customer by their unique id, and optionally add attributes."""
89-
if not id:
89+
if id is None or id == "":
9090
raise CustomerIOException("id cannot be blank in identify")
9191
url = self.get_customer_query_string(id)
9292
return self.send_request("PUT", url, kwargs)
9393

9494
def track(self, customer_id, name, data=None, id=None, timestamp=None):
9595
"""Track an event for a given customer_id."""
96-
if not customer_id:
96+
if customer_id is None or customer_id == "":
9797
raise CustomerIOException("customer_id cannot be blank in track")
9898
url = self.get_event_query_string(customer_id)
9999
post_data = self._build_event(name, data, id=id, timestamp=timestamp)
@@ -103,14 +103,14 @@ def track_anonymous(self, anonymous_id, name, data=None, id=None, timestamp=None
103103
"""Track an event for a given anonymous_id."""
104104
url = self.get_events_query_string()
105105
post_data = self._build_event(name, data, id=id, timestamp=timestamp)
106-
if anonymous_id:
106+
if anonymous_id is not None and anonymous_id != "":
107107
post_data["anonymous_id"] = anonymous_id
108108

109109
return self.send_request("POST", url, post_data)
110110

111111
def pageview(self, customer_id, page, **data):
112112
"""Track a pageview for a given customer_id."""
113-
if not customer_id:
113+
if customer_id is None or customer_id == "":
114114
raise CustomerIOException("customer_id cannot be blank in pageview")
115115
url = self.get_event_query_string(customer_id)
116116
post_data = {
@@ -122,7 +122,7 @@ def pageview(self, customer_id, page, **data):
122122

123123
def backfill(self, customer_id, name, timestamp, **data):
124124
"""Backfill an event (track with timestamp) for a given customer_id."""
125-
if not customer_id:
125+
if customer_id is None or customer_id == "":
126126
raise CustomerIOException("customer_id cannot be blank in backfill")
127127

128128
url = self.get_event_query_string(customer_id)
@@ -166,21 +166,21 @@ def _build_event(self, name, data=None, id=None, timestamp=None):
166166

167167
def delete(self, customer_id):
168168
"""Delete a customer profile."""
169-
if not customer_id:
169+
if customer_id is None or customer_id == "":
170170
raise CustomerIOException("customer_id cannot be blank in delete")
171171

172172
url = self.get_customer_query_string(customer_id)
173173
return self.send_request("DELETE", url, {})
174174

175175
def add_device(self, customer_id, device_id, platform, **data):
176176
"""Add a device to a customer profile."""
177-
if not customer_id:
177+
if customer_id is None or customer_id == "":
178178
raise CustomerIOException("customer_id cannot be blank in add_device")
179179

180-
if not device_id:
180+
if device_id is None or device_id == "":
181181
raise CustomerIOException("device_id cannot be blank in add_device")
182182

183-
if not platform:
183+
if platform is None or platform == "":
184184
raise CustomerIOException("platform cannot be blank in add_device")
185185

186186
data.update(
@@ -195,18 +195,18 @@ def add_device(self, customer_id, device_id, platform, **data):
195195

196196
def delete_device(self, customer_id, device_id):
197197
"""Delete a device from a customer profile."""
198-
if not customer_id:
198+
if customer_id is None or customer_id == "":
199199
raise CustomerIOException("customer_id cannot be blank in delete_device")
200200

201-
if not device_id:
201+
if device_id is None or device_id == "":
202202
raise CustomerIOException("device_id cannot be blank in delete_device")
203203

204204
url = self.get_device_query_string(customer_id)
205205
delete_url = f"{url}/{self._url_encode(device_id)}"
206206
return self.send_request("DELETE", delete_url, {})
207207

208208
def suppress(self, customer_id):
209-
if not customer_id:
209+
if customer_id is None or customer_id == "":
210210
raise CustomerIOException("customer_id cannot be blank in suppress")
211211

212212
return self.send_request(
@@ -216,7 +216,7 @@ def suppress(self, customer_id):
216216
)
217217

218218
def unsuppress(self, customer_id):
219-
if not customer_id:
219+
if customer_id is None or customer_id == "":
220220
raise CustomerIOException("customer_id cannot be blank in unsuppress")
221221

222222
return self.send_request(
@@ -236,10 +236,10 @@ def merge_customers(self, primary_id_type, primary_id, secondary_id_type, second
236236
if not self.is_valid_id_type(secondary_id_type):
237237
raise CustomerIOException("invalid secondary id type")
238238

239-
if not primary_id:
239+
if primary_id is None or primary_id == "":
240240
raise CustomerIOException("primary customer_id cannot be blank")
241241

242-
if not secondary_id:
242+
if secondary_id is None or secondary_id == "":
243243
raise CustomerIOException("secondary customer_id cannot be blank")
244244

245245
url = f"{self.base_url}/merge_customers"

tests/test_customerio.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -672,6 +672,56 @@ def test_merge_customers_call(self):
672672
secondary_id="",
673673
)
674674

675+
def test_identify_with_zero_id(self):
676+
self.cio.http.hooks = dict(
677+
response=partial(
678+
self._check_request,
679+
rq={
680+
"method": "PUT",
681+
"url_suffix": "/customers/0",
682+
"body": {"name": "john"},
683+
},
684+
)
685+
)
686+
687+
self.cio.identify(id=0, name="john")
688+
689+
def test_track_with_zero_customer_id(self):
690+
self.cio.http.hooks = dict(
691+
response=partial(
692+
self._check_request,
693+
rq={
694+
"method": "POST",
695+
"url_suffix": "/customers/0/events",
696+
"body": {"data": {}, "name": "login"},
697+
},
698+
)
699+
)
700+
701+
self.cio.track(customer_id=0, name="login")
702+
703+
def test_identify_with_none_raises(self):
704+
with self.assertRaises(CustomerIOException):
705+
self.cio.identify(id=None, name="john")
706+
707+
def test_identify_with_empty_string_raises(self):
708+
with self.assertRaises(CustomerIOException):
709+
self.cio.identify(id="", name="john")
710+
711+
def test_delete_with_zero_customer_id(self):
712+
self.cio.http.hooks = dict(
713+
response=partial(
714+
self._check_request,
715+
rq={
716+
"method": "DELETE",
717+
"url_suffix": "/customers/0",
718+
"body": {},
719+
},
720+
)
721+
)
722+
723+
self.cio.delete(customer_id=0)
724+
675725
def test_batch_call(self):
676726
self.cio.http.hooks = dict(
677727
response=partial(

0 commit comments

Comments
 (0)