@@ -159,6 +159,124 @@ public void testCustomAttributes() throws Exception {
159159    assertEquals (longValue , metadata .getCustomKeys ().get (key1 ));
160160  }
161161
162+   @ Test 
163+   public  void  testCustomAttributes_retrievedWithEmptyEventKeys () throws  Exception  {
164+     UserMetadata  metadata  = crashlyticsCore .getController ().getUserMetadata ();
165+ 
166+     assertTrue (metadata .getCustomKeys (Map .of ()).isEmpty ());
167+ 
168+     final  String  id  = "id012345" ;
169+     crashlyticsCore .setUserId (id );
170+     crashlyticsWorkers .common .await ();
171+     assertEquals (id , metadata .getUserId ());
172+ 
173+     final  StringBuffer  idBuffer  = new  StringBuffer (id );
174+     while  (idBuffer .length () < UserMetadata .MAX_ATTRIBUTE_SIZE ) {
175+       idBuffer .append ("0" );
176+     }
177+     final  String  longId  = idBuffer .toString ();
178+     final  String  superLongId  = longId  + "more chars" ;
179+ 
180+     crashlyticsCore .setUserId (superLongId );
181+     crashlyticsWorkers .common .await ();
182+     assertEquals (longId , metadata .getUserId ());
183+ 
184+     final  String  key1  = "key1" ;
185+     final  String  value1  = "value1" ;
186+     crashlyticsCore .setCustomKey (key1 , value1 );
187+     crashlyticsWorkers .common .await ();
188+     assertEquals (value1 , metadata .getCustomKeys (Map .of ()).get (key1 ));
189+ 
190+     // Adding an existing key with the same value should return false 
191+     assertFalse (metadata .setCustomKey (key1 , value1 ));
192+     assertTrue (metadata .setCustomKey (key1 , "someOtherValue" ));
193+     assertTrue (metadata .setCustomKey (key1 , value1 ));
194+     assertFalse (metadata .setCustomKey (key1 , value1 ));
195+ 
196+     final  String  longValue  = longId .replaceAll ("0" , "x" );
197+     final  String  superLongValue  = longValue  + "some more chars" ;
198+ 
199+     // test truncation of custom keys and attributes 
200+     crashlyticsCore .setCustomKey (superLongId , superLongValue );
201+     crashlyticsWorkers .common .await ();
202+     assertNull (metadata .getCustomKeys (Map .of ()).get (superLongId ));
203+     assertEquals (longValue , metadata .getCustomKeys ().get (longId ));
204+ 
205+     // test the max number of attributes. We've already set 2. 
206+     for  (int  i  = 2 ; i  < UserMetadata .MAX_ATTRIBUTES ; ++i ) {
207+       final  String  key  = "key"  + i ;
208+       final  String  value  = "value"  + i ;
209+       crashlyticsCore .setCustomKey (key , value );
210+       crashlyticsWorkers .common .await ();
211+       assertEquals (value , metadata .getCustomKeys (Map .of ()).get (key ));
212+     }
213+     // should be full now, extra key, value pairs will be dropped. 
214+     final  String  key  = "new key" ;
215+     crashlyticsCore .setCustomKey (key , "some value" );
216+     crashlyticsWorkers .common .await ();
217+     assertFalse (metadata .getCustomKeys (Map .of ()).containsKey (key ));
218+ 
219+     // should be able to update existing keys 
220+     crashlyticsCore .setCustomKey (key1 , longValue );
221+     crashlyticsWorkers .common .await ();
222+     assertEquals (longValue , metadata .getCustomKeys (Map .of ()).get (key1 ));
223+ 
224+     // when we set a key to null, it should still exist with an empty value 
225+     crashlyticsCore .setCustomKey (key1 , null );
226+     crashlyticsWorkers .common .await ();
227+     assertEquals ("" , metadata .getCustomKeys (Map .of ()).get (key1 ));
228+ 
229+     // keys and values are trimmed. 
230+     crashlyticsCore .setCustomKey (" "  + key1  + " " , " "  + longValue  + " " );
231+     crashlyticsWorkers .common .await ();
232+     assertTrue (metadata .getCustomKeys (Map .of ()).containsKey (key1 ));
233+     assertEquals (longValue , metadata .getCustomKeys (Map .of ()).get (key1 ));
234+   }
235+ 
236+   @ Test 
237+   public  void  testCustomKeysMergedWithEventKeys () throws  Exception  {
238+     UserMetadata  metadata  = crashlyticsCore .getController ().getUserMetadata ();
239+ 
240+     Map <String , String > keysAndValues  = new  HashMap <>();
241+     keysAndValues .put ("1" , "value" );
242+     keysAndValues .put ("2" , "value" );
243+     keysAndValues .put ("3" , "value" );
244+ 
245+     metadata .setCustomKeys (keysAndValues );
246+     crashlyticsWorkers .common .await ();
247+ 
248+     Map <String , String > eventKeysAndValues  = new  HashMap <>();
249+     eventKeysAndValues .put ("4" , "eventValue" );
250+     eventKeysAndValues .put ("5" , "eventValue" );
251+ 
252+     // Tests reading custom keys with event keys. 
253+     assertEquals (keysAndValues .size (), metadata .getCustomKeys ().size ());
254+     assertEquals (keysAndValues .size (), metadata .getCustomKeys (Map .of ()).size ());
255+     assertEquals (
256+         keysAndValues .size () + eventKeysAndValues .size (),
257+         metadata .getCustomKeys (eventKeysAndValues ).size ());
258+ 
259+     // Tests event keys don't add to custom keys in future reads. 
260+     assertEquals (keysAndValues .size (), metadata .getCustomKeys ().size ());
261+     assertEquals (keysAndValues .size (), metadata .getCustomKeys (Map .of ()).size ());
262+ 
263+     // Tests additional event keys. 
264+     eventKeysAndValues .put ("6" , "eventValue" );
265+     eventKeysAndValues .put ("7" , "eventValue" );
266+     assertEquals (
267+         keysAndValues .size () + eventKeysAndValues .size (),
268+         metadata .getCustomKeys (eventKeysAndValues ).size ());
269+ 
270+     // Tests overriding custom key with event keys. 
271+     keysAndValues .put ("7" , "value" );
272+     metadata .setCustomKeys (keysAndValues );
273+     crashlyticsWorkers .common .await ();
274+ 
275+     assertEquals ("value" , metadata .getCustomKeys ().get ("7" ));
276+     assertEquals ("value" , metadata .getCustomKeys (Map .of ()).get ("7" ));
277+     assertEquals ("eventValue" , metadata .getCustomKeys (eventKeysAndValues ).get ("7" ));
278+   }
279+ 
162280  @ Test 
163281  public  void  testBulkCustomKeys () throws  Exception  {
164282    final  double  DELTA  = 1e-15 ;
0 commit comments