@@ -159,6 +159,143 @@ 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 ("customKey1" , "value" );
242+ keysAndValues .put ("customKey2" , "value" );
243+ keysAndValues .put ("customKey3" , "value" );
244+
245+ crashlyticsCore .setCustomKeys (keysAndValues );
246+ crashlyticsWorkers .common .await ();
247+
248+ Map <String , String > eventKeysAndValues = new HashMap <>();
249+ eventKeysAndValues .put ("eventKey1" , "eventValue" );
250+ eventKeysAndValues .put ("eventKey2" , "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 ("eventKey3" , "eventValue" );
265+ eventKeysAndValues .put ("eventKey4" , "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 ("eventKey1" , "value" );
272+ crashlyticsCore .setCustomKeys (keysAndValues );
273+ crashlyticsWorkers .common .await ();
274+
275+ assertEquals ("value" , metadata .getCustomKeys ().get ("eventKey1" ));
276+ assertEquals ("value" , metadata .getCustomKeys (Map .of ()).get ("eventKey1" ));
277+ assertEquals ("eventValue" , metadata .getCustomKeys (eventKeysAndValues ).get ("eventKey1" ));
278+
279+ // Test the event key behavior when the count of custom keys is max.
280+ for (int i = keysAndValues .size (); i < UserMetadata .MAX_ATTRIBUTES ; ++i ) {
281+ final String key = "key" + i ;
282+ final String value = "value" + i ;
283+ crashlyticsCore .setCustomKey (key , value );
284+ crashlyticsWorkers .common .await ();
285+ assertEquals (value , metadata .getCustomKeys ().get (key ));
286+ }
287+
288+ assertEquals (UserMetadata .MAX_ATTRIBUTES , metadata .getCustomKeys ().size ());
289+
290+ // Tests event keys override global custom keys when the key exists.
291+ assertEquals ("value" , metadata .getCustomKeys ().get ("eventKey1" ));
292+ assertEquals ("value" , metadata .getCustomKeys (Map .of ()).get ("eventKey1" ));
293+ assertEquals ("eventValue" , metadata .getCustomKeys (eventKeysAndValues ).get ("eventKey1" ));
294+
295+ // Test when event keys *don't* override global custom keys.
296+ assertNull (metadata .getCustomKeys (eventKeysAndValues ).get ("eventKey2" ));
297+ }
298+
162299 @ Test
163300 public void testBulkCustomKeys () throws Exception {
164301 final double DELTA = 1e-15 ;
0 commit comments