From 388e8286bc277ef1b6ed5d7a34871309324ed60a Mon Sep 17 00:00:00 2001 From: Madhur Gupta <30932899+madhurgupta10@users.noreply.github.com> Date: Mon, 20 Sep 2021 12:31:54 +0530 Subject: [PATCH] Add LeaderboardFragment Unit Tests (#4635) * Add LeaderboardFragment Unit Tests * Add LeaderboardListAdapter Unit Tests --- .../leaderboard/LeaderboardListAdapter.java | 2 +- .../LeaderboardFragmentUnitTests.kt | 203 ++++++++++++++++++ .../LeaderboardListAdapterUnitTests.kt | 101 +++++++++ 3 files changed, 305 insertions(+), 1 deletion(-) create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardFragmentUnitTests.kt create mode 100644 app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardListAdapterUnitTests.kt diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java index 753abbac1..acf065330 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardListAdapter.java @@ -20,7 +20,7 @@ import fr.free.nrw.commons.Utils; */ public class LeaderboardListAdapter extends PagedListAdapter { - protected LeaderboardListAdapter() { + public LeaderboardListAdapter() { super(LeaderboardList.DIFF_CALLBACK); } diff --git a/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardFragmentUnitTests.kt b/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardFragmentUnitTests.kt new file mode 100644 index 000000000..27c1f8f08 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardFragmentUnitTests.kt @@ -0,0 +1,203 @@ +package fr.free.nrw.commons.leaderboard + +import android.accounts.Account +import android.content.Context +import android.view.LayoutInflater +import android.view.View +import android.widget.Button +import android.widget.ProgressBar +import android.widget.Spinner +import androidx.fragment.app.FragmentManager +import androidx.fragment.app.FragmentTransaction +import androidx.recyclerview.widget.RecyclerView +import fr.free.nrw.commons.R +import fr.free.nrw.commons.TestAppAdapter +import fr.free.nrw.commons.TestCommonsApplication +import fr.free.nrw.commons.auth.SessionManager +import fr.free.nrw.commons.profile.ProfileActivity +import fr.free.nrw.commons.profile.leaderboard.LeaderboardFragment +import fr.free.nrw.commons.profile.leaderboard.LeaderboardListAdapter +import fr.free.nrw.commons.profile.leaderboard.LeaderboardListViewModel +import org.junit.Assert +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.Mock +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations +import org.powermock.reflect.Whitebox +import org.robolectric.Robolectric +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode +import org.wikipedia.AppAdapter +import java.lang.reflect.Method + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [21], application = TestCommonsApplication::class) +@LooperMode(LooperMode.Mode.PAUSED) +class LeaderboardFragmentUnitTests { + + private lateinit var fragment: LeaderboardFragment + private lateinit var fragmentManager: FragmentManager + private lateinit var context: Context + private lateinit var view: View + private lateinit var layoutInflater: LayoutInflater + + @Mock + private lateinit var progressBar: ProgressBar + + @Mock + private lateinit var spinner: Spinner + + @Mock + private lateinit var viewModel: LeaderboardListViewModel + + @Mock + private lateinit var recyclerView: RecyclerView + + @Mock + private lateinit var adapter: LeaderboardListAdapter + + @Mock + private lateinit var sessionManager: SessionManager + + @Mock + private lateinit var account: Account + + @Mock + private lateinit var button: Button + + @Before + fun setUp() { + MockitoAnnotations.initMocks(this) + context = RuntimeEnvironment.application.applicationContext + + AppAdapter.set(TestAppAdapter()) + + val activity = Robolectric.buildActivity(ProfileActivity::class.java).create().get() + fragment = LeaderboardFragment() + fragmentManager = activity.supportFragmentManager + val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction() + fragmentTransaction.add(fragment, null) + fragmentTransaction.commitNowAllowingStateLoss() + + layoutInflater = LayoutInflater.from(activity) + view = LayoutInflater.from(activity) + .inflate(R.layout.fragment_leaderboard, null) as View + + Whitebox.setInternalState(fragment, "progressBar", progressBar) + Whitebox.setInternalState(fragment, "categorySpinner", spinner) + Whitebox.setInternalState(fragment, "durationSpinner", spinner) + Whitebox.setInternalState(fragment, "viewModel", viewModel) + Whitebox.setInternalState(fragment, "scrollButton", button) + Whitebox.setInternalState(fragment, "leaderboardListRecyclerView", recyclerView) + } + + @Test + @Throws(Exception::class) + fun checkFragmentNotNull() { + Assert.assertNotNull(fragment) + } + + @Test + @Throws(Exception::class) + fun testOnCreateView() { + fragment.onCreateView(layoutInflater, null, null) + } + + @Test + @Throws(Exception::class) + fun testRefreshLeaderboard() { + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "refreshLeaderboard" + ) + method.isAccessible = true + method.invoke(fragment) + } + + @Test + @Throws(Exception::class) + fun testScrollToUserRank() { + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "scrollToUserRank" + ) + method.isAccessible = true + method.invoke(fragment) + } + + @Test + @Throws(Exception::class) + fun testScrollToUserRankCaseNonZeroTrue() { + Whitebox.setInternalState(fragment, "userRank", 1) + `when`(recyclerView.adapter).thenReturn(adapter) + `when`(adapter.itemCount).thenReturn(3) + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "scrollToUserRank" + ) + method.isAccessible = true + method.invoke(fragment) + } + + @Test + @Throws(Exception::class) + fun testScrollToUserRankCaseNonZeroFalse() { + Whitebox.setInternalState(fragment, "userRank", 1) + `when`(recyclerView.adapter).thenReturn(adapter) + `when`(adapter.itemCount).thenReturn(1) + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "scrollToUserRank" + ) + method.isAccessible = true + method.invoke(fragment) + } + + + @Test + @Throws(Exception::class) + fun testSetLeaderboard() { + Whitebox.setInternalState(fragment, "sessionManager", sessionManager) + `when`(sessionManager.currentAccount).thenReturn(account) + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "setLeaderboard", + String::class.java, + String::class.java, + Int::class.java, + Int::class.java + ) + method.isAccessible = true + method.invoke(fragment, "", "", 0, 0) + } + + @Test + @Throws(Exception::class) + fun testHideProgressBar() { + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "hideProgressBar" + ) + method.isAccessible = true + method.invoke(fragment) + } + + @Test + @Throws(Exception::class) + fun testShowProgressBar() { + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "showProgressBar" + ) + method.isAccessible = true + method.invoke(fragment) + } + + @Test + @Throws(Exception::class) + fun testOnError() { + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "onError" + ) + method.isAccessible = true + method.invoke(fragment) + } + +} \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardListAdapterUnitTests.kt b/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardListAdapterUnitTests.kt new file mode 100644 index 000000000..f24f25ec5 --- /dev/null +++ b/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardListAdapterUnitTests.kt @@ -0,0 +1,101 @@ +package fr.free.nrw.commons.leaderboard + +import android.content.Context +import android.widget.TextView +import androidx.paging.PagedList +import androidx.recyclerview.widget.RecyclerView +import com.facebook.drawee.backends.pipeline.Fresco +import com.facebook.drawee.view.SimpleDraweeView +import com.facebook.soloader.SoLoader +import fr.free.nrw.commons.TestCommonsApplication +import fr.free.nrw.commons.profile.leaderboard.LeaderboardList +import fr.free.nrw.commons.profile.leaderboard.LeaderboardListAdapter +import org.junit.Before +import org.junit.Test +import org.junit.runner.RunWith +import org.mockito.ArgumentMatchers +import org.mockito.Mock +import org.mockito.Mockito +import org.mockito.Mockito.`when` +import org.mockito.MockitoAnnotations +import org.robolectric.RobolectricTestRunner +import org.robolectric.RuntimeEnvironment +import org.robolectric.annotation.Config +import org.robolectric.annotation.LooperMode +import java.lang.reflect.Field + +@RunWith(RobolectricTestRunner::class) +@Config(sdk = [21], application = TestCommonsApplication::class) +@LooperMode(LooperMode.Mode.PAUSED) +class LeaderboardListAdapterUnitTests { + + private lateinit var context: Context + private lateinit var adapter: LeaderboardListAdapter + + @Mock + private lateinit var viewHolder: LeaderboardListAdapter.ListViewHolder + + @Mock + private lateinit var textView: TextView + + @Mock + private lateinit var simpleDraweeView: SimpleDraweeView + + @Before + fun setUp() { + context = RuntimeEnvironment.application.applicationContext + MockitoAnnotations.initMocks(this) + SoLoader.setInTestMode() + Fresco.initialize(context) + + adapter = LeaderboardListAdapter() + + val rank: Field = + LeaderboardListAdapter.ListViewHolder::class.java.getDeclaredField("rank") + rank.isAccessible = true + rank.set(viewHolder, textView) + + val avatar: Field = + LeaderboardListAdapter.ListViewHolder::class.java.getDeclaredField("avatar") + avatar.isAccessible = true + avatar.set(viewHolder, simpleDraweeView) + + val username: Field = + LeaderboardListAdapter.ListViewHolder::class.java.getDeclaredField("username") + username.isAccessible = true + username.set(viewHolder, textView) + + val count: Field = + LeaderboardListAdapter.ListViewHolder::class.java.getDeclaredField("count") + count.isAccessible = true + count.set(viewHolder, textView) + + val itemView: Field = + RecyclerView.ViewHolder::class.java.getDeclaredField("itemView") + itemView.isAccessible = true + itemView.set(viewHolder, textView) + } + + @Test + @Throws(Exception::class) + fun testOnBindViewHolder() { + val list = LeaderboardList() + list.rank = 1 + list.avatar = "" + list.categoryCount = 1 + list.username = "" + adapter.submitList(mockPagedList(listOf(list))) + adapter.onBindViewHolder(viewHolder, 0) + } + + fun mockPagedList(list: List): PagedList { + val pagedList = Mockito.mock(PagedList::class.java) as PagedList + `when`(pagedList[ArgumentMatchers.anyInt()]).then { invocation -> + val index = invocation.arguments.first() as Int + list[index] + } + `when`(pagedList.size).thenReturn(list.size) + return pagedList + } + +} \ No newline at end of file