10000 Encourage users to add widget to home screen (#416) · rzoro/Android@f45e523 · GitHub
[go: up one dir, main page]

Skip to content

Commit f45e523

Browse files
authored
Encourage users to add widget to home screen (duckduckgo#416)
* Make cta layout generic and support multiple CTAs and pixels * Update cta to new design * Add cta landscape support * Add widget instructions page
1 parent d3a6962 commit f45e523

File tree

62 files changed

+10424
-288
lines changed

Some content is hidden

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

62 files changed

+10424
-288
lines changed

app/schemas/com.duckduckgo.app.global.db.AppDatabase/8.json

Lines changed: 399 additions & 0 deletions
Large diffs are not rendered by default.

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

Lines changed: 36 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,9 @@ import com.duckduckgo.app.browser.addToHome.AddToHomeCapabilityDetector
3636
import com.duckduckgo.app.browser.favicon.FaviconDownloader
3737
import com.duckduckgo.app.browser.omnibar.OmnibarEntryConverter
3838
import com.duckduckgo.app.browser.session.WebViewSessionStorage
39+
import com.duckduckgo.app.cta.db.DismissedCtaDao
40+
import com.duckduckgo.app.cta.ui.CtaViewModel
3941
import com.duckduckgo.app.feedback.db.SurveyDao
40-
import com.duckduckgo.app.feedback.model.Survey
41-
import com.duckduckgo.app.feedback.model.Survey.Status.SCHEDULED
4242
import com.duckduckgo.app.global.db.AppConfigurationDao
4343
import com.duckduckgo.app.global.db.AppConfigurationEntity
4444
import com.duckduckgo.app.global.db.AppDatabase
@@ -50,11 +50,14 @@ import com.duckduckgo.app.privacy.db.SiteVisitedEntity
5050
import com.duckduckgo.app.privacy.model.PrivacyPractices
5151
import com.duckduckgo.app.privacy.store.PrevalenceStore
5252
import com.duckduckgo.app.settings.db.SettingsDataStore
53+
import com.duckduckgo.app.statistics.VariantManager
5354
import com.duckduckgo.app.statistics.api.StatisticsUpdater
55+
import com.duckduckgo.app.statistics.pixels.Pixel
5456
import com.duckduckgo.app.tabs.model.TabRepository
5557
import com.duckduckgo.app.trackerdetection.model.TrackerNetwork
5658
import com.duckduckgo.app.trackerdetection.model.TrackerNetworks
5759
import com.duckduckgo.app.trackerdetection.model.TrackingEvent
60+
import com.duckduckgo.app.widget.ui.WidgetCapabilities
5861
import com.nhaarman.mockitokotlin2.*
5962
import org.junit.After
6063
import org.junit.Assert.*
@@ -126,11 +129,25 @@ class BrowserTabViewModelTest {
126129
private lateinit var mockAddToHomeCapabilityDetector: AddToHomeCapabilityDetector
127130

128131
@Mock
129-
private lateinit var surveyDao: SurveyDao
132+
private lateinit var mockSurveyDao: SurveyDao
133+
134+
@Mock
135+
private lateinit var mockDismissedCtaDao: DismissedCtaDao
130136

131137
@Mock
132138
private lateinit var mockAppInstallStore: AppInstallStore
133139

140+
@Mock
141+
private lateinit var mockPixel: Pixel
142+
143+
@Mock
144+
private lateinit var mockVariantManager: VariantManager
145+
146+
@Mock
147+
private lateinit var mockWidgetCapabilities: WidgetCapabilities
148+
149+
private lateinit var ctaViewModel: CtaViewModel
150+
134151
@Captor
135152
private lateinit var commandCaptor: ArgumentCaptor<Command>
136153

@@ -147,13 +164,24 @@ class BrowserTabViewModelTest {
147164
db = Room.inMemoryDatabaseBuilder(getInstrumentation().targetContext, AppDatabase::class.java)
148165
.allowMainThreadQueries()
149166
.build()
167+
150168
appConfigurationDao = db.appConfigurationDao()
151169

170+
ctaViewModel = CtaViewModel(
171+
mockAppInstallStore,
172+
mockPixel,
173+
mockSurveyDao,
174+
mockWidgetCapabilities,
175+
mockDismissedCtaDao,
176+
mockVariantManager
177+
)
178+
152179
val siteFactory = SiteFactory(mockPrivacyPractices, mockTrackerNetworks, prevalenceStore = mockPrevalenceStore)
153180

154181
whenever(mockTabsRepository.retrieveSiteData(any())).thenReturn(MutableLiveData())
155182
whenever(mockPrivacyPractices.privacyPracticesFor(any())).thenReturn(PrivacyPractices.UNKNOWN)
156183
whenever(mockAppInstallStore.installTimestamp).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1))
184+
whenever(mockVariantManager.getVariant(any())).thenReturn(VariantManager.DEFAULT_VARIANT)
157185

158186
testee = BrowserTabViewModel(
159187
statisticsUpdater = mockStatisticsUpdater,
@@ -162,17 +190,16 @@ class BrowserTabViewModelTest {
162190
siteFactory = siteFactory,
163191
tabRepository = mockTabsRepository,
164192
networkLeaderboardDao = mockNetworkLeaderboardDao,
165-
bookmarksDao = bookmarksDao,
166193
autoCompleteApi = mockAutoCompleteApi,
167194
appSettingsPreferencesStore = mockSettingsStore,
195+
bookmarksDao = bookmarksDao,
168196
longPressHandler = mockLongPressHandler,
197+
appConfigurationDao = appConfigurationDao,
169198
webViewSessionStorage = webViewSessionStorage,
170199
specialUrlDetector = SpecialUrlDetectorImpl(),
171200
faviconDownloader = mockFaviconDownloader,
172201
addToHomeCapabilityDetector = mockAddToHomeCapabilityDetector,
173-
appConfigurationDao = appConfigurationDao,
174-
surveyDao = surveyDao,
175-
appInstallStore = mockAppInstallStore
202+
ctaViewModel = ctaViewModel
176203
)
177204

178205
testee.loadData("abc", null)
@@ -228,15 +255,15 @@ class BrowserTabViewModelTest {
228255
testee.url.value = "http://exmaple.com"
229256
testee.onViewVisible()
230257
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
231-
assertTrue(commandCaptor.lastValue is Command.HideKeyboard)
258+
assertTrue(commandCaptor.allValues.contains(Command.HideKeyboard))
232259
}
233260

234261
@Test
235262
fun whenViewBecomesVisibleWithoutActiveSiteThenKeyboardShown() {
236263
testee.url.value = null
237264
testee.onViewVisible()
238265
verify(mockCommandObserver, atLeastOnce()).onChanged(commandCaptor.capture())
239-
assertTrue(commandCaptor.lastValue is Command.ShowKeyboard)
266+
assertTrue(commandCaptor.allValues.contains(Command.ShowKeyboard))
240267
}
241268

242269
@Test
@@ -741,39 +768,6 @@ class BrowserTabViewModelTest {
741768
assertNull(command.url)
742769
}
743770

744-
@Test
745-
fun whenScheduledSurveyChangesAndNewSurveyInstallationDayMatchesDaysInstalledThenHasValidSurveyIsTrue() {
746-
testee.onSurveyChanged(Survey("abc", "http://example.com", 1, SCHEDULED))
747-
assertTrue(testee.surveyViewState.value!!.hasValidSurvey)
748-
}
749-
750-
@Test
751-
fun whenScheduledSurveyChangesAndNewSurveyInstallationDoesNotMatchDaysInstalledThenHasValidSurveyIsFalse() {
752-
testee.onSurveyChanged(Survey("abc", "http://example.com", 2, SCHEDULED))
753-
assertFalse(testee.surveyViewState.value!!.hasValidSurvey)
754-
}
755-
756-
@Test
757-
fun whenScheduledSurveyIsNullThenHasValidSurveyIsFalse() {
758-
testee.onSurveyChanged(null)
759-
assertFalse(testee.surveyViewState.value!!.hasValidSurvey)
760-
}
761-
762-
@Test
763-
fun whenSurveyExistsAndUserOpensSurveyThenSurveyShown() {
764-
testee.onSurveyChanged(Survey("abc", "http://example.com", 1, SCHEDULED))
765-
testee.onUserOpenedSurvey()
766-
val command = captureCommands().value as Command.LaunchSurvey
767-
assertNotNull(command)
768-
}
769-
770-
@Test
771-
fun whenUserDismissesSurveyThenSurveyCancelledAndHasValidSurveyIsFalse() {
772-
testee.onUserDismissedSurvey()
773-
assertFalse(testee.surveyViewState.value!!.hasValidSurvey)
774-
verify(surveyDao).cancelScheduledSurveys()
775-
}
776-
777771
@Test
778772
fun whenUserSelectsToShareLinkWithNullUrlThenShareLinkCommandNotSent() {
779773
testee.userSharingLink(null)
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* Copyright (c) 2019 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.cta.db
18+
19+
import androidx.room.Room
20+
import androidx.test.platform.app.InstrumentationRegistry
21+
import com.duckduckgo.app.cta.model.CtaId
22+
import com.duckduckgo.app.cta.model.DismissedCta
23+
import com.duckduckgo.app.global.db.AppDatabase
24+
import org.junit.Assert.assertFalse
25+
import org.junit.Assert.assertTrue
26+
import org.junit.Before
27+
import org.junit.Test
28+
29+
class DismissedCtaDaoTest {
30+
31+
private lateinit var db: AppDatabase
32+
private lateinit var dao: DismissedCtaDao
33+
34+
@Before
35+
fun before() {
36+
db = Room.inMemoryDatabaseBuilder(InstrumentationRegistry.getInstrumentation().targetContext, AppDatabase::class.java).build()
37+
dao = db.dismissedCtaDao()
38+
}
39+
40+
@Test
41+
fun whenCtaNotInsertedThenEntryDoesNotExist() {
42+
assertFalse(dao.exists(CtaId.ADD_WIDGET))
43+
}
44+
45+
@Test
46+
fun whenInsertedThenEntryExists() {
47+
dao.insert(DismissedCta(CtaId.ADD_WIDGET))
48+
assertTrue(dao.exists(CtaId.ADD_WIDGET))
49+
}
50+
}

0 commit comments

Comments
 (0)
0