Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,10 @@ Click the function names to open their complete docs on the docs site.
- [`getAchievementDistribution()`](https://api-docs.retroachievements.org/v1/get-achievement-distribution.html) - Get how many players have unlocked how many achievements for a game.
- [`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.

### Leaderboard

- [`getLeaderboardEntries()`](https://api-docs.retroachievements.org/v1/get-leaderboard-entries.html) - Get a given leaderboard's entries.

### System

- [`getConsoleIds()`](https://api-docs.retroachievements.org/v1/get-console-ids.html) - Get the complete list of console ID and name pairs on the site.
Expand Down
1 change: 1 addition & 0 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export * from "./comment";
export * from "./console";
export * from "./feed";
export * from "./game";
export * from "./leaderboard";
export * from "./ticket";
export * from "./user";
export * from "./utils/public";
73 changes: 73 additions & 0 deletions src/leaderboard/getLeaderboardEntries.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* eslint-disable sonarjs/no-duplicate-string */

import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";

import { apiBaseUrl } from "../utils/internal";
import { buildAuthorization } from "../utils/public";
import { getLeaderboardEntries } from "./getLeaderboardEntries";
import type { GetLeaderboardEntriesResponse } from "./models";

const server = setupServer();

describe("Function: getLeaderboardEntries", () => {
// MSW Setup
beforeAll(() => server.listen());
afterEach(() => server.resetHandlers());
afterAll(() => server.close());

it("is defined #sanity", () => {
// ASSERT
expect(getLeaderboardEntries).toBeDefined();
});

it("given a leaderboard ID, retrieves the entries in that leaderboard", async () => {
// ARRANGE
const authorization = buildAuthorization({
username: "mockUserName",
webApiKey: "mockWebApiKey",
});

const mockResponse: GetLeaderboardEntriesResponse = {
Count: 100,
Total: 1287,
Results: [
{
Rank: 1,
User: "vani11a",
ULID: "00003EMFWR7XB8SDPEHB3K56ZQ",
Score: 390_490,
FormattedScore: "390,490",
DateSubmitted: "2024-07-25T15:51:00+00:00",
},
],
};

server.use(
http.get(`${apiBaseUrl}/API_GetLeaderboardEntries.php`, () =>
HttpResponse.json(mockResponse)
)
);

// ACT
const response = await getLeaderboardEntries(authorization, {
leaderboardId: 104_370,
});

// ASSERT
expect(response).toEqual({
count: 100,
total: 1287,
results: [
{
rank: 1,
user: "vani11a",
ulid: "00003EMFWR7XB8SDPEHB3K56ZQ",
score: 390_490,
formattedScore: "390,490",
dateSubmitted: "2024-07-25T15:51:00+00:00",
},
],
});
});
});
75 changes: 75 additions & 0 deletions src/leaderboard/getLeaderboardEntries.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
import type { ID } from "../utils/internal";
import {
apiBaseUrl,
buildRequestUrl,
call,
serializeProperties,
} from "../utils/internal";
import type { AuthObject } from "../utils/public";
import type {
GetLeaderboardEntriesResponse,
LeaderboardEntries,
} from "./models";

/**
* A call to this endpoint will retrieve a given leaderboard's entries, targeted by its ID.
*
* @param authorization An object containing your username and webApiKey.
* This can be constructed with `buildAuthorization()`.
*
* @param payload.leaderboardId The target leaderboard ID.
*
* @param payload.offset Defaults to 0. The number of entries to skip.
*
* @param payload.count Defaults to 100, has a max of 500.
*
* @example
* ```
* const leaderboardEntries = await getLeaderboardEntries(
* authorization,
* { leaderboardId: 14402 }
* );
* ```
*
* @returns An object containing a leaderboard's entries.
* ```json
* {
* "count": 100,
* "total": 1287,
* "results": [
* {
* "rank": 1,
* "user": "vani11a",
* "ulid": "00003EMFWR7XB8SDPEHB3K56ZQ",
* "score": 390490,
* "formattedScore": "390,490",
* "dateSubmitted": "2024-07-25T15:51:00+00:00"
* }
* ]
* }
* ```
*/
export const getLeaderboardEntries = async (
authorization: AuthObject,
payload: { leaderboardId: ID; offset?: number; count?: number }
): Promise<LeaderboardEntries> => {
const queryParams: Record<string, any> = {};
queryParams.i = payload.leaderboardId;
if (payload?.offset) {
queryParams.o = payload.offset;
}
if (payload?.count) {
queryParams.c = payload.count;
}

const url = buildRequestUrl(
apiBaseUrl,
"/API_GetLeaderboardEntries.php",
authorization,
queryParams
);

const rawResponse = await call<GetLeaderboardEntriesResponse>({ url });

return serializeProperties(rawResponse);
};
2 changes: 2 additions & 0 deletions src/leaderboard/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./getLeaderboardEntries";
export * from "./models";
12 changes: 12 additions & 0 deletions src/leaderboard/models/get-leaderboard-entries-response.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface GetLeaderboardEntriesResponse {
Count: number;
Total: number;
Results: Array<{
Rank: number;
User: string;
ULID: string;
Score: number;
FormattedScore: string;
DateSubmitted: string;
}>;
}
2 changes: 2 additions & 0 deletions src/leaderboard/models/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from "./get-leaderboard-entries-response.model";
export * from "./leaderboard-entries.model";
12 changes: 12 additions & 0 deletions src/leaderboard/models/leaderboard-entries.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export interface LeaderboardEntries {
count: number;
total: number;
results: Array<{
rank: number;
user: string;
ulid: string;
score: number;
formattedScore: string;
dateSubmitted: string;
}>;
}