Skip to content

Commit

Permalink
Merge branch 'release/5.57.0' into main
Browse files Browse the repository at this point in the history
  • Loading branch information
subsymbolic committed Jun 25, 2020
2 parents b1c863a + d00cd59 commit 321eb8d
Show file tree
Hide file tree
Showing 32 changed files with 635 additions and 95 deletions.
31 changes: 31 additions & 0 deletions .github/ISSUE_TEMPLATE/bug_report.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug, needs triage
assignees: ''

---

**Describe the bug**
A clear and concise description of what the bug is.

**How to Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error

If applicable, please include information about any settings that may be relevant to this issue (e.g. selected theme, auto clear option, etc).

**Expected behavior**
A clear and concise description of what you expected to happen.

**Smartphone (please complete the following information):**
- DDG App Version: (e.g. 5.25.0) Version can be found:
- DDG App settings: Settings -> Version
- System settings: Settings -> Apps & notifications -> App Info
- Device: [e.g. Pixel 2, Samsung s10]
- OS: [e.g. Android 10]
- If applicable, add screenshots to help explain your problem.
17 changes: 17 additions & 0 deletions .github/ISSUE_TEMPLATE/feature_request.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: feature request, needs triage
assignees: ''

---

**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]

**Describe the solution or the user experience you'd like**
A clear and concise description of what you want to happen.

**Additional context**
Add any other context or screenshots about the feature request here.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
Welcome to our android application. We are excited to engage the community in development, see [CONTRIBUTING.md](CONTRIBUTING.md).

## We are hiring!
Are you a talented cross-platform mobile developer? We are looking for a Senior Cross-Platform Engineer to help shape our mobile apps. We embrace diverse perspectives, and seek out passionate, self-motivated people, committed to our shared vision of raising the standard of trust online. Visit our [careers](https://duckduckgo.com/hiring/#open) page to find out more!
DuckDuckGo is growing fast and we continue to expand our fully distributed team. We embrace diverse perspectives, and seek out passionate, self-motivated people, committed to our shared vision of raising the standard of trust online. If you are a senior software engineer capable in either iOS or Android, visit our [careers](https://duckduckgo.com/hiring/#open) page to find out more about our openings!

## Building the Project
We use git submodules and so when you are checking out the app, you'll need to ensure the submodules are initialized properly. You can use the `--recursive` flag when cloning the project to do this.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -49,9 +49,13 @@ import com.duckduckgo.app.browser.session.WebViewSessionStorage
import com.duckduckgo.app.cta.db.DismissedCtaDao
import com.duckduckgo.app.cta.model.CtaId
import com.duckduckgo.app.cta.model.DismissedCta
import com.duckduckgo.app.cta.ui.*
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteDao
import com.duckduckgo.app.fire.fireproofwebsite.data.FireproofWebsiteEntity
import com.duckduckgo.app.cta.ui.Cta
import com.duckduckgo.app.cta.ui.CtaViewModel
import com.duckduckgo.app.cta.ui.DaxBubbleCta
import com.duckduckgo.app.cta.ui.DaxDialogCta
import com.duckduckgo.app.cta.ui.HomePanelCta
import com.duckduckgo.app.global.db.AppDatabase
import com.duckduckgo.app.global.install.AppInstallStore
import com.duckduckgo.app.global.model.SiteFactory
Expand All @@ -65,6 +69,7 @@ import com.duckduckgo.app.privacy.model.TestEntity
import com.duckduckgo.app.privacy.model.UserWhitelistedDomain
import com.duckduckgo.app.runBlocking
import com.duckduckgo.app.settings.db.SettingsDataStore
import com.duckduckgo.app.statistics.Variant
import com.duckduckgo.app.statistics.VariantManager
import com.duckduckgo.app.statistics.VariantManager.Companion.DEFAULT_VARIANT
import com.duckduckgo.app.statistics.api.StatisticsUpdater
Expand All @@ -78,7 +83,14 @@ import com.duckduckgo.app.trackerdetection.EntityLookup
import com.duckduckgo.app.trackerdetection.model.TrackingEvent
import com.duckduckgo.app.usage.search.SearchCountDao
import com.duckduckgo.app.widget.ui.WidgetCapabilities
import com.nhaarman.mockitokotlin2.*
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.anyOrNull
import com.nhaarman.mockitokotlin2.atLeastOnce
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.firstValue
import com.nhaarman.mockitokotlin2.lastValue
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import io.reactivex.Observable
import io.reactivex.Single
import kotlinx.coroutines.ExperimentalCoroutinesApi
Expand All @@ -89,10 +101,14 @@ import org.junit.Assert.*
import org.junit.Before
import org.junit.Rule
import org.junit.Test
import org.mockito.*
import org.mockito.ArgumentCaptor
import org.mockito.ArgumentMatchers.anyString
import org.mockito.Captor
import org.mockito.Mock
import org.mockito.Mockito
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
import java.util.concurrent.TimeUnit

@ExperimentalCoroutinesApi
Expand Down Expand Up @@ -222,7 +238,7 @@ class BrowserTabViewModelTest {

val siteFactory = SiteFactory(mockPrivacyPractices, mockEntityLookup)

whenever(mockOmnibarConverter.convertQueryToUrl(any())).thenReturn("duckduckgo.com")
whenever(mockOmnibarConverter.convertQueryToUrl(any(), any())).thenReturn("duckduckgo.com")
whenever(mockVariantManager.getVariant()).thenReturn(DEFAULT_VARIANT)
whenever(mockTabsRepository.liveSelectedTab).thenReturn(selectedTabLiveData)
whenever(mockTabsRepository.retrieveSiteData(any())).thenReturn(MutableLiveData())
Expand Down Expand Up @@ -250,7 +266,8 @@ class BrowserTabViewModelTest {
searchCountDao = mockSearchCountDao,
pixel = mockPixel,
dispatchers = coroutineRule.testDispatcherProvider,
fireproofWebsiteDao = fireproofWebsiteDao
fireproofWebsiteDao = fireproofWebsiteDao,
variantManager = mockVariantManager
)

testee.loadData("abc", null, false)
Expand Down Expand Up @@ -353,6 +370,7 @@ class BrowserTabViewModelTest {

@Test
fun whenSubmittedQueryHasWhitespaceItIsTrimmed() {
whenever(mockOmnibarConverter.convertQueryToUrl("nytimes.com", null)).thenReturn("nytimes.com")
testee.onUserSubmittedQuery(" nytimes.com ")
assertEquals("nytimes.com", omnibarViewState().omnibarText)
}
Expand Down Expand Up @@ -413,6 +431,7 @@ class BrowserTabViewModelTest {

@Test
fun whenNonEmptyInputThenNavigateCommandSubmittedToActivity() {
whenever(mockOmnibarConverter.convertQueryToUrl("foo", null)).thenReturn("foo.com")
testee.onUserSubmittedQuery("foo")
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
assertTrue(commandCaptor.lastValue is Navigate)
Expand Down Expand Up @@ -701,6 +720,7 @@ class BrowserTabViewModelTest {

@Test
fun whenBrowserShownAndOmnibarInputDoesNotHaveFocusThenPrivacyGradeIsShownAndSearchIconIsHidden() {
whenever(mockOmnibarConverter.convertQueryToUrl("foo", null)).thenReturn("foo.com")
testee.onUserSubmittedQuery("foo")
testee.onOmnibarInputStateChanged(query = "", hasFocus = false, hasQueryChanged = false)
assertTrue(browserViewState().showPrivacyGrade)
Expand All @@ -715,6 +735,7 @@ class BrowserTabViewModelTest {

@Test
fun whenBrowserShownAndOmnibarInputHasFocusThenSearchIconIsShownAndPrivacyGradeIsHidden() {
whenever(mockOmnibarConverter.convertQueryToUrl("foo", null)).thenReturn("foo.com")
testee.onUserSubmittedQuery("foo")
testee.onOmnibarInputStateChanged("", true, hasQueryChanged = false)
assertFalse(browserViewState().showPrivacyGrade)
Expand Down Expand Up @@ -853,6 +874,7 @@ class BrowserTabViewModelTest {

@Test
fun whenEnteringNonEmptyQueryThenHideKeyboardCommandIssued() {
whenever(mockOmnibarConverter.convertQueryToUrl("foo", null)).thenReturn("foo.com")
testee.onUserSubmittedQuery("foo")
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
assertTrue(commandCaptor.allValues.any { it == Command.HideKeyboard })
Expand Down Expand Up @@ -1452,6 +1474,7 @@ class BrowserTabViewModelTest {

@Test
fun whenUserSubmitsQueryThenCaretDoesNotMoveToTheEnd() {
whenever(mockOmnibarConverter.convertQueryToUrl("foo", null)).thenReturn("foo.com")
testee.onUserSubmittedQuery("foo")
assertFalse(omnibarViewState().shouldMoveCaretToEnd)
}
Expand Down Expand Up @@ -1935,6 +1958,38 @@ class BrowserTabViewModelTest {
assertTrue(findInPageViewState().canFindInPage)
}

@Test
fun whenSERPRemovalFeatureIsActiveAndBrowsingDDGSiteAndPrivacyGradeIsVisibleThenShowDaxIconIsTrue() {
val serpRemovalVariant = Variant("foo", 100.0, features = listOf(VariantManager.VariantFeature.SerpHeaderRemoval), filterBy = { true })
whenever(mockVariantManager.getVariant()).thenReturn(serpRemovalVariant)
val url = "https://duckduckgo.com?q=test%20search"
loadUrl(url, isBrowserShowing = true)
assertTrue(browserViewState().showDaxIcon)
}

@Test
fun whenSERPRemovalFeatureIsActiveAndBrowsingNonDDGSiteAndPrivacyGradeIsVisibleThenShowDaxIconIsFalse() {
val serpRemovalVariant = Variant("foo", 100.0, features = listOf(VariantManager.VariantFeature.SerpHeaderRemoval), filterBy = { true })
whenever(mockVariantManager.getVariant()).thenReturn(serpRemovalVariant)
val url = "https://example.com"
loadUrl(url, isBrowserShowing = true)
assertFalse(browserViewState().showDaxIcon)
}

@Test
fun whenSERPRemovalFeatureIsInactiveAndBrowsingDDGSiteAndPrivacyGradeIsVisibleThenShowDaxIconIsFalse() {
val url = "https://duckduckgo.com?q=test%20search"
loadUrl(url, isBrowserShowing = true)
assertFalse(browserViewState().showDaxIcon)
}

@Test
fun whenSERPRemovalFeatureIsInactiveAndBrowsingNonDDGSiteAndPrivacyGradeIsVisibleThenShowDaxIconIsFalse() {
val url = "https://example.com"
loadUrl(url, isBrowserShowing = true)
assertFalse(browserViewState().showDaxIcon)
}

private inline fun <reified T : Command> assertCommandIssued(instanceAssertions: T.() -> Unit = {}) {
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
val issuedCommand = commandCaptor.allValues.find { it is T }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,11 +86,12 @@ class BrowserViewModelTest {
appEnjoymentPromptEmitter = mockAppEnjoymentPromptEmitter,
appEnjoymentUserEventRecorder = mockAppEnjoymentUserEventRecorder
)

testee.command.observeForever(mockCommandObserver)

runBlocking<Unit> {
whenever(mockTabRepository.add()).thenReturn(TAB_ID)
whenever(mockOmnibarEntryConverter.convertQueryToUrl(any())).then { it.arguments.first() }
whenever(mockOmnibarEntryConverter.convertQueryToUrl(any(), any())).then { it.arguments.first() }
}
}

Expand All @@ -108,6 +109,7 @@ class BrowserViewModelTest {
@Test
fun whenOpenInNewTabRequestedThenTabAddedToRepository() = runBlocking<Unit> {
val url = "http://example.com"
whenever(mockOmnibarEntryConverter.convertQueryToUrl(url)).thenReturn(url)
testee.onOpenInNewTabRequested(url)
verify(mockTabRepository).add(url)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ package com.duckduckgo.app.browser
import android.net.Uri
import com.duckduckgo.app.global.AppUrl.ParamKey
import com.duckduckgo.app.referral.AppReferrerDataStore
import com.duckduckgo.app.statistics.Variant
import com.duckduckgo.app.statistics.VariantManager
import com.duckduckgo.app.statistics.model.Atb
import com.duckduckgo.app.statistics.store.StatisticsDataStore
Expand All @@ -35,6 +36,7 @@ class DuckDuckGoRequestRewriterTest {
private val mockVariantManager: VariantManager = mock()
private val mockAppReferrerDataStore: AppReferrerDataStore = mock()
private lateinit var builder: Uri.Builder
private val currentUrl = "http://www.duckduckgo.com"

@Before
fun before() {
Expand Down Expand Up @@ -79,4 +81,23 @@ class DuckDuckGoRequestRewriterTest {
assertFalse(uri.queryParameterNames.contains(ParamKey.ATB))
}

@Test
fun whenSerpRemovalFeatureIsActiveThenHideParamIsAddedToSerpUrl() {
val serpRemovalVariant = Variant("foo", 100.0, features = listOf(VariantManager.VariantFeature.SerpHeaderRemoval), filterBy = { true })
whenever(mockVariantManager.getVariant()).thenReturn(serpRemovalVariant)

testee.addCustomQueryParams(builder)

val uri = builder.build()
assertTrue(uri.queryParameterNames.contains(ParamKey.HIDE_SERP))
}

@Test
fun whenSerpRemovalFeatureIsInactiveThenHideParamIsNotAddedToSerpUrl() {
testee.addCustomQueryParams(builder)

val uri = builder.build()
assertFalse(uri.queryParameterNames.contains(ParamKey.HIDE_SERP))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -70,4 +70,32 @@ class DuckDuckGoUrlDetectorTest {
fun whenNonDDGUrlContainsQueryThenQueryIsNotDetected() {
assertFalse(testee.isDuckDuckGoQueryUrl("https://example.com?q=test%20search"))
}

@Test
fun whenDDGUrlContainsVerticalThenVerticalCanBeExtracted() {
val vertical = testee.extractVertical("https://duckduckgo.com/?q=new+zealand+images&t=ffab&atb=v218-6&iar=images&iax=images&ia=images")
assertEquals("images", vertical)
}

@Test
fun whenDDGUrlDoesNotContainVerticalThenVerticalIsNull() {
val vertical = testee.extractVertical("https://duckduckgo.com")
assertNull(vertical)
}

@Test
fun whenDDGUrlContainsVerticalThenVerticalUrlDetected() {
assertTrue(testee.isDuckDuckGoVerticalUrl("https://duckduckgo.com?ia=images"))
}

@Test
fun whenDDGUrlDoesNotContainsVerticalThenVerticalUrlIsNotDetected() {
assertFalse(testee.isDuckDuckGoVerticalUrl("https://duckduckgo.com"))
}

@Test
fun whenCheckingNonDDGUrThenVerticalUrlIsNotDetected() {
assertFalse(testee.isDuckDuckGoVerticalUrl("https://example.com?ia=images"))
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,11 @@ import com.duckduckgo.app.browser.omnibar.QueryUrlConverter
import com.duckduckgo.app.referral.AppReferrerDataStore
import com.duckduckgo.app.statistics.VariantManager
import com.duckduckgo.app.statistics.store.StatisticsDataStore
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import org.junit.Assert.*
import org.junit.Before
import org.junit.Test

class QueryUrlConverterTest {
Expand All @@ -33,6 +36,11 @@ class QueryUrlConverterTest {
private val requestRewriter = DuckDuckGoRequestRewriter(DuckDuckGoUrlDetector(), mockStatisticsStore, variantManager, mockAppReferrerDataStore)
private val testee: QueryUrlConverter = QueryUrlConverter(requestRewriter)

@Before
fun setup() {
whenever(variantManager.getVariant(any())).thenReturn(VariantManager.DEFAULT_VARIANT)
}

@Test
fun whenSingleWordThenSearchQueryBuilt() {
val input = "foo"
Expand Down
Loading

0 comments on commit 321eb8d

Please sign in to comment.