Skip to content
GitLab
Menu
Projects
Groups
Snippets
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
Menu
Open sidebar
The Tor Project
Applications
android-components
Commits
a3abde47
Commit
a3abde47
authored
Oct 18, 2019
by
Tiger Oakes
Browse files
Abstract away activity/fragment in prompt feature
parent
d40f5a40
Changes
9
Hide whitespace changes
Inline
Side-by-side
components/feature/prompts/src/main/java/mozilla/components/feature/prompts/FilePicker.kt
View file @
a3abde47
...
...
@@ -23,34 +23,18 @@ import mozilla.components.support.ktx.android.content.isPermissionGranted
typealias
OnNeedToRequestPermissions
=
(
permissions
:
Array
<
String
>)
->
Unit
/**
* @property activity The [Activity] which hosts the file picker.
* @property fragment The [Fragment] which hosts the file picker.
* @property container The [Activity] or [Fragment] which hosts the file picker.
* @property store The [BrowserStore] this feature should subscribe to.
* @property onNeedToRequestPermissions a callback invoked when permissions
* need to be requested before a prompt (e.g. a file picker) can be displayed.
* Once the request is completed, [onPermissionsResult] needs to be invoked.
*/
internal
class
FilePicker
private
constructor
(
private
val
activity
:
Activity
?
=
null
,
private
val
fragment
:
Fragment
?
=
null
,
internal
class
FilePicker
(
private
val
container
:
PromptContainer
,
private
val
store
:
BrowserStore
,
private
var
sessionId
:
String
?
=
null
,
override
val
onNeedToRequestPermissions
:
OnNeedToRequestPermissions
)
:
PermissionsFeature
{
constructor
(
activity
:
Activity
,
store
:
BrowserStore
,
sessionId
:
String
?
=
null
,
onNeedToRequestPermissions
:
OnNeedToRequestPermissions
)
:
this
(
activity
,
null
,
store
,
sessionId
,
onNeedToRequestPermissions
)
constructor
(
fragment
:
Fragment
,
store
:
BrowserStore
,
sessionId
:
String
?
=
null
,
onNeedToRequestPermissions
:
OnNeedToRequestPermissions
)
:
this
(
null
,
fragment
,
store
,
sessionId
,
onNeedToRequestPermissions
)
private
val
context
get
()
=
activity
?:
requireNotNull
(
fragment
).
requireContext
()
/**
* The image capture intent doesn't return the URI where the image is saved,
...
...
@@ -68,20 +52,20 @@ internal class FilePicker private constructor(
// Compare the accepted values against image/*, video/*, and audio/*
for
(
type
in
MimeType
.
values
())
{
val
hasPermission
=
context
.
isPermissionGranted
(
type
.
permission
)
val
hasPermission
=
container
.
context
.
isPermissionGranted
(
type
.
permission
)
// The captureMode attribute can be used if the accepted types are exactly for
// image/*, video/*, or audio/*.
if
(
hasPermission
&&
type
.
shouldCapture
(
promptRequest
.
mimeTypes
,
promptRequest
.
captureMode
))
{
type
.
buildIntent
(
context
,
promptRequest
)
?.
also
{
type
.
buildIntent
(
container
.
context
,
promptRequest
)
?.
also
{
saveCaptureUriIfPresent
(
it
)
startActivityForResult
(
it
,
FILE_PICKER_ACTIVITY_REQUEST_CODE
)
container
.
startActivityForResult
(
it
,
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
)
return
}
}
// Otherwise, build the intent and create a chooser later
if
(
type
.
matches
(
promptRequest
.
mimeTypes
))
{
if
(
hasPermission
)
{
type
.
buildIntent
(
context
,
promptRequest
)
?.
also
{
type
.
buildIntent
(
container
.
context
,
promptRequest
)
?.
also
{
saveCaptureUriIfPresent
(
it
)
intents
.
add
(
it
)
}
...
...
@@ -100,7 +84,7 @@ internal class FilePicker private constructor(
putExtra
(
EXTRA_INITIAL_INTENTS
,
intents
.
toTypedArray
())
}
startActivityForResult
(
chooser
,
FILE_PICKER_ACTIVITY_REQUEST_CODE
)
container
.
startActivityForResult
(
chooser
,
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
)
}
else
{
onNeedToRequestPermissions
(
neededPermissions
.
toTypedArray
())
}
...
...
@@ -114,7 +98,7 @@ internal class FilePicker private constructor(
* @param intent The result of the request.
*/
fun
onActivityResult
(
requestCode
:
Int
,
resultCode
:
Int
,
intent
:
Intent
?)
{
if
(
requestCode
==
FILE_PICKER_ACTIVITY_REQUEST_CODE
)
{
if
(
requestCode
==
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
)
{
store
.
consumePromptFrom
(
sessionId
)
{
val
request
=
it
as
File
...
...
@@ -174,28 +158,16 @@ internal class FilePicker private constructor(
if
(
intent
?.
clipData
!=
null
&&
request
.
isMultipleFilesSelection
)
{
intent
.
clipData
?.
run
{
val
uris
=
Array
<
Uri
>(
itemCount
)
{
index
->
getItemAt
(
index
).
uri
}
request
.
onMultipleFilesSelected
(
context
,
uris
)
request
.
onMultipleFilesSelected
(
container
.
context
,
uris
)
}
}
else
{
val
uri
=
intent
?.
data
?:
captureUri
uri
?.
let
{
request
.
onSingleFileSelected
(
context
,
it
)
request
.
onSingleFileSelected
(
container
.
context
,
it
)
}
?:
request
.
onDismiss
}
}
private
fun
saveCaptureUriIfPresent
(
intent
:
Intent
)
=
intent
.
getParcelableExtra
<
Uri
>(
EXTRA_OUTPUT
)
?.
let
{
captureUri
=
it
}
internal
fun
startActivityForResult
(
intent
:
Intent
,
code
:
Int
)
{
if
(
activity
!=
null
)
{
activity
.
startActivityForResult
(
intent
,
code
)
}
else
{
requireNotNull
(
fragment
).
startActivityForResult
(
intent
,
code
)
}
}
companion
object
{
const
val
FILE_PICKER_ACTIVITY_REQUEST_CODE
=
1234
}
}
components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptContainer.kt
0 → 100644
View file @
a3abde47
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package
mozilla.components.feature.prompts
import
android.content.Context
import
android.content.Intent
import
androidx.annotation.StringRes
/**
* Wrapper to hold shared functionality between activities and fragments for [PromptFeature].
*/
internal
sealed
class
PromptContainer
{
/**
* Getter for [Context].
*/
abstract
val
context
:
Context
/**
* Launches an activity for which you would like a result when it finished.
*/
abstract
fun
startActivityForResult
(
intent
:
Intent
,
code
:
Int
)
/**
* Returns a localized string.
*/
abstract
fun
getString
(
@StringRes
res
:
Int
):
String
internal
class
Activity
(
private
val
activity
:
android
.
app
.
Activity
)
:
PromptContainer
()
{
override
val
context
get
()
=
activity
override
fun
startActivityForResult
(
intent
:
Intent
,
code
:
Int
)
=
activity
.
startActivityForResult
(
intent
,
code
)
override
fun
getString
(
res
:
Int
)
=
activity
.
getString
(
res
)
}
internal
class
Fragment
(
private
val
fragment
:
androidx
.
fragment
.
app
.
Fragment
)
:
PromptContainer
()
{
override
val
context
get
()
=
fragment
.
requireContext
()
override
fun
startActivityForResult
(
intent
:
Intent
,
code
:
Int
)
=
fragment
.
startActivityForResult
(
intent
,
code
)
override
fun
getString
(
res
:
Int
)
=
fragment
.
getString
(
res
)
}
}
components/feature/prompts/src/main/java/mozilla/components/feature/prompts/PromptFeature.kt
View file @
a3abde47
...
...
@@ -55,19 +55,12 @@ internal const val FRAGMENT_TAG = "mozac_feature_prompt_dialog"
* onActivityResult in your [Activity] or [Fragment] and forward its calls
* to [onActivityResult].
*
* This feature will subscribe to the currently selected
[S
ession
]
and display
* This feature will subscribe to the currently selected
s
ession and display
* a suitable native dialog based on [Session.Observer.onPromptRequested] events.
* Once the dialog is closed or the user selects an item from the dialog
* the related [PromptRequest] will be consumed.
*
* @property activity The [Activity] which hosts this feature. If hosted by a
* [Fragment], this parameter can be ignored. Note that an
* [IllegalStateException] will be thrown if neither an active nor a fragment
* is specified.
* @property fragment The [Fragment] which hosts this feature. If hosted by an
* [Activity], this parameter can be ignored. Note that an
* [IllegalStateException] will be thrown if neither an active nor a fragment
* is specified.
* @property container The [Activity] or [Fragment] which hosts this feature.
* @property store The [BrowserStore] this feature should subscribe to.
* @property customTabId Optional id of a custom tab. Instead of showing context
* menus for the currently selected tab this feature will show only context menus
...
...
@@ -79,9 +72,8 @@ internal const val FRAGMENT_TAG = "mozac_feature_prompt_dialog"
* Once the request is completed, [onPermissionsResult] needs to be invoked.
*/
@Suppress
(
"TooManyFunctions"
)
class
PromptFeature
(
private
val
activity
:
Activity
?
=
null
,
private
val
fragment
:
Fragment
?
=
null
,
class
PromptFeature
internal
constructor
(
private
val
container
:
PromptContainer
,
private
val
store
:
BrowserStore
,
private
var
customTabId
:
String
?
=
null
,
private
val
fragmentManager
:
FragmentManager
,
...
...
@@ -95,38 +87,43 @@ class PromptFeature(
constructor
(
activity
:
Activity
,
store
:
BrowserStore
,
session
Id
:
String
?
=
null
,
customTab
Id
:
String
?
=
null
,
fragmentManager
:
FragmentManager
,
onNeedToRequestPermissions
:
OnNeedToRequestPermissions
)
:
this
(
activity
,
null
,
store
,
session
Id
,
fragmentManager
,
onNeedToRequestPermissions
PromptContainer
.
Activity
(
activity
),
store
,
customTab
Id
,
fragmentManager
,
onNeedToRequestPermissions
)
constructor
(
fragment
:
Fragment
,
store
:
BrowserStore
,
session
Id
:
String
?
=
null
,
customTab
Id
:
String
?
=
null
,
fragmentManager
:
FragmentManager
,
onNeedToRequestPermissions
:
OnNeedToRequestPermissions
)
:
this
(
null
,
fragment
,
store
,
session
Id
,
fragmentManager
,
onNeedToRequestPermissions
PromptContainer
.
Fragment
(
fragment
)
,
store
,
customTab
Id
,
fragmentManager
,
onNeedToRequestPermissions
)
init
{
if
(
activity
==
null
&&
fragment
==
null
)
{
throw
IllegalStateException
(
@Deprecated
(
"Pass only activity or fragment instead"
)
constructor
(
activity
:
Activity
?
=
null
,
fragment
:
Fragment
?
=
null
,
store
:
BrowserStore
,
customTabId
:
String
?
=
null
,
fragmentManager
:
FragmentManager
,
onNeedToRequestPermissions
:
OnNeedToRequestPermissions
)
:
this
(
activity
?.
let
{
PromptContainer
.
Activity
(
it
)
}
?:
fragment
?.
let
{
PromptContainer
.
Fragment
(
it
)
}
?:
throw
IllegalStateException
(
"activity and fragment references "
+
"must not be both null, at least one must be initialized."
)
}
}
),
store
,
customTabId
,
fragmentManager
,
onNeedToRequestPermissions
)
private
val
context
get
()
=
activity
?:
requireNotNull
(
fragment
).
requireContext
()
private
val
filePicker
=
if
(
activity
!=
null
)
{
FilePicker
(
activity
,
store
,
customTabId
,
onNeedToRequestPermissions
)
}
else
{
FilePicker
(
requireNotNull
(
fragment
),
store
,
customTabId
,
onNeedToRequestPermissions
)
}
private
val
filePicker
=
FilePicker
(
container
,
store
,
customTabId
,
onNeedToRequestPermissions
)
override
val
onNeedToRequestPermissions
get
()
=
filePicker
.
onNeedToRequestPermissions
...
...
@@ -248,23 +245,21 @@ class PromptFeature(
is
MultipleChoice
->
it
.
onConfirm
(
value
as
Array
<
Choice
>)
is
Authentication
->
{
val
pair
=
value
as
Pair
<
String
,
String
>
it
.
onConfirm
(
pair
.
first
,
pair
.
secon
d
)
val
(
user
,
password
)
=
value
as
Pair
<
String
,
String
>
it
.
onConfirm
(
user
,
passwor
d
)
}
is
TextPrompt
->
{
val
pair
=
value
as
Pair
<
Boolean
,
String
>
val
(
shouldNotShowMoreDialogs
,
text
)
=
value
as
Pair
<
Boolean
,
String
>
val
shouldNotShowMoreDialogs
=
pair
.
first
promptAbuserDetector
.
userWantsMoreDialogs
(!
shouldNotShowMoreDialogs
)
it
.
onConfirm
(!
shouldNotShowMoreDialogs
,
pair
.
second
)
it
.
onConfirm
(!
shouldNotShowMoreDialogs
,
text
)
}
is
PromptRequest
.
Confirm
->
{
val
pair
=
value
as
Pair
<
Boolean
,
MultiButtonDialogFragment
.
ButtonType
>
val
isCheckBoxChecked
=
pair
.
first
val
(
isCheckBoxChecked
,
buttonType
)
=
value
as
Pair
<
Boolean
,
MultiButtonDialogFragment
.
ButtonType
>
promptAbuserDetector
.
userWantsMoreDialogs
(!
isCheckBoxChecked
)
when
(
pair
.
second
)
{
when
(
buttonType
)
{
MultiButtonDialogFragment
.
ButtonType
.
POSITIVE
->
it
.
onConfirmPositiveButton
(!
isCheckBoxChecked
)
MultiButtonDialogFragment
.
ButtonType
.
NEGATIVE
->
...
...
@@ -392,9 +387,9 @@ class PromptFeature(
is
PromptRequest
.
Popup
->
{
val
title
=
cont
ext
.
getString
(
R
.
string
.
mozac_feature_prompts_popup_dialog_title
)
val
positiveLabel
=
cont
ext
.
getString
(
R
.
string
.
mozac_feature_prompts_allow
)
val
negativeLabel
=
cont
ext
.
getString
(
R
.
string
.
mozac_feature_prompts_deny
)
val
title
=
cont
ainer
.
getString
(
R
.
string
.
mozac_feature_prompts_popup_dialog_title
)
val
positiveLabel
=
cont
ainer
.
getString
(
R
.
string
.
mozac_feature_prompts_allow
)
val
negativeLabel
=
cont
ainer
.
getString
(
R
.
string
.
mozac_feature_prompts_deny
)
ConfirmDialogFragment
.
newInstance
(
sessionId
=
session
.
id
,
...
...
@@ -408,12 +403,12 @@ class PromptFeature(
is
PromptRequest
.
Confirm
->
{
with
(
promptRequest
)
{
val
positiveButton
=
if
(
positiveButtonTitle
.
isEmpty
())
{
cont
ext
.
getString
(
R
.
string
.
mozac_feature_prompts_ok
)
cont
ainer
.
getString
(
R
.
string
.
mozac_feature_prompts_ok
)
}
else
{
positiveButtonTitle
}
val
negativeButton
=
if
(
positiveButtonTitle
.
isEmpty
())
{
cont
ext
.
getString
(
R
.
string
.
mozac_feature_prompts_cancel
)
cont
ainer
.
getString
(
R
.
string
.
mozac_feature_prompts_cancel
)
}
else
{
positiveButtonTitle
}
...
...
@@ -457,10 +452,6 @@ class PromptFeature(
is
Alert
,
is
TextPrompt
,
is
PromptRequest
.
Confirm
->
promptAbuserDetector
.
shouldShowMoreDialogs
}
}
companion
object
{
const
val
FILE_PICKER_ACTIVITY_REQUEST_CODE
=
1234
}
}
internal
fun
BrowserStore
.
consumePromptFrom
(
...
...
components/feature/prompts/src/main/res/values/ids.xml
0 → 100644
View file @
a3abde47
<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<!-- This Source Code Form is subject to the terms of the Mozilla Public
- License, v. 2.0. If a copy of the MPL was not distributed with this
- file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
<resources>
<!-- Request code for picking a file from another activity -->
<item
name=
"mozac_feature_prompts_file_picker_activity_request_code"
type=
"id"
/>
</resources>
components/feature/prompts/src/test/java/mozilla/components/feature/prompts/FilePickerTest.kt
View file @
a3abde47
...
...
@@ -5,7 +5,6 @@
package
mozilla.components.feature.prompts
import
android.Manifest
import
android.app.Activity
import
android.app.Activity.RESULT_CANCELED
import
android.app.Activity.RESULT_OK
import
android.content.ClipData
...
...
@@ -14,7 +13,6 @@ import android.content.Intent
import
android.content.pm.PackageManager.PERMISSION_DENIED
import
android.content.pm.PackageManager.PERMISSION_GRANTED
import
android.net.Uri
import
androidx.fragment.app.Fragment
import
androidx.test.core.app.ApplicationProvider
import
androidx.test.ext.junit.runners.AndroidJUnit4
import
mozilla.components.browser.state.action.ContentAction
...
...
@@ -52,7 +50,7 @@ class FilePickerTest {
onDismiss
=
{}
)
private
lateinit
var
fragment
:
Fragment
private
lateinit
var
fragment
:
PromptContainer
private
lateinit
var
store
:
BrowserStore
private
lateinit
var
state
:
BrowserState
private
lateinit
var
filePicker
:
FilePicker
...
...
@@ -74,31 +72,15 @@ class FilePickerTest {
whenever
(
state
.
customTabs
).
thenReturn
(
listOf
(
customTab
))
filePicker
=
FilePicker
(
fragment
,
store
,
customTab
.
id
)
{
}
filePicker
.
onActivityResult
(
F
ile
P
icker
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
0
,
null
)
filePicker
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_f
ile
_p
icker
_activity_request_code
,
0
,
null
)
verify
(
store
).
dispatch
(
ContentAction
.
ConsumePromptRequestAction
(
customTab
.
id
))
val
selected
=
prepareSelectedSession
(
request
)
filePicker
=
FilePicker
(
fragment
,
store
)
{
}
filePicker
.
onActivityResult
(
F
ile
P
icker
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
0
,
null
)
filePicker
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_f
ile
_p
icker
_activity_request_code
,
0
,
null
)
verify
(
store
).
dispatch
(
ContentAction
.
ConsumePromptRequestAction
(
selected
.
id
))
}
@Test
fun
`startActivityForResult
must
delegate
its
calls
either
to
an
activity
or
a
fragment`
()
{
val
mockActivity
:
Activity
=
mock
()
val
mockFragment
:
Fragment
=
mock
()
val
intent
=
Intent
()
val
code
=
1
filePicker
=
FilePicker
(
mockActivity
,
store
)
{
}
filePicker
.
startActivityForResult
(
intent
,
code
)
verify
(
mockActivity
).
startActivityForResult
(
intent
,
code
)
filePicker
=
FilePicker
(
mockFragment
,
store
)
{
}
filePicker
.
startActivityForResult
(
intent
,
code
)
verify
(
mockFragment
).
startActivityForResult
(
intent
,
code
)
}
@Test
fun
`handleFilePickerRequest
without
the
required
permission
will
call
onNeedToRequestPermissions`
()
{
var
onRequestPermissionWasCalled
=
false
...
...
@@ -108,7 +90,7 @@ class FilePickerTest {
onRequestPermissionWasCalled
=
true
}
doReturn
(
context
).
`when`
(
fragment
).
requireC
ontext
()
doReturn
(
context
).
`when`
(
fragment
).
c
ontext
filePicker
.
handleFileRequest
(
request
)
...
...
@@ -118,7 +100,7 @@ class FilePickerTest {
@Test
fun
`handleFilePickerRequest
with
the
required
permission
will
call
startActivityForResult`
()
{
val
mockFragment
:
Fragment
=
mock
()
val
mockFragment
:
PromptContainer
=
mock
()
var
onRequestPermissionWasCalled
=
false
val
context
=
ApplicationProvider
.
getApplicationContext
<
Context
>()
...
...
@@ -126,7 +108,7 @@ class FilePickerTest {
onRequestPermissionWasCalled
=
true
}
doReturn
(
context
).
`when`
(
mockFragment
).
requireC
ontext
()
doReturn
(
context
).
`when`
(
mockFragment
).
c
ontext
grantPermission
(
Manifest
.
permission
.
READ_EXTERNAL_STORAGE
)
...
...
@@ -181,7 +163,7 @@ class FilePickerTest {
stubContext
()
filePicker
.
onActivityResult
(
PromptFeature
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
RESULT_OK
,
intent
)
filePicker
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
,
RESULT_OK
,
intent
)
assertTrue
(
onSingleFileSelectionWasCalled
)
verify
(
store
).
dispatch
(
ContentAction
.
ConsumePromptRequestAction
(
selected
.
id
))
...
...
@@ -215,7 +197,7 @@ class FilePickerTest {
stubContext
()
filePicker
.
onActivityResult
(
PromptFeature
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
RESULT_OK
,
intent
)
filePicker
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
,
RESULT_OK
,
intent
)
assertTrue
(
onMultipleFileSelectionWasCalled
)
verify
(
store
).
dispatch
(
ContentAction
.
ConsumePromptRequestAction
(
selected
.
id
))
...
...
@@ -232,7 +214,7 @@ class FilePickerTest {
val
selected
=
prepareSelectedSession
(
filePickerRequest
)
val
intent
=
Intent
()
filePicker
.
onActivityResult
(
PromptFeature
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
RESULT_CANCELED
,
intent
)
filePicker
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
,
RESULT_CANCELED
,
intent
)
assertTrue
(
onDismissWasCalled
)
verify
(
store
).
dispatch
(
ContentAction
.
ConsumePromptRequestAction
(
selected
.
id
))
...
...
@@ -267,7 +249,7 @@ class FilePickerTest {
private
fun
stubContext
()
{
val
context
=
ApplicationProvider
.
getApplicationContext
<
Context
>()
doReturn
(
context
).
`when`
(
fragment
).
requireC
ontext
()
doReturn
(
context
).
`when`
(
fragment
).
c
ontext
filePicker
=
FilePicker
(
fragment
,
store
)
{}
}
}
components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptContainerTest.kt
0 → 100644
View file @
a3abde47
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package
mozilla.components.feature.prompts
import
android.app.Activity
import
android.content.Context
import
android.content.Intent
import
androidx.fragment.app.Fragment
import
mozilla.components.support.test.mock
import
org.junit.Assert.assertEquals
import
org.junit.Before
import
org.junit.Test
import
org.mockito.ArgumentMatchers.anyInt
import
org.mockito.Mock
import
org.mockito.Mockito.doReturn
import
org.mockito.Mockito.verify
import
org.mockito.MockitoAnnotations.initMocks
class
PromptContainerTest
{
@Mock
private
lateinit
var
activity
:
Activity
@Mock
private
lateinit
var
fragment
:
Fragment
@Before
fun
setup
()
{
initMocks
(
this
)
}
@Test
fun
`get
context
from
activity`
()
{
val
container
:
PromptContainer
=
PromptContainer
.
Activity
(
activity
)
assertEquals
(
activity
,
container
.
context
)
}
@Test
fun
`get
context
from
fragment`
()
{
val
mockContext
:
Context
=
mock
()
val
container
=
PromptContainer
.
Fragment
(
fragment
)
doReturn
(
mockContext
).
`when`
(
fragment
).
requireContext
()
assertEquals
(
mockContext
,
container
.
context
)
}
@Test
fun
`startActivityForResult
must
delegate
its
calls
either
to
an
activity
or
a
fragment`
()
{
val
intent
:
Intent
=
mock
()
val
code
=
1
var
container
:
PromptContainer
=
PromptContainer
.
Activity
(
activity
)
container
.
startActivityForResult
(
intent
,
code
)
verify
(
activity
).
startActivityForResult
(
intent
,
code
)
container
=
PromptContainer
.
Fragment
(
fragment
)
container
.
startActivityForResult
(
intent
,
code
)
verify
(
fragment
).
startActivityForResult
(
intent
,
code
)
}
@Test
fun
`getString
must
delegate
its
calls
either
to
an
activity
or
a
fragment`
()
{
doReturn
(
""
).
`when`
(
activity
).
getString
(
anyInt
())
doReturn
(
""
).
`when`
(
fragment
).
getString
(
anyInt
())
var
container
:
PromptContainer
=
PromptContainer
.
Activity
(
activity
)
container
.
getString
(
R
.
string
.
mozac_feature_prompts_ok
)
verify
(
activity
).
getString
(
R
.
string
.
mozac_feature_prompts_ok
)
container
=
PromptContainer
.
Fragment
(
fragment
)
container
.
getString
(
R
.
string
.
mozac_feature_prompts_ok
)
verify
(
fragment
).
getString
(
R
.
string
.
mozac_feature_prompts_ok
)
}
}
components/feature/prompts/src/test/java/mozilla/components/feature/prompts/PromptFeatureTest.kt
View file @
a3abde47
...
...
@@ -388,6 +388,7 @@ class PromptFeatureTest {
feature
.
handleDialogsRequest
(
mock
<
PromptRequest
.
File
>(),
mock
())
}
@Suppress
(
"Deprecation"
)
@Test
(
expected
=
IllegalStateException
::
class
)
fun
`Initializing
a
PromptFeature
without
giving
an
activity
or
fragment
reference
will
throw
an
exception`
()
{
PromptFeature
(
null
,
null
,
store
,
null
,
fragmentManager
)
{
}
...
...
@@ -409,7 +410,7 @@ class PromptFeatureTest {
intent
.
data
=
mock
()
store
.
dispatch
(
ContentAction
.
UpdatePromptRequestAction
(
tabId
,
filePickerRequest
)).
joinBlocking
()
feature
.
onActivityResult
(
PromptFeature
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
RESULT_OK
,
intent
)
feature
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
,
RESULT_OK
,
intent
)
processActions
()
assertTrue
(
onSingleFileSelectionWasCalled
)
assertNull
(
tab
()
?.
content
?.
promptRequest
)
...
...
@@ -441,7 +442,7 @@ class PromptFeatureTest {
store
.
dispatch
(
ContentAction
.
UpdatePromptRequestAction
(
tabId
,
filePickerRequest
)).
joinBlocking
()
feature
.
onActivityResult
(
PromptFeature
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
RESULT_OK
,
intent
)
feature
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
,
RESULT_OK
,
intent
)
processActions
()
assertTrue
(
onMultipleFileSelectionWasCalled
)
assertNull
(
tab
()
?.
content
?.
promptRequest
)
...
...
@@ -461,7 +462,7 @@ class PromptFeatureTest {
store
.
dispatch
(
ContentAction
.
UpdatePromptRequestAction
(
tabId
,
filePickerRequest
)).
joinBlocking
()
feature
.
onActivityResult
(
PromptFeature
.
FILE_PICKER_ACTIVITY_REQUEST_CODE
,
RESULT_CANCELED
,
intent
)
feature
.
onActivityResult
(
R
.
id
.
mozac_feature_prompts_file_picker_activity_request_code
,
RESULT_CANCELED
,
intent
)