Skip to content

Commit 4b800c7

Browse files
committed
Merge branch 'release/4.3.0'
2 parents b6aa866 + f6cd551 commit 4b800c7

Some content is hidden

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

52 files changed

+1006
-293
lines changed

app/build.gradle

Lines changed: 1 addition & 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 = "4.2.0"
9+
VERSION_NAME = "4.3.0"
1010
}
1111

1212
android {
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
* Copyright (c) 2018 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.browser
18+
19+
import android.support.test.InstrumentationRegistry
20+
import android.view.View
21+
import android.webkit.WebChromeClient
22+
import com.nhaarman.mockito_kotlin.mock
23+
import com.nhaarman.mockito_kotlin.times
24+
import com.nhaarman.mockito_kotlin.verify
25+
import org.junit.Before
26+
import org.junit.Test
27+
28+
class BrowserChromeClientTest {
29+
30+
private lateinit var testee: BrowserChromeClient
31+
private lateinit var mockWebViewClientListener: WebViewClientListener
32+
private val fakeView = View(InstrumentationRegistry.getTargetContext())
33+
34+
@Before
35+
fun setup() {
36+
testee = BrowserChromeClient()
37+
mockWebViewClientListener = mock()
38+
testee.webViewClientListener = mockWebViewClientListener
39+
}
40+
41+
@Test
42+
fun whenCustomViewShownForFirstTimeListenerInstructedToGoFullScreen() {
43+
testee.onShowCustomView(fakeView, null)
44+
verify(mockWebViewClientListener).goFullScreen(fakeView)
45+
}
46+
47+
@Test
48+
fun whenCustomViewShownMultipleTimesListenerInstructedToGoFullScreenOnlyOnce() {
49+
testee.onShowCustomView(fakeView, null)
50+
testee.onShowCustomView(fakeView, null)
51+
testee.onShowCustomView(fakeView, null)
52+
verify(mockWebViewClientListener, times(1)).goFullScreen(fakeView)
53+
}
54+
55+
@Test
56+
fun whenCustomViewShownMultipleTimesCallbackInstructedToHideForAllButTheFirstCall() {
57+
val mockCustomViewCallback: WebChromeClient.CustomViewCallback = mock()
58+
testee.onShowCustomView(fakeView, mockCustomViewCallback)
59+
testee.onShowCustomView(fakeView, mockCustomViewCallback)
60+
testee.onShowCustomView(fakeView, mockCustomViewCallback)
61+
verify(mockCustomViewCallback, times(2)).onCustomViewHidden()
62+
}
63+
64+
@Test
65+
fun whenHideCustomViewCalledThenListenerInstructedToExistFullScreen() {
66+
testee.onHideCustomView()
67+
verify(mockWebViewClientListener).exitFullScreen()
68+
}
69+
}

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

Lines changed: 58 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import android.arch.lifecycle.Observer
2323
import android.arch.persistence.room.Room
2424
import android.net.Uri
2525
import android.support.test.InstrumentationRegistry
26+
import android.view.MenuItem
27+
import android.view.View
2628
import com.duckduckgo.app.autocomplete.api.AutoCompleteApi
2729
import com.duckduckgo.app.bookmarks.db.BookmarkEntity
2830
import com.duckduckgo.app.bookmarks.db.BookmarksDao
@@ -50,7 +52,7 @@ import org.junit.Before
5052
import org.junit.Rule
5153
import org.junit.Test
5254
import org.mockito.*
53-
import org.mockito.ArgumentCaptor.forClass
55+
import org.mockito.ArgumentMatchers.anyString
5456
import org.mockito.Mockito.never
5557
import org.mockito.Mockito.verify
5658

@@ -90,11 +92,18 @@ class BrowserViewModelTest {
9092
@Mock
9193
private lateinit var bookmarksDao: BookmarksDao
9294

95+
@Mock
96+
private lateinit var mockLongPressHandler: LongPressHandler
97+
98+
@Mock
99+
private lateinit var mockOmnibarConverter: OmnibarEntryConverter
100+
101+
@Captor
102+
private lateinit var commandCaptor: ArgumentCaptor<Command>
103+
93104
private lateinit var db: AppDatabase
94105
private lateinit var appConfigurationDao: AppConfigurationDao
95106

96-
private val mockOmnibarConverter: OmnibarEntryConverter = mock()
97-
98107
private lateinit var testee: BrowserViewModel
99108

100109
@Before
@@ -116,6 +125,7 @@ class BrowserViewModelTest {
116125
autoCompleteApi = mockAutoCompleteApi,
117126
appSettingsPreferencesStore = mockSettingsStore,
118127
bookmarksDao = bookmarksDao,
128+
longPressHandler = mockLongPressHandler,
119129
appConfigurationDao = appConfigurationDao)
120130

121131
testee.url.observeForever(mockQueryObserver)
@@ -240,10 +250,9 @@ class BrowserViewModelTest {
240250
@Test
241251
fun whenSharedTextReceivedThenNavigationTriggered() {
242252
testee.onSharedTextReceived("http://example.com")
243-
val captor: ArgumentCaptor<Command> = forClass(Command::class.java)
244-
verify(mockCommandObserver, times(2)).onChanged(captor.capture())
245-
assertNotNull(captor.value)
246-
assertTrue(captor.value is Navigate)
253+
verify(mockCommandObserver, times(2)).onChanged(commandCaptor.capture())
254+
assertNotNull(commandCaptor.value)
255+
assertTrue(commandCaptor.value is Navigate)
247256
}
248257

249258
@Test
@@ -394,9 +403,48 @@ class BrowserViewModelTest {
394403

395404
@Test
396405
fun whenEnteringNonEmptyQueryThenHideKeyboardCommandIssued() {
397-
val captor = ArgumentCaptor.forClass(BrowserViewModel.Command::class.java)
398406
testee.onUserSubmittedQuery("foo")
399-
verify(mockCommandObserver, Mockito.atLeastOnce()).onChanged(captor.capture())
400-
assertTrue(captor.value == Command.HideKeyboard)
407+
verify(mockCommandObserver, Mockito.atLeastOnce()).onChanged(commandCaptor.capture())
408+
assertTrue(commandCaptor.value == Command.HideKeyboard)
409+
}
410+
411+
@Test
412+
fun whenNotifiedEnteringFullScreenThenViewStateUpdatedWithFullScreenFlag() {
413+
val stubView = View(InstrumentationRegistry.getTargetContext())
414+
testee.goFullScreen(stubView)
415+
assertTrue(testee.viewState.value!!.isFullScreen)
416+
}
417+
418+
@Test
419+
fun whenNotifiedEnteringFullScreenThenEnterFullScreenCommandIssued() {
420+
val stubView = View(InstrumentationRegistry.getTargetContext())
421+
testee.goFullScreen(stubView)
422+
verify(mockCommandObserver, Mockito.atLeastOnce()).onChanged(commandCaptor.capture())
423+
assertTrue(commandCaptor.lastValue is Command.ShowFullScreen)
424+
}
425+
426+
@Test
427+
fun whenNotifiedLeavingFullScreenThenViewStateUpdatedWithFullScreenFlagDisabled() {
428+
testee.exitFullScreen()
429+
assertFalse(testee.viewState.value!!.isFullScreen)
430+
}
431+
432+
@Test
433+
fun whenViewModelInitialisedThenFullScreenFlagIsDisabled() {
434+
assertFalse(testee.viewState.value!!.isFullScreen)
435+
}
436+
437+
@Test
438+
fun whenUserSelectsDownloadImageOptionFromContextMenuThenDownloadFileCommandIssued() {
439+
whenever(mockLongPressHandler.userSelectedMenuItem(anyString(), any()))
440+
.thenReturn(LongPressHandler.RequiredAction.DownloadFile("example.com"))
441+
442+
val mockMenuItem : MenuItem = mock()
443+
testee.userSelectedItemFromLongPressMenu("example.com", mockMenuItem)
444+
verify(mockCommandObserver, Mockito.atLeastOnce()).onChanged(commandCaptor.capture())
445+
assertTrue(commandCaptor.lastValue is Command.DownloadImage)
446+
447+
val lastCommand = commandCaptor.lastValue as Command.DownloadImage
448+
assertEquals("example.com", lastCommand.url)
401449
}
402450
}
Lines changed: 107 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,107 @@
1+
/*
2+
* Copyright (c) 2018 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.browser
18+
19+
import android.view.ContextMenu
20+
import android.view.MenuItem
21+
import android.webkit.WebView.HitTestResult
22+
import com.nhaarman.mockito_kotlin.eq
23+
import com.nhaarman.mockito_kotlin.never
24+
import com.nhaarman.mockito_kotlin.verify
25+
import com.nhaarman.mockito_kotlin.whenever
26+
import org.junit.Assert.assertEquals
27+
import org.junit.Assert.assertTrue
28+
import org.junit.Before
29+
import org.junit.Test
30+
import org.mockito.ArgumentMatchers.anyInt
31+
import org.mockito.ArgumentMatchers.anyString
32+
import org.mockito.Mock
33+
import org.mockito.MockitoAnnotations
34+
35+
class WebViewLongPressHandlerTest {
36+
37+
private lateinit var testee: WebViewLongPressHandler
38+
39+
@Mock
40+
private lateinit var mockMenu: ContextMenu
41+
42+
@Mock
43+
private lateinit var mockMenuItem: MenuItem
44+
45+
@Before
46+
fun setup() {
47+
MockitoAnnotations.initMocks(this)
48+
testee = WebViewLongPressHandler()
49+
}
50+
51+
@Test
52+
fun whenLongPressedWithImageTypeThenImageOptionsHeaderAddedToMenu() {
53+
testee.handleLongPress(HitTestResult.IMAGE_TYPE, mockMenu)
54+
verify(mockMenu).setHeaderTitle(R.string.imageOptions)
55+
}
56+
57+
@Test
58+
fun whenLongPressedWithAnchorImageTypeThenImageOptionsHeaderAddedToMenu() {
59+
testee.handleLongPress(HitTestResult.SRC_IMAGE_ANCHOR_TYPE, mockMenu)
60+
verify(mockMenu).setHeaderTitle(R.string.imageOptions)
61+
}
62+
63+
@Test
64+
fun whenLongPressedWithImageTypeThenDownloadImageMenuAdded() {
65+
testee.handleLongPress(HitTestResult.IMAGE_TYPE, mockMenu)
66+
verify(mockMenu).add(anyInt(), eq(WebViewLongPressHandler.CONTEXT_MENU_ID_DOWNLOAD_IMAGE), anyInt(), eq(R.string.downloadImage))
67+
}
68+
69+
@Test
70+
fun whenLongPressedWithAnchorImageTypeThenDownloadImageMenuAdded() {
71+
testee.handleLongPress(HitTestResult.SRC_IMAGE_ANCHOR_TYPE, mockMenu)
72+
verify(mockMenu).add(anyInt(), eq(WebViewLongPressHandler.CONTEXT_MENU_ID_DOWNLOAD_IMAGE), anyInt(), eq(R.string.downloadImage))
73+
}
74+
75+
@Test
76+
fun whenLongPressedWithOtherImageTypeThenMenuNotAltered() {
77+
testee.handleLongPress(HitTestResult.UNKNOWN_TYPE, mockMenu)
78+
verify(mockMenu, never()).setHeaderTitle(anyString())
79+
verify(mockMenu, never()).setHeaderTitle(anyInt())
80+
verify(mockMenu, never()).add(anyInt())
81+
verify(mockMenu, never()).add(anyString())
82+
verify(mockMenu, never()).add(anyInt(), anyInt(), anyInt(), anyInt())
83+
verify(mockMenu, never()).add(anyInt(), anyInt(), anyInt(), anyString())
84+
}
85+
86+
@Test
87+
fun whenUserSelectedDownloadImageOptionThenActionIsDownloadFileActionRequired() {
88+
whenever(mockMenuItem.itemId).thenReturn(WebViewLongPressHandler.CONTEXT_MENU_ID_DOWNLOAD_IMAGE)
89+
val action = testee.userSelectedMenuItem("example.com", mockMenuItem)
90+
assertTrue(action is LongPressHandler.RequiredAction.DownloadFile)
91+
}
92+
93+
@Test
94+
fun whenUserSelectedDownloadImageOptionThenDownloadFileWithCorrectUrlReturned() {
95+
whenever(mockMenuItem.itemId).thenReturn(WebViewLongPressHandler.CONTEXT_MENU_ID_DOWNLOAD_IMAGE)
96+
val action = testee.userSelectedMenuItem("example.com", mockMenuItem) as LongPressHandler.RequiredAction.DownloadFile
97+
assertEquals("example.com", action.url)
98+
}
99+
100+
@Test
101+
fun whenUserSelectedUnknownOptionThenNoActionRequiredReturned() {
102+
val unknownMenuId = 123
103+
whenever(mockMenuItem.itemId).thenReturn(unknownMenuId)
104+
val action = testee.userSelectedMenuItem("example.com", mockMenuItem)
105+
assertTrue(action == LongPressHandler.RequiredAction.None)
106+
}
107+
}
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
/*
2+
* Copyright (c) 2018 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.launch
18+
19+
import android.arch.core.executor.testing.InstantTaskExecutorRule
20+
import android.arch.lifecycle.Observer
21+
import com.duckduckgo.app.launch.LaunchViewModel.Command.*
22+
import com.duckduckgo.app.onboarding.store.OnboardingStore
23+
import com.nhaarman.mockito_kotlin.mock
24+
import com.nhaarman.mockito_kotlin.verify
25+
import com.nhaarman.mockito_kotlin.whenever
26+
import org.junit.After
27+
import org.junit.Before
28+
import org.junit.Rule
29+
import org.junit.Test
30+
import org.mockito.Mockito.any
31+
32+
33+
class LaunchViewModelTest {
34+
35+
@get:Rule
36+
@Suppress("unused")
37+
var instantTaskExecutorRule = InstantTaskExecutorRule()
38+
39+
private var onboardingStore: OnboardingStore = mock()
40+
private var mockCommandObserver: Observer<LaunchViewModel.Command> = mock()
41+
42+
private val testee: LaunchViewModel by lazy {
43+
LaunchViewModel(onboardingStore)
44+
}
45+
46+
@After
47+
fun after() {
48+
testee.command.removeObserver(mockCommandObserver)
49+
}
50+
51+
@Test
52+
fun whenOnboardingShouldShowThenCommandIsOnboarding() {
53+
whenever(onboardingStore.shouldShow).thenReturn(true)
54+
testee.command.observeForever(mockCommandObserver)
55+
verify(mockCommandObserver).onChanged(any(Onboarding::class.java))
56+
}
57+
58+
@Test
59+
fun whenOnboardingShouldNotShowThenCommandIsHome() {
60+
whenever(onboardingStore.shouldShow).thenReturn(false)
61+
testee.command.observeForever(mockCommandObserver)
62+
verify(mockCommandObserver).onChanged(any(Home::class.java))
63+
}
64+
65+
@Test
66+
fun whenOnboardingDoneThenCommandIsHome() {
67+
whenever(onboardingStore.shouldShow).thenReturn(true)
68+
testee.command.observeForever(mockCommandObserver)
69+
verify(mockCommandObserver).onChanged(any(Onboarding::class.java))
70+
71+
testee.onOnboardingDone()
72+
verify(mockCommandObserver).onChanged(any(Home::class.java))
73+
}
74+
75+
}

0 commit comments

Comments
 (0)