Skip to content

Commit ad397cc

Browse files
committed
feat: query group of users leaderboard ranking
1 parent 2ea2b55 commit ad397cc

File tree

7 files changed

+313
-6
lines changed

7 files changed

+313
-6
lines changed

core/src/main/java/cn/leancloud/LCLeaderboard.java

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,26 @@ public Observable<LCLeaderboardResult> getResults(int skip, int limit, List<Stri
365365
skip, limit, selectMemberKeys, null, includeStatistics, this.version, withCount);
366366
}
367367

368+
/**
369+
* get group user's ranking.
370+
* @param groupUserIds user id list.
371+
* @param skip skip number.
372+
* @param limit max result limitation.
373+
* @param selectMemberKeys select member(user) keys(optional)
374+
* @param includeStatistics include other statistics(optional)
375+
* @return observable instance.
376+
*/
377+
public Observable<LCLeaderboardResult> getGroupResults(List<String> groupUserIds,
378+
int skip, int limit, List<String> selectMemberKeys,
379+
List<String> includeStatistics) {
380+
if (StringUtil.isEmpty(this.statisticName)) {
381+
return Observable.error(new IllegalArgumentException("name is empty"));
382+
}
383+
String leaderboardType = convertLeaderboardType4Rank(this.memberType);
384+
return PaasClient.getStorageClient().getLeaderboardGroupResults(leaderboardType, this.statisticName,
385+
groupUserIds, skip, limit, selectMemberKeys, null, includeStatistics, this.version);
386+
}
387+
368388
/**
369389
* get leaderboard results around target id(user, object or entity).
370390
* @param targetId target objectId

core/src/main/java/cn/leancloud/core/StorageClient.java

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,6 +1117,47 @@ public Observable<LCLeaderboardResult> getLeaderboardResults(String leaderboardT
11171117
return wrapObservable(apiService.getLeaderboardResults(leaderboardType, statisticName, params));
11181118
}
11191119

1120+
public Observable<LCLeaderboardResult> getLeaderboardGroupResults(String leaderboardType, String statisticName,
1121+
List<String> groupUserIds,
1122+
int skip, int limit, List<String> selectUserKeys,
1123+
List<String> includeUserKeys,
1124+
List<String> includeStatisticNames,
1125+
int version) {
1126+
if (StringUtil.isEmpty(leaderboardType) || StringUtil.isEmpty(statisticName)) {
1127+
return Observable.error(new IllegalArgumentException("memberType or statisticName is null"));
1128+
}
1129+
if (!"user".equalsIgnoreCase(leaderboardType)) {
1130+
return Observable.error(new IllegalArgumentException("only memberType of user is supported."));
1131+
}
1132+
if (null == groupUserIds || groupUserIds.isEmpty()) {
1133+
return Observable.error(new IllegalArgumentException("group user id is empty."));
1134+
}
1135+
String selectKeys = StringUtil.join(",", selectUserKeys);
1136+
String includeKeys = StringUtil.join(",", includeUserKeys);
1137+
String includeStatistics = StringUtil.join(",", includeStatisticNames);
1138+
Map<String, Object> params = new HashMap<>();
1139+
if (skip > 0) {
1140+
params.put("startPosition", skip);
1141+
}
1142+
if (limit > 0) {
1143+
params.put("maxResultsCount", limit);
1144+
}
1145+
if (!StringUtil.isEmpty(selectKeys)) {
1146+
params.put("selectKeys", selectKeys);
1147+
}
1148+
if (!StringUtil.isEmpty(includeKeys)) {
1149+
params.put("includeKeys", includeKeys);
1150+
}
1151+
if (!StringUtil.isEmpty(includeStatistics)) {
1152+
params.put("includeStatistics", includeStatistics);
1153+
}
1154+
if (version > LCLeaderboard.INVALID_VERSION) {
1155+
params.put("version", version);
1156+
}
1157+
params.put("ids", groupUserIds);
1158+
return wrapObservable(apiService.queryLeaderboardGroupResults(leaderboardType, statisticName, params));
1159+
}
1160+
11201161
public Observable<LCLeaderboardResult> getLeaderboardAroundResults(String leaderboardType, String statisticName, String targetId,
11211162
int skip, int limit, List<String> selectUserKeys,
11221163
List<String> includeUserKeys,

core/src/main/java/cn/leancloud/service/APIService.java

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -353,6 +353,11 @@ Observable<LCLeaderboardResult> getLeaderboardAroundResults(@Path("memberType")
353353
@Path("entityId") String entityId,
354354
@QueryMap Map<String, Object> query);
355355

356+
@POST("/1.1/leaderboard/leaderboards/{memberType}/{statisticName}/group/ranks")
357+
Observable<LCLeaderboardResult> queryLeaderboardGroupResults(@Path("memberType") String memberType,
358+
@Path("statisticName") String statisticName,
359+
@Body Map<String, Object> query);
360+
356361
@GET("/1.1/leaderboard/users/self/statistics")
357362
Observable<LCStatisticResult> getAuthenticatedUserStatistics(@Header(HEADER_KEY_LC_SESSIONTOKEN) String sessionToken);
358363

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
package cn.leancloud;
2+
3+
import io.reactivex.Observer;
4+
import io.reactivex.disposables.Disposable;
5+
import junit.framework.Test;
6+
import junit.framework.TestCase;
7+
import junit.framework.TestSuite;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
import java.util.ArrayList;
11+
import java.util.List;
12+
import java.util.concurrent.CountDownLatch;
13+
14+
public class DeletedUserTest extends TestCase {
15+
private static final String USER_PREFIX = "DeletedUserTest";
16+
private List<String> testObjectIds = null;
17+
private boolean operationSucceed = false;
18+
private CountDownLatch latch = null;
19+
20+
public DeletedUserTest(String name) {
21+
super(name);
22+
Configure.initializeRuntime();
23+
}
24+
25+
public static Test suite() {
26+
return new TestSuite(DeletedUserTest.class);
27+
}
28+
29+
@Override
30+
protected void setUp() throws Exception {
31+
testObjectIds = new ArrayList<>(10);
32+
String username = null;
33+
String userEmail = null;
34+
for (int i = 0; i < 10; i++) {
35+
username = USER_PREFIX + i;
36+
userEmail = username + "@abc.com";
37+
LCUser result = UserFollowshipTest.prepareUser(username, userEmail, true);
38+
testObjectIds.add(result.getObjectId());
39+
}
40+
latch = new CountDownLatch(1);
41+
operationSucceed = false;
42+
}
43+
44+
@Override
45+
protected void tearDown() throws Exception {
46+
LCUser.logOut();
47+
}
48+
49+
private void prepareFollowship() throws Exception {
50+
LCUser current = LCUser.logIn(USER_PREFIX+9, UserFollowshipTest.DEFAULT_PASSWD).blockingFirst();
51+
for(int i = 0;i < 9; i++) {
52+
current.followInBackground(testObjectIds.get(i)).blockingFirst();
53+
}
54+
}
55+
56+
public void testFollowList() throws Exception {
57+
prepareFollowship();
58+
59+
LCUser current = LCUser.logIn(USER_PREFIX+9, UserFollowshipTest.DEFAULT_PASSWD).blockingFirst();
60+
current.followeeQuery().findInBackground().subscribe(new Observer<List<LCObject>>() {
61+
@Override
62+
public void onSubscribe(@NotNull Disposable disposable) {
63+
64+
}
65+
66+
@Override
67+
public void onNext(@NotNull List<LCObject> lcObjects) {
68+
for (LCObject obj: lcObjects) {
69+
System.out.println(obj);
70+
}
71+
operationSucceed = true;
72+
latch.countDown();
73+
}
74+
75+
@Override
76+
public void onError(@NotNull Throwable throwable) {
77+
latch.countDown();
78+
}
79+
80+
@Override
81+
public void onComplete() {
82+
83+
}
84+
});
85+
latch.await();
86+
assertTrue(operationSucceed);
87+
}
88+
89+
private void prepareFriendship() throws Exception {
90+
LCUser current = LCUser.logIn(USER_PREFIX+9, UserFollowshipTest.DEFAULT_PASSWD).blockingFirst();
91+
List<LCFriendshipRequest> requests = new ArrayList<>(9);
92+
for (int i = 0; i < 9; i++) {
93+
LCUser target = LCUser.createWithoutData(LCUser.class, testObjectIds.get(i));
94+
LCFriendshipRequest request = current.applyFriendshipInBackground(target, null).blockingFirst();
95+
requests.add(request);
96+
}
97+
for (int i = 0; i < 9; i++) {
98+
LCUser tmp = LCUser.logIn(USER_PREFIX+i, UserFollowshipTest.DEFAULT_PASSWD).blockingFirst();
99+
tmp.acceptFriendshipRequest(requests.get(i), null).blockingFirst();
100+
}
101+
}
102+
public void testFriendList() throws Exception {
103+
prepareFriendship();
104+
LCUser current = LCUser.logIn(USER_PREFIX+9, UserFollowshipTest.DEFAULT_PASSWD).blockingFirst();
105+
List<LCFriendship> friendships = current.queryFriendship().blockingFirst();
106+
for (LCFriendship fs: friendships) {
107+
System.out.println(fs);
108+
}
109+
}
110+
}

core/src/test/java/cn/leancloud/LCLeaderboardTests.java

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,48 @@ public void onComplete() {
128128
assertTrue(testSucceed);
129129
}
130130

131+
public void testUserGroupLeaderboardResult() throws Exception {
132+
LCLeaderboard leaderboard = LCLeaderboard.createWithoutData("LearderBoard_Test");
133+
List<String> userIds=new ArrayList<>();
134+
userIds.add("LeaderBoard_Test_1");
135+
userIds.add("LeaderBoard_Test_Also");
136+
137+
leaderboard.getGroupResults(userIds, 0, 10, null, null)
138+
.subscribe(new Observer<LCLeaderboardResult>() {
139+
@Override
140+
public void onSubscribe(Disposable disposable) {
141+
}
142+
@Override
143+
public void onNext(LCLeaderboardResult leaderboardResult) {
144+
// X获取的结果为Null
145+
List<LCRanking> X = leaderboardResult.getResults();
146+
// process rankings
147+
// 调用获取成功处理...
148+
if (null != X) {
149+
for (LCRanking rank: X) {
150+
System.out.println(rank.toString());
151+
}
152+
}
153+
154+
// ...
155+
testSucceed = true;
156+
latch.countDown();
157+
}
158+
@Override
159+
public void onError(Throwable throwable) {
160+
// handle error
161+
// 调用获取失败处理...
162+
// ...
163+
latch.countDown();
164+
}
165+
@Override
166+
public void onComplete() {
167+
}
168+
});
169+
latch.await();
170+
assertTrue(testSucceed);
171+
}
172+
131173
public void testObjectGroupResultParse() throws Exception {
132174
LCLeaderboard leaderboard = LCLeaderboard.createWithoutData("LearderBoard_Test", LCLeaderboard.MEMBER_TYPE_OBJECT);
133175
List<String> targetIds=new ArrayList<>();
@@ -170,6 +212,39 @@ public void onComplete() {
170212
assertTrue(testSucceed);
171213
}
172214

215+
public void testObjectGroupLeaderboardResult() throws Exception {
216+
LCLeaderboard leaderboard = LCLeaderboard.createWithoutData("LearderBoard_Test", LCLeaderboard.MEMBER_TYPE_OBJECT);
217+
List<String> targetIds=new ArrayList<>();
218+
targetIds.add("LeaderBoard_Test_1");
219+
targetIds.add("LeaderBoard_Test_Also");
220+
221+
leaderboard.getGroupResults(targetIds, 0, 10, null, null)
222+
.subscribe(new Observer<LCLeaderboardResult>() {
223+
@Override
224+
public void onSubscribe(Disposable disposable) {
225+
}
226+
@Override
227+
public void onNext(LCLeaderboardResult leaderboardResult) {
228+
// ...
229+
testSucceed = false;
230+
latch.countDown();
231+
}
232+
@Override
233+
public void onError(Throwable throwable) {
234+
// handle error
235+
// 调用获取失败处理...
236+
throwable.printStackTrace();
237+
testSucceed = true;
238+
latch.countDown();
239+
}
240+
@Override
241+
public void onComplete() {
242+
}
243+
});
244+
latch.await();
245+
assertTrue(testSucceed);
246+
}
247+
173248
public void testEntityGroupResultParse() throws Exception {
174249
LCLeaderboard leaderboard = LCLeaderboard.createWithoutData("LearderBoard_Test", LCLeaderboard.MEMBER_TYPE_ENTITY);
175250
List<String> targetIds=new ArrayList<>();

core/src/test/java/cn/leancloud/LCLeaderboardUserTests.java

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
package cn.leancloud;
22

33
import cn.leancloud.auth.UserBasedTestCase;
4+
import cn.leancloud.json.JSON;
45
import cn.leancloud.json.JSONObject;
6+
import io.reactivex.Observable;
57
import io.reactivex.Observer;
68
import io.reactivex.disposables.Disposable;
79
import junit.framework.Test;
810
import junit.framework.TestSuite;
11+
import org.jetbrains.annotations.NotNull;
912

1013

1114
import java.util.*;
@@ -40,6 +43,57 @@ protected void tearDown() throws Exception {
4043
super.tearDown();
4144
}
4245

46+
public void testQueryUserGroupLeaderboard() throws Exception {
47+
LCLeaderboard leaderboard = LCLeaderboard.fetchByName(LEADERBOARD_NAME).blockingFirst();
48+
49+
final String USER_PREFIX = "DeletedUserTest";
50+
List<String> testObjectIds = new ArrayList<>(10);
51+
String username = null;
52+
String userEmail = null;
53+
Random random = new Random();
54+
for (int i = 0; i < 10; i++) {
55+
username = USER_PREFIX + i;
56+
userEmail = username + "@abc.com";
57+
LCUser result = UserFollowshipTest.prepareUser(username, userEmail, true);
58+
testObjectIds.add(result.getObjectId());
59+
if (!result.isAuthenticated()) {
60+
result = LCUser.logIn(username, passwd).blockingFirst();
61+
}
62+
Map<String, Double> scores = new HashMap<>();
63+
scores.put("leancloudgogo", random.nextDouble());
64+
LCLeaderboard.updateStatistic(result, scores).blockingFirst();
65+
}
66+
leaderboard.getGroupResults(testObjectIds, 0, 20, null, null)
67+
.subscribe(new Observer<LCLeaderboardResult>() {
68+
@Override
69+
public void onSubscribe(@NotNull Disposable disposable) {
70+
71+
}
72+
73+
@Override
74+
public void onNext(@NotNull LCLeaderboardResult lcLeaderboardResult) {
75+
for (LCRanking ranking: lcLeaderboardResult.getResults()) {
76+
System.out.println(JSON.toJSONString(ranking));
77+
}
78+
testSucceed = true;
79+
latch.countDown();
80+
}
81+
82+
@Override
83+
public void onError(@NotNull Throwable throwable) {
84+
testSucceed = false;
85+
latch.countDown();
86+
}
87+
88+
@Override
89+
public void onComplete() {
90+
91+
}
92+
});
93+
latch.await();
94+
assertTrue(testSucceed);
95+
}
96+
4397
public void testUpdateUserNotExistStatistic() throws Exception {
4498
LCLeaderboard leaderboard = LCLeaderboard.fetchByName(LEADERBOARD_NAME).blockingFirst();
4599
Map<String, Double> scores = new HashMap<>();

core/src/test/java/cn/leancloud/UserFollowshipTest.java

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -54,13 +54,13 @@ protected void tearDown() throws Exception {
5454
LCUser.logOut();
5555
}
5656

57-
public static void prepareUser(String username, final String email, final boolean loginOnFailed) throws Exception {
58-
LCUser user = new LCUser();
59-
user.setEmail(email);
60-
user.setUsername(username);
61-
user.setPassword(DEFAULT_PASSWD);
57+
public static LCUser prepareUser(String username, final String email, final boolean loginOnFailed) throws Exception {
58+
final LCUser[] user = {new LCUser()};
59+
user[0].setEmail(email);
60+
user[0].setUsername(username);
61+
user[0].setPassword(DEFAULT_PASSWD);
6262
final CountDownLatch latch = new CountDownLatch(1);
63-
user.signUpInBackground().subscribe(new Observer<LCUser>() {
63+
user[0].signUpInBackground().subscribe(new Observer<LCUser>() {
6464
public void onSubscribe(Disposable disposable) {
6565

6666
}
@@ -87,6 +87,7 @@ public void onError(Throwable throwable) {
8787
} else if (email.startsWith("dennis")) {
8888
DENNIS_OBJECT_ID = tmp.getObjectId();
8989
}
90+
user[0] = tmp;
9091
} catch (Exception ex) {
9192
System.out.println("failed to loginWithEmail. cause: " + ex.getMessage());
9293
}
@@ -100,6 +101,7 @@ public void onComplete() {
100101
}
101102
});
102103
latch.await();
104+
return user[0];
103105
}
104106

105107
public void testFolloweeQuery() throws Exception {

0 commit comments

Comments
 (0)