Skip to content

Commit

Permalink
Merge pull request #12196 from wordpress-mobile/issue-12195/persist_p…
Browse files Browse the repository at this point in the history
…ost_for_prepublishing_post_list

Prepublishing Nudges : Persist post changes that occur in the bottom sheet
  • Loading branch information
malinajirka authored Jun 26, 2020
2 parents 815a9b9 + 9049ef0 commit 186ce3b
Show file tree
Hide file tree
Showing 8 changed files with 74 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -705,7 +705,7 @@ private void startObserving() {
return null;
}));
mEditPostRepository.getPostChanged().observe(this, postEvent -> postEvent.applyIfNotHandled(post -> {
mViewModel.savePostToDb(this, mEditPostRepository, mSite);
mViewModel.savePostToDb(mEditPostRepository, mSite);
return null;
}));
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
package org.wordpress.android.ui.posts

import android.content.Context
import android.content.Intent
import androidx.lifecycle.Lifecycle
import androidx.lifecycle.LifecycleOwner
import androidx.lifecycle.LifecycleRegistry
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.Observer
import androidx.lifecycle.ViewModel
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -78,6 +80,7 @@ class PostListMainViewModel @Inject constructor(
private val postListEventListenerFactory: PostListEventListener.Factory,
private val previewStateHelper: PreviewStateHelper,
private val analyticsTracker: AnalyticsTrackerWrapper,
private val savePostToDbUseCase: SavePostToDbUseCase,
@Named(UI_THREAD) private val mainDispatcher: CoroutineDispatcher,
@Named(BG_THREAD) private val bgDispatcher: CoroutineDispatcher,
private val uploadStarter: UploadStarter
Expand Down Expand Up @@ -211,7 +214,8 @@ class PostListMainViewModel @Inject constructor(
site: SiteModel,
initPreviewState: PostListRemotePreviewState,
currentBottomSheetPostId: LocalId,
editPostRepository: EditPostRepository
editPostRepository: EditPostRepository,
context: Context
) {
this.site = site
this.editPostRepository = editPostRepository
Expand Down Expand Up @@ -273,6 +277,12 @@ class PostListMainViewModel @Inject constructor(
lifecycleRegistry.markState(Lifecycle.State.STARTED)

uploadStarter.queueUploadFromSite(site)

editPostRepository.run {
postChanged.observe(this@PostListMainViewModel, Observer {
savePostToDbUseCase.savePostToDb(editPostRepository, site)
})
}
}

override fun onCleared() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -247,7 +247,7 @@ class PostsListActivity : LocaleAwareActivity(),

private fun initViewModel(initPreviewState: PostListRemotePreviewState, currentBottomSheetPostId: LocalId) {
viewModel = ViewModelProviders.of(this, viewModelFactory).get(PostListMainViewModel::class.java)
viewModel.start(site, initPreviewState, currentBottomSheetPostId, editPostRepository)
viewModel.start(site, initPreviewState, currentBottomSheetPostId, editPostRepository, this)

viewModel.viewState.observe(this, Observer { state ->
state?.let {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,10 +15,10 @@ class SavePostToDbUseCase
private val uploadUtils: UploadUtilsWrapper,
private val dateTimeUtils: DateTimeUtilsWrapper,
private val dispatcher: Dispatcher,
private val pendingDraftsNotificationsUtils: PendingDraftsNotificationsUtilsWrapper
private val pendingDraftsNotificationsUtils: PendingDraftsNotificationsUtilsWrapper,
private val context: Context
) {
fun savePostToDb(
context: Context,
postRepository: EditPostRepository,
site: SiteModel
) {
Expand All @@ -43,14 +43,13 @@ class SavePostToDbUseCase
post.setIsLocallyChanged(true)
}
post.setDateLocallyChanged(dateTimeUtils.currentTimeInIso8601())
handlePendingDraftNotifications(context, postRepository)
handlePendingDraftNotifications(postRepository)
postRepository.savePostSnapshot()
dispatcher.dispatch(PostActionBuilder.newUpdatePostAction(post))
}
}

private fun handlePendingDraftNotifications(
context: Context,
editPostRepository: EditPostRepository
) {
if (editPostRepository.status == PostStatus.DRAFT) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ class StorePostViewModel
editPostRepository: EditPostRepository,
site: SiteModel
): ActivityFinishState {
savePostToDbUseCase.savePostToDb(context, editPostRepository, site)
savePostToDbUseCase.savePostToDb(editPostRepository, site)
return if (networkUtils.isNetworkAvailable()) {
postUtils.trackSavePostAnalytics(
editPostRepository.getPost(),
Expand All @@ -79,11 +79,10 @@ class StorePostViewModel
}

fun savePostToDb(
context: Context,
postRepository: EditPostRepository,
site: SiteModel
) {
savePostToDbUseCase.savePostToDb(context, postRepository, site)
savePostToDbUseCase.savePostToDb(postRepository, site)
}

fun updatePostObjectWithUIAsync(
Expand Down
Original file line number Diff line number Diff line change
@@ -1,31 +1,42 @@
package org.wordpress.android.ui.posts

import androidx.lifecycle.MutableLiveData
import com.nhaarman.mockitokotlin2.any
import com.nhaarman.mockitokotlin2.doReturn
import com.nhaarman.mockitokotlin2.eq
import com.nhaarman.mockitokotlin2.mock
import com.nhaarman.mockitokotlin2.times
import com.nhaarman.mockitokotlin2.verify
import com.nhaarman.mockitokotlin2.whenever
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
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.Dispatcher
import org.wordpress.android.fluxc.model.LocalOrRemoteId.LocalId
import org.wordpress.android.fluxc.model.PostModel
import org.wordpress.android.fluxc.model.SiteModel
import org.wordpress.android.ui.posts.PostListViewLayoutType.COMPACT
import org.wordpress.android.ui.posts.PostListViewLayoutType.STANDARD
import org.wordpress.android.ui.prefs.AppPrefsWrapper
import org.wordpress.android.ui.uploads.UploadStarter
import org.wordpress.android.viewmodel.Event

class PostListMainViewModelTest : BaseUnitTest() {
lateinit var site: SiteModel
private val currentBottomSheetPostId = LocalId(0)
@Mock lateinit var uploadStarter: UploadStarter
@Mock lateinit var dispatcher: Dispatcher
@Mock lateinit var editPostRepository: EditPostRepository
@Mock lateinit var savePostToDbUseCase: SavePostToDbUseCase
private lateinit var viewModel: PostListMainViewModel

@InternalCoroutinesApi
@UseExperimental(ExperimentalCoroutinesApi::class)
@Before
fun setUp() {
Expand All @@ -35,8 +46,10 @@ class PostListMainViewModelTest : BaseUnitTest() {

site = SiteModel()

whenever(editPostRepository.postChanged).thenReturn(MutableLiveData(Event(PostModel())))

viewModel = PostListMainViewModel(
dispatcher = mock(),
dispatcher = dispatcher,
postStore = mock(),
accountStore = mock(),
uploadStore = mock(),
Expand All @@ -49,21 +62,22 @@ class PostListMainViewModelTest : BaseUnitTest() {
bgDispatcher = Dispatchers.Unconfined,
postListEventListenerFactory = mock(),
uploadStarter = uploadStarter,
uploadActionUseCase = mock()
uploadActionUseCase = mock(),
savePostToDbUseCase = savePostToDbUseCase
)
}

@Test
fun `when started, it uploads all local drafts`() {
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())

verify(uploadStarter, times(1)).queueUploadFromSite(eq(site))
}

@Test
fun `search is available for wpcom and jetpack sites`() {
site.origin = SiteModel.ORIGIN_WPCOM_REST
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())

var isSearchAvailable = false
viewModel.isSearchAvailable.observeForever {
Expand All @@ -76,7 +90,7 @@ class PostListMainViewModelTest : BaseUnitTest() {
@Test
fun `search is not available for xmlrpc sites`() {
site.origin = SiteModel.ORIGIN_XMLRPC
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())

var isSearchAvailable = true
viewModel.isSearchAvailable.observeForever {
Expand All @@ -89,7 +103,7 @@ class PostListMainViewModelTest : BaseUnitTest() {
@Test
fun `calling onSearch() updates search query`() {
val testSearch = "keyword"
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())

var searchQuery: String? = null
viewModel.searchQuery.observeForever {
Expand All @@ -103,7 +117,7 @@ class PostListMainViewModelTest : BaseUnitTest() {

@Test
fun `expanding and collapsing search triggers isSearchExpanded`() {
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())

var isSearchExpanded = false
viewModel.isSearchExpanded.observeForever {
Expand All @@ -121,7 +135,7 @@ class PostListMainViewModelTest : BaseUnitTest() {
fun `expanding search after configuration change preserves search query`() {
val testSearch = "keyword"

viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())

var searchQuery: String? = null
viewModel.searchQuery.observeForever {
Expand All @@ -144,7 +158,7 @@ class PostListMainViewModelTest : BaseUnitTest() {

@Test
fun `search is using compact view mode independently from normal post list`() {
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, mock())
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())
assertThat(viewModel.viewLayoutType.value).isEqualTo(STANDARD) // default value

var viewLayoutType: PostListViewLayoutType? = null
Expand All @@ -164,11 +178,10 @@ class PostListMainViewModelTest : BaseUnitTest() {
@Test
fun `if currentBottomSheetPostId isn't 0 then set the post in editPostRepository from the postStore`() {
// arrange
val editPostRepository: EditPostRepository = mock()
val bottomSheetPostId = LocalId(2)

// act
viewModel.start(site, PostListRemotePreviewState.NONE, bottomSheetPostId, editPostRepository)
viewModel.start(site, PostListRemotePreviewState.NONE, bottomSheetPostId, editPostRepository, mock())

// assert
verify(editPostRepository, times(1)).loadPostByLocalPostId(any())
Expand All @@ -177,13 +190,29 @@ class PostListMainViewModelTest : BaseUnitTest() {
@Test
fun `if currentBottomSheetPostId is 0 then don't set the post in editPostRepository from the postStore`() {
// arrange
val editPostRepository: EditPostRepository = mock()
val bottomSheetPostId = LocalId(0)

// act
viewModel.start(site, PostListRemotePreviewState.NONE, bottomSheetPostId, editPostRepository)
viewModel.start(site, PostListRemotePreviewState.NONE, bottomSheetPostId, editPostRepository, mock())

// assert
verify(editPostRepository, times(0)).loadPostByLocalPostId(any())
}

@InternalCoroutinesApi
@Test
fun `if post in EditPostRepository is modified then the savePostToDbUseCase should update the post`() {
// arrange
val editPostRepository = EditPostRepository(mock(), mock(), mock(), TEST_DISPATCHER, TEST_DISPATCHER)
editPostRepository.set { mock() }
val action = { _: PostModel -> true }

// act
viewModel.start(site, PostListRemotePreviewState.NONE, currentBottomSheetPostId, editPostRepository, mock())
// simulates the Publish Date, Status & Visibility or Tags being updated in the bottom sheet.
editPostRepository.updateAsync(action, null)

// assert
verify(savePostToDbUseCase, times(1)).savePostToDb(any(), any())
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,15 @@ class SavePostToDbUseCaseTest {
private lateinit var actionCaptor: KArgumentCaptor<Action<PostModel>>
private val currentTime = "2019-08-09T10:01:03+00:00"
private val postId = 1

@Before
fun setUp() {
savePostToDbUseCase = SavePostToDbUseCase(
uploadUtils,
dateTimeUtils,
dispatcher,
pendingDraftsNotificationsUtils
pendingDraftsNotificationsUtils,
context
)
actionCaptor = argumentCaptor()
whenever(dateTimeUtils.currentTimeInIso8601()).thenReturn(currentTime)
Expand All @@ -63,7 +65,7 @@ class SavePostToDbUseCaseTest {
// Given
setupPost(postHasChanges = true)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
verify(postRepository).savePostSnapshot()
assertThat(actionCaptor.firstValue).isNotNull
Expand All @@ -76,7 +78,7 @@ class SavePostToDbUseCaseTest {
// Given
setupPost(postHasChanges = false)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
verify(postRepository, never()).savePostSnapshot()
assertThat(actionCaptor.allValues).isEmpty()
Expand All @@ -95,7 +97,7 @@ class SavePostToDbUseCaseTest {
// Given
setupPost(userCanPublish = false, postStatus = postStatus)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
assertThat(postModel.status).isEqualTo(PENDING.toString())
}
Expand All @@ -111,7 +113,7 @@ class SavePostToDbUseCaseTest {
// Given
setupPost(userCanPublish = false, postStatus = postStatus)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
assertThat(postModel.status).isEqualTo(postStatus.toString())
}
Expand All @@ -131,7 +133,7 @@ class SavePostToDbUseCaseTest {
// Given
setupPost(userCanPublish = true, postStatus = postStatus)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
assertThat(postModel.status).isEqualTo(postStatus.toString())
}
Expand All @@ -142,7 +144,7 @@ class SavePostToDbUseCaseTest {
// Given
setupPost(postStatus = PUBLISHED)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
verify(pendingDraftsNotificationsUtils).cancelPendingDraftAlarms(context, postId)
}
Expand All @@ -153,7 +155,7 @@ class SavePostToDbUseCaseTest {
setupPost(postStatus = DRAFT)
whenever(postRepository.dateLocallyChanged).thenReturn(currentTime)
// When
savePostToDbUseCase.savePostToDb(context, postRepository, siteModel)
savePostToDbUseCase.savePostToDb(postRepository, siteModel)
// Then
verify(pendingDraftsNotificationsUtils).scheduleNextNotifications(
context,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -92,9 +92,9 @@ class StorePostViewModelTest : BaseUnitTest() {

@Test
fun `saves post to DB`() {
viewModel.savePostToDb(context, postRepository, site)
viewModel.savePostToDb(postRepository, site)

verify(savePostToDbUseCase).savePostToDb(context, postRepository, site)
verify(savePostToDbUseCase).savePostToDb(postRepository, site)
}

@Test
Expand Down Expand Up @@ -206,7 +206,7 @@ class StorePostViewModelTest : BaseUnitTest() {
site
)

verify(savePostToDbUseCase).savePostToDb(context, postRepository, site)
verify(savePostToDbUseCase).savePostToDb(postRepository, site)
assertThat(result).isEqualTo(SAVED_LOCALLY)
verifyZeroInteractions(postUtils)
verifyZeroInteractions(uploadService)
Expand All @@ -224,7 +224,7 @@ class StorePostViewModelTest : BaseUnitTest() {
site
)

verify(savePostToDbUseCase).savePostToDb(context, postRepository, site)
verify(savePostToDbUseCase).savePostToDb(postRepository, site)
assertThat(result).isEqualTo(SAVED_ONLINE)
verify(postUtils).trackSavePostAnalytics(postModel, site)
verify(uploadService).uploadPost(context, postId, isFirstTimePublish)
Expand Down

0 comments on commit 186ce3b

Please sign in to comment.