1+ package com .uid2 .client ;
2+
3+ import org .junit .jupiter .api .Test ;
4+
5+ import java .time .Instant ;
6+ import java .util .*;
7+
8+ import static org .junit .jupiter .api .Assertions .*;
9+
10+ public class IdentityMapV3ResponseTest {
11+ private final static String SOME_EMAIL = "email1@example.com" ;
12+
13+ @ Test
14+ void mappedIdentity () {
15+ String email1 = "email1@example.com" ;
16+ String email2 = "email2@example.com" ;
17+ String phone1 = "+1234567890" ;
18+ String phone2 = "+0987654321" ;
19+ String hashedEmail1 = "email 1 hash" ;
20+ String hashedEmail2 = "email 2 hash" ;
21+ String hashedPhone1 = "phone 1 hash" ;
22+ String hashedPhone2 = "phone 2 hash" ;
23+
24+ Instant email1RefreshFrom = Instant .parse ("2025-01-01T00:00:01Z" );
25+ Instant email2RefreshFrom = Instant .parse ("2025-06-30T00:00:20Z" );
26+ Instant phone1RefreshFrom = Instant .parse ("2025-01-01T00:05:00Z" );
27+ Instant phone2RefreshFrom = Instant .parse ("2025-06-30T00:00:22Z" );
28+ Instant hashedEmail1RefreshFrom = Instant .parse ("2025-01-01T00:00:33Z" );
29+ Instant hashedEmail2RefreshFrom = Instant .parse ("2025-06-30T00:00:00Z" );
30+ Instant hashedPhone1RefreshFrom = Instant .parse ("2025-01-01T00:00:11Z" );
31+ Instant hashedPhone2RefreshFrom = Instant .parse ("2025-06-30T00:00:01Z" );
32+
33+ // Response from Operator
34+ String [] emailHashEntries = {
35+ mappedResponsePayloadEntry ("email 1 current uid" , "email 1 previous uid" , email1RefreshFrom ),
36+ mappedResponsePayloadEntry ("email 2 current uid" , "email 2 previous uid" , email2RefreshFrom ),
37+ mappedResponsePayloadEntry ("hashed email 1 current uid" , "hashed email 1 previous uid" , hashedEmail1RefreshFrom ),
38+ mappedResponsePayloadEntry ("hashed email 2 current uid" , "hashed email 2 previous uid" , hashedEmail2RefreshFrom )
39+ };
40+
41+ String [] phoneHashEntries = {
42+ mappedResponsePayloadEntry ("phone 1 current uid" , "phone 1 previous uid" , phone1RefreshFrom ),
43+ mappedResponsePayloadEntry ("phone 2 current uid" , "phone 2 previous uid" , phone2RefreshFrom ),
44+ mappedResponsePayloadEntry ("hashed phone 1 current uid" , "hashed phone 1 previous uid" , hashedPhone1RefreshFrom ),
45+ mappedResponsePayloadEntry ("hashed phone 2 current uid" , "hashed phone 2 previous uid" , hashedPhone2RefreshFrom )
46+ };
47+
48+ String responsePayload = mappedResponsePayload (emailHashEntries , phoneHashEntries );
49+
50+ IdentityMapV3Input input = new IdentityMapV3Input ()
51+ .withEmails (Arrays .asList (email1 , email2 ))
52+ .withHashedEmails (Arrays .asList (hashedEmail1 , hashedEmail2 ))
53+ .withPhones (Arrays .asList (phone1 , phone2 ))
54+ .withHashedPhones (Arrays .asList (hashedPhone1 , hashedPhone2 ));
55+
56+ IdentityMapV3Response response = new IdentityMapV3Response (responsePayload , input );
57+
58+ assertTrue (response .isSuccess ());
59+ assertEquals (8 , response .getMappedIdentities ().size ());
60+ assertEquals (0 , response .getUnmappedIdentities ().size ());
61+
62+ // Email
63+ IdentityMapV3Response .MappedIdentity rawEmailMapping1 = response .getMappedIdentities ().get (email1 );
64+ assertEquals ("email 1 current uid" , rawEmailMapping1 .getCurrentRawUid ());
65+ assertEquals ("email 1 previous uid" , rawEmailMapping1 .getPreviousRawUid ());
66+ assertEquals (email1RefreshFrom , rawEmailMapping1 .getRefreshFrom ());
67+
68+ IdentityMapV3Response .MappedIdentity rawEmailMapping2 = response .getMappedIdentities ().get (email2 );
69+ assertEquals ("email 2 current uid" , rawEmailMapping2 .getCurrentRawUid ());
70+ assertEquals ("email 2 previous uid" , rawEmailMapping2 .getPreviousRawUid ());
71+ assertEquals (email2RefreshFrom , rawEmailMapping2 .getRefreshFrom ());
72+
73+ // Phone
74+ IdentityMapV3Response .MappedIdentity rawPhoneMapping1 = response .getMappedIdentities ().get (phone1 );
75+ assertEquals ("phone 1 current uid" , rawPhoneMapping1 .getCurrentRawUid ());
76+ assertEquals ("phone 1 previous uid" , rawPhoneMapping1 .getPreviousRawUid ());
77+ assertEquals (phone1RefreshFrom , rawPhoneMapping1 .getRefreshFrom ());
78+
79+ IdentityMapV3Response .MappedIdentity rawPhoneMapping2 = response .getMappedIdentities ().get (phone2 );
80+ assertEquals ("phone 2 current uid" , rawPhoneMapping2 .getCurrentRawUid ());
81+ assertEquals ("phone 2 previous uid" , rawPhoneMapping2 .getPreviousRawUid ());
82+ assertEquals (phone2RefreshFrom , rawPhoneMapping2 .getRefreshFrom ());
83+
84+ // Hashed Email
85+ IdentityMapV3Response .MappedIdentity hashedEmailMapping1 = response .getMappedIdentities ().get (hashedEmail1 );
86+ assertEquals ("hashed email 1 current uid" , hashedEmailMapping1 .getCurrentRawUid ());
87+ assertEquals ("hashed email 1 previous uid" , hashedEmailMapping1 .getPreviousRawUid ());
88+ assertEquals (hashedEmail1RefreshFrom , hashedEmailMapping1 .getRefreshFrom ());
89+
90+ IdentityMapV3Response .MappedIdentity hashedEmailMapping2 = response .getMappedIdentities ().get (hashedEmail2 );
91+ assertEquals ("hashed email 2 current uid" , hashedEmailMapping2 .getCurrentRawUid ());
92+ assertEquals ("hashed email 2 previous uid" , hashedEmailMapping2 .getPreviousRawUid ());
93+ assertEquals (hashedEmail2RefreshFrom , hashedEmailMapping2 .getRefreshFrom ());
94+
95+ // Hashed Phone
96+ IdentityMapV3Response .MappedIdentity hashedPhoneMapping1 = response .getMappedIdentities ().get (hashedPhone1 );
97+ assertEquals ("hashed phone 1 current uid" , hashedPhoneMapping1 .getCurrentRawUid ());
98+ assertEquals ("hashed phone 1 previous uid" , hashedPhoneMapping1 .getPreviousRawUid ());
99+ assertEquals (hashedPhone1RefreshFrom , hashedPhoneMapping1 .getRefreshFrom ());
100+
101+ IdentityMapV3Response .MappedIdentity hashedPhoneMapping2 = response .getMappedIdentities ().get (hashedPhone2 );
102+ assertEquals ("hashed phone 2 current uid" , hashedPhoneMapping2 .getCurrentRawUid ());
103+ assertEquals ("hashed phone 2 previous uid" , hashedPhoneMapping2 .getPreviousRawUid ());
104+ assertEquals (hashedPhone2RefreshFrom , hashedPhoneMapping2 .getRefreshFrom ());
105+ }
106+
107+ @ Test
108+ void unmappedIdentityReasonUnknown () {
109+ IdentityMapV3Input input = IdentityMapV3Input .fromEmails (Arrays .asList (SOME_EMAIL ));
110+
111+ IdentityMapV3Response response = new IdentityMapV3Response (unmappedResponsePayload ("SOME_NEW_UNMAPPED_REASON" ), input );
112+ assertTrue (response .isSuccess ());
113+
114+ IdentityMapV3Response .UnmappedIdentity unmappedIdentity = response .getUnmappedIdentities ().get (SOME_EMAIL );
115+ assertEquals (UnmappedIdentityReason .UNKNOWN , unmappedIdentity .getReason ());
116+ assertEquals ("SOME_NEW_UNMAPPED_REASON" , unmappedIdentity .getRawReason ());
117+ }
118+
119+ @ Test
120+ void unmappedIdentityReasonOptout () {
121+ IdentityMapV3Input input = IdentityMapV3Input .fromEmails (Arrays .asList (SOME_EMAIL ));
122+
123+ IdentityMapV3Response response = new IdentityMapV3Response (unmappedResponsePayload ("OPTOUT" ), input );
124+ assertTrue (response .isSuccess ());
125+
126+ IdentityMapV3Response .UnmappedIdentity unmappedIdentity = response .getUnmappedIdentities ().get (SOME_EMAIL );
127+ assertEquals (UnmappedIdentityReason .OPTOUT , unmappedIdentity .getReason ());
128+ assertEquals ("OPTOUT" , unmappedIdentity .getRawReason ());
129+ }
130+
131+ @ Test
132+ void unmappedIdentityReasonInvalid () {
133+ IdentityMapV3Input input = IdentityMapV3Input .fromEmails (Arrays .asList (SOME_EMAIL ));
134+
135+ IdentityMapV3Response response = new IdentityMapV3Response (unmappedResponsePayload ("INVALID" ), input );
136+ assertTrue (response .isSuccess ());
137+
138+ IdentityMapV3Response .UnmappedIdentity unmappedIdentity = response .getUnmappedIdentities ().get (SOME_EMAIL );
139+ assertEquals (UnmappedIdentityReason .INVALID , unmappedIdentity .getReason ());
140+ assertEquals ("INVALID" , unmappedIdentity .getRawReason ());
141+ }
142+
143+ @ Test
144+ void unmappedIdentityReasonCaseInsensitive () {
145+ IdentityMapV3Input input = IdentityMapV3Input .fromEmails (Arrays .asList (SOME_EMAIL ));
146+
147+ IdentityMapV3Response .UnmappedIdentity lowercaseOptout =
148+ new IdentityMapV3Response (unmappedResponsePayload ("optout" ), input ).getUnmappedIdentities ().get (SOME_EMAIL );
149+ assertEquals (UnmappedIdentityReason .OPTOUT , lowercaseOptout .getReason ());
150+ assertEquals ("optout" , lowercaseOptout .getRawReason ());
151+
152+ IdentityMapV3Response .UnmappedIdentity lowercaseInvalid =
153+ new IdentityMapV3Response (unmappedResponsePayload ("invalid" ), input ).getUnmappedIdentities ().get (SOME_EMAIL );
154+ assertEquals (UnmappedIdentityReason .INVALID , lowercaseInvalid .getReason ());
155+ assertEquals ("invalid" , lowercaseInvalid .getRawReason ());
156+
157+ IdentityMapV3Response .UnmappedIdentity mixedOptout =
158+ new IdentityMapV3Response (unmappedResponsePayload ("OptOut" ), input ).getUnmappedIdentities ().get (SOME_EMAIL );
159+ assertEquals (UnmappedIdentityReason .OPTOUT , mixedOptout .getReason ());
160+ assertEquals ("OptOut" , mixedOptout .getRawReason ());
161+
162+ IdentityMapV3Response .UnmappedIdentity mixedInvalid =
163+ new IdentityMapV3Response (unmappedResponsePayload ("InVaLiD" ), input ).getUnmappedIdentities ().get (SOME_EMAIL );
164+ assertEquals (UnmappedIdentityReason .INVALID , mixedInvalid .getReason ());
165+ assertEquals ("InVaLiD" , mixedInvalid .getRawReason ());
166+ }
167+
168+ @ Test
169+ void responseStatusNotSuccess () {
170+ IdentityMapV3Input input = IdentityMapV3Input .fromEmails (Arrays .asList (SOME_EMAIL ));
171+
172+ String failureResponsePayload = "{\" status\" :\" error\" ,\" body\" :{}}" ;
173+
174+ Uid2Exception exception = assertThrows (Uid2Exception .class , () -> {
175+ new IdentityMapV3Response (failureResponsePayload , input );
176+ });
177+
178+ assertEquals ("Got unexpected identity map status: error" , exception .getMessage ());
179+ }
180+
181+ private static String unmappedResponsePayload (String reason ) {
182+ return "{\" status\" :\" success\" ,\" body\" :{\" email_hash\" :[{\" e\" :\" " + reason + "\" }]}}" ;
183+ }
184+
185+ private static String mappedResponsePayload (String [] emailHashEntries , String [] phoneHashEntries ) {
186+ return "{\" status\" :\" success\" ,\" body\" :{" +
187+ "\" email_hash\" :[" + String .join ("," , emailHashEntries ) + "]," +
188+ "\" phone_hash\" :[" + String .join ("," , phoneHashEntries ) + "]" +
189+ "}}" ;
190+ }
191+
192+ private static String mappedResponsePayloadEntry (String currentUid , String previousUid , Instant refreshFrom ) {
193+ return "{\" u\" :\" " + currentUid + "\" ,\" p\" :\" " + previousUid + "\" ,\" r\" :" + refreshFrom .getEpochSecond () + "}" ;
194+ }
195+ }
0 commit comments