Skip to content

Commit ee3e52d

Browse files
commons-app#3980 Hitting "My Rank" button from a list position below your rank on leaderboard takes you to the person ranked below you (commons-app#3990)
* Refactored scrollToUserRank to account for users scrolling from below their rank * Refactored my change to use a similar method * Added comments to change * Removed leftover cruft * Reverted package updates * Added tests for the LeaderBoard UI
1 parent 39221f5 commit ee3e52d

File tree

2 files changed

+100
-1
lines changed

2 files changed

+100
-1
lines changed
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
package fr.free.nrw.commons
2+
3+
import android.app.Activity
4+
import android.app.Instrumentation.ActivityResult
5+
import android.view.View
6+
import androidx.test.espresso.Espresso
7+
import androidx.test.espresso.PerformException
8+
import androidx.test.espresso.UiController
9+
import androidx.test.espresso.ViewAction
10+
import androidx.test.espresso.action.ViewActions
11+
import androidx.test.espresso.contrib.DrawerActions
12+
import androidx.test.espresso.intent.Intents
13+
import androidx.test.espresso.intent.Intents.intending
14+
import androidx.test.espresso.intent.matcher.IntentMatchers.isInternal
15+
import androidx.test.espresso.matcher.ViewMatchers
16+
import androidx.test.rule.ActivityTestRule
17+
import androidx.test.runner.AndroidJUnit4
18+
import fr.free.nrw.commons.auth.LoginActivity
19+
import androidx.test.espresso.matcher.ViewMatchers.isAssignableFrom
20+
import androidx.test.espresso.matcher.ViewMatchers.isDisplayed
21+
import com.google.android.material.tabs.TabLayout
22+
import org.hamcrest.CoreMatchers.allOf
23+
import org.hamcrest.CoreMatchers.not
24+
import org.junit.Before
25+
import org.junit.Rule
26+
import org.junit.Test
27+
import org.junit.runner.RunWith
28+
29+
@RunWith(AndroidJUnit4::class)
30+
class LeaderboardActivityTest {
31+
@get:Rule
32+
var activityRule = ActivityTestRule(LoginActivity::class.java)
33+
34+
@Before
35+
fun setup() {
36+
try {
37+
Intents.init()
38+
} catch (ex: IllegalStateException) {
39+
40+
}
41+
UITestHelper.skipWelcome()
42+
intending(not(isInternal())).respondWith(ActivityResult(Activity.RESULT_OK, null))
43+
}
44+
45+
@Test
46+
fun testScrollToRankFromAbove() {
47+
Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
48+
Espresso.onView(ViewMatchers.withId(R.id.user_icon)).perform(ViewActions.click())
49+
50+
Espresso.onView(ViewMatchers.withId(R.id.tab_layout)).perform(ViewActions.click())
51+
Espresso.onView(ViewMatchers.withId(R.id.tab_layout)).perform(selectTabAtPosition(1))
52+
53+
UITestHelper.sleep(10000)
54+
55+
Espresso.onView(ViewMatchers.withId(R.id.scroll)).perform(ViewActions.click())
56+
}
57+
58+
@Test
59+
fun testScrollToRankFromBelow() {
60+
Espresso.onView(ViewMatchers.withId(R.id.drawer_layout)).perform(DrawerActions.open())
61+
Espresso.onView(ViewMatchers.withId(R.id.user_icon)).perform(ViewActions.click())
62+
63+
Espresso.onView(ViewMatchers.withId(R.id.tab_layout)).perform(ViewActions.click())
64+
Espresso.onView(ViewMatchers.withId(R.id.tab_layout)).perform(selectTabAtPosition(1))
65+
66+
UITestHelper.sleep(10000)
67+
68+
Espresso.onView(ViewMatchers.withId(R.id.leaderboard_list)).perform(ViewActions.swipeUp())
69+
Espresso.onView(ViewMatchers.withId(R.id.leaderboard_list)).perform(ViewActions.swipeUp())
70+
71+
Espresso.onView(ViewMatchers.withId(R.id.scroll)).perform(ViewActions.click())
72+
}
73+
74+
private fun selectTabAtPosition(tabIndex: Int): ViewAction {
75+
return object : ViewAction {
76+
override fun getDescription() = "with tab at index $tabIndex"
77+
78+
override fun getConstraints() = allOf(isDisplayed(), isAssignableFrom(TabLayout::class.java))
79+
80+
override fun perform(uiController: UiController, view: View) {
81+
val tabLayout = view as TabLayout
82+
val tabAtIndex: TabLayout.Tab = tabLayout.getTabAt(tabIndex)
83+
?: throw PerformException.Builder()
84+
.withCause(Throwable("No tab at index $tabIndex"))
85+
.build()
86+
87+
tabAtIndex.select()
88+
}
89+
}
90+
}
91+
}

app/src/main/java/fr/free/nrw/commons/profile/leaderboard/LeaderboardFragment.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -173,10 +173,18 @@ private void refreshLeaderboard() {
173173
/**
174174
* Performs Auto Scroll to the User's Rank
175175
* We use userRank+1 to load one extra user and prevent overlapping of my rank button
176+
* If you are viewing the leaderboard below userRank, it scrolls to the user rank at the top
176177
*/
177178
private void scrollToUserRank() {
178179
if (Objects.requireNonNull(leaderboardListRecyclerView.getAdapter()).getItemCount() > userRank + 1) {
179-
leaderboardListRecyclerView.smoothScrollToPosition(userRank + 1);
180+
int currPosition = ((LinearLayoutManager) leaderboardListRecyclerView.getLayoutManager())
181+
.findFirstCompletelyVisibleItemPosition();
182+
// if you are below your rank, scroll to userRank
183+
if (currPosition > userRank) {
184+
leaderboardListRecyclerView.smoothScrollToPosition(userRank);
185+
} else {
186+
leaderboardListRecyclerView.smoothScrollToPosition(userRank + 1);
187+
}
180188
} else {
181189
if (viewModel != null) {
182190
viewModel.refresh(duration, category, userRank + 1, 0);

0 commit comments

Comments
 (0)