Skip to content

Commit 0504e22

Browse files
committed
feat: add getLeaderboardEntries()
1 parent a92f238 commit 0504e22

File tree

8 files changed

+181
-0
lines changed

8 files changed

+181
-0
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,10 @@ Click the function names to open their complete docs on the docs site.
101101
- [`getAchievementDistribution()`](https://api-docs.retroachievements.org/v1/get-achievement-distribution.html) - Get how many players have unlocked how many achievements for a game.
102102
- [`getGameRankAndScore()`](https://api-docs.retroachievements.org/v1/get-game-rank-and-score.html) - Get a list of either the latest masters or highest hardcore points earners for a game.
103103

104+
### Leaderboard
105+
106+
- [`getLeaderboardEntries()`](https://api-docs.retroachievements.org/v1/get-leaderboard-entries.html) - Get a given leaderboard's entries.
107+
104108
### System
105109

106110
- [`getConsoleIds()`](https://api-docs.retroachievements.org/v1/get-console-ids.html) - Get the complete list of console ID and name pairs on the site.

src/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export * from "./comment";
55
export * from "./console";
66
export * from "./feed";
77
export * from "./game";
8+
export * from "./leaderboard";
89
export * from "./ticket";
910
export * from "./user";
1011
export * from "./utils/public";
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/* eslint-disable sonarjs/no-duplicate-string */
2+
3+
import { http, HttpResponse } from "msw";
4+
import { setupServer } from "msw/node";
5+
6+
import { apiBaseUrl } from "../utils/internal";
7+
import { buildAuthorization } from "../utils/public";
8+
import { getLeaderboardEntries } from "./getLeaderboardEntries";
9+
import type { GetLeaderboardEntriesResponse } from "./models";
10+
11+
const server = setupServer();
12+
13+
describe("Function: getLeaderboardEntries", () => {
14+
// MSW Setup
15+
beforeAll(() => server.listen());
16+
afterEach(() => server.resetHandlers());
17+
afterAll(() => server.close());
18+
19+
it("is defined #sanity", () => {
20+
// ASSERT
21+
expect(getLeaderboardEntries).toBeDefined();
22+
});
23+
24+
it("given a leaderboard ID, retrieves the entries in that leaderboard", async () => {
25+
// ARRANGE
26+
const authorization = buildAuthorization({
27+
username: "mockUserName",
28+
webApiKey: "mockWebApiKey",
29+
});
30+
31+
const mockResponse: GetLeaderboardEntriesResponse = {
32+
Count: 100,
33+
Total: 1287,
34+
Results: [
35+
{
36+
Rank: 1,
37+
User: "vani11a",
38+
ULID: "00003EMFWR7XB8SDPEHB3K56ZQ",
39+
Score: 390_490,
40+
FormattedScore: "390,490",
41+
DateSubmitted: "2024-07-25T15:51:00+00:00",
42+
},
43+
],
44+
};
45+
46+
server.use(
47+
http.get(`${apiBaseUrl}/API_GetLeaderboardEntries.php`, () =>
48+
HttpResponse.json(mockResponse)
49+
)
50+
);
51+
52+
// ACT
53+
const response = await getLeaderboardEntries(authorization, {
54+
leaderboardId: 104_370,
55+
});
56+
57+
// ASSERT
58+
expect(response).toEqual({
59+
count: 100,
60+
total: 1287,
61+
results: [
62+
{
63+
rank: 1,
64+
user: "vani11a",
65+
ulid: "00003EMFWR7XB8SDPEHB3K56ZQ",
66+
score: 390_490,
67+
formattedScore: "390,490",
68+
dateSubmitted: "2024-07-25T15:51:00+00:00",
69+
},
70+
],
71+
});
72+
});
73+
});
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
import type { ID } from "../utils/internal";
2+
import {
3+
apiBaseUrl,
4+
buildRequestUrl,
5+
call,
6+
serializeProperties,
7+
} from "../utils/internal";
8+
import type { AuthObject } from "../utils/public";
9+
import type {
10+
GetLeaderboardEntriesResponse,
11+
LeaderboardEntries,
12+
} from "./models";
13+
14+
/**
15+
* A call to this endpoint will retrieve a given leaderboard's entries, targeted by its ID.
16+
*
17+
* @param authorization An object containing your username and webApiKey.
18+
* This can be constructed with `buildAuthorization()`.
19+
*
20+
* @param payload.leaderboardId The target leaderboard ID.
21+
*
22+
* @param payload.offset Defaults to 0. The number of entries to skip.
23+
*
24+
* @param payload.count Defaults to 100, has a max of 500.
25+
*
26+
* @example
27+
* ```
28+
* const wantToPlayList = await getLeaderboardEntries(
29+
* authorization,
30+
* { leaderboardId: 14402 }
31+
* );
32+
* ```
33+
*
34+
* @returns An object containing a user's list of "Want to Play Games".
35+
* ```json
36+
* {
37+
* "count": 100,
38+
* "total": 1287,
39+
* "results": [
40+
* {
41+
* "rank": 1,
42+
* "user": "vani11a",
43+
* "ulid": "00003EMFWR7XB8SDPEHB3K56ZQ",
44+
* "score": 390490,
45+
* "formattedScore": "390,490",
46+
* "dateSubmitted": "2024-07-25T15:51:00+00:00"
47+
* }
48+
* ]
49+
* }
50+
* ```
51+
*/
52+
export const getLeaderboardEntries = async (
53+
authorization: AuthObject,
54+
payload: { leaderboardId: ID; offset?: number; count?: number }
55+
): Promise<LeaderboardEntries> => {
56+
const queryParams: Record<string, any> = {};
57+
queryParams.i = payload.leaderboardId;
58+
if (payload?.offset) {
59+
queryParams.o = payload.offset;
60+
}
61+
if (payload?.count) {
62+
queryParams.c = payload.count;
63+
}
64+
65+
const url = buildRequestUrl(
66+
apiBaseUrl,
67+
"/API_GetLeaderboardEntries.php",
68+
authorization,
69+
queryParams
70+
);
71+
72+
const rawResponse = await call<GetLeaderboardEntriesResponse>({ url });
73+
74+
return serializeProperties(rawResponse);
75+
};

src/leaderboard/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./getLeaderboardEntries";
2+
export * from "./models";
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export interface GetLeaderboardEntriesResponse {
2+
Count: number;
3+
Total: number;
4+
Results: Array<{
5+
Rank: number;
6+
User: string;
7+
ULID: string;
8+
Score: number;
9+
FormattedScore: string;
10+
DateSubmitted: string;
11+
}>;
12+
}

src/leaderboard/models/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export * from "./get-leaderboard-entries-response.model";
2+
export * from "./leaderboard-entries.model";
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
export interface LeaderboardEntries {
2+
count: number;
3+
total: number;
4+
results: Array<{
5+
rank: number;
6+
user: string;
7+
ulid: string;
8+
score: number;
9+
formattedScore: string;
10+
dateSubmitted: string;
11+
}>;
12+
}

0 commit comments

Comments
 (0)