@@ -99,6 +99,7 @@ class SpecialUrlDetectorImplTest {
9999 whenever(mockAIChatQueryDetectionFeatureToggle.isEnabled()).thenReturn(false )
100100 whenever(mockAIChatQueryDetectionFeature.self()).thenReturn(mockAIChatQueryDetectionFeatureToggle)
101101 androidBrowserConfigFeature.handleIntentScheme().setRawStoredState(State (true ))
102+ androidBrowserConfigFeature.validateIntentResolution().setRawStoredState(State (true ))
102103 }
103104
104105 @Test
@@ -293,21 +294,64 @@ class SpecialUrlDetectorImplTest {
293294 @Test
294295 fun whenUrlIsCustomUriSchemeThenNonHttpAppLinkTypeDetectedWithAdditionalIntentFlags () {
295296 externalAppIntentFlagsFeature.self().setRawStoredState(State (true ))
297+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(ResolveInfo ())
296298 val type = testee.determineType(" myapp:foo bar" ) as NonHttpAppLink
297299 assertEquals(" myapp:foo bar" , type.uriString)
298300 assertEquals(Intent .FLAG_ACTIVITY_NEW_TASK or Intent .FLAG_ACTIVITY_CLEAR_TOP , type.intent.flags)
299301 assertEquals(Intent .CATEGORY_BROWSABLE , type.intent.categories.first())
300302 }
301303
304+ @Test
305+ fun whenUrlIsCustomUriSchemeAndRedirectThenNonHttpAppLinkTypeDetectedWithAdditionalIntentFlags () {
306+ externalAppIntentFlagsFeature.self().setRawStoredState(State (true ))
307+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(ResolveInfo ())
308+ val actual = testee.determineType(" https://www.example.com" , " myapp:foo bar" .toUri()) as NonHttpAppLink
309+ assertEquals(" myapp:foo bar" , actual.uriString)
310+ assertEquals(Intent .FLAG_ACTIVITY_NEW_TASK or Intent .FLAG_ACTIVITY_CLEAR_TOP , actual.intent.flags)
311+ assertEquals(Intent .CATEGORY_BROWSABLE , actual.intent.categories.first())
312+ }
313+
314+ @Test
315+ fun whenUrlIsCustomUriSchemeAndNoResolveInfoThenUnknownTypeDetected () {
316+ externalAppIntentFlagsFeature.self().setRawStoredState(State (true ))
317+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(null )
318+ val expected = Unknown ::class
319+ val actual = testee.determineType(" myapp:foo bar" )
320+ assertEquals(expected, actual::class )
321+ }
322+
323+ @Test
324+ fun whenUrlIsCustomUriSchemeAndNoResolveInfoAndRedirectThenNonHttpAppLinkDetected () {
325+ externalAppIntentFlagsFeature.self().setRawStoredState(State (true ))
326+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(null )
327+ val expected = NonHttpAppLink ::class
328+ val actual = testee.determineType(" https://www.example.com" , " myapp:foo bar" .toUri()) as NonHttpAppLink
329+ assertEquals(expected, actual::class )
330+ assertEquals(" myapp:foo bar" , actual.uriString)
331+ assertEquals(Intent .FLAG_ACTIVITY_NEW_TASK or Intent .FLAG_ACTIVITY_CLEAR_TOP , actual.intent.flags)
332+ assertEquals(Intent .CATEGORY_BROWSABLE , actual.intent.categories.first())
333+ }
334+
302335 @Test
303336 fun whenUrlIsCustomUriSchemeThenNonHttpAppLinkTypeDetectedWithoutAdditionalIntentFlags () {
304337 externalAppIntentFlagsFeature.self().setRawStoredState(State (false ))
338+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(ResolveInfo ())
305339 val type = testee.determineType(" myapp:foo bar" ) as NonHttpAppLink
306340 assertEquals(" myapp:foo bar" , type.uriString)
307341 assertEquals(0 , type.intent.flags)
308342 assertNull(type.intent.categories)
309343 }
310344
345+ @Test
346+ fun whenUrlIsCustomUriSchemeAndRedirectThenNonHttpAppLinkTypeDetectedWithoutAdditionalIntentFlags () {
347+ externalAppIntentFlagsFeature.self().setRawStoredState(State (false ))
348+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(ResolveInfo ())
349+ val actual = testee.determineType(" https://www.example.com" , " myapp:foo bar" .toUri()) as NonHttpAppLink
350+ assertEquals(" myapp:foo bar" , actual.uriString)
351+ assertEquals(0 , actual.intent.flags)
352+ assertNull(actual.intent.categories)
353+ }
354+
311355 @Test
312356 fun whenUrlIsNotPrivacyProThenQueryTypeDetected () {
313357 whenever(subscriptions.shouldLaunchPrivacyProForUrl(any())).thenReturn(false )
@@ -520,7 +564,7 @@ class SpecialUrlDetectorImplTest {
520564
521565 testee.determineType(" intent://path#Intent;scheme=testscheme;package=com.example.app;end" )
522566
523- verify(testee).checkForIntent(eq(" intent" ), any(), eq(URI_INTENT_SCHEME ))
567+ verify(testee).checkForIntent(eq(" intent" ), any(), eq(URI_INTENT_SCHEME ), eq( true ) )
524568 }
525569
526570 @Test
@@ -529,7 +573,50 @@ class SpecialUrlDetectorImplTest {
529573
530574 testee.determineType(" intent://path#Intent;scheme=testscheme;package=com.example.app;end" )
531575
532- verify(testee).checkForIntent(eq(" intent" ), any(), eq(URI_ANDROID_APP_SCHEME ))
576+ verify(testee).checkForIntent(eq(" intent" ), any(), eq(URI_ANDROID_APP_SCHEME ), eq(true ))
577+ }
578+
579+ @Test
580+ fun whenValidateIntentResolutionEnabledAndNoResolveInfoThenReturnUnknownType () {
581+ androidBrowserConfigFeature.validateIntentResolution().setRawStoredState(State (true ))
582+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(null )
583+
584+ val result = testee.determineType(" myapp:foo bar" )
585+
586+ assertTrue(result is Unknown )
587+ }
588+
589+ @Test
590+ fun whenValidateIntentResolutionDisabledAndNoResolveInfoThenReturnNonHttpAppLinkType () {
591+ androidBrowserConfigFeature.validateIntentResolution().setRawStoredState(State (false ))
592+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(null )
593+
594+ val result = testee.determineType(" myapp:foo bar" )
595+
596+ assertTrue(result is NonHttpAppLink )
597+ assertEquals(" myapp:foo bar" , (result as NonHttpAppLink ).uriString)
598+ }
599+
600+ @Test
601+ fun whenValidateIntentResolutionEnabledAndResolveInfoExistsThenReturnNonHttpAppLinkType () {
602+ androidBrowserConfigFeature.validateIntentResolution().setRawStoredState(State (true ))
603+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(ResolveInfo ())
604+
605+ val result = testee.determineType(" myapp:foo bar" )
606+
607+ assertTrue(result is NonHttpAppLink )
608+ assertEquals(" myapp:foo bar" , (result as NonHttpAppLink ).uriString)
609+ }
610+
611+ @Test
612+ fun whenValidateIntentResolutionDisabledAndResolveInfoExistsThenReturnNonHttpAppLinkType () {
613+ androidBrowserConfigFeature.validateIntentResolution().setRawStoredState(State (false ))
614+ whenever(mockPackageManager.resolveActivity(any(), anyInt())).thenReturn(ResolveInfo ())
615+
616+ val result = testee.determineType(" myapp:foo bar" )
617+
618+ assertTrue(result is NonHttpAppLink )
619+ assertEquals(" myapp:foo bar" , (result as NonHttpAppLink ).uriString)
533620 }
534621
535622 private fun randomString (length : Int ): String {
0 commit comments