Skip to content

Commit cc20d56

Browse files
committed
Merge branch 'release/5.93.0' into main
2 parents 1075f22 + 234c83d commit cc20d56

File tree

147 files changed

+5485
-487
lines changed

Some content is hidden

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

147 files changed

+5485
-487
lines changed

.githooks/pre-commit

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
./gradlew spotlessApply
2+
git add `git diff --name-only`
3+
exit 0

app/src/androidTest/java/com/duckduckgo/app/bookmarks/model/FavoritesDataRepositoryTest.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -139,6 +139,14 @@ class FavoritesDataRepositoryTest {
139139
verify(mockFaviconManager).deletePersistedFavicon(favorite.url)
140140
}
141141

142+
@Test
143+
fun whenUserHasFavoritesThenReturnTrue() = coroutineRule.runBlocking {
144+
val favorite = Favorite(1, "Favorite", "http://favexample.com", 1)
145+
givenFavorite(favorite)
146+
147+
assertTrue(repository.userHasFavorites())
148+
}
149+
142150
private fun givenFavorite(vararg favorite: Favorite) {
143151
favorite.forEach {
144152
favoritesDao.insert(FavoriteEntity(it.id, it.title, it.url, it.position))

app/src/androidTest/java/com/duckduckgo/app/bookmarks/ui/BookmarksViewModelTest.kt

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,9 @@ import com.duckduckgo.app.bookmarks.model.FavoritesRepository
2727
import com.duckduckgo.app.bookmarks.model.SavedSite
2828
import com.duckduckgo.app.bookmarks.service.SavedSitesManager
2929
import com.duckduckgo.app.browser.favicon.FaviconManager
30+
import com.duckduckgo.app.pixels.AppPixelName
3031
import com.duckduckgo.app.runBlocking
32+
import com.duckduckgo.app.statistics.pixels.Pixel
3133
import com.nhaarman.mockitokotlin2.mock
3234
import com.nhaarman.mockitokotlin2.verify
3335
import com.nhaarman.mockitokotlin2.whenever
@@ -65,13 +67,14 @@ class BookmarksViewModelTest {
6567
private val favoritesRepository: FavoritesRepository = mock()
6668
private val faviconManager: FaviconManager = mock()
6769
private val savedSitesManager: SavedSitesManager = mock()
70+
private val pixel: Pixel = mock()
6871

6972
private val bookmark = SavedSite.Bookmark(id = 0, title = "title", url = "www.example.com")
7073
private val favorite = SavedSite.Favorite(id = 0, title = "title", url = "www.example.com", position = 0)
7174
private val bookmarkEntity = BookmarkEntity(id = bookmark.id, title = bookmark.title, url = bookmark.url)
7275

7376
private val testee: BookmarksViewModel by lazy {
74-
val model = BookmarksViewModel(favoritesRepository, bookmarksDao, faviconManager, savedSitesManager, coroutineRule.testDispatcherProvider)
77+
val model = BookmarksViewModel(favoritesRepository, bookmarksDao, faviconManager, savedSitesManager, pixel, coroutineRule.testDispatcherProvider)
7578
model.viewState.observeForever(viewStateObserver)
7679
model.command.observeForever(commandObserver)
7780
model
@@ -142,6 +145,13 @@ class BookmarksViewModelTest {
142145
assertTrue(captor.value is BookmarksViewModel.Command.OpenSavedSite)
143146
}
144147

148+
@Test
149+
fun whenFavoriteSelectedThenPixelSent() {
150+
testee.onSelected(favorite)
151+
152+
verify(pixel).fire(AppPixelName.FAVORITE_BOOKMARKS_ITEM_PRESSED)
153+
}
154+
145155
@Test
146156
fun whenDeleteRequestedThenConfirmCommand() {
147157
testee.onDeleteSavedSiteRequested(bookmark)

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

Lines changed: 61 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ import com.duckduckgo.app.bookmarks.model.SavedSite
4444
import com.duckduckgo.app.bookmarks.model.SavedSite.Favorite
4545
import com.duckduckgo.app.browser.BrowserTabViewModel.Command
4646
import com.duckduckgo.app.browser.BrowserTabViewModel.Command.Navigate
47-
import com.duckduckgo.app.browser.BrowserTabViewModel.FireButton
47+
import com.duckduckgo.app.browser.BrowserTabViewModel.HighlightableButton
4848
import com.duckduckgo.app.browser.LongPressHandler.RequiredAction.DownloadFile
4949
import com.duckduckgo.app.browser.LongPressHandler.RequiredAction.OpenInNewTab
5050
import com.duckduckgo.app.browser.addtohome.AddToHomeCapabilityDetector
@@ -382,7 +382,7 @@ class BrowserTabViewModelTest {
382382
temporaryTrackingWhitelistDao = mockTemporaryTrackingWhitelistDao
383383
)
384384

385-
testee.loadData("abc", null, false)
385+
testee.loadData("abc", null, false, false)
386386
testee.command.observeForever(mockCommandObserver)
387387
}
388388

@@ -504,21 +504,21 @@ class BrowserTabViewModelTest {
504504
fun whenBrowsingAndUrlPresentThenAddBookmarkFavoriteButtonsEnabled() {
505505
loadUrl("www.example.com", isBrowserShowing = true)
506506
assertTrue(browserViewState().canAddBookmarks)
507-
assertTrue(browserViewState().canAddFavorite)
507+
assertTrue(browserViewState().addFavorite.isEnabled())
508508
}
509509

510510
@Test
511511
fun whenBrowsingAndNoUrlThenAddBookmarkFavoriteButtonsDisabled() {
512512
loadUrl(null, isBrowserShowing = true)
513513
assertFalse(browserViewState().canAddBookmarks)
514-
assertFalse(browserViewState().canAddFavorite)
514+
assertFalse(browserViewState().addFavorite.isEnabled())
515515
}
516516

517517
@Test
518518
fun whenNotBrowsingAndUrlPresentThenAddBookmarkFavoriteButtonsDisabled() {
519519
loadUrl("www.example.com", isBrowserShowing = false)
520520
assertFalse(browserViewState().canAddBookmarks)
521-
assertFalse(browserViewState().canAddFavorite)
521+
assertFalse(browserViewState().addFavorite.isEnabled())
522522
}
523523

524524
@Test
@@ -973,31 +973,31 @@ class BrowserTabViewModelTest {
973973

974974
@Test
975975
fun whenInitialisedThenFireButtonIsShown() {
976-
assertTrue(browserViewState().fireButton is FireButton.Visible)
976+
assertTrue(browserViewState().fireButton is HighlightableButton.Visible)
977977
}
978978

979979
@Test
980980
fun whenOmnibarInputDoesNotHaveFocusAndHasQueryThenFireButtonIsShown() {
981981
testee.onOmnibarInputStateChanged("query", false, hasQueryChanged = false)
982-
assertTrue(browserViewState().fireButton is FireButton.Visible)
982+
assertTrue(browserViewState().fireButton is HighlightableButton.Visible)
983983
}
984984

985985
@Test
986986
fun whenOmnibarInputDoesNotHaveFocusOrQueryThenFireButtonIsShown() {
987987
testee.onOmnibarInputStateChanged("", false, hasQueryChanged = false)
988-
assertTrue(browserViewState().fireButton is FireButton.Visible)
988+
assertTrue(browserViewState().fireButton is HighlightableButton.Visible)
989989
}
990990

991991
@Test
992992
fun whenOmnibarInputHasFocusAndNoQueryThenFireButtonIsShown() {
993993
testee.onOmnibarInputStateChanged("", true, hasQueryChanged = false)
994-
assertTrue(browserViewState().fireButton is FireButton.Visible)
994+
assertTrue(browserViewState().fireButton is HighlightableButton.Visible)
995995
}
996996

997997
@Test
998998
fun whenOmnibarInputHasFocusAndQueryThenFireButtonIsHidden() {
999999
testee.onOmnibarInputStateChanged("query", true, hasQueryChanged = false)
1000-
assertTrue(browserViewState().fireButton is FireButton.Gone)
1000+
assertTrue(browserViewState().fireButton is HighlightableButton.Gone)
10011001
}
10021002

10031003
@Test
@@ -1031,31 +1031,31 @@ class BrowserTabViewModelTest {
10311031

10321032
@Test
10331033
fun whenInitialisedThenMenuButtonIsShown() {
1034-
assertTrue(browserViewState().showMenuButton)
1034+
assertTrue(browserViewState().showMenuButton.isEnabled())
10351035
}
10361036

10371037
@Test
10381038
fun whenOmnibarInputDoesNotHaveFocusOrQueryThenMenuButtonIsShown() {
10391039
testee.onOmnibarInputStateChanged("", false, hasQueryChanged = false)
1040-
assertTrue(browserViewState().showMenuButton)
1040+
assertTrue(browserViewState().showMenuButton.isEnabled())
10411041
}
10421042

10431043
@Test
10441044
fun whenOmnibarInputDoesNotHaveFocusAndHasQueryThenMenuButtonIsShown() {
10451045
testee.onOmnibarInputStateChanged("query", false, hasQueryChanged = false)
1046-
assertTrue(browserViewState().showMenuButton)
1046+
assertTrue(browserViewState().showMenuButton.isEnabled())
10471047
}
10481048

10491049
@Test
10501050
fun whenOmnibarInputHasFocusAndNoQueryThenMenuButtonIsShown() {
10511051
testee.onOmnibarInputStateChanged("", true, hasQueryChanged = false)
1052-
assertTrue(browserViewState().showMenuButton)
1052+
assertTrue(browserViewState().showMenuButton.isEnabled())
10531053
}
10541054

10551055
@Test
10561056
fun whenOmnibarInputHasFocusAndQueryThenMenuButtonIsHidden() {
10571057
testee.onOmnibarInputStateChanged("query", true, hasQueryChanged = false)
1058-
assertFalse(browserViewState().showMenuButton)
1058+
assertFalse(browserViewState().showMenuButton.isEnabled())
10591059
}
10601060

10611061
@Test
@@ -1569,25 +1569,64 @@ class BrowserTabViewModelTest {
15691569

15701570
@Test
15711571
fun whenUrlNullThenSetBrowserNotShowing() = coroutineRule.runBlocking {
1572-
testee.loadData("id", null, false)
1572+
testee.loadData("id", null, false, false)
15731573
testee.determineShowBrowser()
15741574
assertEquals(false, testee.browserViewState.value?.browserShowing)
15751575
}
15761576

15771577
@Test
15781578
fun whenUrlBlankThenSetBrowserNotShowing() = coroutineRule.runBlocking {
1579-
testee.loadData("id", " ", false)
1579+
testee.loadData("id", " ", false, false)
15801580
testee.determineShowBrowser()
15811581
assertEquals(false, testee.browserViewState.value?.browserShowing)
15821582
}
15831583

15841584
@Test
15851585
fun whenUrlPresentThenSetBrowserShowing() = coroutineRule.runBlocking {
1586-
testee.loadData("id", "https://example.com", false)
1586+
testee.loadData("id", "https://example.com", false, false)
15871587
testee.determineShowBrowser()
15881588
assertEquals(true, testee.browserViewState.value?.browserShowing)
15891589
}
15901590

1591+
@Test
1592+
fun whenFavoritesOnboardingAndSiteLoadedThenHighglightMenuButton() = coroutineRule.runBlocking {
1593+
testee.loadData("id", "https://example.com", false, true)
1594+
testee.determineShowBrowser()
1595+
assertEquals(true, testee.browserViewState.value?.showMenuButton?.isHighlighted())
1596+
}
1597+
1598+
@Test
1599+
fun whenFavoritesOnboardingAndUserOpensOptionsMenuThenHighglightAddFavoriteOption() = coroutineRule.runBlocking {
1600+
testee.loadData("id", "https://example.com", false, true)
1601+
testee.determineShowBrowser()
1602+
1603+
testee.onBrowserMenuClicked()
1604+
1605+
assertEquals(true, testee.browserViewState.value?.addFavorite?.isHighlighted())
1606+
}
1607+
1608+
@Test
1609+
fun whenFavoritesOnboardingAndUserClosesOptionsMenuThenMenuButtonNotHighlighted() = coroutineRule.runBlocking {
1610+
testee.loadData("id", "https://example.com", false, true)
1611+
testee.determineShowBrowser()
1612+
1613+
testee.onBrowserMenuClosed()
1614+
1615+
assertEquals(false, testee.browserViewState.value?.addFavorite?.isHighlighted())
1616+
}
1617+
1618+
@Test
1619+
fun whenFavoritesOnboardingAndUserClosesOptionsMenuThenLoadingNewSiteDoesNotHighlightMenuOption() = coroutineRule.runBlocking {
1620+
testee.loadData("id", "https://example.com", false, true)
1621+
testee.determineShowBrowser()
1622+
testee.onBrowserMenuClicked()
1623+
testee.onBrowserMenuClosed()
1624+
1625+
testee.determineShowBrowser()
1626+
1627+
assertEquals(false, testee.browserViewState.value?.addFavorite?.isHighlighted())
1628+
}
1629+
15911630
@Test
15921631
fun whenRecoveringFromProcessGoneThenShowErrorWithAction() {
15931632
testee.recoverFromRenderProcessGone()
@@ -2231,7 +2270,7 @@ class BrowserTabViewModelTest {
22312270
setupNavigation(skipHome = false, isBrowsing = true, canGoBack = false)
22322271
assertTrue(testee.onUserPressedBack())
22332272
assertFalse(browserViewState().canAddBookmarks)
2234-
assertFalse(browserViewState().canAddFavorite)
2273+
assertFalse(browserViewState().addFavorite.isEnabled())
22352274
}
22362275

22372276
@Test
@@ -2289,7 +2328,7 @@ class BrowserTabViewModelTest {
22892328
testee.onUserPressedBack()
22902329
testee.onUserPressedForward()
22912330
assertTrue(browserViewState().canAddBookmarks)
2292-
assertTrue(browserViewState().canAddFavorite)
2331+
assertTrue(browserViewState().addFavorite.isEnabled())
22932332
}
22942333

22952334
@Test
@@ -3345,7 +3384,7 @@ class BrowserTabViewModelTest {
33453384

33463385
private fun givenOneActiveTabSelected() {
33473386
selectedTabLiveData.value = TabEntity("TAB_ID", "https://example.com", "", skipHome = false, viewed = true, position = 0)
3348-
testee.loadData("TAB_ID", "https://example.com", false)
3387+
testee.loadData("TAB_ID", "https://example.com", false, false)
33493388
}
33503389

33513390
private fun givenFireproofWebsiteDomain(vararg fireproofWebsitesDomain: String) {
@@ -3363,7 +3402,7 @@ class BrowserTabViewModelTest {
33633402
val siteLiveData = MutableLiveData<Site>()
33643403
siteLiveData.value = site
33653404
whenever(mockTabRepository.retrieveSiteData("TAB_ID")).thenReturn(siteLiveData)
3366-
testee.loadData("TAB_ID", domain, false)
3405+
testee.loadData("TAB_ID", domain, false, false)
33673406
}
33683407

33693408
private fun setBrowserShowing(isBrowsing: Boolean) {

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

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,22 @@ class BrowserViewModelTest {
208208
verify(mockPixel).fire(AppPixelName.SHORTCUT_OPENED)
209209
}
210210

211+
@Test
212+
fun whenOpenFavoriteThenSelectByUrlOrNewTab() = coroutinesTestRule.runBlocking {
213+
val url = "example.com"
214+
whenever(mockOmnibarEntryConverter.convertQueryToUrl(url)).thenReturn(url)
215+
testee.onOpenFavoriteFromWidget(url)
216+
verify(mockTabRepository).selectByUrlOrNewTab(url)
217+
}
218+
219+
@Test
220+
fun whenOpenFavoriteFromWidgetThenFirePixel() = coroutinesTestRule.runBlocking {
221+
val url = "example.com"
222+
whenever(mockOmnibarEntryConverter.convertQueryToUrl(url)).thenReturn(url)
223+
testee.onOpenFavoriteFromWidget(url)
224+
verify(mockPixel).fire(AppPixelName.APP_FAVORITES_ITEM_WIDGET_LAUNCH)
225+
}
226+
211227
companion object {
212228
const val TAB_ID = "TAB_ID"
213229
}

app/src/androidTest/java/com/duckduckgo/app/cta/ui/CtaViewModelTest.kt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,12 @@ class CtaViewModelTest {
490490
assertNull(value)
491491
}
492492

493+
@Test
494+
fun whenRefreshCtaInHomeTabDuringFavoriteOnboardingThenReturnNull() = runBlockingTest {
495+
val value = testee.refreshCta(coroutineRule.testDispatcher, isBrowserShowing = false, favoritesOnboarding = true)
496+
assertTrue(value is BubbleCta.DaxFavoritesOnboardingCta)
497+
}
498+
493499
@Test
494500
fun whenUserHidesAllTipsThenFireButtonAnimationShouldNotShow() = coroutineRule.runBlocking {
495501
givenOnboardingActive()
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright (c) 2021 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.api
18+
19+
import com.duckduckgo.app.pixels.AppPixelName
20+
import org.junit.Assert.assertEquals
21+
import org.junit.Before
22+
import org.junit.Test
23+
24+
class PixelAtbRemovalInterceptorTest {
25+
private lateinit var pixelAtbRemovalInterceptor: PixelAtbRemovalInterceptor
26+
27+
@Before
28+
fun setup() {
29+
pixelAtbRemovalInterceptor = PixelAtbRemovalInterceptor()
30+
}
31+
32+
@Test
33+
fun whenSendPixelTheRedactAtvInfoFromDefinedPixels() {
34+
AppPixelName.values().map { it.pixelName }.forEach { pixelName ->
35+
val pixelUrl = String.format(PIXEL_TEMPLATE, pixelName)
36+
val removalExpected = PixelAtbRemovalInterceptor.pixels.contains(pixelName)
37+
38+
val interceptedUrl = pixelAtbRemovalInterceptor.intercept(FakeChain(pixelUrl)).request.url
39+
assertEquals(removalExpected, interceptedUrl.queryParameter("atb") == null)
40+
}
41+
}
42+
43+
companion object {
44+
private const val PIXEL_TEMPLATE = "https://improving.duckduckgo.com/t/%s_android_phone?atb=v255-7zu&appVersion=5.74.0&test=1"
45+
}
46+
47+
}

app/src/androidTest/java/com/duckduckgo/app/statistics/VariantManagerTest.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,20 @@ class VariantManagerTest {
4242
assertEquals(0, variant.features.size)
4343
}
4444

45+
@Test
46+
fun serpGxControlVariantHasExpectedWeightAndNoFeatures() {
47+
val variant = variants.first { it.key == "gx" }
48+
assertEqualsDouble(0.1, variant.weight)
49+
assertEquals(0, variant.features.size)
50+
}
51+
52+
@Test
53+
fun serpGyExperimentalVariantHasExpectedWeightAndNoFeatures() {
54+
val variant = variants.first { it.key == "gy" }
55+
assertEqualsDouble(0.1, variant.weight)
56+
assertEquals(0, variant.features.size)
57+
}
58+
4559
@Test
4660
fun verifyNoDuplicateVariantNames() {
4761
val existingNames = mutableSetOf<String>()

0 commit comments

Comments
 (0)