1919package com.duckduckgo.app.browser
2020
2121import android.net.Uri
22+ import android.webkit.WebBackForwardList
23+ import android.webkit.WebHistoryItem
2224import android.webkit.WebResourceRequest
2325import android.webkit.WebResourceResponse
2426import android.webkit.WebView
2527import androidx.test.annotation.UiThreadTest
2628import com.duckduckgo.app.CoroutineTestRule
29+ import com.duckduckgo.app.globalprivacycontrol.GlobalPrivacyControl
30+ import com.duckduckgo.app.globalprivacycontrol.GlobalPrivacyControlManager
2731import com.duckduckgo.app.httpsupgrade.HttpsUpgrader
2832import com.duckduckgo.app.privacy.db.PrivacyProtectionCountDao
2933import com.duckduckgo.app.surrogates.ResourceSurrogates
@@ -53,19 +57,22 @@ class WebViewRequestInterceptorTest {
5357 private var mockResourceSurrogates: ResourceSurrogates = mock()
5458 private var mockRequest: WebResourceRequest = mock()
5559 private val mockPrivacyProtectionCountDao: PrivacyProtectionCountDao = mock()
60+ private val mockGlobalPrivacyControl: GlobalPrivacyControl = mock()
61+ private val mockWebBackForwardList: WebBackForwardList = mock()
5662
5763 private var webView: WebView = mock()
5864
5965 @UiThreadTest
6066 @Before
6167 fun setup () {
62- MockitoAnnotations .initMocks (this )
68+ MockitoAnnotations .openMocks (this )
6369
6470 testee = WebViewRequestInterceptor (
6571 trackerDetector = mockTrackerDetector,
6672 httpsUpgrader = mockHttpsUpgrader,
6773 resourceSurrogates = mockResourceSurrogates,
68- privacyProtectionCountDao = mockPrivacyProtectionCountDao
74+ privacyProtectionCountDao = mockPrivacyProtectionCountDao,
75+ globalPrivacyControl = mockGlobalPrivacyControl
6976 )
7077 }
7178
@@ -333,6 +340,106 @@ class WebViewRequestInterceptorTest {
333340 verify(mockWebViewClientListener).upgradedToHttps()
334341 }
335342
343+ @Test
344+ fun whenUrlShouldBeUpgradedAndGcpActiveThenLoadUrlWithGpcHeaders () = runBlocking<Unit > {
345+ configureShouldUpgrade()
346+ configureShouldAddGpcHeader()
347+ val mockWebViewClientListener: WebViewClientListener = mock()
348+
349+ testee.shouldIntercept(
350+ request = mockRequest,
351+ documentUrl = null ,
352+ webView = webView,
353+ webViewClientListener = mockWebViewClientListener
354+ )
355+
356+ verify(webView).loadUrl(validHttpsUri().toString(), mockGlobalPrivacyControl.getHeaders())
357+ }
358+
359+ @Test
360+ fun whenRequestShouldAddGcpHeadersThenRedirectTriggeredByGpcCalled () = runBlocking<Unit > {
361+ configureShouldNotUpgrade()
362+ configureShouldAddGpcHeader()
363+ configureUrlDoesNotExistInTheStack()
364+ val mockWebViewClientListener: WebViewClientListener = mock()
365+
366+ testee.shouldIntercept(
367+ request = mockRequest,
368+ documentUrl = null ,
369+ webView = webView,
370+ webViewClientListener = mockWebViewClientListener
371+ )
372+
373+ verify(mockWebViewClientListener).redirectTriggeredByGpc()
374+ }
375+
376+ @Test
377+ fun whenRequestShouldAddGcpHeadersThenLoadUrlWithGpcHeaders () = runBlocking<Unit > {
378+ configureShouldNotUpgrade()
379+ configureShouldAddGpcHeader()
380+ configureUrlDoesNotExistInTheStack()
381+ val mockWebViewClientListener: WebViewClientListener = mock()
382+
383+ testee.shouldIntercept(
384+ request = mockRequest,
385+ documentUrl = null ,
386+ webView = webView,
387+ webViewClientListener = mockWebViewClientListener
388+ )
389+
390+ verify(webView).loadUrl(validUri().toString(), mockGlobalPrivacyControl.getHeaders())
391+ }
392+
393+ @Test
394+ fun whenRequestShouldAddGcpHeadersButUrlExistsInTheStackThenLoadUrlNotCalled () = runBlocking<Unit > {
395+ configureShouldNotUpgrade()
396+ configureShouldAddGpcHeader()
397+ configureUrlExistsInTheStack()
398+ val mockWebViewClientListener: WebViewClientListener = mock()
399+
400+ testee.shouldIntercept(
401+ request = mockRequest,
402+ documentUrl = null ,
403+ webView = webView,
404+ webViewClientListener = mockWebViewClientListener
405+ )
406+
407+ verify(webView, never()).loadUrl(any())
408+ }
409+
410+ @Test
411+ fun whenRequestShouldAddGcpHeadersButAlreadyContainsHeadersThenLoadUrlNotCalled () = runBlocking<Unit > {
412+ configureShouldNotUpgrade()
413+ configureRequestContainsGcpHeader()
414+
415+ val mockWebViewClientListener: WebViewClientListener = mock()
416+
417+ testee.shouldIntercept(
418+ request = mockRequest,
419+ documentUrl = null ,
420+ webView = webView,
421+ webViewClientListener = mockWebViewClientListener
422+ )
423+
424+ verify(webView, never()).loadUrl(any(), any())
425+ }
426+
427+ @Test
428+ fun whenRequestShouldNotAddGcpHeadersThenLoadUrlNotCalled () = runBlocking<Unit > {
429+ configureShouldNotUpgrade()
430+ configureShouldNotAddGpcHeader()
431+ val mockWebViewClientListener: WebViewClientListener = mock()
432+
433+ testee.shouldIntercept(
434+ request = mockRequest,
435+ documentUrl = null ,
436+ webView = webView,
437+ webViewClientListener = mockWebViewClientListener
438+ )
439+
440+ verify(webView, never()).loadUrl(any(), any())
441+ }
442+
336443 private fun assertRequestCanContinueToLoad (response : WebResourceResponse ? ) {
337444 assertNull(response)
338445 }
@@ -349,6 +456,41 @@ class WebViewRequestInterceptorTest {
349456 whenever(mockTrackerDetector.evaluate(any(), any())).thenReturn(blockTrackingEvent)
350457 }
351458
459+ private fun configureUrlExistsInTheStack () {
460+ val mockWebHistoryItem: WebHistoryItem = mock()
461+ whenever(mockWebHistoryItem.url).thenReturn(validUri().toString())
462+ whenever(mockWebBackForwardList.currentItem).thenReturn(mockWebHistoryItem)
463+ whenever(webView.copyBackForwardList()).thenReturn(mockWebBackForwardList)
464+ }
465+
466+ private fun configureUrlDoesNotExistInTheStack () {
467+ val mockWebHistoryItem: WebHistoryItem = mock()
468+ whenever(mockWebHistoryItem.url).thenReturn(" www.test.com" )
469+ whenever(mockWebBackForwardList.currentItem).thenReturn(mockWebHistoryItem)
470+ whenever(webView.copyBackForwardList()).thenReturn(mockWebBackForwardList)
471+ }
472+
473+ private fun configureRequestContainsGcpHeader () = runBlocking<Unit > {
474+ whenever(mockGlobalPrivacyControl.isGpcActive()).thenReturn(true )
475+ whenever(mockRequest.method).thenReturn(" GET" )
476+ whenever(mockRequest.requestHeaders).thenReturn(mapOf (GlobalPrivacyControlManager .GPC_HEADER to " test" ))
477+
478+ }
479+
480+ private fun configureShouldAddGpcHeader () = runBlocking<Unit > {
481+ whenever(mockGlobalPrivacyControl.isGpcActive()).thenReturn(true )
482+ whenever(mockGlobalPrivacyControl.getHeaders()).thenReturn(mapOf (" test" to " test" ))
483+ whenever(mockGlobalPrivacyControl.shouldAddHeaders(any())).thenReturn(true )
484+ whenever(mockRequest.method).thenReturn(" GET" )
485+ }
486+
487+ private fun configureShouldNotAddGpcHeader () = runBlocking<Unit > {
488+ whenever(mockGlobalPrivacyControl.isGpcActive()).thenReturn(false )
489+ whenever(mockGlobalPrivacyControl.getHeaders()).thenReturn(mapOf (" test" to " test" ))
490+ whenever(mockGlobalPrivacyControl.shouldAddHeaders(any())).thenReturn(false )
491+ whenever(mockRequest.method).thenReturn(" GET" )
492+ }
493+
352494 private fun configureShouldUpgrade () = runBlocking<Unit > {
353495 whenever(mockHttpsUpgrader.shouldUpgrade(any())).thenReturn(true )
354496 whenever(mockHttpsUpgrader.upgrade(any())).thenReturn(validHttpsUri())
0 commit comments