From 2c75c230d2be6ac3b4b5a25b5e3ca1876ffc8f44 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 14:38:04 -0500 Subject: [PATCH 01/17] Add notice item layout, styles, and strings --- .../layout/activity_log_list_notice_item.xml | 54 +++++++++++++++++++ WordPress/src/main/res/values/strings.xml | 5 ++ WordPress/src/main/res/values/styles.xml | 41 ++++++++++++++ 3 files changed, 100 insertions(+) create mode 100644 WordPress/src/main/res/layout/activity_log_list_notice_item.xml diff --git a/WordPress/src/main/res/layout/activity_log_list_notice_item.xml b/WordPress/src/main/res/layout/activity_log_list_notice_item.xml new file mode 100644 index 000000000000..0877b4552ebf --- /dev/null +++ b/WordPress/src/main/res/layout/activity_log_list_notice_item.xml @@ -0,0 +1,54 @@ + + + + + + + + + + + + + diff --git a/WordPress/src/main/res/values/strings.xml b/WordPress/src/main/res/values/strings.xml index 13d75d319c0d..583864b02464 100644 --- a/WordPress/src/main/res/values/strings.xml +++ b/WordPress/src/main/res/values/strings.xml @@ -1054,6 +1054,11 @@ Restore to this point Download backup + + @string/backup_download_complete_description_with_two_parameters + Download + Dismiss + Backup Your first backup will be ready soon diff --git a/WordPress/src/main/res/values/styles.xml b/WordPress/src/main/res/values/styles.xml index 47590b0fff9d..f4cde589e72c 100644 --- a/WordPress/src/main/res/values/styles.xml +++ b/WordPress/src/main/res/values/styles.xml @@ -1540,4 +1540,45 @@ + + + + + + + From 29369e496469528ed0c3d3eb288416a5fda5429e Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 14:45:49 -0500 Subject: [PATCH 02/17] Add notice view type and list item holder --- .../activitylog/list/ActivityLogListItem.kt | 12 +++++++++++- .../activitylog/list/NoticeItemViewHolder.kt | 19 +++++++++++++++++++ 2 files changed, 30 insertions(+), 1 deletion(-) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/NoticeItemViewHolder.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListItem.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListItem.kt index 8954a6aebe1d..5d853ce724e4 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListItem.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListItem.kt @@ -9,6 +9,7 @@ import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType.EV import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType.FOOTER import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType.HEADER import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType.LOADING +import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType.NOTICE import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType.PROGRESS import org.wordpress.android.util.toFormattedDateString import org.wordpress.android.util.toFormattedTimeString @@ -81,12 +82,21 @@ sealed class ActivityLogListItem(val type: ViewType) { object Loading : ActivityLogListItem(LOADING) + data class Notice( + val label: String, + val primaryActionButtonClickListener: (String) -> Unit, + val secondaryActionButtonClickListener: (Long) -> Unit, + val url: String, + val downloadId: Long + ) : ActivityLogListItem(NOTICE) + enum class ViewType(val id: Int) { EVENT(0), PROGRESS(1), HEADER(2), FOOTER(3), - LOADING(4) + LOADING(4), + NOTICE(5) } enum class Status(val value: String, @DrawableRes val color: Int) { diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/NoticeItemViewHolder.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/NoticeItemViewHolder.kt new file mode 100644 index 000000000000..c678d169eeb2 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/NoticeItemViewHolder.kt @@ -0,0 +1,19 @@ +package org.wordpress.android.ui.activitylog.list + +import android.view.ViewGroup +import android.widget.TextView +import org.wordpress.android.R +import org.wordpress.android.ui.utils.UiHelpers + +class NoticeItemViewHolder(parent: ViewGroup) : + ActivityLogViewHolder(parent, R.layout.activity_log_list_notice_item) { + private val label: TextView = itemView.findViewById(R.id.label) + private val primaryButton: TextView = itemView.findViewById(R.id.primary_button) + private val secondaryButton: TextView = itemView.findViewById(R.id.secondary_button) + + fun bind(item: ActivityLogListItem.Notice, uiHelpers: UiHelpers) { + uiHelpers.setTextOrHide(label, item.label) + primaryButton.setOnClickListener { item.primaryActionButtonClickListener(item.url) } + secondaryButton.setOnClickListener { item.secondaryActionButtonClickListener(item.downloadId) } + } +} From 79ff64aee1337e27d73667c5500826114884dcbd Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 14:50:56 -0500 Subject: [PATCH 03/17] Add support for notice list item --- .../android/ui/activitylog/list/ActivityLogAdapter.kt | 7 ++++++- .../android/ui/activitylog/list/ActivityLogDiffCallback.kt | 2 ++ .../android/ui/activitylog/list/ActivityLogListFragment.kt | 6 +++++- 3 files changed, 13 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogAdapter.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogAdapter.kt index 64cdda6d2973..5a2de29900a7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogAdapter.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogAdapter.kt @@ -6,13 +6,16 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.RecyclerView.Adapter import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Event import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Header +import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Notice import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Progress import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.ViewType +import org.wordpress.android.ui.utils.UiHelpers class ActivityLogAdapter( private val itemClickListener: (ActivityLogListItem) -> Unit, private val rewindClickListener: (ActivityLogListItem) -> Unit, - private val secondaryActionClickListener: (ActivityLogListItem.SecondaryAction, ActivityLogListItem) -> Boolean + private val secondaryActionClickListener: (ActivityLogListItem.SecondaryAction, ActivityLogListItem) -> Boolean, + private val uiHelpers: UiHelpers ) : Adapter() { private val list = mutableListOf() @@ -32,6 +35,7 @@ class ActivityLogAdapter( is HeaderItemViewHolder -> holder.bind(list[position] as Header) is FooterItemViewHolder -> {} is LoadingItemViewHolder -> {} + is NoticeItemViewHolder -> holder.bind(list[position] as Notice, uiHelpers) else -> throw IllegalArgumentException("Unexpected view holder in ActivityLog") } } @@ -64,6 +68,7 @@ class ActivityLogAdapter( ViewType.HEADER.id -> HeaderItemViewHolder(parent) ViewType.FOOTER.id -> FooterItemViewHolder(parent) ViewType.LOADING.id -> LoadingItemViewHolder(parent) + ViewType.NOTICE.id -> NoticeItemViewHolder(parent) else -> throw IllegalArgumentException("Unexpected view type in ActivityLog") } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogDiffCallback.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogDiffCallback.kt index 7819f32150ee..e5cef3f43ce7 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogDiffCallback.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogDiffCallback.kt @@ -4,6 +4,7 @@ import android.os.Bundle import androidx.recyclerview.widget.DiffUtil import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Event import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.IActionableItem +import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Notice import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Progress class ActivityLogDiffCallback( @@ -21,6 +22,7 @@ class ActivityLogDiffCallback( return when { oldItem is Event && newItem is Event -> oldItem.activityId == newItem.activityId oldItem is Progress && newItem is Progress -> oldItem == newItem + oldItem is Notice && newItem is Notice -> oldItem == newItem else -> false } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt index 6c6bbf9bc9ed..6034d0c8c35a 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt @@ -322,7 +322,11 @@ class ActivityLogListFragment : Fragment() { private fun setEvents(events: List) { val adapter: ActivityLogAdapter if (log_list_view.adapter == null) { - adapter = ActivityLogAdapter(this::onItemClicked, this::onItemButtonClicked, this::onSecondaryActionClicked) + adapter = ActivityLogAdapter( + this::onItemClicked, + this::onItemButtonClicked, + this::onSecondaryActionClicked, + uiHelpers) log_list_view.adapter = adapter } else { adapter = log_list_view.adapter as ActivityLogAdapter From 99cd5311fc6b29f54921f88b910a1c2c735840db Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 14:53:50 -0500 Subject: [PATCH 04/17] Add validUntil to Complete request state --- .../android/ui/jetpack/backup/download/BackupDownloadStates.kt | 3 ++- .../backup/download/usecases/GetBackupDownloadStatusUseCase.kt | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadStates.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadStates.kt index e1006f4cb71a..03f56b8d43f2 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadStates.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadStates.kt @@ -96,7 +96,8 @@ sealed class BackupDownloadRequestState { val rewindId: String, val downloadId: Long, val url: String?, - val published: Date? = null + val published: Date? = null, + val validUntil: Date? = null ) : BackupDownloadRequestState() object Empty : BackupDownloadRequestState() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCase.kt index 593513885abd..41a77d798dfa 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCase.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCase.kt @@ -68,7 +68,7 @@ class GetBackupDownloadStatusUseCase @Inject constructor( ): Boolean { val published = activityLogStore.getActivityLogItemByRewindId(status.rewindId)?.published return if (status.progress == null) { - emit(Complete(status.rewindId, status.downloadId, status.url, published)) + emit(Complete(status.rewindId, status.downloadId, status.url, published, status.validUntil)) true } else { emit(Progress(status.rewindId, status.progress, published)) From 2fd65c5f25da85729b9050a997eb3c816dd94980 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 14:56:53 -0500 Subject: [PATCH 05/17] New use case for dismissing backup download file download --- .../PostDismissBackupDownloadUseCase.kt | 54 +++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCase.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCase.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCase.kt new file mode 100644 index 000000000000..f67eb229f0c7 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCase.kt @@ -0,0 +1,54 @@ +package org.wordpress.android.ui.jetpack.backup.download.usecases + +import kotlinx.coroutines.CoroutineDispatcher +import kotlinx.coroutines.delay +import kotlinx.coroutines.withContext +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.store.ActivityLogStore +import org.wordpress.android.fluxc.store.ActivityLogStore.DismissBackupDownloadPayload +import org.wordpress.android.modules.BG_THREAD +import org.wordpress.android.util.AppLog +import org.wordpress.android.util.AppLog.T +import org.wordpress.android.util.NetworkUtilsWrapper +import javax.inject.Inject +import javax.inject.Named +import kotlin.math.max + +class PostDismissBackupDownloadUseCase @Inject constructor( + private val networkUtilsWrapper: NetworkUtilsWrapper, + private val activityLogStore: ActivityLogStore, + @Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher +) { + private val tag = javaClass.simpleName + @Suppress("ComplexMethod", "LoopWithTooManyJumpStatements") + suspend fun dismissBackupDownload( + downloadId: Long, + site: SiteModel + ): Boolean = withContext(bgDispatcher) { + var retryAttempts = 0 + var dismissed = false + while (true) { + if (!networkUtilsWrapper.isNetworkAvailable()) { + val retryAttemptsExceeded = handleError(retryAttempts++) + if (retryAttemptsExceeded) break else continue + } + val result = activityLogStore.dismissBackupDownload(DismissBackupDownloadPayload(site, downloadId)) + if (result.isError) break + dismissed = true + break + } + dismissed + } + + private suspend fun handleError( + retryAttempts: Int + ): Boolean { + return if (retryAttempts >= MAX_RETRY) { + AppLog.d(T.JETPACK_BACKUP, "$tag: Exceeded $MAX_RETRY retries while dismiss download backup file") + true + } else { + delay(DELAY_MILLIS * (max(1, DELAY_FACTOR * retryAttempts))) + false + } + } +} From 369cbea86fb7d86db74c7050eb003cf5c804efbe Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 15:00:53 -0500 Subject: [PATCH 06/17] Add tracking for download and dismiss button taps --- .../android/util/analytics/ActivityLogTracker.kt | 16 ++++++++++++++++ .../android/analytics/AnalyticsTracker.java | 6 +++++- .../analytics/AnalyticsTrackerNosara.java | 8 ++++++++ 3 files changed, 29 insertions(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt b/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt index 3752659ae979..4441311cfabd 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt @@ -78,4 +78,20 @@ class ActivityLogTracker @Inject constructor( AnalyticsUtils.trackWithSiteDetails(Stat.ACTIVITY_LOG_REWIND_STARTED, site, properties) } } + + fun trackDownloadBackupDownloadButtonClicked(rewindableOnly: Boolean) { + if (rewindableOnly) { + tracker.track(Stat.JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED) + } else { + tracker.track(Stat.ACTIVITY_LOG_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED) + } + } + + fun trackDownloadBackupDismissButtonClicked(rewindableOnly: Boolean) { + if (rewindableOnly) { + tracker.track(Stat.JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DISMISSED_TAPPED) + } else { + tracker.track(Stat.ACTIVITY_LOG_DOWNLOAD_FILE_NOTICE_DISMISSED_TAPPED) + } + } } diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java index b5e0d3f26af6..c473a67f6868 100644 --- a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java +++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTracker.java @@ -765,7 +765,11 @@ public enum Stat { INVITE_LINKS_GET_STATUS, INVITE_LINKS_GENERATE, INVITE_LINKS_DISABLE, - INVITE_LINKS_SHARE + INVITE_LINKS_SHARE, + JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED, + JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DISMISSED_TAPPED, + ACTIVITY_LOG_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED, + ACTIVITY_LOG_DOWNLOAD_FILE_NOTICE_DISMISSED_TAPPED } private static final List TRACKERS = new ArrayList<>(); diff --git a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java index 36e3b1a8d262..5fef3f92ac63 100644 --- a/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java +++ b/libs/analytics/WordPressAnalytics/src/main/java/org/wordpress/android/analytics/AnalyticsTrackerNosara.java @@ -2036,6 +2036,14 @@ public static String getEventNameForStat(AnalyticsTracker.Stat stat) { return "invite_links_disable"; case INVITE_LINKS_SHARE: return "invite_links_share"; + case JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED: + return "jetpack_backup_download_file_notice_download_tapped"; + case JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DISMISSED_TAPPED: + return "jetpack_backup_download_file_notice_dismissed_tapped"; + case ACTIVITY_LOG_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED: + return "activity_log_download_file_notice_download_tapped"; + case ACTIVITY_LOG_DOWNLOAD_FILE_NOTICE_DISMISSED_TAPPED: + return "activity_log_download_file_notice_dismissed_tapped"; } return null; } From 520a72e2f59de585915bd6a14cae71e2960de740 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 15:02:56 -0500 Subject: [PATCH 07/17] Add DownloadBackupFile navigation event --- .../android/ui/activitylog/ActivityLogNavigationEvents.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/ActivityLogNavigationEvents.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/ActivityLogNavigationEvents.kt index becb69c81d7e..33d536ceae46 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/ActivityLogNavigationEvents.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/ActivityLogNavigationEvents.kt @@ -6,4 +6,5 @@ sealed class ActivityLogNavigationEvents { data class ShowBackupDownload(val event: ActivityLogListItem.Event) : ActivityLogNavigationEvents() data class ShowRestore(val event: ActivityLogListItem.Event) : ActivityLogNavigationEvents() data class ShowRewindDialog(val event: ActivityLogListItem.Event) : ActivityLogNavigationEvents() + data class DownloadBackupFile(val url: String) : ActivityLogNavigationEvents() } From 38c205477ddeb65b97218c1bae00d32e721c93ad Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 15:03:51 -0500 Subject: [PATCH 08/17] Add blank line spacer: --- .../org/wordpress/android/util/analytics/ActivityLogTracker.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt b/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt index 4441311cfabd..e81e7fc6e002 100644 --- a/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt +++ b/WordPress/src/main/java/org/wordpress/android/util/analytics/ActivityLogTracker.kt @@ -78,7 +78,7 @@ class ActivityLogTracker @Inject constructor( AnalyticsUtils.trackWithSiteDetails(Stat.ACTIVITY_LOG_REWIND_STARTED, site, properties) } } - + fun trackDownloadBackupDownloadButtonClicked(rewindableOnly: Boolean) { if (rewindableOnly) { tracker.track(Stat.JETPACK_BACKUP_DOWNLOAD_FILE_NOTICE_DOWNLOAD_TAPPED) From 92433729700da6e294aa1a13bf2c7caf47b470fe Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 15:05:55 -0500 Subject: [PATCH 09/17] Add DownloadBackupFile navigation event to navigationEvents observer --- .../android/ui/activitylog/list/ActivityLogListFragment.kt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt index 6034d0c8c35a..ec65ae79a0c6 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt @@ -22,6 +22,7 @@ import org.wordpress.android.fluxc.model.LocalOrRemoteId.RemoteId import org.wordpress.android.fluxc.model.SiteModel import org.wordpress.android.ui.ActivityLauncher import org.wordpress.android.ui.RequestCodes +import org.wordpress.android.ui.activitylog.ActivityLogNavigationEvents.DownloadBackupFile import org.wordpress.android.ui.activitylog.ActivityLogNavigationEvents.ShowBackupDownload import org.wordpress.android.ui.activitylog.ActivityLogNavigationEvents.ShowRestore import org.wordpress.android.ui.activitylog.ActivityLogNavigationEvents.ShowRewindDialog @@ -224,6 +225,7 @@ class ActivityLogListFragment : Fragment() { trackingSource ) is ShowRewindDialog -> displayRewindDialog(event) + is DownloadBackupFile -> ActivityLauncher.downloadBackupDownloadFile(requireActivity(), url) } } }) From 6b5139fe87164acc7136b9c899fb5665206a11c1 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 17:29:56 -0500 Subject: [PATCH 10/17] Add tests for use case --- .../PostDismissBackupDownloadUseCaseTest.kt | 91 +++++++++++++++++++ 1 file changed, 91 insertions(+) create mode 100644 WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCaseTest.kt diff --git a/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCaseTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCaseTest.kt new file mode 100644 index 000000000000..b215594d1f28 --- /dev/null +++ b/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/PostDismissBackupDownloadUseCaseTest.kt @@ -0,0 +1,91 @@ +package org.wordpress.android.ui.jetpack.backup.download.usecases + +import com.nhaarman.mockitokotlin2.any +import com.nhaarman.mockitokotlin2.whenever +import kotlinx.coroutines.InternalCoroutinesApi +import org.assertj.core.api.Assertions.assertThat +import org.junit.Before +import org.junit.Test +import org.mockito.Mock +import org.wordpress.android.BaseUnitTest +import org.wordpress.android.TEST_DISPATCHER +import org.wordpress.android.fluxc.action.ActivityLogAction.DISMISS_BACKUP_DOWNLOAD +import org.wordpress.android.fluxc.model.SiteModel +import org.wordpress.android.fluxc.store.ActivityLogStore +import org.wordpress.android.fluxc.store.ActivityLogStore.DismissBackupDownloadError +import org.wordpress.android.fluxc.store.ActivityLogStore.DismissBackupDownloadErrorType.GENERIC_ERROR +import org.wordpress.android.fluxc.store.ActivityLogStore.DismissBackupDownloadErrorType.INVALID_RESPONSE +import org.wordpress.android.fluxc.store.ActivityLogStore.OnDismissBackupDownload +import org.wordpress.android.test +import org.wordpress.android.util.NetworkUtilsWrapper + +@InternalCoroutinesApi +class PostDismissBackupDownloadUseCaseTest : BaseUnitTest() { + private lateinit var useCase: PostDismissBackupDownloadUseCase + @Mock lateinit var networkUtilsWrapper: NetworkUtilsWrapper + @Mock lateinit var activityLogStore: ActivityLogStore + @Mock lateinit var siteModel: SiteModel + + @Before + fun setup() = test { + useCase = PostDismissBackupDownloadUseCase(networkUtilsWrapper, activityLogStore, TEST_DISPATCHER) + whenever(networkUtilsWrapper.isNetworkAvailable()).thenReturn(true) + } + + @Test + fun `given no network, when dismiss is triggered, then false is returned`() = test { + whenever(networkUtilsWrapper.isNetworkAvailable()).thenReturn(false) + + val result = useCase.dismissBackupDownload(downloadId, siteModel) + + assertThat(result).isEqualTo(false) + } + + @Test + fun `given invalid response, when dismiss is triggered, then false is returned`() = test { + whenever(activityLogStore.dismissBackupDownload(any())).thenReturn( + OnDismissBackupDownload( + downloadId, DismissBackupDownloadError( + INVALID_RESPONSE + ), DISMISS_BACKUP_DOWNLOAD + ) + ) + + val result = useCase.dismissBackupDownload(downloadId, siteModel) + + assertThat(result).isEqualTo(false) + } + + @Test + fun `given generic error response, when dismiss download is triggered, then false is returned`() = test { + whenever(activityLogStore.dismissBackupDownload(any())) + .thenReturn( + OnDismissBackupDownload( + downloadId, DismissBackupDownloadError( + GENERIC_ERROR + ), DISMISS_BACKUP_DOWNLOAD + ) + ) + + val result = useCase.dismissBackupDownload(downloadId, siteModel) + + assertThat(result).isEqualTo(false) + } + + @Test + fun `when dismiss download is triggered successfully, then true is returned`() = test { + whenever(activityLogStore.dismissBackupDownload(any())).thenReturn( + OnDismissBackupDownload( + downloadId = downloadId, + isDismissed = true, + causeOfChange = DISMISS_BACKUP_DOWNLOAD + ) + ) + + val result = useCase.dismissBackupDownload(downloadId, siteModel) + + assertThat(result).isEqualTo(true) + } + + private val downloadId = 100L +} From 0d19bc909c9bbb78cdb4d51a4b426d4e2fdc75a6 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Tue, 23 Feb 2021 17:32:59 -0500 Subject: [PATCH 11/17] Fix broken tests --- .../activitylog/ActivityLogViewModelTest.kt | 71 ++++++++++++++++--- 1 file changed, 62 insertions(+), 9 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt index 1a44a8b40bf0..ef9095d85412 100644 --- a/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt @@ -44,6 +44,7 @@ import org.wordpress.android.ui.jetpack.JetpackCapabilitiesUseCase import org.wordpress.android.ui.jetpack.JetpackCapabilitiesUseCase.JetpackPurchasedProducts import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadRequestState import org.wordpress.android.ui.jetpack.backup.download.usecases.GetBackupDownloadStatusUseCase +import org.wordpress.android.ui.jetpack.backup.download.usecases.PostDismissBackupDownloadUseCase import org.wordpress.android.ui.jetpack.restore.RestoreRequestState import org.wordpress.android.ui.jetpack.restore.usecases.GetRestoreStatusUseCase import org.wordpress.android.ui.jetpack.restore.usecases.PostRestoreUseCase @@ -88,6 +89,7 @@ private const val BACKING_UP_DATE_TIME = "Backing up site from date time" private const val BACKING_UP_NO_DATE = "Backing up site" private const val BACKED_UP_DATE_TIME = "Your site has been successfully backed up\nBacked up from date time" private const val BACKED_UP_NO_DATE = "Your site has been successfully backed up" +private const val BACKUP_NOTICE = "We successfully created a backup of your site from date time" private const val REWIND_ID = "rewindId" private const val RESTORE_ID = 123456789L @@ -110,6 +112,7 @@ class ActivityLogViewModelTest { @Mock private lateinit var activityLogTracker: ActivityLogTracker @Mock private lateinit var jetpackCapabilitiesUseCase: JetpackCapabilitiesUseCase @Mock private lateinit var restoreFeatureConfig: RestoreFeatureConfig + @Mock private lateinit var postDismissBackupDownloadUseCase: PostDismissBackupDownloadUseCase private lateinit var fetchActivityLogCaptor: KArgumentCaptor private lateinit var formatDateRangeTimezoneCaptor: KArgumentCaptor @@ -139,7 +142,8 @@ class ActivityLogViewModelTest { dateUtils, activityLogTracker, jetpackCapabilitiesUseCase, - restoreFeatureConfig + restoreFeatureConfig, + postDismissBackupDownloadUseCase ) viewModel.site = site viewModel.rewindableOnly = rewindableOnly @@ -806,10 +810,14 @@ class ActivityLogViewModelTest { @Test fun `given no backup progress item, when reloading events, then the menu items are visible`() { val displayBackupProgressItem = false + val displayNoticeItem = false viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = displayBackupProgressItem) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem + ) ) assertEquals( @@ -831,10 +839,14 @@ class ActivityLogViewModelTest { @Test fun `given no backup progress item, when reloading events, then item is not visible`() { val displayBackupProgressItem = false + val displayNoticeItem = false viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = displayBackupProgressItem) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem + ) ) assertEquals( @@ -856,10 +868,14 @@ class ActivityLogViewModelTest { @Test fun `given no backup progress item, when reloading events, then move to top is not triggered`() { val displayBackupProgressItem = false + val displayNoticeItem = false viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = displayBackupProgressItem) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem + ) ) assertTrue(moveToTopEvents.isEmpty()) @@ -869,11 +885,15 @@ class ActivityLogViewModelTest { fun `given backup progress item, when reloading events, then the menu items are not visible`() { val displayBackupProgressItem = true val displayBackupProgressWithDate = false + val displayNoticeItem = false initBackupProgressMocks(displayBackupProgressWithDate) viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = displayBackupProgressItem) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem + ) ) assertEquals( @@ -896,12 +916,14 @@ class ActivityLogViewModelTest { fun `given backup progress item with date, when reloading events, then item is visible with date`() { val displayBackupProgressItem = true val displayBackupProgressWithDate = true + val displayNoticeItem = false initBackupProgressMocks(displayBackupProgressWithDate) viewModel.reloadEvents( done = false, backupDownloadEvent = BackupDownloadEvent( displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem, rewindId = REWIND_ID ) ) @@ -926,11 +948,15 @@ class ActivityLogViewModelTest { fun `given backup progress item without date, when reloading events, then item is visible without date`() { val displayBackupProgressItem = true val displayBackupProgressWithDate = false + val displayNoticeItem = false initBackupProgressMocks(displayBackupProgressWithDate) viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = displayBackupProgressItem) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem + ) ) assertEquals( @@ -955,7 +981,11 @@ class ActivityLogViewModelTest { viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = true, rewindId = REWIND_ID) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = true, + displayNotice = false, + rewindId = REWIND_ID + ) ) assertTrue(moveToTopEvents.isNotEmpty()) @@ -964,15 +994,31 @@ class ActivityLogViewModelTest { @Test fun `given backup finished with date, when reloading events, then show backup finished message with date`() { val date = activity().published + val url = "www.wordpress.com" + val validUntil = activity().published + val downloadId = 10L initBackupProgressFinishedMocks(date, true) + whenever( + resourceProvider.getString( + eq(R.string.activity_log_backup_download_notice_description_with_two_params), + any(), + any() + ) + ) + .thenReturn(BACKUP_NOTICE) + viewModel.reloadEvents( done = false, backupDownloadEvent = BackupDownloadEvent( displayProgress = false, + displayNotice = true, isCompleted = true, rewindId = REWIND_ID, - published = date + published = date, + downloadId = downloadId, + url = url, + validUntil = validUntil ) ) @@ -988,6 +1034,7 @@ class ActivityLogViewModelTest { done = false, backupDownloadEvent = BackupDownloadEvent( displayProgress = false, + displayNotice = true, isCompleted = true, rewindId = REWIND_ID, published = date @@ -1005,6 +1052,7 @@ class ActivityLogViewModelTest { val displayRestoreProgressWithDate = true val displayBackupProgressItem = true val displayBackupProgressWithDate = true + val displayNoticeItem = false initRestoreProgressMocks(displayRestoreProgressWithDate) initBackupProgressMocks(displayBackupProgressWithDate) @@ -1016,6 +1064,7 @@ class ActivityLogViewModelTest { ), backupDownloadEvent = BackupDownloadEvent( displayProgress = displayBackupProgressItem, + displayNotice = displayNoticeItem, rewindId = REWIND_ID ) ) @@ -1610,7 +1659,11 @@ class ActivityLogViewModelTest { initBackupProgressMocks(displayProgressWithDate) viewModel.reloadEvents( done = false, - backupDownloadEvent = BackupDownloadEvent(displayProgress = true, rewindId = REWIND_ID) + backupDownloadEvent = BackupDownloadEvent( + displayProgress = true, + displayNotice = false, + rewindId = REWIND_ID + ) ) if (date != null) { whenever( From a0b22dbdca2ad1f6c687b78793fbdb62325a570f Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Wed, 24 Feb 2021 10:45:06 -0500 Subject: [PATCH 12/17] Introduce new action state for return to calling activity --- .../list/ActivityLogListActivity.kt | 12 ++++++---- .../list/ActivityLogListFragment.kt | 15 +++++++----- .../backup/download/BackupDownloadFragment.kt | 21 ++++++++++++---- .../download/BackupDownloadViewModel.kt | 24 ++++++++++++++++--- .../JetpackBackupDownloadActionState.kt | 7 ++++++ 5 files changed, 61 insertions(+), 18 deletions(-) create mode 100644 WordPress/src/main/java/org/wordpress/android/ui/jetpack/common/JetpackBackupDownloadActionState.kt diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListActivity.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListActivity.kt index 7c51f6ce149e..f04ed9acb9a1 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListActivity.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListActivity.kt @@ -10,8 +10,10 @@ import org.wordpress.android.WordPress import org.wordpress.android.ui.LocaleAwareActivity import org.wordpress.android.ui.RequestCodes import org.wordpress.android.ui.activitylog.detail.ActivityLogDetailActivity +import org.wordpress.android.ui.jetpack.backup.download.KEY_BACKUP_DOWNLOAD_ACTION_STATE_ID import org.wordpress.android.ui.jetpack.backup.download.KEY_BACKUP_DOWNLOAD_DOWNLOAD_ID import org.wordpress.android.ui.jetpack.backup.download.KEY_BACKUP_DOWNLOAD_REWIND_ID +import org.wordpress.android.ui.jetpack.common.JetpackBackupDownloadActionState import org.wordpress.android.ui.jetpack.restore.KEY_RESTORE_RESTORE_ID import org.wordpress.android.ui.jetpack.restore.KEY_RESTORE_REWIND_ID import org.wordpress.android.ui.posts.BasicFragmentDialog @@ -96,8 +98,10 @@ class ActivityLogListActivity : LocaleAwareActivity(), private fun onActivityResultForBackupDownload(data: Intent?) { val rewindId = data?.getStringExtra(KEY_BACKUP_DOWNLOAD_REWIND_ID) val downloadId = data?.getLongExtra(KEY_BACKUP_DOWNLOAD_DOWNLOAD_ID, 0) - if (rewindId != null && downloadId != null) { - passQueryBackupDownloadStatus(rewindId, downloadId) + val actionState = data?.getIntExtra(KEY_BACKUP_DOWNLOAD_ACTION_STATE_ID, 0) + ?: JetpackBackupDownloadActionState.CANCEL.id + if (actionState != JetpackBackupDownloadActionState.CANCEL.id && rewindId != null && downloadId != null) { + passQueryBackupDownloadStatus(rewindId, downloadId, actionState) } } @@ -123,10 +127,10 @@ class ActivityLogListActivity : LocaleAwareActivity(), } } - private fun passQueryBackupDownloadStatus(rewindId: String, downloadId: Long) { + private fun passQueryBackupDownloadStatus(rewindId: String, downloadId: Long, actionState: Int) { val fragment = supportFragmentManager.findFragmentById(R.id.fragment_container) if (fragment is ActivityLogListFragment) { - fragment.onQueryBackupDownloadStatus(rewindId, downloadId) + fragment.onQueryBackupDownloadStatus(rewindId, downloadId, actionState) } } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt index ec65ae79a0c6..c78260f77032 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/activitylog/list/ActivityLogListFragment.kt @@ -45,6 +45,7 @@ private const val ACTIVITY_TYPE_FILTER_TAG = "activity_log_type_filter_tag" private const val DATE_PICKER_TAG = "activity_log_date_picker_tag" private const val ACTIVITY_LOG_TRACKING_SOURCE = "activity_log" private const val BACKUP_TRACKING_SOURCE = "backup" + /** * It was decided to reuse the 'Activity Log' screen instead of creating a new 'Backup' screen. This was due to the * fact that there will be lots of code that would need to be duplicated for the new 'Backup' screen. On the other @@ -137,8 +138,8 @@ class ActivityLogListFragment : Fragment() { viewModel.onQueryRestoreStatus(rewindId, restoreId) } - fun onQueryBackupDownloadStatus(rewindId: String, downloadId: Long) { - viewModel.onQueryBackupDownloadStatus(rewindId, downloadId) + fun onQueryBackupDownloadStatus(rewindId: String, downloadId: Long, actionState: Int) { + viewModel.onQueryBackupDownloadStatus(rewindId, downloadId, actionState) } private fun setupObservers() { @@ -201,9 +202,10 @@ class ActivityLogListFragment : Fragment() { viewModel.navigationEvents.observe(viewLifecycleOwner, { it.applyIfNotHandled { val trackingSource = when { - requireNotNull( - requireActivity().intent.extras?.containsKey(ACTIVITY_LOG_REWINDABLE_ONLY_KEY)) -> - BACKUP_TRACKING_SOURCE + requireNotNull( + requireActivity().intent.extras?.containsKey(ACTIVITY_LOG_REWINDABLE_ONLY_KEY) + ) -> + BACKUP_TRACKING_SOURCE else -> { ACTIVITY_LOG_TRACKING_SOURCE } @@ -328,7 +330,8 @@ class ActivityLogListFragment : Fragment() { this::onItemClicked, this::onItemButtonClicked, this::onSecondaryActionClicked, - uiHelpers) + uiHelpers + ) log_list_view.adapter = adapter } else { adapter = log_list_view.adapter as ActivityLogAdapter diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadFragment.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadFragment.kt index 38b8add5a5d6..82833fb160a5 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadFragment.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadFragment.kt @@ -10,7 +10,7 @@ import androidx.appcompat.app.AppCompatActivity import androidx.fragment.app.Fragment import androidx.lifecycle.ViewModelProvider import com.google.android.material.snackbar.Snackbar -import kotlinx.android.synthetic.main.jetpack_backup_restore_fragment.recycler_view +import kotlinx.android.synthetic.main.jetpack_backup_restore_fragment.* import org.wordpress.android.R import org.wordpress.android.WordPress import org.wordpress.android.fluxc.model.SiteModel @@ -20,6 +20,7 @@ import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadNavigation import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadViewModel.BackupDownloadWizardState.BackupDownloadCanceled import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadViewModel.BackupDownloadWizardState.BackupDownloadCompleted import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadViewModel.BackupDownloadWizardState.BackupDownloadInProgress +import org.wordpress.android.ui.jetpack.common.JetpackBackupDownloadActionState import org.wordpress.android.ui.jetpack.common.adapters.JetpackBackupRestoreAdapter import org.wordpress.android.ui.jetpack.scan.adapters.HorizontalMarginItemDecoration import org.wordpress.android.ui.pages.SnackbarMessageHolder @@ -32,6 +33,7 @@ import javax.inject.Inject const val KEY_BACKUP_DOWNLOAD_REWIND_ID = "key_backup_download_rewind_id" const val KEY_BACKUP_DOWNLOAD_DOWNLOAD_ID = "key_backup_download_download_id" +const val KEY_BACKUP_DOWNLOAD_ACTION_STATE_ID = "key_backup_download_action_state_id" class BackupDownloadFragment : Fragment(R.layout.jetpack_backup_restore_fragment) { @Inject lateinit var viewModelFactory: ViewModelProvider.Factory @@ -126,13 +128,22 @@ class BackupDownloadFragment : Fragment(R.layout.jetpack_backup_restore_fragment viewModel.wizardFinishedObservable.observe(viewLifecycleOwner, { it.applyIfNotHandled { val intent = Intent() - val (backupDownloadCreated, ids) = when (this) { - is BackupDownloadCanceled -> Pair(false, null) - is BackupDownloadInProgress -> Pair(true, Pair(rewindId, downloadId)) - is BackupDownloadCompleted -> Pair(true, null) + val (backupDownloadCreated, ids, actionType) = when (this) { + is BackupDownloadCanceled -> Triple(false, null, JetpackBackupDownloadActionState.CANCEL) + is BackupDownloadInProgress -> Triple( + true, + Pair(rewindId, downloadId), + JetpackBackupDownloadActionState.PROGRESS + ) + is BackupDownloadCompleted -> Triple( + true, + Pair(rewindId, downloadId), + JetpackBackupDownloadActionState.COMPLETE + ) } intent.putExtra(KEY_BACKUP_DOWNLOAD_REWIND_ID, ids?.first) intent.putExtra(KEY_BACKUP_DOWNLOAD_DOWNLOAD_ID, ids?.second) + intent.putExtra(KEY_BACKUP_DOWNLOAD_ACTION_STATE_ID, actionType.id) requireActivity().let { activity -> activity.setResult(if (backupDownloadCreated) RESULT_OK else RESULT_CANCELED, intent) activity.finish() diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadViewModel.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadViewModel.kt index 0beed6b8b26e..bb1a036beafd 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/BackupDownloadViewModel.kt @@ -151,7 +151,7 @@ class BackupDownloadViewModel @Inject constructor( when (wizardManager.currentStep) { DETAILS.id -> _wizardFinishedObservable.value = Event(BackupDownloadCanceled) PROGRESS.id -> constructProgressEvent() - COMPLETE.id -> _wizardFinishedObservable.value = Event(BackupDownloadCompleted) + COMPLETE.id -> constructCompleteEvent() ERROR.id -> _wizardFinishedObservable.value = Event(BackupDownloadCanceled) } } @@ -169,6 +169,19 @@ class BackupDownloadViewModel @Inject constructor( } } + private fun constructCompleteEvent() { + _wizardFinishedObservable.value = if (backupDownloadState.downloadId != null) { + Event( + BackupDownloadCompleted( + backupDownloadState.rewindId as String, + backupDownloadState.downloadId as Long + ) + ) + } else { + Event(BackupDownloadCanceled) + } + } + fun writeToBundle(outState: Bundle) { outState.putInt(KEY_BACKUP_DOWNLOAD_CURRENT_STEP, wizardManager.currentStep) outState.putParcelable(KEY_BACKUP_DOWNLOAD_STATE, backupDownloadState) @@ -441,10 +454,15 @@ class BackupDownloadViewModel @Inject constructor( @Parcelize data class BackupDownloadInProgress( val rewindId: String, - val downloadId: Long + val downloadId: Long, + val inProgress: Boolean = true ) : BackupDownloadWizardState() @Parcelize - object BackupDownloadCompleted : BackupDownloadWizardState() + data class BackupDownloadCompleted( + val rewindId: String, + val downloadId: Long, + val inProgress: Boolean = false + ) : BackupDownloadWizardState() } } diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/common/JetpackBackupDownloadActionState.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/common/JetpackBackupDownloadActionState.kt new file mode 100644 index 000000000000..78d934808118 --- /dev/null +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/common/JetpackBackupDownloadActionState.kt @@ -0,0 +1,7 @@ +package org.wordpress.android.ui.jetpack.common + +enum class JetpackBackupDownloadActionState(val id: Int) { + CANCEL(0), + COMPLETE(1), + PROGRESS(2) +} From b4272166ee7af3763cf70d46c501b33dc5567c37 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Wed, 24 Feb 2021 11:39:56 -0500 Subject: [PATCH 13/17] Add support for BackupDownload notice item --- .../activitylog/ActivityLogViewModel.kt | 120 ++++++++++++++---- 1 file changed, 93 insertions(+), 27 deletions(-) diff --git a/WordPress/src/main/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModel.kt b/WordPress/src/main/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModel.kt index 080aa7690f1d..cbc16fa54bcd 100644 --- a/WordPress/src/main/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModel.kt +++ b/WordPress/src/main/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModel.kt @@ -21,6 +21,8 @@ import org.wordpress.android.ui.activitylog.list.ActivityLogListItem import org.wordpress.android.ui.jetpack.JetpackCapabilitiesUseCase import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadRequestState import org.wordpress.android.ui.jetpack.backup.download.usecases.GetBackupDownloadStatusUseCase +import org.wordpress.android.ui.jetpack.backup.download.usecases.PostDismissBackupDownloadUseCase +import org.wordpress.android.ui.jetpack.common.JetpackBackupDownloadActionState.PROGRESS import org.wordpress.android.ui.jetpack.restore.RestoreRequestState import org.wordpress.android.ui.jetpack.restore.usecases.GetRestoreStatusUseCase import org.wordpress.android.ui.jetpack.restore.usecases.PostRestoreUseCase @@ -41,6 +43,7 @@ import org.wordpress.android.viewmodel.ResourceProvider import org.wordpress.android.viewmodel.SingleLiveEvent import org.wordpress.android.viewmodel.activitylog.ActivityLogViewModel.FiltersUiState.FiltersHidden import org.wordpress.android.viewmodel.activitylog.ActivityLogViewModel.FiltersUiState.FiltersShown +import java.util.Calendar import java.util.Date import javax.inject.Inject @@ -62,6 +65,7 @@ typealias DateRange = Pair * necessity to split those features in separate screens in order not to increase further the complexity of this * screen's architecture. */ +@Suppress("LargeClass") class ActivityLogViewModel @Inject constructor( private val activityLogStore: ActivityLogStore, private val postRestoreUseCase: PostRestoreUseCase, @@ -73,7 +77,8 @@ class ActivityLogViewModel @Inject constructor( private val dateUtils: DateUtils, private val activityLogTracker: ActivityLogTracker, private val jetpackCapabilitiesUseCase: JetpackCapabilitiesUseCase, - private val restoreFeatureConfig: RestoreFeatureConfig + private val restoreFeatureConfig: RestoreFeatureConfig, + private val postDismissBackupDownloadUseCase: PostDismissBackupDownloadUseCase ) : ViewModel() { enum class ActivityLogListStatus { CAN_LOAD_MORE, @@ -130,6 +135,7 @@ class ActivityLogViewModel @Inject constructor( it is ActivityLogListItem.Progress && it.progressType == ActivityLogListItem.Progress.Type.RESTORE } != null + private val isBackupDownloadProgressItemShown: Boolean get() = events.value?.find { it is ActivityLogListItem.Progress && @@ -142,6 +148,7 @@ class ActivityLogViewModel @Inject constructor( private var fetchActivitiesJob: Job? = null private var restoreStatusJob: Job? = null private var backupDownloadStatusJob: Job? = null + private var dismissBackupDownloadJob: Job? = null private var currentDateRangeFilter: DateRange? = null private var currentActivityTypeFilter: List = listOf() @@ -150,7 +157,7 @@ class ActivityLogViewModel @Inject constructor( var rewindableOnly: Boolean = false private var currentRestoreEvent = RestoreEvent(false) - private var currentBackupDownloadEvent = BackupDownloadEvent(false) + private var currentBackupDownloadEvent = BackupDownloadEvent(false, displayNotice = false) fun start(site: SiteModel, rewindableOnly: Boolean) { if (isStarted) { @@ -167,6 +174,7 @@ class ActivityLogViewModel @Inject constructor( showFiltersIfSupported() } + @Suppress("LongMethod", "ComplexMethod") @VisibleForTesting fun reloadEvents( done: Boolean = isDone, @@ -184,6 +192,7 @@ class ActivityLogViewModel @Inject constructor( var moveToTop = false val withRestoreProgressItem = restoreEvent.displayProgress && !restoreEvent.isCompleted val withBackupDownloadProgressItem = backupDownloadEvent.displayProgress && !backupDownloadEvent.isCompleted + val withBackupDownloadNoticeItem = backupDownloadEvent.displayNotice if (withRestoreProgressItem || withBackupDownloadProgressItem) { items.add(ActivityLogListItem.Header(resourceProvider.getString(R.string.now))) moveToTop = eventListStatus.value != ActivityLogListStatus.LOADING_MORE @@ -194,6 +203,12 @@ class ActivityLogViewModel @Inject constructor( if (withBackupDownloadProgressItem) { items.add(getBackupDownloadProgressItem(backupDownloadEvent.rewindId, backupDownloadEvent.published)) } + if (withBackupDownloadNoticeItem) { + getBackupDownloadNoticeItem(backupDownloadEvent)?.let { + items.add(it) + moveToTop = true + } + } eventList.forEach { model -> val currentItem = ActivityLogListItem.Event( model, @@ -223,8 +238,7 @@ class ActivityLogViewModel @Inject constructor( currentRestoreEvent = RestoreEvent(false) } if (backupDownloadEvent.isCompleted) { - showBackupDownloadFinishedMessage(backupDownloadEvent.rewindId, backupDownloadEvent.published) - currentBackupDownloadEvent = BackupDownloadEvent(false) + currentBackupDownloadEvent = currentBackupDownloadEvent.copy(displayProgress = false) } } @@ -265,6 +279,23 @@ class ActivityLogViewModel @Inject constructor( ) } + private fun getBackupDownloadNoticeItem(backupDownloadEvent: BackupDownloadEvent): ActivityLogListItem.Notice? { + val rewindDate = backupDownloadEvent.published + ?: backupDownloadEvent.rewindId?.let { activityLogStore.getActivityLogItemByRewindId(it)?.published } + return rewindDate?.let { + ActivityLogListItem.Notice( + label = resourceProvider.getString( + R.string.activity_log_backup_download_notice_description_with_two_params, + rewindDate.toFormattedDateString(), rewindDate.toFormattedTimeString() + ), + primaryActionButtonClickListener = this@ActivityLogViewModel::onDownloadBackupFileClicked, + secondaryActionButtonClickListener = this@ActivityLogViewModel::dismissNoticeClicked, + url = backupDownloadEvent.url as String, + downloadId = backupDownloadEvent.downloadId as Long + ) + } + } + private fun showRestoreFinishedMessage(rewindId: String?, published: Date?) { val rewindDate = published ?: rewindId?.let { activityLogStore.getActivityLogItemByRewindId(it)?.published } if (rewindDate != null) { @@ -477,7 +508,7 @@ class ActivityLogViewModel @Inject constructor( } } - // todo: annmarie - Remove once the feature exclusively uses the more menu + // todo: This code block should be removed once the restore feature exclusively uses the more menu fun onActionButtonClicked(item: ActivityLogListItem) { if (item is ActivityLogListItem.Event) { val navigationEvent = if (item.launchRestoreWizard) { @@ -511,6 +542,21 @@ class ActivityLogViewModel @Inject constructor( return true } + private fun onDownloadBackupFileClicked(url: String) { + activityLogTracker.trackDownloadBackupDownloadButtonClicked(rewindableOnly) + _navigationEvents.value = Event(ActivityLogNavigationEvents.DownloadBackupFile(url)) + } + + private fun dismissNoticeClicked(downloadId: Long) { + activityLogTracker.trackDownloadBackupDismissButtonClicked(rewindableOnly) + dismissBackupDownloadJob?.cancel() + dismissBackupDownloadJob = viewModelScope.launch { + postDismissBackupDownloadUseCase.dismissBackupDownload(downloadId, site) + // Always optimistic on a dismiss. If it doesn't work, the banner returns on the next PTR + reloadEvents(backupDownloadEvent = BackupDownloadEvent(displayNotice = false, displayProgress = false)) + } + } + fun dateRangePickerClicked() { activityLogTracker.trackDateRangeFilterButtonClicked(rewindableOnly) _showDateRangePicker.value = ShowDateRangePicker(initialSelection = currentDateRangeFilter) @@ -628,9 +674,14 @@ class ActivityLogViewModel @Inject constructor( } } - fun onQueryBackupDownloadStatus(rewindId: String, downloadId: Long) { + fun onQueryBackupDownloadStatus(rewindId: String, downloadId: Long, actionState: Int) { queryBackupDownloadStatus(downloadId) - showBackupDownloadStartedMessage(rewindId) + + if (actionState == PROGRESS.id) { + showBackupDownloadStartedMessage(rewindId) + } else { + showBackupDownloadFinishedMessage(rewindId, null) + } } private fun queryBackupDownloadStatus(downloadId: Long? = null) { @@ -650,29 +701,32 @@ class ActivityLogViewModel @Inject constructor( } private fun handleBackupDownloadStatusForProgress(state: BackupDownloadRequestState.Progress) { - if (!isBackupDownloadProgressItemShown) { - reloadEvents( - backupDownloadEvent = BackupDownloadEvent( - displayProgress = true, - isCompleted = false, - rewindId = state.rewindId, - published = state.published - ) - ) - } + reloadEvents( + backupDownloadEvent = BackupDownloadEvent( + displayProgress = true, + displayNotice = false, + isCompleted = false, + rewindId = state.rewindId, + published = state.published + ) + ) } private fun handleBackupDownloadStatusForComplete(state: BackupDownloadRequestState.Complete) { + val backupDownloadEvent = BackupDownloadEvent( + displayProgress = false, + displayNotice = isBackupDownloadFileValid(state.url, state.validUntil, state.downloadId), + isCompleted = true, + rewindId = state.rewindId, + published = state.published, + url = state.url, + validUntil = state.validUntil, + downloadId = state.downloadId + ) if (isBackupDownloadProgressItemShown) { - requestEventsUpdate( - loadMore = false, - backupDownloadEvent = BackupDownloadEvent( - displayProgress = false, - isCompleted = true, - rewindId = state.rewindId, - published = state.published - ) - ) + requestEventsUpdate(loadMore = false, backupDownloadEvent = backupDownloadEvent) + } else { + reloadEvents(backupDownloadEvent = backupDownloadEvent) } } @@ -686,6 +740,14 @@ class ActivityLogViewModel @Inject constructor( } } + private fun isBackupDownloadFileValid(url: String?, validUntil: Date?, downloadId: Long?): Boolean { + if (validUntil == null || url == null || downloadId == null) return false + // Now represents the current time using the current locale and timezone + val now = Calendar.getInstance().apply { time = Date() } + val expires = Calendar.getInstance().apply { time = validUntil } + return now.before(expires) + } + data class ShowDateRangePicker(val initialSelection: DateRange?) data class ShowActivityTypePicker( val siteId: RemoteId, @@ -702,9 +764,13 @@ class ActivityLogViewModel @Inject constructor( data class BackupDownloadEvent( val displayProgress: Boolean, + val displayNotice: Boolean, val isCompleted: Boolean = false, val rewindId: String? = null, - val published: Date? = null + val published: Date? = null, + val downloadId: Long? = null, + val url: String? = null, + val validUntil: Date? = null ) sealed class FiltersUiState(val visibility: Boolean) { From fdfd91bdd0318fc32d4043b4ab903bb5ef372a28 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Wed, 24 Feb 2021 11:42:42 -0500 Subject: [PATCH 14/17] Set progress footnote to visible --- .../download/builders/BackupDownloadStateListItemBuilder.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/builders/BackupDownloadStateListItemBuilder.kt b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/builders/BackupDownloadStateListItemBuilder.kt index 1270dbd3266c..e228d4becacf 100644 --- a/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/builders/BackupDownloadStateListItemBuilder.kt +++ b/WordPress/src/main/java/org/wordpress/android/ui/jetpack/backup/download/builders/BackupDownloadStateListItemBuilder.kt @@ -84,7 +84,7 @@ class BackupDownloadStateListItemBuilder @Inject constructor( iconRes = R.drawable.ic_info_outline_white_24dp, iconSizeResId = R.dimen.jetpack_backup_restore_footnote_icon_size, textRes = R.string.backup_download_progress_footnote, - isVisible = false) + isVisible = true) ) } From 51b3740600f597d82f158848727c51003f4a5453 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Wed, 24 Feb 2021 13:28:11 -0500 Subject: [PATCH 15/17] Add, remove, and update tests for backup download --- .../activitylog/ActivityLogViewModelTest.kt | 125 ++++++++---------- 1 file changed, 58 insertions(+), 67 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt b/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt index ef9095d85412..2339594569bf 100644 --- a/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/viewmodel/activitylog/ActivityLogViewModelTest.kt @@ -37,7 +37,9 @@ import org.wordpress.android.fluxc.store.ActivityLogStore.FetchActivityLogPayloa import org.wordpress.android.fluxc.store.ActivityLogStore.OnActivityLogFetched import org.wordpress.android.test import org.wordpress.android.ui.activitylog.ActivityLogNavigationEvents +import org.wordpress.android.ui.activitylog.ActivityLogNavigationEvents.DownloadBackupFile import org.wordpress.android.ui.activitylog.list.ActivityLogListItem +import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Notice import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Progress.Type.BACKUP_DOWNLOAD import org.wordpress.android.ui.activitylog.list.ActivityLogListItem.Progress.Type.RESTORE import org.wordpress.android.ui.jetpack.JetpackCapabilitiesUseCase @@ -45,6 +47,7 @@ import org.wordpress.android.ui.jetpack.JetpackCapabilitiesUseCase.JetpackPurcha import org.wordpress.android.ui.jetpack.backup.download.BackupDownloadRequestState import org.wordpress.android.ui.jetpack.backup.download.usecases.GetBackupDownloadStatusUseCase import org.wordpress.android.ui.jetpack.backup.download.usecases.PostDismissBackupDownloadUseCase +import org.wordpress.android.ui.jetpack.common.JetpackBackupDownloadActionState import org.wordpress.android.ui.jetpack.restore.RestoreRequestState import org.wordpress.android.ui.jetpack.restore.usecases.GetRestoreStatusUseCase import org.wordpress.android.ui.jetpack.restore.usecases.PostRestoreUseCase @@ -992,58 +995,47 @@ class ActivityLogViewModelTest { } @Test - fun `given backup finished with date, when reloading events, then show backup finished message with date`() { - val date = activity().published - val url = "www.wordpress.com" - val validUntil = activity().published - val downloadId = 10L - initBackupProgressFinishedMocks(date, true) + fun `given backup complete, when reloading events, then move to top is triggered`() { + initBackupDownloadCompleteMocks() - whenever( - resourceProvider.getString( - eq(R.string.activity_log_backup_download_notice_description_with_two_params), - any(), - any() - ) - ) - .thenReturn(BACKUP_NOTICE) + viewModel.reloadEvents(done = false, backupDownloadEvent = backupDownloadCompleteEvent()) - viewModel.reloadEvents( - done = false, - backupDownloadEvent = BackupDownloadEvent( - displayProgress = false, - displayNotice = true, - isCompleted = true, - rewindId = REWIND_ID, - published = date, - downloadId = downloadId, - url = url, - validUntil = validUntil - ) - ) + assertTrue(moveToTopEvents.isNotEmpty()) + } + + @Test + fun `given backup finished, when reloading events, then list contains notice item`() { + initBackupDownloadCompleteMocks() + + viewModel.reloadEvents(done = false, backupDownloadEvent = backupDownloadCompleteEvent()) - assertEquals(snackbarMessages.firstOrNull(), BACKED_UP_DATE_TIME) + assertThat(events.first()?.first()).isInstanceOf(Notice::class.java) } @Test - fun `given backup finished without date, when reloading events, then show backup finished msg without date`() { - val date = null - initBackupProgressFinishedMocks(date, false) + fun `given notice shown, when download clicked, then a navigationEvent is posted`() { + initBackupDownloadCompleteMocks() - viewModel.reloadEvents( - done = false, - backupDownloadEvent = BackupDownloadEvent( - displayProgress = false, - displayNotice = true, - isCompleted = true, - rewindId = REWIND_ID, - published = date - ) - ) + viewModel.reloadEvents(done = false, backupDownloadEvent = backupDownloadCompleteEvent()) - assertEquals(snackbarMessages.firstOrNull(), BACKED_UP_NO_DATE) + val notice = events.first()?.filterIsInstance() + notice?.first()?.primaryActionButtonClickListener?.invoke(backupDownloadCompleteEvent().url as String) + assertThat(navigationEvents.last().peekContent()).isInstanceOf(DownloadBackupFile::class.java) } + @Test + fun `given notice shown, when dismiss clicked, then item is removed from list`() { + initBackupDownloadCompleteMocks() + + viewModel.reloadEvents(done = false, backupDownloadEvent = backupDownloadCompleteEvent()) + + events.first() + ?.filterIsInstance() + ?.first() + ?.secondaryActionButtonClickListener + ?.invoke(backupDownloadCompleteEvent().downloadId as Long) + assertThat(events.last()?.filterIsInstance()).isEmpty() + } /* RELOAD EVENTS - RESTORE AND BACKUP DOWNLOAD */ @Test @@ -1395,7 +1387,7 @@ class ActivityLogViewModelTest { @Test fun `when query backup status, then trigger get backup download status`() = test { - viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID) + viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID, JetpackBackupDownloadActionState.PROGRESS.id) verify(getBackupDownloadStatusUseCase).getBackupDownloadStatus(site, DOWNLOAD_ID) } @@ -1407,7 +1399,7 @@ class ActivityLogViewModelTest { .thenReturn(flow { emit(progress) }) initBackupProgressMocks() - viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID) + viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID, JetpackBackupDownloadActionState.PROGRESS.id) assertEquals( viewModel.events.value, @@ -1435,7 +1427,7 @@ class ActivityLogViewModelTest { whenever(store.fetchActivities(anyOrNull())) .thenReturn(OnActivityLogFetched(10, false, ActivityLogAction.FETCH_ACTIVITIES)) - viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID) + viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID, JetpackBackupDownloadActionState.COMPLETE.id) assertEquals( viewModel.events.value, @@ -1453,13 +1445,14 @@ class ActivityLogViewModelTest { ) } + // todo: annmarie this might not be the case anymore @Test fun `given status is something else, when query backup status, then do not trigger anything`() = test { val success = BackupDownloadRequestState.Success(REWIND_ID, REWIND_ID, DOWNLOAD_ID) whenever(getBackupDownloadStatusUseCase.getBackupDownloadStatus(site, DOWNLOAD_ID)) .thenReturn(flow { emit(success) }) - viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID) + viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID, JetpackBackupDownloadActionState.CANCEL.id) assertNull(viewModel.events.value) } @@ -1470,7 +1463,7 @@ class ActivityLogViewModelTest { whenever(resourceProvider.getString(eq(R.string.activity_log_backup_started_snackbar_message), any(), any())) .thenReturn(BACKUP_STARTED) - viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID) + viewModel.onQueryBackupDownloadStatus(REWIND_ID, DOWNLOAD_ID, JetpackBackupDownloadActionState.PROGRESS.id) assertEquals(snackbarMessages.firstOrNull(), BACKUP_STARTED) } @@ -1603,6 +1596,17 @@ class ActivityLogViewModelTest { isProgressBarVisible = false ) + private fun backupDownloadCompleteEvent() = BackupDownloadEvent( + displayProgress = false, + displayNotice = true, + isCompleted = true, + rewindId = REWIND_ID, + published = activity().published, + url = "www.wordpress.com", + validUntil = activity().published, + downloadId = 10L + ) + private fun initRestoreProgressMocks(displayProgressWithDate: Boolean = true) { if (displayProgressWithDate) { whenever(store.getActivityLogItemByRewindId(REWIND_ID)).thenReturn(activity()) @@ -1655,27 +1659,14 @@ class ActivityLogViewModelTest { } } - private fun initBackupProgressFinishedMocks(date: Date?, displayProgressWithDate: Boolean) { - initBackupProgressMocks(displayProgressWithDate) - viewModel.reloadEvents( - done = false, - backupDownloadEvent = BackupDownloadEvent( - displayProgress = true, - displayNotice = false, - rewindId = REWIND_ID + private fun initBackupDownloadCompleteMocks() { + whenever( + resourceProvider.getString( + eq(R.string.activity_log_backup_download_notice_description_with_two_params), + any(), + any() ) ) - if (date != null) { - whenever( - resourceProvider.getString( - eq(R.string.activity_log_backup_finished_snackbar_message), - any(), - any() - ) - ).thenReturn(BACKED_UP_DATE_TIME) - } else { - whenever(resourceProvider.getString(R.string.activity_log_backup_finished_snackbar_message_no_dates)) - .thenReturn(BACKED_UP_NO_DATE) - } + .thenReturn(BACKUP_NOTICE) } } From e0d2f324a02aa6462274fa90f2cc637a17381108 Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Wed, 24 Feb 2021 14:22:44 -0500 Subject: [PATCH 16/17] Update fluxC version to point to commit --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 2fad008f5d93..1eedf2226abe 100644 --- a/build.gradle +++ b/build.gradle @@ -154,7 +154,7 @@ ext { androidxWorkVersion = "2.4.0" daggerVersion = '2.29.1' - fluxCVersion = '1.11.0' + fluxCVersion = '20ee318' appCompatVersion = '1.0.2' From 84d812ae4ab34b29adf0b22f32fa73cf4c9302ea Mon Sep 17 00:00:00 2001 From: Annmarie Ziegler Date: Wed, 24 Feb 2021 15:46:10 -0500 Subject: [PATCH 17/17] Fix failing test --- .../usecases/GetBackupDownloadStatusUseCaseTest.kt | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCaseTest.kt b/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCaseTest.kt index 7565d2b75167..c68d9a43859e 100644 --- a/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCaseTest.kt +++ b/WordPress/src/test/java/org/wordpress/android/ui/jetpack/backup/download/usecases/GetBackupDownloadStatusUseCaseTest.kt @@ -230,6 +230,7 @@ class GetBackupDownloadStatusUseCaseTest : BaseUnitTest() { private val downloadId = 100L private val progress = 50 private val published = Date() + private val validUntil = Date() private val statusModel = BackupDownloadStatusModel( downloadId = downloadId, @@ -238,7 +239,7 @@ class GetBackupDownloadStatusUseCaseTest : BaseUnitTest() { startedAt = Date(1609690147756), progress = null, downloadCount = 0, - validUntil = Date(1609690147756), + validUntil = validUntil, url = url ) @@ -249,7 +250,7 @@ class GetBackupDownloadStatusUseCaseTest : BaseUnitTest() { startedAt = Date(1609690147756), progress = progress, downloadCount = 0, - validUntil = Date(1609690147756), + validUntil = validUntil, url = url ) @@ -267,6 +268,6 @@ class GetBackupDownloadStatusUseCaseTest : BaseUnitTest() { actor = null ) - private val completeStatus = Complete(rewindId, downloadId, url, published) + private val completeStatus = Complete(rewindId, downloadId, url, published, validUntil) private val progressStatus = Progress(rewindId, progress, published) }