diff --git a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java index 7f4b10c69..51371da44 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/achievements/AchievementsFragment.java @@ -3,6 +3,7 @@ package fr.free.nrw.commons.profile.achievements; import android.accounts.Account; import android.app.AlertDialog; import android.app.AlertDialog.Builder; +import android.content.Context; import android.net.Uri; import android.os.Bundle; import android.util.DisplayMetrics; @@ -15,6 +16,7 @@ import android.widget.LinearLayout; import android.widget.ProgressBar; import android.widget.RelativeLayout; import android.widget.TextView; +import android.widget.Toast; import androidx.annotation.Nullable; import androidx.appcompat.view.ContextThemeWrapper; import androidx.appcompat.widget.AppCompatTextView; @@ -29,6 +31,7 @@ import fr.free.nrw.commons.Utils; import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient; +import fr.free.nrw.commons.utils.ConfigUtils; import fr.free.nrw.commons.utils.ViewUtil; import fr.free.nrw.commons.profile.ProfileActivity; import io.reactivex.android.schedulers.AndroidSchedulers; @@ -179,11 +182,46 @@ public class AchievementsFragment extends CommonsDaggerSupportFragment { tvAchievementsOfUser.setVisibility(View.VISIBLE); tvAchievementsOfUser.setText(getString(R.string.achievements_of_user,userName)); } + + // Achievements currently unimplemented in Beta flavor. Skip all API calls. + if(ConfigUtils.isBetaFlavour()) { + progressBar.setVisibility(View.GONE); + imageByWikiText.setText(R.string.no_image); + imageRevertedText.setText(R.string.no_image_reverted); + imageUploadedText.setText(R.string.no_image_uploaded); + wikidataEditsText.setText("0"); + imagesFeatured.setText("0"); + tvQualityImages.setText("0"); + thanksReceived.setText("0"); + setMenuVisibility(true); + return rootView; + } setWikidataEditCount(); setAchievements(); return rootView; } + @Override + public void setMenuVisibility(boolean visible) { + super.setMenuVisibility(visible); + + // Whenever this fragment is revealed in a menu, + // notify Beta users the page data is unavailable + if(ConfigUtils.isBetaFlavour() && visible) { + Context ctx = null; + if(getContext() != null) { + ctx = getContext(); + } else if(getView() != null && getView().getContext() != null) { + ctx = getView().getContext(); + } + if(ctx != null) { + Toast.makeText(ctx, + R.string.achievements_unavailable_beta, + Toast.LENGTH_LONG).show(); + } + } + } + /** * To invoke the AlertDialog on clicking info button */ diff --git a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java index 0cd6f41d3..6705f408c 100644 --- a/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java +++ b/app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java @@ -6,6 +6,7 @@ import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.PAGE_ import static fr.free.nrw.commons.profile.leaderboard.LeaderboardConstants.START_OFFSET; import android.accounts.Account; +import android.content.Context; import android.os.Bundle; import android.view.LayoutInflater; import android.view.View; @@ -29,6 +30,7 @@ import fr.free.nrw.commons.auth.SessionManager; import fr.free.nrw.commons.di.CommonsDaggerSupportFragment; import fr.free.nrw.commons.mwapi.OkHttpJsonApiClient; import fr.free.nrw.commons.profile.ProfileActivity; +import fr.free.nrw.commons.utils.ConfigUtils; import fr.free.nrw.commons.utils.ViewUtil; import io.reactivex.android.schedulers.AndroidSchedulers; import io.reactivex.disposables.CompositeDisposable; @@ -121,8 +123,16 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment { View rootView = inflater.inflate(R.layout.fragment_leaderboard, container, false); ButterKnife.bind(this, rootView); - progressBar.setVisibility(View.VISIBLE); hideLayouts(); + + // Leaderboard currently unimplemented in Beta flavor. Skip all API calls and disable menu + if(ConfigUtils.isBetaFlavour()) { + progressBar.setVisibility(View.GONE); + scrollButton.setVisibility(View.GONE); + return rootView; + } + + progressBar.setVisibility(View.VISIBLE); setSpinners(); /** @@ -174,6 +184,27 @@ public class LeaderboardFragment extends CommonsDaggerSupportFragment { return rootView; } + @Override + public void setMenuVisibility(boolean visible) { + super.setMenuVisibility(visible); + + // Whenever this fragment is revealed in a menu, + // notify Beta users the page data is unavailable + if(ConfigUtils.isBetaFlavour() && visible) { + Context ctx = null; + if(getContext() != null) { + ctx = getContext(); + } else if(getView() != null && getView().getContext() != null) { + ctx = getView().getContext(); + } + if(ctx != null) { + Toast.makeText(ctx, + R.string.leaderboard_unavailable_beta, + Toast.LENGTH_LONG).show(); + } + } + } + /** * Refreshes the leaderboard list */ diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 2b4e4215e..7df28eb75 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -686,4 +686,6 @@ Upload your first media by tapping on the add button. How about adding the place where this image was taken?\nLocation data helps Wiki editors find your picture, making it much more useful.\nThank you! Add location Please remove from this email any information that you are not comfortable sharing publicly. Also, please be aware that your email address with which you are posting, and the associated name and profile picture, will be visible publicly. + Achievements are only available in the prod flavor. + The leaderboard is only available in the prod flavor. 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 index 27c1f8f08..1adf5b7d0 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardFragmentUnitTests.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/leaderboard/LeaderboardFragmentUnitTests.kt @@ -4,6 +4,7 @@ import android.accounts.Account import android.content.Context import android.view.LayoutInflater import android.view.View +import android.view.ViewGroup import android.widget.Button import android.widget.ProgressBar import android.widget.Spinner @@ -18,6 +19,7 @@ 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 fr.free.nrw.commons.utils.ConfigUtils.isBetaFlavour import org.junit.Assert import org.junit.Before import org.junit.Test @@ -31,6 +33,7 @@ import org.robolectric.RobolectricTestRunner import org.robolectric.RuntimeEnvironment import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode +import org.robolectric.shadows.ShadowToast import org.wikipedia.AppAdapter import java.lang.reflect.Method @@ -69,6 +72,9 @@ class LeaderboardFragmentUnitTests { @Mock private lateinit var button: Button + @Mock + private lateinit var parentView: ViewGroup + @Before fun setUp() { MockitoAnnotations.initMocks(this) @@ -93,6 +99,7 @@ class LeaderboardFragmentUnitTests { Whitebox.setInternalState(fragment, "viewModel", viewModel) Whitebox.setInternalState(fragment, "scrollButton", button) Whitebox.setInternalState(fragment, "leaderboardListRecyclerView", recyclerView) + Whitebox.setInternalState(fragment, "mView", parentView) } @Test @@ -200,4 +207,29 @@ class LeaderboardFragmentUnitTests { method.invoke(fragment) } + @Test + @Throws(Exception::class) + fun testMenuVisibilityOverrideNotVisible() { + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "setMenuVisibility", + Boolean::class.java + ) + method.isAccessible = true + method.invoke(fragment, false) + Assert.assertNull(ShadowToast.getLatestToast()) + } + + @Test + @Throws(Exception::class) + fun testMenuVisibilityOverrideVisibleWithContext() { + `when`(parentView.context).thenReturn(context) + val method: Method = LeaderboardFragment::class.java.getDeclaredMethod( + "setMenuVisibility", + Boolean::class.java + ) + method.isAccessible = true + method.invoke(fragment, true) + Assert.assertEquals(ShadowToast.getTextOfLatestToast().toString(), context.getString(R.string.leaderboard_unavailable_beta)) + } + } \ No newline at end of file diff --git a/app/src/test/kotlin/fr/free/nrw/commons/profile/achievements/AchievementsFragmentUnitTests.kt b/app/src/test/kotlin/fr/free/nrw/commons/profile/achievements/AchievementsFragmentUnitTests.kt index 96d99061c..3e6b0f1cf 100644 --- a/app/src/test/kotlin/fr/free/nrw/commons/profile/achievements/AchievementsFragmentUnitTests.kt +++ b/app/src/test/kotlin/fr/free/nrw/commons/profile/achievements/AchievementsFragmentUnitTests.kt @@ -2,13 +2,17 @@ package fr.free.nrw.commons.profile.achievements import android.content.Context import android.os.Looper +import android.view.LayoutInflater import android.view.MenuItem +import android.view.View +import android.view.ViewGroup import android.widget.ImageView import android.widget.ProgressBar import android.widget.TextView import androidx.fragment.app.FragmentManager import androidx.fragment.app.FragmentTransaction import com.dinuscxj.progressbar.CircleProgressBar +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 @@ -28,6 +32,7 @@ import org.robolectric.Shadows import org.robolectric.annotation.Config import org.robolectric.annotation.LooperMode import org.robolectric.fakes.RoboMenuItem +import org.robolectric.shadows.ShadowToast import org.wikipedia.AppAdapter import java.lang.reflect.Method @@ -45,6 +50,10 @@ class AchievementsFragmentUnitTests { private lateinit var achievements: Achievements + private lateinit var view: View + + private lateinit var layoutInflater: LayoutInflater + @Mock private lateinit var imageView: ImageView @@ -90,6 +99,9 @@ class AchievementsFragmentUnitTests { @Mock private lateinit var sessionManager: SessionManager + @Mock + private lateinit var parentView: ViewGroup + @Before fun setUp() { MockitoAnnotations.initMocks(this) @@ -101,7 +113,11 @@ class AchievementsFragmentUnitTests { val fragmentManager: FragmentManager = activity.supportFragmentManager val fragmentTransaction: FragmentTransaction = fragmentManager.beginTransaction() fragmentTransaction.add(fragment, null) - fragmentTransaction.commit() + fragmentTransaction.commitNowAllowingStateLoss() + + layoutInflater = LayoutInflater.from(activity) + view = LayoutInflater.from(activity) + .inflate(R.layout.fragment_achievements, null) as View achievements = Achievements(0, 0, 0, 0, 0, 0, 0) @@ -137,11 +153,18 @@ class AchievementsFragmentUnitTests { Whitebox.setInternalState(fragment, "imagesRevertLimitText", imagesRevertLimitText) Whitebox.setInternalState(fragment, "item", menuItem) Whitebox.setInternalState(fragment, "sessionManager", sessionManager) + Whitebox.setInternalState(fragment, "mView", parentView) Mockito.`when`(sessionManager.userName).thenReturn("Test") } + @Test + @Throws(Exception::class) + fun testOnCreateView() { + fragment.onCreateView(layoutInflater, null, null) + } + @Test @Throws(Exception::class) fun checkFragmentNotNull() { @@ -326,4 +349,30 @@ class AchievementsFragmentUnitTests { method.isAccessible = true method.invoke(fragment) } + + @Test + @Throws(Exception::class) + fun testMenuVisibilityOverrideNotVisible() { + val method: Method = AchievementsFragment::class.java.getDeclaredMethod( + "setMenuVisibility", + Boolean::class.java + ) + method.isAccessible = true + method.invoke(fragment, false) + Assert.assertNull(ShadowToast.getLatestToast()) + } + + @Test + @Throws(Exception::class) + fun testMenuVisibilityOverrideVisibleWithContext() { + Mockito.`when`(parentView.context).thenReturn(context) + val method: Method = AchievementsFragment::class.java.getDeclaredMethod( + "setMenuVisibility", + Boolean::class.java + ) + method.isAccessible = true + method.invoke(fragment, true) + Assert.assertEquals(ShadowToast.getTextOfLatestToast().toString(), context.getString(R.string.achievements_unavailable_beta)) + } + } \ No newline at end of file