Skip to content

Commit 34f87c4

Browse files
committed
add comments, tests for normalization, change email in example
1 parent 033bf3f commit 34f87c4

File tree

4 files changed

+127
-3
lines changed

4 files changed

+127
-3
lines changed

examples/sample_token_generate_refresh.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ def _usage():
2020

2121
publisher_client = Uid2PublisherClient(base_url, auth_key, secret_key)
2222
print("Generating Token")
23-
token_generate_response = publisher_client.generate_token(TokenGenerateInput.from_email("test@email.com").do_not_generate_tokens_for_opted_out())
23+
token_generate_response = publisher_client.generate_token(TokenGenerateInput.from_email("testpythonsdksampletokengenerate@email.com").do_not_generate_tokens_for_opted_out())
2424

2525
status = token_generate_response.status
2626
tokens = token_generate_response.get_identity()

tests/test_normalization.py

Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import json
2+
import unittest
3+
from unittest.mock import patch
4+
5+
from uid2_client import TokenGenerateInput
6+
from uid2_client.input_util import *
7+
import random
8+
import string
9+
10+
11+
class InputNormalizationTests(unittest.TestCase):
12+
13+
def test_invalid_email_normalization(self):
14+
invalid_test_cases = ["", " @", "@", "a@", "@b", "@b.com", "+", " ", "[email protected]", "[email protected]",
15+
16+
for s in invalid_test_cases:
17+
print("Negative case " + s)
18+
with self.assertRaises(ValueError) as context:
19+
TokenGenerateInput.from_email(s).get_as_json_string()
20+
self.assertTrue("invalid email address" in context.exception)
21+
22+
def test_valid_email_normalization(self):
23+
valid_test_cases = [
24+
["[email protected] ", "[email protected]", "dvECjPKZHya0/SIhSGwP0m8SgTv1vzLxPULUOsm880M="],
25+
["[email protected]", "[email protected]", "dvECjPKZHya0/SIhSGwP0m8SgTv1vzLxPULUOsm880M="],
26+
["[email protected]", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
27+
["[email protected]", "[email protected]", "rQ4yzdOz4uG8N54326QyZD6/JwqrXn4lmy34cVCojB8="],
28+
["[email protected]", "[email protected]", "weFizOVVWKlLfyorbBU8oxYDv4HJtTZCPMyZ4THzUQE="],
29+
["[email protected]", "[email protected]", "h5JGBrQTGorO7q6IaFMfu5cSqqB6XTp1aybOD11spnQ="],
30+
["[email protected]", "[email protected]", "d1Lr/s4GLLX3SvQVMoQdIMfbQPMAGZYry+2V+0pZlQg="],
31+
[" [email protected]", "[email protected]", "d1Lr/s4GLLX3SvQVMoQdIMfbQPMAGZYry+2V+0pZlQg="],
32+
["[email protected] ", "[email protected]", "d1Lr/s4GLLX3SvQVMoQdIMfbQPMAGZYry+2V+0pZlQg="],
33+
[" [email protected] ", "[email protected]", "d1Lr/s4GLLX3SvQVMoQdIMfbQPMAGZYry+2V+0pZlQg="],
34+
[" [email protected] ", "[email protected]", "d1Lr/s4GLLX3SvQVMoQdIMfbQPMAGZYry+2V+0pZlQg="],
35+
[" [email protected]", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
36+
["[email protected] ", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
37+
[" [email protected] ", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
38+
[" [email protected] ", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
39+
["[email protected] ", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
40+
["[email protected] ", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
41+
[" [email protected] ", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
42+
["[email protected]", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
43+
["[email protected]", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
44+
["[email protected]", "[email protected]", "LkLfFrut8Tc3h/fIvYDiBKSbaMiau/DtaLBPQYszdMw="],
45+
["[email protected] ", "[email protected]", "dvECjPKZHya0/SIhSGwP0m8SgTv1vzLxPULUOsm880M="],
46+
["[email protected] ", "[email protected]", "dvECjPKZHya0/SIhSGwP0m8SgTv1vzLxPULUOsm880M="],
47+
48+
"fAFEUqApQ0V/M9mLj/IO54CgKgtQuARKsOMqtFklD4k="],
49+
["testtest@😊test.com", "testtest@😊test.com",
50+
"tcng5pttf7Y2z4ylZTROvIMw1+IVrMpR4D1KeXSrdiM="],
51+
52+
"0qI21FPLkuez/8RswfmircHPYz9Dtf7/Nch1rSWEQf0="],
53+
]
54+
55+
for test_case in valid_test_cases:
56+
print(f"Positive Test case {test_case[0]} Expected: {test_case[1]}")
57+
normalized = normalize_email_string(test_case[0])
58+
json_string = TokenGenerateInput.from_email(test_case[0]).get_as_json_string()
59+
hashed = json.loads(json_string)["email_hash"]
60+
self.assertEqual(test_case[1], normalized)
61+
self.assertEqual(test_case[2], hashed)
62+
63+
64+
def test_phone_number_is_normalized_negative(self):
65+
test_cases = [
66+
None,
67+
"",
68+
"asdaksjdakfj",
69+
"DH5qQFhi5ALrdqcPiib8cy0Hwykx6frpqxWCkR0uijs",
70+
"QFhi5ALrdqcPiib8cy0Hwykx6frpqxWCkR0uijs",
71+
"06a418f467a14e1631a317b107548a1039d26f12ea45301ab14e7684b36ede58",
72+
"0C7E6A405862E402EB76A70F8A26FC732D07C32931E9FAE9AB1582911D2E8A3B",
73+
"+",
74+
"12345678",
75+
"123456789",
76+
"1234567890",
77+
"+12345678",
78+
"+123456789",
79+
"+ 12345678",
80+
"+ 123456789",
81+
"+ 1234 5678",
82+
"+ 1234 56789",
83+
"+1234567890123456",
84+
"+1234567890A",
85+
"+1234567890 ",
86+
"+1234567890+",
87+
"+12345+67890",
88+
"555-555-5555",
89+
"(555) 555-5555"
90+
]
91+
92+
for s in test_cases:
93+
print(f"Testing phone number '{s}'")
94+
with self.assertRaises(ValueError) as context:
95+
TokenGenerateInput.from_phone(s).get_as_json_string()
96+
self.assertTrue("phone number is not normalized" in context.exception)
97+
98+
def test_phone_number_is_normalized_positive(self):
99+
test_cases = [
100+
"+1234567890",
101+
"+12345678901",
102+
"+123456789012",
103+
"+1234567890123",
104+
"+12345678901234",
105+
"+123456789012345"
106+
]
107+
108+
for s in test_cases:
109+
print(f"Testing phone number '{s}'")
110+
self.assertTrue(is_phone_number_normalized(s))
111+

tests/test_publisher_client.py

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,10 @@ def setUpClass(cls):
2626

2727
if cls.EUID_BASE_URL and cls.EUID_API_KEY and cls.EUID_SECRET_KEY:
2828
cls.publisher_client = Uid2PublisherClient(cls.EUID_BASE_URL, cls.EUID_API_KEY, cls.EUID_SECRET_KEY)
29+
else:
30+
raise Exception("set the required EUID_BASE_URL/EUID_API_KEY/EUID_SECRET_KEY environment variables first")
2931

32+
# this test requires these env vars to be configured: EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY
3033
def test_integration_tc_string(self):
3134
tc_string = "CPhJRpMPhJRpMABAMBFRACBoALAAAEJAAIYgAKwAQAKgArABAAqAAA"
3235

@@ -42,12 +45,13 @@ def test_integration_tc_string(self):
4245
self.assertIsNotNone(identity.get_json_string())
4346
self.assertTrue(identity.is_refreshable())
4447

48+
# this test requires these env vars to be configured: EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY
4549
def test_integration_tc_string_with_insufficient_consent(self):
4650
tc_string = "CPehXK9PehXK9ABAMBFRACBoADAAAEJAAIYgAKwAQAKgArABAAqAAA"
4751
with self.assertRaises(ValueError):
4852
self.publisher_client.generate_token(TokenGenerateInput.from_email("[email protected]").with_transparency_and_consent_string(tc_string))
4953

50-
54+
# this test requires these env vars to be configured: EUID_BASE_URL, EUID_API_KEY, EUID_SECRET_KEY
5155
def test_integration_optout_generate_token(self):
5256
publisher_client = Uid2PublisherClient(self.EUID_BASE_URL, self.EUID_API_KEY, self.EUID_SECRET_KEY)
5357
tc_string = "CPhJRpMPhJRpMABAMBFRACBoALAAAEJAAIYgAKwAQAKgArABAAqAAA"
@@ -75,8 +79,10 @@ def setUpClass(cls):
7579

7680
if cls.UID2_BASE_URL and cls.UID2_API_KEY and cls.UID2_SECRET_KEY:
7781
cls.publisher_client = Uid2PublisherClient(cls.UID2_BASE_URL, cls.UID2_API_KEY, cls.UID2_SECRET_KEY)
82+
else:
83+
raise Exception("set the required UID2_BASE_URL/UID2_API_KEY/UID2_SECRET_KEY environment variables first")
7884

79-
# Test methods
85+
# this test requires these env vars to be configured: UID2_BASE_URL, UID2_API_KEY, UID2_SECRET_KEY
8086
def test_integration_generate_and_refresh(self):
8187

8288
token_generate_response = self.publisher_client.generate_token(
@@ -105,6 +111,7 @@ def test_integration_generate_and_refresh(self):
105111
self.assertIsNotNone(refreshed_identity.get_json_string())
106112
self.assertTrue(identity.is_refreshable())
107113

114+
# this test requires these env vars to be configured: UID2_BASE_URL, UID2_API_KEY, UID2_SECRET_KEY
108115
def test_integration_optout(self):
109116

110117
token_generate_response = self.publisher_client.generate_token(TokenGenerateInput.from_email("[email protected]"))
@@ -125,6 +132,7 @@ def test_integration_optout(self):
125132
self.assertIsNone(token_refresh_response.get_identity_json_string())
126133
self.assertIsNone(token_refresh_response.get_identity())
127134

135+
# this test requires these env vars to be configured: UID2_BASE_URL, UID2_API_KEY, UID2_SECRET_KEY
128136
def test_integration_phone(self):
129137

130138
token_generate_response = self.publisher_client.generate_token(
@@ -152,6 +160,7 @@ def test_integration_phone(self):
152160
self.assertIsNotNone(refreshed_identity.get_json_string())
153161
self.assertTrue(identity.is_refreshable())
154162

163+
# this test requires these env vars to be configured: UID2_BASE_URL, UID2_API_KEY, UID2_SECRET_KEY
155164
def test_integration_bad_requests(self):
156165

157166
with self.assertRaises(ValueError):

uid2_client/input_util.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,10 @@ def is_phone_number_normalized(phone_number):
1212
if phone_number[0] != '+':
1313
return False
1414

15+
for char in phone_number[1:]:
16+
if not char.isdigit():
17+
return False
18+
1519
total_digits = sum(char.isdigit() for char in phone_number[1:])
1620

1721
return min_phone_number_digits <= total_digits <= max_phone_number_digits

0 commit comments

Comments
 (0)