Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
29 commits
Select commit Hold shift + click to select a range
165adc0
Update to latest tooling
subsymbolic Jan 30, 2020
b0a920c
Remove unused parameter
subsymbolic Jan 30, 2020
84cdb3a
Remove unneeded unwrapping as per lint warning
subsymbolic Jan 30, 2020
75ae65e
Remove duplicate data and presentation logic from AutoCompleteApi
subsymbolic Jan 30, 2020
3271174
Initial interstitial screen
subsymbolic Jan 30, 2020
b4365ba
Add app list to view
subsymbolic Feb 3, 2020
45676b3
Tidy up device lookup and move off main thread
subsymbolic Feb 9, 2020
ea4578c
Use mini logo for better sizing
subsymbolic Feb 9, 2020
2214715
Merge branch 'develop' into feature/mia/interstitial_search
subsymbolic Feb 9, 2020
36b1d4b
Add scrolling
subsymbolic Feb 9, 2020
026a68e
Add view state reset and tweak app label text size
subsymbolic Feb 9, 2020
12b22bc
Remove colon from system search text as per design feedback
subsymbolic Feb 17, 2020
3be73e3
Update layout to show shadow at the bottom of autocomplete
subsymbolic Feb 17, 2020
b9b06de
Enable "no suggestions" and ensure it doesn't flash up on the screen
subsymbolic Feb 17, 2020
7a6cf08
Fix scrolling
subsymbolic Feb 20, 2020
e545232
Improve app lookup speed by reducing package manager lookups
subsymbolic Feb 20, 2020
bda60f6
Remove additional dev logging
subsymbolic Feb 20, 2020
b0ddd90
Tweak scrolling further
subsymbolic Feb 21, 2020
b235b09
Switch to word prefix matching
subsymbolic Feb 21, 2020
61fe705
Small tidy ups, remove dev logging, add explanatory comment and cance…
subsymbolic Feb 21, 2020
fa43e94
Make dax launch DuckDuckGo
subsymbolic Feb 21, 2020
6864a0e
Merge branch 'develop' into feature/mia/interstitial_search
subsymbolic Feb 21, 2020
95284bb
Add pixels
subsymbolic Feb 21, 2020
96d672f
Merge branch 'develop' into feature/mia/interstitial_search
subsymbolic Feb 21, 2020
005e188
Unit tests
subsymbolic Feb 24, 2020
cbea4ca
Merge branch 'develop' into feature/mia/interstitial_search
subsymbolic Feb 24, 2020
12451af
Rename variables and methods for clarity
subsymbolic Feb 26, 2020
c1343bd
Store app icon to avoid duplicate lookups and show message when app n…
subsymbolic Feb 26, 2020
4353881
Lint
subsymbolic Feb 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

package com.duckduckgo.app.autocomplete.api

import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteResult
import com.duckduckgo.app.bookmarks.db.BookmarkEntity
import com.duckduckgo.app.bookmarks.db.BookmarksDao
import com.nhaarman.mockitokotlin2.verify
Expand Down Expand Up @@ -59,7 +60,7 @@ class AutoCompleteApiTest {
@Test
fun whenQueryIsBlankThenReturnAnEmptyList() {
val result = testee.autoComplete("").test()
val value = result.values()[0] as AutoCompleteApi.AutoCompleteResult
val value = result.values()[0] as AutoCompleteResult

assertTrue(value.suggestions.isEmpty())
}
Expand All @@ -70,7 +71,7 @@ class AutoCompleteApiTest {
whenever(mockBookmarksDao.bookmarksByQuery(anyString())).thenReturn(Single.just(listOf(BookmarkEntity(0, "title", "https://example.com"))))

val result = testee.autoComplete("foo").test()
val value = result.values()[0] as AutoCompleteApi.AutoCompleteResult
val value = result.values()[0] as AutoCompleteResult

assertSame("https://example.com", value.suggestions[0].phrase)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
import com.duckduckgo.app.CoroutineTestRule
import com.duckduckgo.app.InstantSchedulersRule
import com.duckduckgo.app.ValueCaptorObserver
import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteResult
import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteBookmarkSuggestion
import com.duckduckgo.app.autocomplete.api.AutoComplete.AutoCompleteSuggestion.AutoCompleteSearchSuggestion
import com.duckduckgo.app.autocomplete.api.AutoCompleteApi
import com.duckduckgo.app.autocomplete.api.AutoCompleteApi.AutoCompleteSuggestion.AutoCompleteBookmarkSuggestion
import com.duckduckgo.app.autocomplete.api.AutoCompleteApi.AutoCompleteSuggestion.AutoCompleteSearchSuggestion
import com.duckduckgo.app.autocomplete.api.AutoCompleteService
import com.duckduckgo.app.bookmarks.db.BookmarkEntity
import com.duckduckgo.app.bookmarks.db.BookmarksDao
Expand Down Expand Up @@ -227,7 +228,7 @@ class BrowserTabViewModelTest {
siteFactory = siteFactory,
tabRepository = mockTabsRepository,
networkLeaderboardDao = mockNetworkLeaderboardDao,
autoCompleteApi = mockAutoCompleteApi,
autoComplete = mockAutoCompleteApi,
appSettingsPreferencesStore = mockSettingsStore,
bookmarksDao = mockBookmarksDao,
longPressHandler = mockLongPressHandler,
Expand Down Expand Up @@ -1263,16 +1264,17 @@ class BrowserTabViewModelTest {
@Test
fun whenBookmarkSuggestionSubmittedThenAutoCompleteBookmarkSelectionPixelSent() = runBlocking {
whenever(mockBookmarksDao.hasBookmarks()).thenReturn(true)
testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteApi.AutoCompleteResult("", emptyList(), true))
testee.fireAutocompletePixel(AutoCompleteBookmarkSuggestion("example", "Example", "https://example.com"))

val suggestion = AutoCompleteBookmarkSuggestion("example", "Example", "https://example.com")
testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteResult("", listOf(suggestion)))
testee.fireAutocompletePixel(suggestion)
verify(mockPixel).fire(Pixel.PixelName.AUTOCOMPLETE_BOOKMARK_SELECTION, pixelParams(showedBookmarks = true, bookmarkCapable = true))
}

@Test
fun whenSearchSuggestionSubmittedWithBookmarksThenAutoCompleteSearchSelectionPixelSent() = runBlocking {
whenever(mockBookmarksDao.hasBookmarks()).thenReturn(true)
testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteApi.AutoCompleteResult("", emptyList(), true))
val suggestions = listOf(AutoCompleteSearchSuggestion("", false), AutoCompleteBookmarkSuggestion("", "", ""))
testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteResult("", suggestions))
testee.fireAutocompletePixel(AutoCompleteSearchSuggestion("example", false))

verify(mockPixel).fire(Pixel.PixelName.AUTOCOMPLETE_SEARCH_SELECTION, pixelParams(showedBookmarks = true, bookmarkCapable = true))
Expand All @@ -1281,7 +1283,7 @@ class BrowserTabViewModelTest {
@Test
fun whenSearchSuggestionSubmittedWithoutBookmarksThenAutoCompleteSearchSelectionPixelSent() = runBlocking {
whenever(mockBookmarksDao.hasBookmarks()).thenReturn(false)
testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteApi.AutoCompleteResult("", emptyList(), false))
testee.autoCompleteViewState.value = autoCompleteViewState().copy(searchResults = AutoCompleteResult("", emptyList()))
testee.fireAutocompletePixel(AutoCompleteSearchSuggestion("example", false))

verify(mockPixel).fire(Pixel.PixelName.AUTOCOMPLETE_SEARCH_SELECTION, pixelParams(showedBookmarks = false, bookmarkCapable = false))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ import javax.inject.Singleton
NetworkModule::class,
StoreModule::class,
JsonModule::class,
SystemComponentsModule::class,
BrowserModule::class,
BrowserAutoCompleteModule::class,
HttpsUpgraderModule::class,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ class TrackerNetworksViewModelTest {
assertEquals(1, result[Entity.MINOR_ENTITY_B]?.count())
}

private fun site(url: String = "", networkCount: Int = 0, trackingEvents: List<TrackingEvent> = emptyList()): Site {
private fun site(url: String = "", trackingEvents: List<TrackingEvent> = emptyList()): Site {
val site: Site = mock()
whenever(site.url).thenReturn(url)
whenever(site.uri).thenReturn(Uri.parse(url))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class VariantManagerTest {
fun conceptTestNoCtaVariantIsInactiveAndHasSuppressCtaFeatures() {
val variant = variants.firstOrNull { it.key == "md" }
assertEqualsDouble(0.0, variant!!.weight)
assertEquals(2, variant!!.features.size)
assertEquals(2, variant.features.size)
assertTrue(variant.hasFeature(SuppressWidgetCta))
assertTrue(variant.hasFeature(SuppressDefaultBrowserCta))
}
Expand All @@ -62,12 +62,13 @@ class VariantManagerTest {
fun conceptTestExperimentalVariantIsInactiveAndHasConceptTestAndSuppressCtaFeatures() {
val variant = variants.firstOrNull { it.key == "me" }
assertEqualsDouble(0.0, variant!!.weight)
assertEquals(3, variant!!.features.size)
assertEquals(3, variant.features.size)
assertTrue(variant.hasFeature(ConceptTest))
assertTrue(variant.hasFeature(SuppressWidgetCta))
assertTrue(variant.hasFeature(SuppressDefaultBrowserCta))
}


// CTA on Concept Test experiments

@Test
Expand All @@ -81,7 +82,7 @@ class VariantManagerTest {
fun insertCtaConceptTestVariantIsActiveAndHasConceptTestAndSuppressCtaFeatures() {
val variant = variants.firstOrNull { it.key == "mv" }
assertEqualsDouble(1.0, variant!!.weight)
assertEquals(3, variant!!.features.size)
assertEquals(3, variant.features.size)
assertTrue(variant.hasFeature(ConceptTest))
assertTrue(variant.hasFeature(SuppressWidgetCta))
assertTrue(variant.hasFeature(SuppressDefaultBrowserCta))
Expand All @@ -91,7 +92,7 @@ class VariantManagerTest {
fun insertCtaConceptTestWithAllCtaExperimentalVariantIsActiveAndHasConceptTestAndSuppressCtaFeatures() {
val variant = variants.firstOrNull { it.key == "mz" }
assertEqualsDouble(1.0, variant!!.weight)
assertEquals(2, variant!!.features.size)
assertEquals(2, variant.features.size)
assertTrue(variant.hasFeature(ConceptTest))
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
/*
* Copyright (c) 2020 DuckDuckGo
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

package com.duckduckgo.app.systemsearch

import android.content.Intent
import com.duckduckgo.app.systemsearch.DeviceAppLookupTest.AppName.DDG_MOVIES
import com.duckduckgo.app.systemsearch.DeviceAppLookupTest.AppName.DDG_MUSIC
import com.duckduckgo.app.systemsearch.DeviceAppLookupTest.AppName.FILES
import com.duckduckgo.app.systemsearch.DeviceAppLookupTest.AppName.LIVE_DDG
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.whenever
import org.junit.Assert.assertEquals
import org.junit.Assert.assertTrue
import org.junit.Test

class DeviceAppLookupTest {

private val mockAppProvider: DeviceAppListProvider = mock()

private val testee = InstalledDeviceAppLookup(mockAppProvider)

@Test
fun whenQueryMatchesWordInShortNameThenMatchesAreReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("DDG")
assertEquals(3, result.size)
assertEquals(DDG_MOVIES, result[0].shortName)
assertEquals(DDG_MUSIC, result[1].shortName)
assertEquals(LIVE_DDG, result[2].shortName)
}

@Test
fun whenQueryMatchesWordPrefixInShortNameThenMatchesAreReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("DDG")
assertEquals(3, result.size)
assertEquals(DDG_MOVIES, result[0].shortName)
assertEquals(DDG_MUSIC, result[1].shortName)
assertEquals(LIVE_DDG, result[2].shortName)
}

@Test
fun whenQueryMatchesPastShortNameWordBoundaryToNextPrefixThenMatchesAreReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("DDG M")
assertEquals(2, result.size)
assertEquals(DDG_MOVIES, result[0].shortName)
assertEquals(DDG_MUSIC, result[1].shortName)
}

@Test
fun whenQueryMatchesWordPrefixInShortNameWithDifferentCaseThenMatchesAreReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("ddg")
assertEquals(3, result.size)
assertEquals(DDG_MOVIES, result[0].shortName)
assertEquals(DDG_MUSIC, result[1].shortName)
assertEquals(LIVE_DDG, result[2].shortName)
}

@Test
fun whenQueryMatchesMiddleOrSuffixOfAppNameWordThenNoAppsReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("DG")
assertTrue(result.isEmpty())
}

@Test
fun whenQueryDoesNotMatchAnyPartOfAppNameThenNoAppsReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("nonmatching")
assertTrue(result.isEmpty())
}

@Test
fun whenQueryIsEmptyThenNoAppsReturned() {
whenever(mockAppProvider.get()).thenReturn(apps)
val result = testee.query("")
assertTrue(result.isEmpty())
}

@Test
fun whenAppsListIsEmptyThenNoAppsReturned() {
whenever(mockAppProvider.get()).thenReturn(noApps)
val result = testee.query("DDG")
assertTrue(result.isEmpty())
}

object AppName {
const val DDG_MOVIES = "DDG Movies"
const val DDG_MUSIC = "DDG Music"
const val LIVE_DDG = "Live DDG"
const val FILES = "Files"
}

companion object {
val noApps = emptyList<DeviceApp>()

val apps = listOf(
DeviceApp(DDG_MOVIES, "", Intent()),
DeviceApp(DDG_MUSIC, "", Intent()),
DeviceApp(FILES, "", Intent()),
DeviceApp(LIVE_DDG, "", Intent())
)
}
}
Loading