For #3709: Add save to PDF UI.
This commit is contained in:
parent
5391b4cbc3
commit
5cce4b5f15
|
@ -449,6 +449,22 @@ events:
|
|||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: 113
|
||||
save_to_pdf_tapped:
|
||||
type: event
|
||||
description: |
|
||||
A user tapped the save to pdf option in the share sheet.
|
||||
bugs:
|
||||
- https://github.com/mozilla-mobile/fenix/issues/3709
|
||||
data_reviews:
|
||||
- https://github.com/mozilla-mobile/fenix/pull/27257
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- android-probes@mozilla.com
|
||||
expires: 122
|
||||
metadata:
|
||||
tags:
|
||||
- Sharing
|
||||
|
||||
onboarding:
|
||||
syn_cfr_shown:
|
||||
|
|
|
@ -118,4 +118,9 @@ object FeatureFlags {
|
|||
* Enables the wallpaper v2 enhancements.
|
||||
*/
|
||||
const val wallpaperV2Enabled = true
|
||||
|
||||
/**
|
||||
* Enables the save to PDF feature.
|
||||
*/
|
||||
val saveToPDF = Config.channel.isNightlyOrDebug
|
||||
}
|
||||
|
|
|
@ -211,6 +211,7 @@ class DefaultBrowserToolbarMenuController(
|
|||
}
|
||||
is ToolbarMenu.Item.Share -> {
|
||||
val directions = NavGraphDirections.actionGlobalShareFragment(
|
||||
sessionId = currentSession?.id,
|
||||
data = arrayOf(
|
||||
ShareData(
|
||||
url = getProperUrl(currentSession),
|
||||
|
|
|
@ -583,6 +583,7 @@ class DefaultSessionControlController(
|
|||
|
||||
private fun showShareFragment(shareSubject: String, data: List<ShareData>) {
|
||||
val directions = HomeFragmentDirections.actionGlobalShareFragment(
|
||||
sessionId = store.state.selectedTabId,
|
||||
shareSubject = shareSubject,
|
||||
data = data.toTypedArray(),
|
||||
)
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
/* 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 org.mozilla.fenix.share
|
||||
|
||||
/**
|
||||
* Callbacks for possible user interactions on the [SaveToPDFItem]
|
||||
*/
|
||||
interface SaveToPDFInteractor {
|
||||
/**
|
||||
* Generates a PDF from the given [tabId].
|
||||
* @param tabId The ID of the tab to save as PDF.
|
||||
*/
|
||||
fun onSaveToPDF(tabId: String?)
|
||||
}
|
|
@ -0,0 +1,70 @@
|
|||
/* 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 org.mozilla.fenix.share
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.material.Icon
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
/**
|
||||
* A save to PDF item.
|
||||
*
|
||||
* @param onClick event handler when the save to PDF item is clicked.
|
||||
*/
|
||||
@Composable
|
||||
fun SaveToPDFItem(
|
||||
onClick: () -> Unit,
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.height(56.dp)
|
||||
.fillMaxWidth()
|
||||
.clickable(onClick = onClick),
|
||||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Spacer(Modifier.width(16.dp))
|
||||
|
||||
Icon(
|
||||
painter = painterResource(R.drawable.ic_download),
|
||||
contentDescription = stringResource(
|
||||
R.string.content_description_close_button,
|
||||
),
|
||||
tint = FirefoxTheme.colors.iconPrimary,
|
||||
)
|
||||
|
||||
Spacer(Modifier.width(32.dp))
|
||||
|
||||
Text(
|
||||
color = FirefoxTheme.colors.textPrimary,
|
||||
text = stringResource(R.string.share_save_to_pdf),
|
||||
style = FirefoxTheme.typography.subtitle1,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
@Preview
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
@Preview(uiMode = Configuration.UI_MODE_NIGHT_NO)
|
||||
private fun SaveToPDFItemPreview() {
|
||||
FirefoxTheme {
|
||||
SaveToPDFItem {}
|
||||
}
|
||||
}
|
|
@ -29,9 +29,11 @@ import mozilla.components.concept.engine.prompt.ShareData
|
|||
import mozilla.components.concept.sync.Device
|
||||
import mozilla.components.concept.sync.TabData
|
||||
import mozilla.components.feature.accounts.push.SendTabUseCases
|
||||
import mozilla.components.feature.session.SessionUseCases
|
||||
import mozilla.components.feature.share.RecentAppsStorage
|
||||
import mozilla.components.service.glean.private.NoExtras
|
||||
import mozilla.components.support.ktx.kotlin.isExtensionUrl
|
||||
import org.mozilla.fenix.GleanMetrics.Events
|
||||
import org.mozilla.fenix.GleanMetrics.SyncAccount
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
|
@ -47,6 +49,11 @@ interface ShareController {
|
|||
fun handleReauth()
|
||||
fun handleShareClosed()
|
||||
fun handleShareToApp(app: AppShareOption)
|
||||
|
||||
/**
|
||||
* Handles when a save to PDF action was requested.
|
||||
*/
|
||||
fun handleSaveToPDF(tabId: String?)
|
||||
fun handleAddNewDevice()
|
||||
fun handleShareToDevice(device: Device)
|
||||
fun handleShareToAllDevices(devices: List<Device>)
|
||||
|
@ -68,12 +75,13 @@ interface ShareController {
|
|||
* @param navController - [NavController] used for navigation.
|
||||
* @param dismiss - callback signalling sharing can be closed.
|
||||
*/
|
||||
@Suppress("TooManyFunctions")
|
||||
@Suppress("TooManyFunctions", "LongParameterList")
|
||||
class DefaultShareController(
|
||||
private val context: Context,
|
||||
private val shareSubject: String?,
|
||||
private val shareData: List<ShareData>,
|
||||
private val sendTabUseCases: SendTabUseCases,
|
||||
private val saveToPdfUseCase: SessionUseCases.SaveToPdfUseCase,
|
||||
private val snackbar: FenixSnackbar,
|
||||
private val navController: NavController,
|
||||
private val recentAppsStorage: RecentAppsStorage,
|
||||
|
@ -130,6 +138,12 @@ class DefaultShareController(
|
|||
dismiss(result)
|
||||
}
|
||||
|
||||
override fun handleSaveToPDF(tabId: String?) {
|
||||
Events.saveToPdfTapped.record(NoExtras())
|
||||
handleShareClosed()
|
||||
saveToPdfUseCase.invoke(tabId)
|
||||
}
|
||||
|
||||
override fun handleAddNewDevice() {
|
||||
val directions = ShareFragmentDirections.actionShareFragmentToAddNewDeviceFragment()
|
||||
navController.navigate(directions)
|
||||
|
|
|
@ -10,6 +10,8 @@ import android.view.LayoutInflater
|
|||
import android.view.View
|
||||
import android.view.ViewGroup
|
||||
import androidx.appcompat.app.AppCompatDialogFragment
|
||||
import androidx.compose.ui.platform.ViewCompositionStrategy
|
||||
import androidx.core.view.isVisible
|
||||
import androidx.fragment.app.clearFragmentResult
|
||||
import androidx.fragment.app.setFragmentResult
|
||||
import androidx.fragment.app.viewModels
|
||||
|
@ -22,11 +24,13 @@ import mozilla.components.browser.state.selector.findTabOrCustomTab
|
|||
import mozilla.components.concept.engine.prompt.PromptRequest
|
||||
import mozilla.components.feature.accounts.push.SendTabUseCases
|
||||
import mozilla.components.feature.share.RecentAppsStorage
|
||||
import org.mozilla.fenix.FeatureFlags
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
import org.mozilla.fenix.databinding.FragmentShareBinding
|
||||
import org.mozilla.fenix.ext.getRootView
|
||||
import org.mozilla.fenix.ext.requireComponents
|
||||
import org.mozilla.fenix.theme.FirefoxTheme
|
||||
|
||||
class ShareFragment : AppCompatDialogFragment() {
|
||||
|
||||
|
@ -80,6 +84,7 @@ class ShareFragment : AppCompatDialogFragment() {
|
|||
),
|
||||
navController = findNavController(),
|
||||
sendTabUseCases = SendTabUseCases(accountManager),
|
||||
saveToPdfUseCase = requireComponents.useCases.sessionUseCases.saveToPdf,
|
||||
recentAppsStorage = RecentAppsStorage(requireContext()),
|
||||
viewLifecycleScope = viewLifecycleOwner.lifecycleScope,
|
||||
) { result ->
|
||||
|
@ -111,6 +116,20 @@ class ShareFragment : AppCompatDialogFragment() {
|
|||
}
|
||||
shareToAppsView = ShareToAppsView(binding.appsShareLayout, shareInteractor)
|
||||
|
||||
if (FeatureFlags.saveToPDF) {
|
||||
binding.dividerLineAppsShareAndPdfSection.isVisible = true
|
||||
binding.savePdf.apply {
|
||||
isVisible = true
|
||||
setViewCompositionStrategy(ViewCompositionStrategy.DisposeOnViewTreeLifecycleDestroyed)
|
||||
setContent {
|
||||
FirefoxTheme {
|
||||
SaveToPDFItem {
|
||||
shareInteractor.onSaveToPDF(tabId = args.sessionId)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return binding.root
|
||||
}
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ import org.mozilla.fenix.share.listadapters.AppShareOption
|
|||
*/
|
||||
class ShareInteractor(
|
||||
private val controller: ShareController,
|
||||
) : ShareCloseInteractor, ShareToAccountDevicesInteractor, ShareToAppsInteractor {
|
||||
) : ShareCloseInteractor, ShareToAccountDevicesInteractor, ShareToAppsInteractor, SaveToPDFInteractor {
|
||||
override fun onReauth() {
|
||||
controller.handleReauth()
|
||||
}
|
||||
|
@ -40,4 +40,8 @@ class ShareInteractor(
|
|||
override fun onShareToApp(appToShareTo: AppShareOption) {
|
||||
controller.handleShareToApp(appToShareTo)
|
||||
}
|
||||
|
||||
override fun onSaveToPDF(tabId: String?) {
|
||||
controller.handleSaveToPDF(tabId)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -34,18 +34,18 @@
|
|||
android:background="@drawable/bottom_sheet_dialog_fragment_background"
|
||||
app:layout_constraintBottom_toBottomOf="parent">
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/appsShareLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/devicesShareLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toTopOf="@id/divider_line" />
|
||||
|
||||
<FrameLayout
|
||||
android:id="@+id/appsShareLayout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintTop_toBottomOf="@id/divider_line" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider_line"
|
||||
android:layout_width="match_parent"
|
||||
|
@ -54,6 +54,23 @@
|
|||
android:background="?borderPrimary"
|
||||
app:layout_constraintBottom_toTopOf="@id/appsShareLayout" />
|
||||
|
||||
<View
|
||||
android:id="@+id/divider_line_apps_share_and_pdf_section"
|
||||
android:visibility="gone"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="1dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:background="?borderPrimary"
|
||||
app:layout_constraintTop_toBottomOf="@id/appsShareLayout" />
|
||||
|
||||
<androidx.compose.ui.platform.ComposeView
|
||||
android:visibility="gone"
|
||||
android:id="@+id/save_pdf"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
app:layout_constraintBottom_toBottomOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/divider_line_apps_share_and_pdf_section" />
|
||||
|
||||
<androidx.constraintlayout.widget.Group
|
||||
android:id="@+id/devicesShareGroup"
|
||||
android:layout_width="wrap_content"
|
||||
|
|
|
@ -895,7 +895,7 @@
|
|||
app:destination="@id/addNewDeviceFragment" />
|
||||
<argument
|
||||
android:name="sessionId"
|
||||
android:defaultValue="null"
|
||||
android:defaultValue="@null"
|
||||
app:argType="string"
|
||||
app:nullable="true" />
|
||||
<argument
|
||||
|
|
|
@ -1030,6 +1030,8 @@
|
|||
<!-- Content description (not visible, for screen readers etc.):
|
||||
"Share" button. Opens the share menu when pressed. -->
|
||||
<string name="share_button_content_description">Share</string>
|
||||
<!-- Text for the Save to PDF feature in the share menu -->
|
||||
<string name="share_save_to_pdf">Save as PDF</string>
|
||||
<!-- Sub-header in the dialog to share a link to another sync device -->
|
||||
<string name="share_device_subheader">Send to device</string>
|
||||
<!-- Sub-header in the dialog to share a link to an app from the full list -->
|
||||
|
|
|
@ -623,6 +623,7 @@ class DefaultBrowserToolbarMenuControllerTest {
|
|||
navController.navigate(
|
||||
directionsEq(
|
||||
NavGraphDirections.actionGlobalShareFragment(
|
||||
sessionId = browserStore.state.selectedTabId,
|
||||
data = arrayOf(ShareData(url = "https://mozilla.org", title = "Mozilla")),
|
||||
showPage = true,
|
||||
),
|
||||
|
@ -656,6 +657,7 @@ class DefaultBrowserToolbarMenuControllerTest {
|
|||
navController.navigate(
|
||||
directionsEq(
|
||||
NavGraphDirections.actionGlobalShareFragment(
|
||||
sessionId = browserStore.state.selectedTabId,
|
||||
data = arrayOf(ShareData(url = "https://mozilla.org", title = "Mozilla")),
|
||||
showPage = true,
|
||||
),
|
||||
|
|
|
@ -24,6 +24,7 @@ import mozilla.components.concept.sync.Device
|
|||
import mozilla.components.concept.sync.DeviceType
|
||||
import mozilla.components.concept.sync.TabData
|
||||
import mozilla.components.feature.accounts.push.SendTabUseCases
|
||||
import mozilla.components.feature.session.SessionUseCases
|
||||
import mozilla.components.feature.share.RecentAppsStorage
|
||||
import mozilla.components.service.glean.testing.GleanTestRule
|
||||
import mozilla.components.support.test.robolectric.testContext
|
||||
|
@ -37,6 +38,7 @@ import org.junit.Assert.assertTrue
|
|||
import org.junit.Rule
|
||||
import org.junit.Test
|
||||
import org.junit.runner.RunWith
|
||||
import org.mozilla.fenix.GleanMetrics.Events
|
||||
import org.mozilla.fenix.GleanMetrics.SyncAccount
|
||||
import org.mozilla.fenix.R
|
||||
import org.mozilla.fenix.components.FenixSnackbar
|
||||
|
@ -61,6 +63,7 @@ class ShareControllerTest {
|
|||
)
|
||||
private val textToShare = "${shareData[0].url}\n\n${shareData[1].url}"
|
||||
private val sendTabUseCases = mockk<SendTabUseCases>(relaxed = true)
|
||||
private val saveToPdfUseCase = mockk<SessionUseCases.SaveToPdfUseCase>(relaxed = true)
|
||||
private val snackbar = mockk<FenixSnackbar>(relaxed = true)
|
||||
private val navController = mockk<NavController>(relaxed = true)
|
||||
private val dismiss = mockk<(ShareController.Result) -> Unit>(relaxed = true)
|
||||
|
@ -74,7 +77,7 @@ class ShareControllerTest {
|
|||
private val testDispatcher = coroutinesTestRule.testDispatcher
|
||||
private val testCoroutineScope = coroutinesTestRule.scope
|
||||
private val controller = DefaultShareController(
|
||||
context, shareSubject, shareData, sendTabUseCases, snackbar, navController,
|
||||
context, shareSubject, shareData, sendTabUseCases, saveToPdfUseCase, snackbar, navController,
|
||||
recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
)
|
||||
|
||||
|
@ -96,7 +99,7 @@ class ShareControllerTest {
|
|||
// need to use an Activity Context.
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(
|
||||
activityContext, shareSubject, shareData, mockk(),
|
||||
activityContext, shareSubject, shareData, mockk(), mockk(),
|
||||
mockk(), mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
)
|
||||
every { activityContext.startActivity(capture(shareIntent)) } just Runs
|
||||
|
@ -133,8 +136,17 @@ class ShareControllerTest {
|
|||
// need to use an Activity Context.
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(
|
||||
activityContext, shareSubject, shareData, mockk(),
|
||||
snackbar, mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = shareSubject,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = snackbar,
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
every { recentAppStorage.updateRecentApp(appShareOption.activityName) } just Runs
|
||||
every { activityContext.startActivity(capture(shareIntent)) } throws SecurityException()
|
||||
|
@ -161,8 +173,17 @@ class ShareControllerTest {
|
|||
// need to use an Activity Context.
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(
|
||||
activityContext, shareSubject, shareData, mockk(),
|
||||
snackbar, mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = shareSubject,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = snackbar,
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
every { recentAppStorage.updateRecentApp(appShareOption.activityName) } just Runs
|
||||
every { activityContext.startActivity(capture(shareIntent)) } throws ActivityNotFoundException()
|
||||
|
@ -178,12 +199,47 @@ class ShareControllerTest {
|
|||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN handleSaveToPDF THEN send telemetry, close the dialog and save the page to pdf`() {
|
||||
val testController = DefaultShareController(
|
||||
context = mockk(),
|
||||
shareSubject = shareSubject,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = saveToPdfUseCase,
|
||||
snackbar = snackbar,
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
testController.handleSaveToPDF("tabID")
|
||||
|
||||
verify {
|
||||
saveToPdfUseCase.invoke("tabID")
|
||||
dismiss(ShareController.Result.DISMISSED)
|
||||
}
|
||||
|
||||
assertNotNull(Events.saveToPdfTapped.testGetValue())
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `getShareSubject should return the shareSubject when shareSubject is not null`() {
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(
|
||||
activityContext, shareSubject, shareData, mockk(),
|
||||
mockk(), mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = shareSubject,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = mockk(),
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
assertEquals(shareSubject, testController.getShareSubject())
|
||||
|
@ -193,8 +249,17 @@ class ShareControllerTest {
|
|||
fun `getShareSubject should return a combination of non-null titles when shareSubject is null`() {
|
||||
val activityContext: Context = mockk<Activity>()
|
||||
val testController = DefaultShareController(
|
||||
activityContext, null, shareData, mockk(),
|
||||
mockk(), mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = null,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = mockk(),
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
assertEquals("title0, title1", testController.getShareSubject())
|
||||
|
@ -208,8 +273,17 @@ class ShareControllerTest {
|
|||
ShareData(url = "url1", title = "title1"),
|
||||
)
|
||||
val testController = DefaultShareController(
|
||||
activityContext, null, partialTitlesShareData, mockk(),
|
||||
mockk(), mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = null,
|
||||
shareData = partialTitlesShareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = mockk(),
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
assertEquals("title1", testController.getShareSubject())
|
||||
|
@ -223,8 +297,17 @@ class ShareControllerTest {
|
|||
ShareData(url = "url1", title = null),
|
||||
)
|
||||
val testController = DefaultShareController(
|
||||
activityContext, null, noTitleShareData, mockk(),
|
||||
mockk(), mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = null,
|
||||
shareData = noTitleShareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = mockk(),
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
assertEquals("", testController.getShareSubject())
|
||||
|
@ -238,8 +321,17 @@ class ShareControllerTest {
|
|||
ShareData(url = "url1", title = ""),
|
||||
)
|
||||
val testController = DefaultShareController(
|
||||
activityContext, null, noTitleShareData, mockk(),
|
||||
mockk(), mockk(), recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = activityContext,
|
||||
shareSubject = null,
|
||||
shareData = noTitleShareData,
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = mockk(),
|
||||
navController = mockk(),
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
assertEquals("", testController.getShareSubject())
|
||||
|
@ -384,16 +476,17 @@ class ShareControllerTest {
|
|||
@Test
|
||||
fun `getSuccessMessage should return different strings depending on the number of shared tabs`() {
|
||||
val controllerWithOneSharedTab = DefaultShareController(
|
||||
context,
|
||||
shareSubject,
|
||||
listOf(ShareData(url = "url0", title = "title0")),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
mockk(),
|
||||
context = context,
|
||||
shareSubject = shareSubject,
|
||||
shareData = listOf(ShareData(url = "url0", title = "title0")),
|
||||
sendTabUseCases = mockk(),
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = mockk(),
|
||||
navController = mockk(),
|
||||
recentAppsStorage = mockk(),
|
||||
viewLifecycleScope = mockk(),
|
||||
dispatcher = mockk(),
|
||||
dismiss = mockk(),
|
||||
)
|
||||
val controllerWithMoreSharedTabs = controller
|
||||
val expectedTabSharedMessage = context.getString(R.string.sync_sent_tab_snackbar)
|
||||
|
@ -420,8 +513,17 @@ class ShareControllerTest {
|
|||
ShareData(url = "url1"),
|
||||
)
|
||||
val controller = DefaultShareController(
|
||||
context, shareSubject, shareData, sendTabUseCases, snackbar, navController,
|
||||
recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = context,
|
||||
shareSubject = shareSubject,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = sendTabUseCases,
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = snackbar,
|
||||
navController = navController,
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
val expectedShareText = "${shareData[0].url}\n\nurl0\n\n${shareData[2].url}"
|
||||
|
@ -436,8 +538,17 @@ class ShareControllerTest {
|
|||
@Test
|
||||
fun `getShareSubject will return a concatenation of tab titles if 'shareSubject' is null`() {
|
||||
val controller = DefaultShareController(
|
||||
context, null, shareData, sendTabUseCases, snackbar, navController,
|
||||
recentAppStorage, testCoroutineScope, testDispatcher, dismiss,
|
||||
context = context,
|
||||
shareSubject = null,
|
||||
shareData = shareData,
|
||||
sendTabUseCases = sendTabUseCases,
|
||||
saveToPdfUseCase = mockk(),
|
||||
snackbar = snackbar,
|
||||
navController = navController,
|
||||
recentAppsStorage = recentAppStorage,
|
||||
viewLifecycleScope = testCoroutineScope,
|
||||
dispatcher = testDispatcher,
|
||||
dismiss = dismiss,
|
||||
)
|
||||
|
||||
assertEquals("title0, title1", controller.getShareSubject())
|
||||
|
|
|
@ -68,4 +68,11 @@ class ShareInteractorTest {
|
|||
|
||||
verify { controller.handleShareToApp(app) }
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `WHEN onSaveToPDF is call THEN call handleSaveToPDF`() {
|
||||
interactor.onSaveToPDF("tabID")
|
||||
|
||||
verify { controller.handleSaveToPDF("tabID") }
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue