Skip to content

Commit 2bf6772

Browse files
committed
Merge branch 'release/0.6.0'
2 parents 38e257c + 2b5af15 commit 2bf6772

File tree

132 files changed

+2157
-92
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

132 files changed

+2157
-92
lines changed

app/build.gradle

Lines changed: 4 additions & 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.5.0"
9+
VERSION_NAME = "0.6.0"
1010
}
1111

1212
android {
@@ -25,6 +25,9 @@ android {
2525
release
2626
}
2727
buildTypes {
28+
debug {
29+
testCoverageEnabled = true
30+
}
2831
release {
2932
minifyEnabled false
3033
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'

app/lint.xml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<lint>
33
<issue id="IconColors">
4-
<ignore path="src/main/res/drawable*/privacy_icon_unknown.*" />
4+
<ignore path="src/main/res/drawable*/privacygrade_icon_*" />
55
</issue>
66
<issue id="IconExpectedSize">
7-
<ignore path="src/main/res/drawable-*/privacy_icon_unknown.*" />
7+
<ignore path="src/main/res/drawable-*/privacygrade_icon_*" />
88
</issue>
99
</lint>

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

Lines changed: 37 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,12 @@ import android.arch.core.executor.testing.InstantTaskExecutorRule
2020
import android.arch.lifecycle.Observer
2121
import android.net.Uri
2222
import com.duckduckgo.app.browser.BrowserViewModel.NavigationCommand
23-
import com.duckduckgo.app.browser.BrowserViewModel.ViewState
2423
import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter
24+
import com.duckduckgo.app.privacymonitor.model.PrivacyGrade
2525
import com.duckduckgo.app.privacymonitor.store.PrivacyMonitorRepository
26+
import com.duckduckgo.app.privacymonitor.store.TermsOfServiceStore
27+
import com.duckduckgo.app.trackerdetection.model.TrackerNetworks
28+
import com.duckduckgo.app.trackerdetection.model.TrackingEvent
2629
import com.nhaarman.mockito_kotlin.mock
2730
import org.junit.After
2831
import org.junit.Assert.*
@@ -39,9 +42,9 @@ class BrowserViewModelTest {
3942
@Suppress("unused")
4043
var instantTaskExecutorRule = InstantTaskExecutorRule()
4144

42-
private lateinit var viewStateObserver: Observer<ViewState>
4345
private lateinit var queryObserver: Observer<String>
4446
private lateinit var navigationObserver: Observer<NavigationCommand>
47+
private lateinit var termsOfServiceStore: TermsOfServiceStore
4548
private lateinit var testee: BrowserViewModel
4649

4750
private val testOmnibarConverter: OmnibarEntryConverter = object : OmnibarEntryConverter {
@@ -52,19 +55,17 @@ class BrowserViewModelTest {
5255

5356
@Before
5457
fun before() {
55-
viewStateObserver = mock()
5658
queryObserver = mock()
5759
navigationObserver = mock()
58-
testee = BrowserViewModel(testOmnibarConverter, DuckDuckGoUrlDetector(), PrivacyMonitorRepository())
60+
termsOfServiceStore = mock()
61+
testee = BrowserViewModel(testOmnibarConverter, DuckDuckGoUrlDetector(), termsOfServiceStore, TrackerNetworks(), PrivacyMonitorRepository())
5962
testee.query.observeForever(queryObserver)
60-
testee.viewState.observeForever(viewStateObserver)
6163
testee.navigation.observeForever(navigationObserver)
6264
}
6365

6466
@After
6567
fun after() {
6668
testee.query.removeObserver(queryObserver)
67-
testee.viewState.removeObserver(viewStateObserver)
6869
testee.navigation.removeObserver(navigationObserver)
6970
}
7071

@@ -155,4 +156,34 @@ class BrowserViewModelTest {
155156
testee.urlChanged("")
156157
assertFalse(testee.userDismissedKeyboard())
157158
}
159+
160+
@Test
161+
fun whenLoadingStartedThenPrivacyGradeIsCleared() {
162+
testee.loadingStarted()
163+
assertNull(testee.viewState.value!!.privacyGrade)
164+
}
165+
166+
@Test
167+
fun whenUrlChangedThenPrivacyGradeIsReset() {
168+
testee.urlChanged("https://example.com")
169+
assertEquals(PrivacyGrade.B, testee.viewState.value!!.privacyGrade)
170+
}
171+
172+
@Test
173+
fun whenTrackerDetectedThenPrivacyGradeIsUpdated() {
174+
testee.urlChanged("https://example.com")
175+
testee.trackerDetected(TrackingEvent("", "", null, false))
176+
assertEquals(PrivacyGrade.C, testee.viewState.value!!.privacyGrade)
177+
}
178+
179+
@Test
180+
fun whenInitialisedThenPrivacyGradeIsNotShown() {
181+
assertFalse(testee.viewState.value!!.showPrivacyGrade)
182+
}
183+
184+
@Test
185+
fun whenUrlUpdatedThenPrivacyGradeIsShown() {
186+
testee.urlChanged((""))
187+
assertTrue(testee.viewState.value!!.showPrivacyGrade)
188+
}
158189
}

app/src/androidTest/java/com/duckduckgo/app/global/UriExtensionTest.kt

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,4 +90,16 @@ class UriExtensionTest {
9090
fun whenUriIsMalformedThenIsHtpsIsFalse() {
9191
assertFalse(Uri.parse("[example com]").isHttps)
9292
}
93-
}
93+
94+
@Test
95+
fun whenIpUriThenHasIpHostIsTrue() {
96+
assertTrue(Uri.parse("https://54.229.105.203/something").hasIpHost)
97+
assertTrue(Uri.parse("54.229.105.203/something").hasIpHost)
98+
}
99+
100+
@Test
101+
fun whenStandardUriThenHasIpHostIsFalse() {
102+
assertFalse(Uri.parse("http://example.com").hasIpHost)
103+
}
104+
105+
}
Lines changed: 194 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,194 @@
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.privacymonitor
18+
19+
import com.duckduckgo.app.privacymonitor.HttpsStatus.*
20+
import com.duckduckgo.app.privacymonitor.model.TermsOfService
21+
import com.duckduckgo.app.privacymonitor.ui.improvedScore
22+
import com.duckduckgo.app.privacymonitor.ui.potentialScore
23+
import com.duckduckgo.app.privacymonitor.ui.score
24+
import com.duckduckgo.app.trackerdetection.model.TrackerNetwork
25+
import com.nhaarman.mockito_kotlin.mock
26+
import com.nhaarman.mockito_kotlin.whenever
27+
import org.junit.Assert.assertEquals
28+
import org.junit.Test
29+
30+
class PrivacyMonitorGradeExtensionTest {
31+
32+
companion object {
33+
val defaultScore = 1
34+
}
35+
36+
@Test
37+
fun whenHttpsMixedThenScoreIsIncrementedByOne() {
38+
val privacyMonitor = monitor(https = MIXED)
39+
assertEquals(defaultScore + 1, privacyMonitor.score)
40+
}
41+
42+
@Test
43+
fun whenHttpThenScoreIsIncrementedByOne() {
44+
val privacyMonitor = monitor(https = NONE)
45+
assertEquals(defaultScore + 1, privacyMonitor.score)
46+
}
47+
48+
@Test
49+
fun whenHttpsThenScoreIsUnchanged() {
50+
val privacyMonitor = monitor(https = SECURE)
51+
assertEquals(defaultScore, privacyMonitor.score)
52+
}
53+
54+
@Test
55+
fun whenTermsClassificationIsAThenScoreIsDecrementedByOne() {
56+
val privacyMonitor = monitor(terms = TermsOfService(classification = "A"))
57+
assertEquals(defaultScore - 1, privacyMonitor.score)
58+
}
59+
60+
@Test
61+
fun whenTermsClassificationIsBThenScoreIsUnchanged() {
62+
val privacyMonitor = monitor(terms = TermsOfService(classification = "B"))
63+
assertEquals(defaultScore, privacyMonitor.score)
64+
}
65+
66+
@Test
67+
fun whenTermsClassificationIsCThenScoreIsUnchanged() {
68+
val privacyMonitor = monitor(terms = TermsOfService(classification = "C"))
69+
assertEquals(defaultScore, privacyMonitor.score)
70+
}
71+
72+
@Test
73+
fun whenTermsClassificationIsDThenScoreIsIncrementedByOne() {
74+
val privacyMonitor = monitor(terms = TermsOfService(classification = "D"))
75+
assertEquals(defaultScore + 1, privacyMonitor.score)
76+
}
77+
78+
@Test
79+
fun whenTermsClassificationIsEThenScoreIsIncrementedByTwo() {
80+
val privacyMonitor = monitor(terms = TermsOfService(classification = "E"))
81+
assertEquals(defaultScore + 2, privacyMonitor.score)
82+
}
83+
84+
@Test
85+
fun whenTermsScoreIsPositiveThenScoreIsIncrementedByOne() {
86+
val privacyMonitor = monitor(terms = TermsOfService(score = 5))
87+
assertEquals(defaultScore + 1, privacyMonitor.score)
88+
}
89+
90+
@Test
91+
fun whenTermsScoreIsNegativeThenScoreIsDecrementedByOne() {
92+
val privacyMonitor = monitor(terms = TermsOfService(score = -5))
93+
assertEquals(defaultScore - 1, privacyMonitor.score)
94+
}
95+
96+
@Test
97+
fun whenTermsScoreIsZeroThenScoreIsUnchanged() {
98+
val privacyMonitor = monitor(terms = TermsOfService(score = 0))
99+
assertEquals(defaultScore, privacyMonitor.score)
100+
}
101+
102+
@Test
103+
fun whenZeroTrackersThenScoreIsDefault() {
104+
val privacyMonitor = monitor(trackerCount = 0)
105+
assertEquals(defaultScore, privacyMonitor.score)
106+
}
107+
108+
@Test
109+
fun whenOneTrackerThenScoreIsIncrementedByOne() {
110+
val privacyMonitor = monitor(trackerCount = 1)
111+
assertEquals(defaultScore + 1, privacyMonitor.score)
112+
}
113+
114+
@Test
115+
fun whenElevenTrackersThenScoreIsIncrementedByTwo() {
116+
val privacyMonitor = monitor(trackerCount = 11)
117+
assertEquals(defaultScore + 2, privacyMonitor.score)
118+
}
119+
120+
@Test
121+
fun whenSiteIsMajorNetworkMemberThenScoreIsIncrementedByPercentage() {
122+
val privacyMonitor = monitor(memberNetwork = TrackerNetwork("", "", 45, true))
123+
assertEquals(defaultScore + 5, privacyMonitor.score)
124+
}
125+
126+
@Test
127+
fun whenHasMajorTrackerThenScoreIsIncrementedByOne() {
128+
val privacyMonitor = monitor(majorTrackerCount = 1)
129+
assertEquals(defaultScore + 1, privacyMonitor.score)
130+
}
131+
132+
@Test
133+
fun whenHasObscureTrackerThenScoreIsIncrementedByOne() {
134+
val privacyMonitor = monitor(hasObscureTracker = true)
135+
assertEquals(defaultScore + 1, privacyMonitor.score)
136+
}
137+
138+
@Test
139+
fun whenPotentialScoreThenTrackerMetricsIgnored() {
140+
val privacyMonitor = monitor(
141+
TrackerNetwork("", "", 5, true),
142+
TermsOfService(classification = "D"),
143+
NONE,
144+
5,
145+
2,
146+
true)
147+
assertEquals(defaultScore + 6, privacyMonitor.score)
148+
assertEquals(defaultScore + 3, privacyMonitor.potentialScore)
149+
}
150+
151+
@Test
152+
fun whenAllTrackersBlockedThenImporvedScoreIsEqualToPotentialScore() {
153+
val privacyMonitor = monitor(
154+
TrackerNetwork("", "", 5, true),
155+
TermsOfService(classification = "D"),
156+
NONE,
157+
5,
158+
2,
159+
true,
160+
allTrackerBlocked = true)
161+
assertEquals(privacyMonitor.potentialScore, privacyMonitor.improvedScore)
162+
}
163+
164+
@Test
165+
fun whenNotAllTrackersBlockedThenImprovedScoreIsEqualToScore() {
166+
val privacyMonitor = monitor(
167+
TrackerNetwork("", "", 5, true),
168+
TermsOfService(classification = "D"),
169+
NONE,
170+
5,
171+
2,
172+
true,
173+
allTrackerBlocked = false)
174+
assertEquals(privacyMonitor.score, privacyMonitor.improvedScore)
175+
}
176+
177+
private fun monitor(memberNetwork: TrackerNetwork? = null,
178+
terms: TermsOfService = TermsOfService(),
179+
https: HttpsStatus = SECURE,
180+
trackerCount: Int = 0,
181+
majorTrackerCount: Int = 0,
182+
hasObscureTracker: Boolean = false,
183+
allTrackerBlocked: Boolean = true): PrivacyMonitor {
184+
val monitor: PrivacyMonitor = mock()
185+
whenever(monitor.memberNetwork).thenReturn(memberNetwork)
186+
whenever(monitor.termsOfService).thenReturn(terms)
187+
whenever(monitor.trackerCount).thenReturn(trackerCount)
188+
whenever(monitor.majorNetworkCount).thenReturn(majorTrackerCount)
189+
whenever(monitor.hasObscureTracker).thenReturn(hasObscureTracker)
190+
whenever(monitor.https).thenReturn(https)
191+
whenever(monitor.allTrackersBlocked).thenReturn(allTrackerBlocked)
192+
return monitor
193+
}
194+
}

app/src/androidTest/java/com/duckduckgo/app/privacymonitor/SiteMonitorInstrumentationTests.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -16,39 +16,51 @@
1616

1717
package com.duckduckgo.app.privacymonitor
1818

19+
import com.duckduckgo.app.privacymonitor.model.TermsOfService
20+
import com.duckduckgo.app.trackerdetection.model.TrackerNetworks
21+
import com.duckduckgo.app.trackerdetection.model.TrackingEvent
1922
import org.junit.Assert.assertEquals
23+
import org.junit.Assert.assertTrue
2024
import org.junit.Test
2125

2226
class SiteMonitorInstrumentationTests {
2327

2428
companion object {
2529
private const val httpDocument = "http://example.com"
2630
private const val httpsDocument = "https://example.com"
27-
private const val malformesDocument = "[example com]"
31+
private const val malformedDocument = "[example com]"
2832
}
2933

3034
@Test
3135
fun whenUrlIsHttpsThenHttpsStatusIsSecure() {
32-
val testee = SiteMonitor(httpsDocument)
36+
val testee = SiteMonitor(httpsDocument, TermsOfService(), TrackerNetworks())
3337
assertEquals(HttpsStatus.SECURE, testee.https)
3438
}
3539

3640
@Test
3741
fun whenUrlIsHttpThenHttpsStatusIsNone() {
38-
val testee = SiteMonitor(httpDocument)
42+
val testee = SiteMonitor(httpDocument, TermsOfService(), TrackerNetworks())
3943
assertEquals(HttpsStatus.NONE, testee.https)
4044
}
4145

4246
@Test
4347
fun whenUrlIsHttpsWithHttpResourcesThenHttpsStatusIsMixed() {
44-
val testee = SiteMonitor(httpsDocument)
48+
val testee = SiteMonitor(httpsDocument, TermsOfService(), TrackerNetworks())
4549
testee.hasHttpResources = true
4650
assertEquals(HttpsStatus.MIXED, testee.https)
4751
}
4852

4953
@Test
5054
fun whenUrlIsMalformedThenHttpsStatusIsNone() {
51-
val testee = SiteMonitor(malformesDocument)
55+
val testee = SiteMonitor(malformedDocument, TermsOfService(), TrackerNetworks())
5256
assertEquals(HttpsStatus.NONE, testee.https)
5357
}
58+
59+
@Test
60+
fun whenIpTrackerDetectedThenHasObscureTrackerIsTrue() {
61+
val testee = SiteMonitor(httpDocument, TermsOfService(), TrackerNetworks())
62+
testee.trackerDetected(TrackingEvent(httpDocument, "http://54.229.105.203/abc", null, true))
63+
assertTrue(testee.hasObscureTracker)
64+
}
65+
5466
}

0 commit comments

Comments
 (0)