@@ -492,6 +492,128 @@ class DeepLinkEntryTest {
492492 assertThat(placeholderFirstEntry.compareTo(configurableFirstEntry)).isGreaterThan(0 )
493493 }
494494
495+ // ============== templatesMatchesSameUrls tests ==============
496+
497+ @Test
498+ fun `templatesMatchesSameUrls returns true for identical templates` () {
499+ val entry1 = activityDeepLinkEntry(" airbnb://host/path" )
500+ val entry2 = activityDeepLinkEntry(" airbnb://host/path" )
501+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isTrue
502+ }
503+
504+ @Test
505+ fun `templatesMatchesSameUrls returns false for completely different templates` () {
506+ val entry1 = activityDeepLinkEntry(" airbnb://host/path1" )
507+ val entry2 = activityDeepLinkEntry(" airbnb://host/path2" )
508+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isFalse
509+ }
510+
511+ @Test
512+ fun `templatesMatchesSameUrls returns true for templates with same placeholders` () {
513+ val entry1 = activityDeepLinkEntry(" airbnb://host/{id}" )
514+ val entry2 = activityDeepLinkEntry(" airbnb://host/{param}" )
515+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isTrue
516+ }
517+
518+ @Test
519+ fun `templatesMatchesSameUrls returns true when placeholder matches concrete value` () {
520+ // A placeholder can match any value, so it could match "path"
521+ val entryWithPlaceholder = activityDeepLinkEntry(" airbnb://host/{id}" )
522+ val entryWithConcrete = activityDeepLinkEntry(" airbnb://host/path" )
523+ assertThat(entryWithPlaceholder.templatesMatchesSameUrls(entryWithConcrete)).isTrue
524+ assertThat(entryWithConcrete.templatesMatchesSameUrls(entryWithPlaceholder)).isTrue
525+ }
526+
527+ @Test
528+ fun `templatesMatchesSameUrls returns true when allowed value matches concrete value` () {
529+ // Placeholder with allowed values (a|b) - "a" matches concrete "a"
530+ val entryWithAllowedValues = activityDeepLinkEntry(" airbnb://host/{type(a|b)}" )
531+ val entryWithConcrete = activityDeepLinkEntry(" airbnb://host/a" )
532+ assertThat(entryWithAllowedValues.templatesMatchesSameUrls(entryWithConcrete)).isTrue
533+ assertThat(entryWithConcrete.templatesMatchesSameUrls(entryWithAllowedValues)).isTrue
534+ }
535+
536+ @Test
537+ fun `templatesMatchesSameUrls returns false when no allowed value matches concrete value` () {
538+ // Placeholder with allowed values (a|b) - neither matches concrete "c"
539+ val entryWithAllowedValues = activityDeepLinkEntry(" airbnb://host/{type(a|b)}" )
540+ val entryWithConcrete = activityDeepLinkEntry(" airbnb://host/c" )
541+ assertThat(entryWithAllowedValues.templatesMatchesSameUrls(entryWithConcrete)).isFalse
542+ assertThat(entryWithConcrete.templatesMatchesSameUrls(entryWithAllowedValues)).isFalse
543+ }
544+
545+ @Test
546+ fun `templatesMatchesSameUrls returns true when allowed values overlap` () {
547+ // Both have allowed values with "b" in common
548+ val entry1 = activityDeepLinkEntry(" airbnb://host/{type1(a|b)}" )
549+ val entry2 = activityDeepLinkEntry(" airbnb://host/{type2(b|c)}" )
550+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isTrue
551+ }
552+
553+ @Test
554+ fun `templatesMatchesSameUrls returns false when allowed values dont overlap` () {
555+ // No common allowed values
556+ val entry1 = activityDeepLinkEntry(" airbnb://host/{type1(a|b)}" )
557+ val entry2 = activityDeepLinkEntry(" airbnb://host/{type2(c|d)}" )
558+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isFalse
559+ }
560+
561+ @Test
562+ fun `templatesMatchesSameUrls returns true when placeholder could match allowed value` () {
563+ // Regular placeholder can match any value including "a" or "b"
564+ val entryWithPlaceholder = activityDeepLinkEntry(" airbnb://host/{id}" )
565+ val entryWithAllowedValues = activityDeepLinkEntry(" airbnb://host/{type(a|b)}" )
566+ assertThat(entryWithPlaceholder.templatesMatchesSameUrls(entryWithAllowedValues)).isTrue
567+ assertThat(entryWithAllowedValues.templatesMatchesSameUrls(entryWithPlaceholder)).isTrue
568+ }
569+
570+ @Test
571+ fun `templatesMatchesSameUrls handles partial placeholders with same prefix` () {
572+ // Both have "pre" prefix, placeholder can match
573+ val entry1 = activityDeepLinkEntry(" airbnb://host/pre{id}post" )
574+ val entry2 = activityDeepLinkEntry(" airbnb://host/pre{name}post" )
575+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isTrue
576+ }
577+
578+ @Test
579+ fun `templatesMatchesSameUrls returns false for partial placeholders with different prefix` () {
580+ val entry1 = activityDeepLinkEntry(" airbnb://host/pre{id}post" )
581+ val entry2 = activityDeepLinkEntry(" airbnb://host/other{name}post" )
582+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isFalse
583+ }
584+
585+ @Test
586+ fun `templatesMatchesSameUrls returns false for different number of path segments` () {
587+ val entry1 = activityDeepLinkEntry(" airbnb://host/path1/path2" )
588+ val entry2 = activityDeepLinkEntry(" airbnb://host/path1" )
589+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isFalse
590+ }
591+
592+ @Test
593+ fun `templatesMatchesSameUrls handles complex scheme placeholders` () {
594+ // http{s} scheme placeholder - "http" matches "http", "https" matches "https"
595+ val entry1 = activityDeepLinkEntry(" http{scheme(|s)}://host/path" )
596+ val entry2 = activityDeepLinkEntry(" http://host/path" )
597+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isTrue
598+
599+ val entry3 = activityDeepLinkEntry(" https://host/path" )
600+ assertThat(entry1.templatesMatchesSameUrls(entry3)).isTrue
601+ }
602+
603+ @Test
604+ fun `templatesMatchesSameUrls handles host placeholders with allowed values` () {
605+ // Host with allowed prefixes
606+ val entry1 = activityDeepLinkEntry(" http://{prefix(|www.)}airbnb.com/path" )
607+ val entry2 = activityDeepLinkEntry(" http://airbnb.com/path" )
608+ assertThat(entry1.templatesMatchesSameUrls(entry2)).isTrue
609+
610+ val entry3 = activityDeepLinkEntry(" http://www.airbnb.com/path" )
611+ assertThat(entry1.templatesMatchesSameUrls(entry3)).isTrue
612+
613+ val entry4 = activityDeepLinkEntry(" http://m.airbnb.com/path" )
614+ assertThat(entry1.templatesMatchesSameUrls(entry4)).isFalse
615+ }
616+
495617 companion object {
496618 private fun activityDeepLinkEntry (
497619 uriTemplate : String ,
0 commit comments