Skip to content

Commit f5d32c7

Browse files
committed
Merge branch 'release/0.3.0'
2 parents 46ff655 + aa8d165 commit f5d32c7

38 files changed

+634
-342
lines changed

app/build.gradle

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ apply plugin: 'kotlin-kapt'
66
apply from: '../versioning.gradle'
77

88
ext {
9-
VERSION_NAME = "0.2.0"
9+
VERSION_NAME = "0.3.0"
1010
}
1111

1212
android {

app/src/androidTest/java/com/duckduckgo/app/browser/BrowserViewModelTest.kt

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ package com.duckduckgo.app.browser
1919
import android.arch.core.executor.testing.InstantTaskExecutorRule
2020
import android.arch.lifecycle.Observer
2121
import android.net.Uri
22+
import com.duckduckgo.app.browser.BrowserViewModel.NavigationCommand
23+
import com.duckduckgo.app.browser.BrowserViewModel.ViewState
2224
import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter
2325
import com.duckduckgo.app.trackerdetection.model.NetworkTrackers
2426
import com.nhaarman.mockito_kotlin.mock
@@ -38,10 +40,13 @@ class BrowserViewModelTest {
3840
var instantTaskExecutorRule = InstantTaskExecutorRule()
3941

4042
@Mock
41-
val viewStateObserver: Observer<BrowserViewModel.ViewState> = mock()
43+
private val viewStateObserver: Observer<ViewState> = mock()
4244

4345
@Mock
44-
private val observer: Observer<String> = mock()
46+
private val queryObserver: Observer<String> = mock()
47+
48+
@Mock
49+
private val navigationObserver: Observer<NavigationCommand> = mock()
4550

4651
private val testOmnibarConverter: OmnibarEntryConverter = object : OmnibarEntryConverter {
4752
override fun convertUri(input: String): String = "duckduckgo.com"
@@ -54,32 +59,34 @@ class BrowserViewModelTest {
5459
@Before
5560
fun before() {
5661
testee = BrowserViewModel(testOmnibarConverter, DuckDuckGoUrlDetector(), NetworkTrackers())
57-
testee.query.observeForever(observer)
62+
testee.query.observeForever(queryObserver)
5863
testee.viewState.observeForever(viewStateObserver)
64+
testee.navigation.observeForever(navigationObserver)
5965
}
6066

6167
@After
6268
fun after() {
63-
testee.query.removeObserver(observer)
69+
testee.query.removeObserver(queryObserver)
6470
testee.viewState.removeObserver(viewStateObserver)
71+
testee.navigation.removeObserver(navigationObserver)
6572
}
6673

6774
@Test
6875
fun whenEmptyInputQueryThenNoQueryMadeAvailableToActivity() {
6976
testee.onUserSubmittedQuery("")
70-
verify(observer, never()).onChanged(ArgumentMatchers.anyString())
77+
verify(queryObserver, never()).onChanged(ArgumentMatchers.anyString())
7178
}
7279

7380
@Test
7481
fun whenBlankInputQueryThenNoQueryMadeAvailableToActivity() {
7582
testee.onUserSubmittedQuery(" ")
76-
verify(observer, never()).onChanged(ArgumentMatchers.anyString())
83+
verify(queryObserver, never()).onChanged(ArgumentMatchers.anyString())
7784
}
7885

7986
@Test
8087
fun whenNonEmptyInputThenQueryMadeAvailableToActivity() {
8188
testee.onUserSubmittedQuery("foo")
82-
verify(observer).onChanged(ArgumentMatchers.anyString())
89+
verify(queryObserver).onChanged(ArgumentMatchers.anyString())
8390
}
8491

8592
@Test
@@ -128,4 +135,27 @@ class BrowserViewModelTest {
128135
testee.progressChanged(100)
129136
assertEquals(100, testee.viewState.value!!.progress)
130137
}
138+
139+
@Test
140+
fun whenUserDismissesKeyboardBeforeBrowserShownThenShouldNavigateToLandingPage() {
141+
testee.userDismissedKeyboard()
142+
verify(navigationObserver).onChanged(NavigationCommand.LANDING_PAGE)
143+
}
144+
145+
@Test
146+
fun whenUserDismissesKeyboardAfterBrowserShownThenShouldNotNavigateToLandingPage() {
147+
testee.urlChanged("")
148+
verify(navigationObserver, never()).onChanged(NavigationCommand.LANDING_PAGE)
149+
}
150+
151+
@Test
152+
fun whenUserDismissesKeyboardBeforeBrowserShownThenShouldConsumeBackButtonEvent() {
153+
assertTrue(testee.userDismissedKeyboard())
154+
}
155+
156+
@Test
157+
fun whenUserDismissesKeyboardAfterBrowserShownThenShouldNotConsumeBackButtonEvent() {
158+
testee.urlChanged("")
159+
assertFalse(testee.userDismissedKeyboard())
160+
}
131161
}

app/src/androidTest/java/com/duckduckgo/app/browser/DuckDuckGoUrlDetectorTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ class DuckDuckGoUrlDetectorTest {
2626
private lateinit var testee: DuckDuckGoUrlDetector
2727

2828
@Before
29-
fun setup(){
29+
fun setup() {
3030
testee = DuckDuckGoUrlDetector()
3131
}
3232

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright (c) 2017 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.global
18+
19+
import com.duckduckgo.app.global.UriString.Companion.sameOrSubdomain
20+
import org.junit.Assert.assertFalse
21+
import org.junit.Assert.assertTrue
22+
import org.junit.Test
23+
24+
class UriStringTest {
25+
26+
@Test
27+
fun whenUrlsHaveSameDomainThenSameOrSubdomainIsTrue() {
28+
assertTrue(sameOrSubdomain("http://example.com/index.html", "http://example.com/home.html"))
29+
}
30+
31+
@Test
32+
fun whenUrlIsSubdomainThenSameOrSubdomainIsTrue() {
33+
assertTrue(sameOrSubdomain("http://subdomain.example.com/index.html", "http://example.com/home.html"))
34+
}
35+
36+
@Test
37+
fun whenUrlIsAParentDomainThenSameOrSubdomainIsFalse() {
38+
assertFalse(sameOrSubdomain("http://example.com/index.html", "http://parent.example.com/home.html"))
39+
}
40+
41+
@Test
42+
fun whenChildUrlIsMalformedThenSameOrSubdomainIsFalse() {
43+
assertFalse(sameOrSubdomain("??.example.com/index.html", "http://example.com/home.html"))
44+
}
45+
46+
@Test
47+
fun whenParentUrlIsMalformedThenSameOrSubdomainIsFalse() {
48+
assertFalse(sameOrSubdomain("http://example.com/index.html", "??.example.com/home.html"))
49+
}
50+
51+
}

app/src/androidTest/java/com/duckduckgo/app/trackerdetection/TrackerDetectorInstrumentationTest.kt

Lines changed: 77 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -16,62 +16,107 @@
1616

1717
package com.duckduckgo.app.trackerdetection
1818

19-
20-
import android.support.test.runner.AndroidJUnit4
21-
import com.duckduckgo.app.trackerdetection.Client.ClientName.EASYLIST
22-
import com.duckduckgo.app.trackerdetection.Client.ClientName.EASYPRIVACY
19+
import com.duckduckgo.app.trackerdetection.model.DisconnectTracker
20+
import com.duckduckgo.app.trackerdetection.model.NetworkTrackers
2321
import com.duckduckgo.app.trackerdetection.model.ResourceType
22+
import com.nhaarman.mockito_kotlin.any
23+
import com.nhaarman.mockito_kotlin.mock
24+
import com.nhaarman.mockito_kotlin.whenever
2425
import org.junit.Assert.assertFalse
2526
import org.junit.Assert.assertTrue
26-
import org.junit.Before
2727
import org.junit.Test
28-
import org.junit.runner.RunWith
28+
import org.mockito.ArgumentMatchers.anyString
29+
import java.util.*
2930

3031

31-
@RunWith(AndroidJUnit4::class)
3232
class TrackerDetectorInstrumentationTest {
3333

34+
private val networkTrackers = NetworkTrackers()
35+
private val trackerDetector = TrackerDetector(networkTrackers)
36+
3437
companion object {
35-
private val documentUrl = "http://example.com"
3638
private val resourceType = ResourceType.UNKNOWN
39+
private val network = "Network"
40+
}
41+
42+
@Test
43+
fun whenThereAreNoClientsThenShouldBlockIsFalse() {
44+
assertFalse(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
45+
}
46+
47+
@Test
48+
fun whenAllClientsFailToMatchThenShouldBlockIsFalse() {
49+
trackerDetector.addClient(neverMatchingClient())
50+
trackerDetector.addClient(neverMatchingClient())
51+
assertFalse(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
52+
}
53+
54+
@Test
55+
fun whenAllClientsMatchThenShouldBlockIsTrue() {
56+
trackerDetector.addClient(alwaysMatchingClient())
57+
trackerDetector.addClient(alwaysMatchingClient())
58+
assertTrue(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
3759
}
3860

39-
private lateinit var testee: TrackerDetector
61+
@Test
62+
fun whenSomeClientsMatchThenShouldBlockIsTrue() {
63+
trackerDetector.addClient(neverMatchingClient())
64+
trackerDetector.addClient(alwaysMatchingClient())
65+
assertTrue(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
66+
}
67+
68+
@Test
69+
fun whenUrlHasSameDomainAsDocumentThenShouldBlockIsFalse() {
70+
trackerDetector.addClient(alwaysMatchingClient())
71+
assertFalse(trackerDetector.shouldBlock("http://example.com/update.js", "http://example.com/index.com", resourceType))
72+
}
4073

41-
@Before
42-
fun before() {
43-
val easylistAdblock = adblockClient(EASYLIST, "binary/easylist_sample")
44-
val easyprivacyAdblock = adblockClient(EASYPRIVACY, "binary/easyprivacy_sample")
45-
testee = TrackerDetector()
46-
testee.addClient(easyprivacyAdblock)
47-
testee.addClient(easylistAdblock)
74+
@Test
75+
fun whenUrlIsSubdomainOfDocumentThenShouldBlockIsFalse() {
76+
trackerDetector.addClient(alwaysMatchingClient())
77+
assertFalse(trackerDetector.shouldBlock("http://mobile.example.com/update.js", "http://example.com/index.com", resourceType))
4878
}
4979

5080
@Test
51-
fun whenUrlIsInEasyListThenShouldBlockIsTrue() {
52-
val url = "http://imasdk.googleapis.com/js/sdkloader/ima3.js"
53-
assertTrue(testee.shouldBlock(url, documentUrl, resourceType))
81+
fun whenUrlIsParentOfDocumentThenShouldBlockIsFalse() {
82+
trackerDetector.addClient(alwaysMatchingClient())
83+
assertFalse(trackerDetector.shouldBlock("http://example.com/update.js", "http://mobile.example.com/index.com", resourceType))
5484
}
5585

5686
@Test
57-
fun whenUrlIsInEasyPrivacyListThenShouldBlockIsTrue() {
58-
val url = "http://cdn.tagcommander.com/1705/tc_catalog.css"
59-
assertTrue(testee.shouldBlock(url, documentUrl, resourceType))
87+
fun whenUrlIsNetworkOfDocumentThenShouldBlockIsFalse() {
88+
val networks = Arrays.asList(DisconnectTracker("example.com", "", network, "http://thirdparty.com/"))
89+
networkTrackers.updateData(networks)
90+
assertFalse(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
6091
}
6192

6293
@Test
63-
fun whenUrlIsNotInAnyTrackerListsThenShouldBlockIsFalse() {
64-
val url = "https://duckduckgo.com/index.html"
65-
assertFalse(testee.shouldBlock(url, documentUrl, resourceType))
94+
fun whenDocumentIsNetworkOfUrlThenShouldBlockIsFalse() {
95+
val networks = Arrays.asList(DisconnectTracker("thirdparty.com", "", network, "http://example.com"))
96+
networkTrackers.updateData(networks)
97+
assertFalse(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
98+
}
99+
100+
@Test
101+
fun whenUrlSharesSameNetworkAsDocumentThenShouldBlockIsFalse() {
102+
val networks = Arrays.asList(
103+
DisconnectTracker("thirdparty.com", "", network, "http://network.com"),
104+
DisconnectTracker("example.com", "", network, "http://network.com")
105+
)
106+
networkTrackers.updateData(networks)
107+
assertFalse(trackerDetector.shouldBlock("http://thirdparty.com/update.js", "http://example.com/index.com", resourceType))
108+
}
109+
110+
private fun alwaysMatchingClient(): Client {
111+
val client: Client = mock()
112+
whenever(client.matches(anyString(), anyString(), any())).thenReturn(true)
113+
return client
66114
}
67115

68-
private fun adblockClient(name: Client.ClientName, dataFile: String): Client {
69-
val data = javaClass.classLoader.getResource(dataFile).readBytes()
70-
val initialAdBlock = AdBlockClient(name)
71-
initialAdBlock.loadBasicData(data)
72-
val adblockWithProcessedData = AdBlockClient(name)
73-
adblockWithProcessedData.loadProcessedData(initialAdBlock.getProcessedData())
74-
return adblockWithProcessedData
116+
private fun neverMatchingClient(): Client {
117+
val client: Client = mock()
118+
whenever(client.matches(anyString(), anyString(), any())).thenReturn(false)
119+
return client
75120
}
76121

77122
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
/*
2+
* Copyright (c) 2017 DuckDuckGo
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package com.duckduckgo.app.trackerdetection
18+
19+
20+
import android.support.test.runner.AndroidJUnit4
21+
import com.duckduckgo.app.trackerdetection.Client.ClientName.EASYLIST
22+
import com.duckduckgo.app.trackerdetection.Client.ClientName.EASYPRIVACY
23+
import com.duckduckgo.app.trackerdetection.model.NetworkTrackers
24+
import com.duckduckgo.app.trackerdetection.model.ResourceType
25+
import org.junit.Assert.assertFalse
26+
import org.junit.Assert.assertTrue
27+
import org.junit.Before
28+
import org.junit.Test
29+
import org.junit.runner.RunWith
30+
31+
32+
@RunWith(AndroidJUnit4::class)
33+
class TrackerDetectorListInstrumentationTest {
34+
35+
companion object {
36+
private val documentUrl = "http://example.com"
37+
private val resourceType = ResourceType.UNKNOWN
38+
}
39+
40+
private lateinit var testee: TrackerDetector
41+
42+
@Before
43+
fun before() {
44+
val easylistAdblock = adblockClient(EASYLIST, "binary/easylist_sample")
45+
val easyprivacyAdblock = adblockClient(EASYPRIVACY, "binary/easyprivacy_sample")
46+
testee = TrackerDetector(NetworkTrackers())
47+
testee.addClient(easyprivacyAdblock)
48+
testee.addClient(easylistAdblock)
49+
}
50+
51+
@Test
52+
fun whenUrlIsInEasyListThenShouldBlockIsTrue() {
53+
val url = "http://imasdk.googleapis.com/js/sdkloader/ima3.js"
54+
assertTrue(testee.shouldBlock(url, documentUrl, resourceType))
55+
}
56+
57+
@Test
58+
fun whenUrlIsInEasyPrivacyListThenShouldBlockIsTrue() {
59+
val url = "http://cdn.tagcommander.com/1705/tc_catalog.css"
60+
assertTrue(testee.shouldBlock(url, documentUrl, resourceType))
61+
}
62+
63+
@Test
64+
fun whenUrlIsNotInAnyTrackerListsThenShouldBlockIsFalse() {
65+
val url = "https://duckduckgo.com/index.html"
66+
assertFalse(testee.shouldBlock(url, documentUrl, resourceType))
67+
}
68+
69+
private fun adblockClient(name: Client.ClientName, dataFile: String): Client {
70+
val data = javaClass.classLoader.getResource(dataFile).readBytes()
71+
val initialAdBlock = AdBlockClient(name)
72+
initialAdBlock.loadBasicData(data)
73+
val adblockWithProcessedData = AdBlockClient(name)
74+
adblockWithProcessedData.loadProcessedData(initialAdBlock.getProcessedData())
75+
return adblockWithProcessedData
76+
}
77+
78+
}

0 commit comments

Comments
 (0)