@@ -383,4 +383,194 @@ public void testParseProductUpdateLongStrings() throws Exception {
383383 assertNotNull (result .getDescription ());
384384 assertEquals (result .getDescription ().length (), 10000 );
385385 }
386+
387+ @ Test
388+ public void testParseProductUpdateWithClientId () throws Exception {
389+ String jsonString =
390+ "{"
391+ + "\" enabled\" : true,"
392+ + "\" id\" : \" v1.0.0\" ,"
393+ + "\" title\" : \" What's New\" ,"
394+ + "\" ctaLink\" : \" https://example.com\" "
395+ + "}" ;
396+ JsonNode jsonNode = objectMapper .readTree (jsonString );
397+ String clientId = "abc-123-def-456" ;
398+
399+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
400+
401+ assertNotNull (result );
402+ assertEquals (result .getCtaLink (), "https://example.com?q=abc-123-def-456" );
403+ }
404+
405+ @ Test
406+ public void testParseProductUpdateWithClientIdAndExistingQueryParams () throws Exception {
407+ String jsonString =
408+ "{"
409+ + "\" enabled\" : true,"
410+ + "\" id\" : \" v1.0.0\" ,"
411+ + "\" title\" : \" What's New\" ,"
412+ + "\" ctaLink\" : \" https://example.com?foo=bar\" "
413+ + "}" ;
414+ JsonNode jsonNode = objectMapper .readTree (jsonString );
415+ String clientId = "abc-123-def-456" ;
416+
417+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
418+
419+ assertNotNull (result );
420+ assertEquals (result .getCtaLink (), "https://example.com?foo=bar&q=abc-123-def-456" );
421+ }
422+
423+ @ Test
424+ public void testParseProductUpdateWithClientIdMultipleQueryParams () throws Exception {
425+ String jsonString =
426+ "{"
427+ + "\" enabled\" : true,"
428+ + "\" id\" : \" v1.0.0\" ,"
429+ + "\" title\" : \" What's New\" ,"
430+ + "\" ctaLink\" : \" https://example.com?foo=bar&baz=qux#anchor\" "
431+ + "}" ;
432+ JsonNode jsonNode = objectMapper .readTree (jsonString );
433+ String clientId = "test-uuid" ;
434+
435+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
436+
437+ assertNotNull (result );
438+ assertEquals (result .getCtaLink (), "https://example.com?foo=bar&baz=qux#anchor&q=test-uuid" );
439+ }
440+
441+ @ Test
442+ public void testParseProductUpdateWithNullClientId () throws Exception {
443+ String jsonString =
444+ "{"
445+ + "\" enabled\" : true,"
446+ + "\" id\" : \" v1.0.0\" ,"
447+ + "\" title\" : \" What's New\" ,"
448+ + "\" ctaLink\" : \" https://example.com\" "
449+ + "}" ;
450+ JsonNode jsonNode = objectMapper .readTree (jsonString );
451+
452+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), null );
453+
454+ assertNotNull (result );
455+ assertEquals (result .getCtaLink (), "https://example.com" );
456+ }
457+
458+ @ Test
459+ public void testParseProductUpdateWithEmptyClientId () throws Exception {
460+ String jsonString =
461+ "{"
462+ + "\" enabled\" : true,"
463+ + "\" id\" : \" v1.0.0\" ,"
464+ + "\" title\" : \" What's New\" ,"
465+ + "\" ctaLink\" : \" https://example.com\" "
466+ + "}" ;
467+ JsonNode jsonNode = objectMapper .readTree (jsonString );
468+
469+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), "" );
470+
471+ assertNotNull (result );
472+ assertEquals (result .getCtaLink (), "https://example.com" );
473+ }
474+
475+ @ Test
476+ public void testParseProductUpdateWithWhitespaceClientId () throws Exception {
477+ String jsonString =
478+ "{"
479+ + "\" enabled\" : true,"
480+ + "\" id\" : \" v1.0.0\" ,"
481+ + "\" title\" : \" What's New\" ,"
482+ + "\" ctaLink\" : \" https://example.com\" "
483+ + "}" ;
484+ JsonNode jsonNode = objectMapper .readTree (jsonString );
485+
486+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), " " );
487+
488+ assertNotNull (result );
489+ assertEquals (result .getCtaLink (), "https://example.com" );
490+ }
491+
492+ @ Test
493+ public void testParseProductUpdateWithClientIdAndEmptyCtaLink () throws Exception {
494+ String jsonString =
495+ "{"
496+ + "\" enabled\" : true,"
497+ + "\" id\" : \" v1.0.0\" ,"
498+ + "\" title\" : \" What's New\" ,"
499+ + "\" ctaLink\" : \" \" "
500+ + "}" ;
501+ JsonNode jsonNode = objectMapper .readTree (jsonString );
502+ String clientId = "abc-123" ;
503+
504+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
505+
506+ assertNotNull (result );
507+ assertEquals (result .getCtaLink (), "" );
508+ }
509+
510+ @ Test
511+ public void testParseProductUpdateWithClientIdAndNoCtaLink () throws Exception {
512+ String jsonString =
513+ "{" + "\" enabled\" : true," + "\" id\" : \" v1.0.0\" ," + "\" title\" : \" What's New\" " + "}" ;
514+ JsonNode jsonNode = objectMapper .readTree (jsonString );
515+ String clientId = "abc-123" ;
516+
517+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
518+
519+ assertNotNull (result );
520+ assertEquals (result .getCtaLink (), "" );
521+ }
522+
523+ @ Test
524+ public void testParseProductUpdateWithClientIdSpecialCharacters () throws Exception {
525+ String jsonString =
526+ "{"
527+ + "\" enabled\" : true,"
528+ + "\" id\" : \" v1.0.0\" ,"
529+ + "\" title\" : \" What's New\" ,"
530+ + "\" ctaLink\" : \" https://example.com\" "
531+ + "}" ;
532+ JsonNode jsonNode = objectMapper .readTree (jsonString );
533+ String clientId = "abc 123+def/456" ;
534+
535+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
536+
537+ assertNotNull (result );
538+ assertEquals (result .getCtaLink (), "https://example.com?q=abc+123%2Bdef%2F456" );
539+ }
540+
541+ @ Test
542+ public void testParseProductUpdateWithClientIdUnicodeCharacters () throws Exception {
543+ String jsonString =
544+ "{"
545+ + "\" enabled\" : true,"
546+ + "\" id\" : \" v1.0.0\" ,"
547+ + "\" title\" : \" What's New\" ,"
548+ + "\" ctaLink\" : \" https://example.com\" "
549+ + "}" ;
550+ JsonNode jsonNode = objectMapper .readTree (jsonString );
551+ String clientId = "测试-client-id-🎉" ;
552+
553+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ), clientId );
554+
555+ assertNotNull (result );
556+ assertTrue (result .getCtaLink ().startsWith ("https://example.com?q=" ));
557+ assertTrue (result .getCtaLink ().contains ("%" ));
558+ }
559+
560+ @ Test
561+ public void testParseProductUpdateBackwardCompatibilityWithoutClientId () throws Exception {
562+ String jsonString =
563+ "{"
564+ + "\" enabled\" : true,"
565+ + "\" id\" : \" v1.0.0\" ,"
566+ + "\" title\" : \" What's New\" ,"
567+ + "\" ctaLink\" : \" https://example.com\" "
568+ + "}" ;
569+ JsonNode jsonNode = objectMapper .readTree (jsonString );
570+
571+ ProductUpdate result = ProductUpdateParser .parseProductUpdate (Optional .of (jsonNode ));
572+
573+ assertNotNull (result );
574+ assertEquals (result .getCtaLink (), "https://example.com" );
575+ }
386576}
0 commit comments