diff --git a/Simplenote/src/main/java/com/automattic/simplenote/AddCollaboratorFragment.kt b/Simplenote/src/main/java/com/automattic/simplenote/AddCollaboratorFragment.kt index 2e67c5971..e6d223922 100644 --- a/Simplenote/src/main/java/com/automattic/simplenote/AddCollaboratorFragment.kt +++ b/Simplenote/src/main/java/com/automattic/simplenote/AddCollaboratorFragment.kt @@ -1,12 +1,12 @@ package com.automattic.simplenote import android.app.Dialog -import android.content.Context import android.content.DialogInterface import android.os.Bundle import android.os.Handler import android.view.ContextThemeWrapper import android.view.LayoutInflater +import androidx.annotation.StringRes import androidx.appcompat.app.AlertDialog import androidx.appcompat.app.AppCompatDialogFragment import androidx.core.widget.doAfterTextChanged @@ -14,6 +14,7 @@ import androidx.fragment.app.viewModels import com.automattic.simplenote.databinding.AddCollaboratorBinding import com.automattic.simplenote.utils.DisplayUtils import com.automattic.simplenote.viewmodels.AddCollaboratorViewModel +import com.automattic.simplenote.viewmodels.AddCollaboratorViewModel.Event import com.automattic.simplenote.widgets.MorphCircleToRectangle import dagger.hilt.android.AndroidEntryPoint @@ -83,16 +84,17 @@ class AddCollaboratorFragment(private val noteId: String) : AppCompatDialogFragm private fun setObservers() { viewModel.event.observe(this, { event -> when (event) { - AddCollaboratorViewModel.Event.Close, - AddCollaboratorViewModel.Event.NoteDeleted, // In case the note is deleted, the activity handles it. - AddCollaboratorViewModel.Event.NoteInTrash, // In case the note is trashed, the activity handles it. - AddCollaboratorViewModel.Event.CollaboratorAdded -> dismiss() - AddCollaboratorViewModel.Event.InvalidCollaborator -> setErrorInputField() + Event.Close, + Event.NoteDeleted, // In case the note is deleted, the activity handles it. + Event.NoteInTrash, // In case the note is trashed, the activity handles it. + Event.CollaboratorAdded -> dismiss() + Event.InvalidCollaborator -> setErrorInputField(R.string.invalid_collaborator) + Event.CollaboratorCurrentUser -> setErrorInputField(R.string.collaborator_is_current_user) } }) } - private fun setErrorInputField() { - binding.collaboratorInput.error = getString(R.string.invalid_collaborator) + private fun setErrorInputField(@StringRes message: Int) { + binding.collaboratorInput.error = getString(message) } } diff --git a/Simplenote/src/main/java/com/automattic/simplenote/CollaboratorsActivity.kt b/Simplenote/src/main/java/com/automattic/simplenote/CollaboratorsActivity.kt index a29ad2e67..e61e65142 100644 --- a/Simplenote/src/main/java/com/automattic/simplenote/CollaboratorsActivity.kt +++ b/Simplenote/src/main/java/com/automattic/simplenote/CollaboratorsActivity.kt @@ -13,6 +13,8 @@ import androidx.appcompat.widget.Toolbar import androidx.recyclerview.widget.LinearLayoutManager import com.automattic.simplenote.databinding.ActivityCollaboratorsBinding import com.automattic.simplenote.utils.CollaboratorsAdapter +import com.automattic.simplenote.utils.CollaboratorsAdapter.* +import com.automattic.simplenote.utils.CollaboratorsAdapter.CollaboratorDataItem.* import com.automattic.simplenote.utils.toast import com.automattic.simplenote.viewmodels.CollaboratorsViewModel import com.automattic.simplenote.viewmodels.CollaboratorsViewModel.Event @@ -73,8 +75,13 @@ class CollaboratorsActivity : ThemedAppCompatActivity() { collaboratorsList.adapter = CollaboratorsAdapter(viewModel::clickRemoveCollaborator) collaboratorsList.isNestedScrollingEnabled = false collaboratorsList.layoutManager = LinearLayoutManager(this@CollaboratorsActivity) + collaboratorsList.setEmptyView(empty.root) - rowAddCollaborator.setOnClickListener { viewModel.clickAddCollaborator() } + buttonAddCollaborator.setOnClickListener { viewModel.clickAddCollaborator() } + + empty.image.setImageResource(R.drawable.ic_collaborate_24dp) + empty.title.text = getString(R.string.no_collaborators) + empty.message.text = getString(R.string.add_email_collaborator_message) } private fun setupToolbar() { @@ -113,21 +120,26 @@ class CollaboratorsActivity : ThemedAppCompatActivity() { } private fun ActivityCollaboratorsBinding.handleCollaboratorsList(collaborators: List) { - sharedMessage.visibility = View.VISIBLE - collaboratorsList.visibility = View.VISIBLE - dividerLine.visibility = View.VISIBLE - buttonAddCollaborator.visibility = View.VISIBLE - emptyMessage.visibility = View.GONE - - (collaboratorsList.adapter as CollaboratorsAdapter).submitList(collaborators) + hideEmptyView() + val items = listOf(HeaderItem) + collaborators.map { CollaboratorItem(it) } + (collaboratorsList.adapter as CollaboratorsAdapter).submitList(items) } private fun ActivityCollaboratorsBinding.handleEmptyCollaborators() { - sharedMessage.visibility = View.GONE - collaboratorsList.visibility = View.GONE - dividerLine.visibility = View.GONE - buttonAddCollaborator.visibility = View.VISIBLE - emptyMessage.visibility = View.VISIBLE + showEmptyView() + (collaboratorsList.adapter as CollaboratorsAdapter).submitList(emptyList()) + } + + private fun ActivityCollaboratorsBinding.hideEmptyView() { + empty.image.visibility = View.GONE + empty.title.visibility = View.GONE + empty.message.visibility = View.GONE + } + + private fun ActivityCollaboratorsBinding.showEmptyView() { + empty.image.visibility = View.VISIBLE + empty.title.visibility = View.VISIBLE + empty.message.visibility = View.VISIBLE } private fun showAddCollaboratorFragment(event: Event.AddCollaboratorEvent) { diff --git a/Simplenote/src/main/java/com/automattic/simplenote/NoteMarkdownFragment.java b/Simplenote/src/main/java/com/automattic/simplenote/NoteMarkdownFragment.java index a908d75e5..5421fd26b 100644 --- a/Simplenote/src/main/java/com/automattic/simplenote/NoteMarkdownFragment.java +++ b/Simplenote/src/main/java/com/automattic/simplenote/NoteMarkdownFragment.java @@ -1,6 +1,11 @@ package com.automattic.simplenote; +import static com.automattic.simplenote.Simplenote.SCROLL_POSITION_PREFERENCES; +import static com.automattic.simplenote.analytics.AnalyticsTracker.CATEGORY_NOTE; +import static com.automattic.simplenote.utils.SimplenoteLinkify.SIMPLENOTE_LINK_PREFIX; + import android.content.Context; +import android.content.Intent; import android.content.SharedPreferences; import android.os.AsyncTask; import android.os.Bundle; @@ -41,9 +46,6 @@ import java.lang.ref.SoftReference; import java.util.Set; -import static com.automattic.simplenote.Simplenote.SCROLL_POSITION_PREFERENCES; -import static com.automattic.simplenote.utils.SimplenoteLinkify.SIMPLENOTE_LINK_PREFIX; - public class NoteMarkdownFragment extends Fragment implements Bucket.Listener { public static final String ARG_ITEM_ID = "item_id"; @@ -185,6 +187,9 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { case R.id.menu_delete: NoteUtils.showDialogDeletePermanently(requireActivity(), mNote); return true; + case R.id.menu_collaborators: + navigateToCollaborators(); + return true; case R.id.menu_trash: if (!isAdded()) { return false; @@ -194,9 +199,9 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { return true; case R.id.menu_copy_internal: AnalyticsTracker.track( - AnalyticsTracker.Stat.INTERNOTE_LINK_COPIED, - AnalyticsTracker.CATEGORY_LINK, - "internote_link_copied_markdown" + AnalyticsTracker.Stat.INTERNOTE_LINK_COPIED, + AnalyticsTracker.CATEGORY_LINK, + "internote_link_copied_markdown" ); if (!isAdded()) { @@ -215,6 +220,22 @@ public boolean onOptionsItemSelected(@NonNull MenuItem item) { } } + private void navigateToCollaborators() { + if (getActivity() == null || mNote == null) { + return; + } + + Intent intent = new Intent(requireActivity(), CollaboratorsActivity.class); + intent.putExtra(CollaboratorsActivity.NOTE_ID_ARG, mNote.getSimperiumKey()); + startActivity(intent); + + AnalyticsTracker.track( + AnalyticsTracker.Stat.EDITOR_COLLABORATORS_ACCESSED, + CATEGORY_NOTE, + "collaborators_ui_accessed" + ); + } + private void deleteNote() { NoteUtils.deleteNote(mNote, getActivity()); requireActivity().finish(); diff --git a/Simplenote/src/main/java/com/automattic/simplenote/authentication/SessionManager.kt b/Simplenote/src/main/java/com/automattic/simplenote/authentication/SessionManager.kt new file mode 100644 index 000000000..47c49debe --- /dev/null +++ b/Simplenote/src/main/java/com/automattic/simplenote/authentication/SessionManager.kt @@ -0,0 +1,21 @@ +package com.automattic.simplenote.authentication + +import com.simperium.Simperium +import com.simperium.client.User +import javax.inject.Inject + +sealed class UserSession { + object UnauthorizedUser : UserSession() + data class AuthorizedUser(val user: User) : UserSession() +} + +class SessionManager @Inject constructor(private val simperium: Simperium) { + fun getCurrentUser(): UserSession { + val currentUser = simperium.user ?: return UserSession.UnauthorizedUser + + return when (currentUser.email != null && !currentUser.needsAuthorization()) { + true -> UserSession.AuthorizedUser(currentUser) + false -> UserSession.UnauthorizedUser + } + } +} diff --git a/Simplenote/src/main/java/com/automattic/simplenote/di/DataModule.kt b/Simplenote/src/main/java/com/automattic/simplenote/di/DataModule.kt index daa55b411..763935ba2 100644 --- a/Simplenote/src/main/java/com/automattic/simplenote/di/DataModule.kt +++ b/Simplenote/src/main/java/com/automattic/simplenote/di/DataModule.kt @@ -1,6 +1,5 @@ package com.automattic.simplenote.di -import android.content.Context import com.automattic.simplenote.Simplenote import com.automattic.simplenote.models.Note import com.automattic.simplenote.models.Tag @@ -8,14 +7,16 @@ import com.automattic.simplenote.repositories.CollaboratorsRepository import com.automattic.simplenote.repositories.SimperiumCollaboratorsRepository import com.automattic.simplenote.repositories.SimperiumTagsRepository import com.automattic.simplenote.repositories.TagsRepository +import com.simperium.Simperium import com.simperium.client.Bucket import dagger.Binds import dagger.Module import dagger.Provides import dagger.hilt.InstallIn -import dagger.hilt.android.qualifiers.ApplicationContext import dagger.hilt.components.SingletonComponent +import kotlinx.coroutines.ExperimentalCoroutinesApi +@ExperimentalCoroutinesApi @Module @InstallIn(SingletonComponent::class) abstract class DataModule { @@ -25,6 +26,9 @@ abstract class DataModule { @Provides fun providesNotesBucket(simplenote: Simplenote): Bucket = simplenote.notesBucket + + @Provides + fun providesSimperium(simplenote: Simplenote): Simperium = simplenote.simperium } @Binds diff --git a/Simplenote/src/main/java/com/automattic/simplenote/utils/CollaboratorsAdapter.kt b/Simplenote/src/main/java/com/automattic/simplenote/utils/CollaboratorsAdapter.kt index 6897426d2..5bfcb7efd 100644 --- a/Simplenote/src/main/java/com/automattic/simplenote/utils/CollaboratorsAdapter.kt +++ b/Simplenote/src/main/java/com/automattic/simplenote/utils/CollaboratorsAdapter.kt @@ -6,38 +6,73 @@ import androidx.recyclerview.widget.DiffUtil import androidx.recyclerview.widget.ListAdapter import androidx.recyclerview.widget.RecyclerView import com.automattic.simplenote.databinding.CollaboratorRowBinding +import com.automattic.simplenote.databinding.CollaboratorsHeaderBinding class CollaboratorsAdapter( private val onDeleteClick: (collaborator: String) -> Unit, -) : ListAdapter(DIFF_CALLBACK) { +) : ListAdapter(DIFF_CALLBACK) { - override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): CollaboratorViewHolder { - val binding = CollaboratorRowBinding.inflate(LayoutInflater.from(parent.context), parent, false) - return CollaboratorViewHolder(binding, onDeleteClick) + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder { + return when (viewType) { + ITEM_VIEW_TYPE_HEADER -> { + val binding = CollaboratorsHeaderBinding.inflate(LayoutInflater.from(parent.context), parent, false) + CollaboratorHeaderViewHolder(binding) + } + ITEM_VIEW_TYPE_ITEM -> { + val binding = CollaboratorRowBinding.inflate(LayoutInflater.from(parent.context), parent, false) + CollaboratorViewHolder(binding, onDeleteClick) + } + else -> throw ClassCastException("Unknown viewType $viewType") + } } - override fun onBindViewHolder(holder: CollaboratorViewHolder, position: Int) { - holder.bind(getItem(position)) + override fun getItemViewType(position: Int): Int { + return when (getItem(position)) { + is CollaboratorDataItem.HeaderItem -> ITEM_VIEW_TYPE_HEADER + is CollaboratorDataItem.CollaboratorItem -> ITEM_VIEW_TYPE_ITEM + } + } + + override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) { + if (holder is CollaboratorViewHolder) { + holder.bind(getItem(position) as CollaboratorDataItem.CollaboratorItem) + } } + sealed class CollaboratorDataItem { + abstract val id: Int + object HeaderItem : CollaboratorDataItem() { + override val id = Int.MIN_VALUE + } + data class CollaboratorItem(val email: String) : CollaboratorDataItem() { + override val id = email.hashCode() + } + } + + class CollaboratorHeaderViewHolder( + binding: CollaboratorsHeaderBinding + ) : RecyclerView.ViewHolder(binding.root) + class CollaboratorViewHolder( private val binding: CollaboratorRowBinding, private val onDeleteClick: (collaborator: String) -> Unit ): RecyclerView.ViewHolder(binding.root) { - fun bind(collaborator: String) { - binding.collaboratorText.text = collaborator - binding.collaboratorRemoveButton.setOnClickListener { onDeleteClick(collaborator) } + fun bind(collaborator: CollaboratorDataItem.CollaboratorItem) { + binding.collaboratorText.text = collaborator.email + binding.collaboratorRemoveButton.setOnClickListener { onDeleteClick(collaborator.email) } } } companion object { - val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { - override fun areItemsTheSame(oldItem: String, newItem: String): Boolean { - return oldItem == newItem + private const val ITEM_VIEW_TYPE_HEADER = 0 + private const val ITEM_VIEW_TYPE_ITEM = 1 + private val DIFF_CALLBACK = object : DiffUtil.ItemCallback() { + override fun areItemsTheSame(oldItem: CollaboratorDataItem, newItem: CollaboratorDataItem): Boolean { + return oldItem.id == newItem.id } - override fun areContentsTheSame(oldItem: String, newItem: String): Boolean { + override fun areContentsTheSame(oldItem: CollaboratorDataItem, newItem: CollaboratorDataItem): Boolean { return oldItem == newItem } } diff --git a/Simplenote/src/main/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModel.kt b/Simplenote/src/main/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModel.kt index 9d26f643b..f47d95c06 100644 --- a/Simplenote/src/main/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModel.kt +++ b/Simplenote/src/main/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModel.kt @@ -4,6 +4,8 @@ import androidx.lifecycle.LiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.automattic.simplenote.analytics.AnalyticsTracker +import com.automattic.simplenote.authentication.SessionManager +import com.automattic.simplenote.authentication.UserSession import com.automattic.simplenote.repositories.CollaboratorsActionResult import com.automattic.simplenote.repositories.CollaboratorsRepository import dagger.hilt.android.lifecycle.HiltViewModel @@ -12,39 +14,51 @@ import javax.inject.Inject @HiltViewModel class AddCollaboratorViewModel @Inject constructor( - private val collaboratorsRepository: CollaboratorsRepository + private val collaboratorsRepository: CollaboratorsRepository, + private val sessionManager: SessionManager ) : ViewModel() { private val _event = SingleLiveEvent() val event: LiveData = _event fun addCollaborator(noteId: String, collaborator: String) { - viewModelScope.launch { - when (collaboratorsRepository.isValidCollaborator(collaborator)) { - true -> when (collaboratorsRepository.addCollaborator(noteId, collaborator)) { - is CollaboratorsActionResult.CollaboratorsList -> { - _event.value = Event.CollaboratorAdded + when (isCurrentUser(collaborator)) { + true -> _event.value = Event.CollaboratorCurrentUser + false -> viewModelScope.launch { + when (collaboratorsRepository.isValidCollaborator(collaborator)) { + true -> when (collaboratorsRepository.addCollaborator(noteId, collaborator)) { + is CollaboratorsActionResult.CollaboratorsList -> { + _event.value = Event.CollaboratorAdded - AnalyticsTracker.track( - AnalyticsTracker.Stat.COLLABORATOR_ADDED, - AnalyticsTracker.CATEGORY_NOTE, - "collaborator_added_to_note", - mapOf("source" to "collaborators") - ) + AnalyticsTracker.track( + AnalyticsTracker.Stat.COLLABORATOR_ADDED, + AnalyticsTracker.CATEGORY_NOTE, + "collaborator_added_to_note", + mapOf("source" to "collaborators") + ) + } + CollaboratorsActionResult.NoteDeleted -> _event.value = Event.NoteDeleted + CollaboratorsActionResult.NoteInTrash -> _event.value = Event.NoteInTrash } - CollaboratorsActionResult.NoteDeleted -> _event.value = Event.NoteDeleted - CollaboratorsActionResult.NoteInTrash -> _event.value = Event.NoteInTrash + false -> _event.value = Event.InvalidCollaborator } - false -> _event.value = Event.InvalidCollaborator } } } + private fun isCurrentUser(collaborator: String): Boolean { + return when (val currentUser = sessionManager.getCurrentUser()) { + is UserSession.AuthorizedUser -> currentUser.user.email == collaborator + is UserSession.UnauthorizedUser -> false // This should not happen. + } + } + fun close() { _event.value = Event.Close } sealed class Event { object InvalidCollaborator : Event() + object CollaboratorCurrentUser : Event() object CollaboratorAdded : Event() object Close : Event() object NoteInTrash : Event() diff --git a/Simplenote/src/main/res/layout/activity_collaborators.xml b/Simplenote/src/main/res/layout/activity_collaborators.xml index 88384f426..8ebf76e98 100644 --- a/Simplenote/src/main/res/layout/activity_collaborators.xml +++ b/Simplenote/src/main/res/layout/activity_collaborators.xml @@ -1,7 +1,7 @@ - + android:layout_height="match_parent" + android:orientation="vertical"> - + android:layout_height="match_parent" + android:layout_marginBottom="10dp" + android:background="@android:color/transparent" + android:clipToPadding="false" + android:divider="?attr/listDividerDrawable" + android:dividerHeight="@dimen/divider_height" + android:paddingBottom="@dimen/padding_list_bottom" + android:scrollbarStyle="outsideOverlay" + android:scrollbars="vertical" /> + + + + + + - - - - - - - - - - - - - - - - diff --git a/Simplenote/src/main/res/layout/activity_tags.xml b/Simplenote/src/main/res/layout/activity_tags.xml index 3bb513c73..dbe2b091e 100644 --- a/Simplenote/src/main/res/layout/activity_tags.xml +++ b/Simplenote/src/main/res/layout/activity_tags.xml @@ -1,20 +1,17 @@ - - - + - + layout="@layout/empty_view" /> - + app:tint="?attr/fabIconColor" /> diff --git a/Simplenote/src/main/res/layout/collaborator_row.xml b/Simplenote/src/main/res/layout/collaborator_row.xml index 4fc48ce04..dd4ef5dd1 100644 --- a/Simplenote/src/main/res/layout/collaborator_row.xml +++ b/Simplenote/src/main/res/layout/collaborator_row.xml @@ -15,12 +15,12 @@ android:layout_height="wrap_content" android:layout_weight="1" android:layout_width="0dp" + style="?android:attr/textAppearanceMedium" + android:layout_marginStart="@dimen/padding_large" android:textColor="?attr/noteTitleColor" tools:text="Test" - android:layout_marginEnd="@dimen/padding_small" android:textSize="16sp" - style="?android:attr/textAppearanceMedium"> - + android:layout_marginEnd="@dimen/padding_small" /> diff --git a/Simplenote/src/main/res/layout/collaborators_header.xml b/Simplenote/src/main/res/layout/collaborators_header.xml new file mode 100644 index 000000000..66d530929 --- /dev/null +++ b/Simplenote/src/main/res/layout/collaborators_header.xml @@ -0,0 +1,20 @@ + + + + + diff --git a/Simplenote/src/main/res/layout/empty_view_message.xml b/Simplenote/src/main/res/layout/empty_view_message.xml new file mode 100644 index 000000000..eccc061e8 --- /dev/null +++ b/Simplenote/src/main/res/layout/empty_view_message.xml @@ -0,0 +1,48 @@ + + + + + + + + + + + diff --git a/Simplenote/src/main/res/menu/note_markdown.xml b/Simplenote/src/main/res/menu/note_markdown.xml index 1e5f87902..28ff28050 100644 --- a/Simplenote/src/main/res/menu/note_markdown.xml +++ b/Simplenote/src/main/res/menu/note_markdown.xml @@ -1,7 +1,6 @@ - @@ -18,79 +17,77 @@ android:enabled="false" android:icon="@drawable/ic_info_24dp" android:title="@string/information" - app:showAsAction="always"/> + app:showAsAction="always" /> - + - + app:showAsAction="never" /> - + app:showAsAction="never" /> - + app:showAsAction="never" /> - + app:showAsAction="never" /> - + app:showAsAction="never" /> - + app:showAsAction="never" /> - + app:showAsAction="never" /> - + - + app:showAsAction="never" /> - + app:showAsAction="never" /> + + + + + diff --git a/Simplenote/src/main/res/values/strings.xml b/Simplenote/src/main/res/values/strings.xml index 0717c567a..b396a2f0b 100644 --- a/Simplenote/src/main/res/values/strings.xml +++ b/Simplenote/src/main/res/values/strings.xml @@ -341,8 +341,10 @@ Email Address Accept Please enter a valid email address + You cannot add yourself as a collaborator Note was deleted. You cannot edit collaborators on a note that was deleted. Note was trashed. You cannot edit collaborators on a note that is in the trash. + No Collaborators Change passcode diff --git a/Simplenote/src/test/java/com/automattic/simplenote/authentication/SessionManagerTest.kt b/Simplenote/src/test/java/com/automattic/simplenote/authentication/SessionManagerTest.kt new file mode 100644 index 000000000..f43d47ac6 --- /dev/null +++ b/Simplenote/src/test/java/com/automattic/simplenote/authentication/SessionManagerTest.kt @@ -0,0 +1,48 @@ +package com.automattic.simplenote.authentication + +import com.simperium.Simperium +import com.simperium.client.User +import org.junit.Assert.assertEquals +import org.junit.Test +import org.mockito.Mockito +import org.mockito.kotlin.whenever + +class SessionManagerTest { + private val simperium = Mockito.mock(Simperium::class.java) + private val sessionManager = SessionManager(simperium) + + @Test + fun whenUserHasTokenShouldReturnAuthorizedUser() { + val user = User().apply { + email = "test@test.com" + accessToken = "124556" + } + whenever(simperium.user).thenReturn(user) + + val result = sessionManager.getCurrentUser() + + assertEquals(UserSession.AuthorizedUser(user), result) + } + + @Test + fun whenUserDoesNotHasTokenShouldReturnUnauthorizedUser() { + val user = User().apply { + email = "test@test.com" + accessToken = null + } + whenever(simperium.user).thenReturn(user) + + val result = sessionManager.getCurrentUser() + + assertEquals(UserSession.UnauthorizedUser, result) + } + + @Test + fun whenUserIsNullShouldReturnUnauthorizedUser() { + whenever(simperium.user).thenReturn(null) + + val result = sessionManager.getCurrentUser() + + assertEquals(UserSession.UnauthorizedUser, result) + } +} \ No newline at end of file diff --git a/Simplenote/src/test/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModelTest.kt b/Simplenote/src/test/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModelTest.kt index 48127f96d..b45d41a8d 100644 --- a/Simplenote/src/test/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModelTest.kt +++ b/Simplenote/src/test/java/com/automattic/simplenote/viewmodels/AddCollaboratorViewModelTest.kt @@ -1,10 +1,13 @@ package com.automattic.simplenote.viewmodels import androidx.arch.core.executor.testing.InstantTaskExecutorRule +import com.automattic.simplenote.authentication.SessionManager import com.automattic.simplenote.models.Note import com.automattic.simplenote.repositories.SimperiumCollaboratorsRepository +import com.simperium.Simperium import com.simperium.client.Bucket import com.simperium.client.BucketObjectMissingException +import com.simperium.client.User import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestCoroutineDispatcher import kotlinx.coroutines.test.runBlockingTest @@ -23,7 +26,8 @@ class AddCollaboratorViewModelTest { private val notesBucket = Mockito.mock(Bucket::class.java) as Bucket private val collaboratorsRepository = SimperiumCollaboratorsRepository(notesBucket, TestCoroutineDispatcher()) - private val viewModel = AddCollaboratorViewModel(collaboratorsRepository) + private val simperium = Mockito.mock(Simperium::class.java) + private val viewModel = AddCollaboratorViewModel(collaboratorsRepository, SessionManager(simperium)) private val noteId = "key1" private val note = Note(noteId).apply { @@ -35,6 +39,11 @@ class AddCollaboratorViewModelTest { @Before fun setup() { whenever(notesBucket.get(any())).thenReturn(note) + val user = User().apply { + email = "test@test.com" + accessToken = "124556" + } + whenever(simperium.user).thenReturn(user) } @Test @@ -69,6 +78,13 @@ class AddCollaboratorViewModelTest { assertEquals(AddCollaboratorViewModel.Event.NoteDeleted, viewModel.event.value) } + @Test + fun addSameAccountShouldTriggerCollaboratorCurrentUser() = runBlockingTest { + viewModel.addCollaborator(noteId, "test@test.com") + + assertEquals(AddCollaboratorViewModel.Event.CollaboratorCurrentUser, viewModel.event.value) + } + @Test fun closeShouldTriggerEventClose() { viewModel.close()