Skip to content

Commit

Permalink
feat(getRecentGameAwards): add function (#98)
Browse files Browse the repository at this point in the history
  • Loading branch information
wescopeland authored May 24, 2024
1 parent 3be63a0 commit c3fe412
Show file tree
Hide file tree
Showing 13 changed files with 208 additions and 24 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ Click the function names to open their complete docs on the docs site.

- [`getActiveClaims()`](https://api-docs.retroachievements.org/v1/get-active-claims.html) - Get all active set claims on the site.
- [`getClaims()`](https://api-docs.retroachievements.org/v1/get-claims.html) - Get all claims of other kinds on the site.
- [`getRecentGameAwards()`](https://api-docs.retroachievements.org/v1/get-recent-game-awards.html) - Get all recent mastery, completion, and beaten awards earned on the site.
- [`getTopTenUsers()`](https://api-docs.retroachievements.org/v1/get-top-ten-users.html) - Get the list of top ten points earners.

### Event
Expand Down
73 changes: 73 additions & 0 deletions src/feed/getRecentGameAwards.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";

import { apiBaseUrl } from "../utils/internal";
import { buildAuthorization } from "../utils/public";
import { getRecentGameAwards } from "./getRecentGameAwards";
import type { GetRecentGameAwardsResponse, RecentGameAwards } from "./models";

const server = setupServer();

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

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

it("retrieves metadata about all recently-earned game awards on the site", async () => {
// ARRANGE
const authorization = buildAuthorization({
username: "mockUserName",
webApiKey: "mockWebApiKey",
});

const mockResponse: GetRecentGameAwardsResponse = {
Count: 1,
Total: 1,
Results: [
{
User: "renanbrj",
AwardKind: "mastered",
AwardDate: "2022-01-01T23:48:04+00:00",
GameID: 14_284,
GameTitle: "Batman Returns",
ConsoleID: 15,
ConsoleName: "Game Gear",
},
],
};

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

// ACT
const response = await getRecentGameAwards(authorization);

const expectedResponse: RecentGameAwards = {
count: 1,
total: 1,
results: [
{
user: "renanbrj",
awardKind: "mastered",
awardDate: "2022-01-01T23:48:04+00:00",
gameId: 14_284,
gameTitle: "Batman Returns",
consoleId: 15,
consoleName: "Game Gear",
},
],
};

// ASSERT
expect(response).toEqual(expectedResponse);
});
});
85 changes: 85 additions & 0 deletions src/feed/getRecentGameAwards.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
import {
apiBaseUrl,
buildRequestUrl,
call,
serializeProperties,
} from "../utils/internal";
import type { AuthObject, AwardKind } from "../utils/public";
import type { GetRecentGameAwardsResponse, RecentGameAwards } from "./models";

/**
* A call to this function will retrieve all recently granted game
* awards across the site's userbase.
*
* @param authorization An object containing your username and webApiKey.
* This can be constructed with `buildAuthorization()`.
*
* @param payload.startDate The date to fetch awards from.
*
* @param payload.offset Optional. Defaults to 0.
*
* @param payload.count Optional. Defaults to 25.
*
* @param payload.desiredAwardKinds Optional. Defaults to all. Accepts "beaten-softcore", "beaten-hardcore", "completed", and/or "mastered".
*
* @example
* ```
* const recentGameAwards = await getRecentGameAwards(
* authorization,
* );
* ```
*
* @returns An object containing metadata about all recently granted game
* awards across the site's userbase
* ```
* {
* count: 1,
* total: 1,
* results: [
* {
* user: "renanbrj",
* awardKind: "mastered",
* awardDate: "2022-01-01T23:48:04+00:00",
* gameId: 14_284,
* gameTitle: "Batman Returns",
* consoleId: 15,
* consoleName: "Game Gear",
* },
* ],
* }
* ```
*/
export const getRecentGameAwards = async (
authorization: AuthObject,
payload?: Partial<{
startDate: string;
offset: number;
count: number;
desiredAwardKinds: AwardKind[];
}>
): Promise<RecentGameAwards> => {
const queryParams: Record<string, any> = {};
if (payload?.startDate) {
queryParams.d = payload.startDate;
}
if (payload?.offset) {
queryParams.o = payload.offset;
}
if (payload?.count) {
queryParams.c = payload.count;
}
if (payload?.desiredAwardKinds) {
queryParams.k = payload.desiredAwardKinds.join(",");
}

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

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

return serializeProperties(rawResponse);
};
1 change: 1 addition & 0 deletions src/feed/index.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
export * from "./getAchievementOfTheWeek";
export * from "./getActiveClaims";
export * from "./getClaims";
export * from "./getRecentGameAwards";
export * from "./getTopTenUsers";
export * from "./models";
15 changes: 15 additions & 0 deletions src/feed/models/get-recent-game-awards-response.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { AwardKind } from "../../utils/public";

export interface GetRecentGameAwardsResponse {
Count: number;
Total: number;
Results: Array<{
User: string;
AwardKind: AwardKind;
AwardDate: string;
GameID: number;
GameTitle: string;
ConsoleID: number;
ConsoleName: string;
}>;
}
2 changes: 2 additions & 0 deletions src/feed/models/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ export * from "./claim-set-type.enum";
export * from "./claim-status.enum";
export * from "./claim-type.enum";
export * from "./get-achievement-of-the-week-response.model";
export * from "./get-recent-game-awards-response.model";
export * from "./get-set-claims-response.model";
export * from "./get-top-ten-users-response.model";
export * from "./recent-game-awards.model";
export * from "./set-claim.model";
export * from "./top-ten-users.model";
export * from "./top-ten-users-entity.model";
15 changes: 15 additions & 0 deletions src/feed/models/recent-game-awards.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import type { AwardKind } from "../../utils/public";

export interface RecentGameAwards {
count: number;
total: number;
results: Array<{
user: string;
awardKind: AwardKind;
awardDate: string;
gameId: number;
gameTitle: string;
consoleId: number;
consoleName: string;
}>;
}
8 changes: 2 additions & 6 deletions src/user/models/game-info-and-user-progress.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
GameExtended,
GameExtendedAchievementEntity,
} from "../../game/models";
import type { AwardKind } from "../../utils/public";

export type GameExtendedAchievementEntityWithUserProgress =
GameExtendedAchievementEntity & {
Expand All @@ -17,11 +18,6 @@ export interface GameInfoAndUserProgress extends GameExtended {
userCompletion: string;
userCompletionHardcore: string;

highestAwardKind?:
| "mastered"
| "completed"
| "beaten-hardcore"
| "beaten-softcore"
| null;
highestAwardKind?: AwardKind | null;
highestAwardDate?: string;
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import type {
GameExtendedRawAchievementEntity,
GetGameExtendedResponse,
} from "../../game/models";
import type { AwardKind } from "../../utils/public";

type GetGameExtendedResponseWithoutClaims = Omit<
GetGameExtendedResponse,
Expand All @@ -26,11 +27,6 @@ export interface GetGameInfoAndUserProgressResponse
UserCompletion: string;
UserCompletionHardcore: string;

HighestAwardKind?:
| "mastered"
| "completed"
| "beaten-hardcore"
| "beaten-softcore"
| null;
HighestAwardKind?: AwardKind | null;
HighestAwardDate?: string;
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { AwardKind } from "../../utils/public";

interface RawUserCompletionProgressEntity {
GameID: number;
Title: string;
Expand All @@ -9,12 +11,7 @@ interface RawUserCompletionProgressEntity {
NumAwardedHardcore: number;

MostRecentAwardedDate?: string;
HighestAwardKind?:
| "mastered"
| "completed"
| "beaten-hardcore"
| "beaten-softcore"
| null;
HighestAwardKind?: AwardKind | null;
HighestAwardDate?: string | null;
}

Expand Down
9 changes: 3 additions & 6 deletions src/user/models/user-completion-progress-entity.model.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import type { AwardKind } from "../../utils/public";

export interface UserCompletionProgressEntity {
gameId: number;
title: string;
Expand All @@ -9,11 +11,6 @@ export interface UserCompletionProgressEntity {
numAwardedHardcore: number;

mostRecentAwardedDate?: string;
highestAwardKind?:
| "mastered"
| "completed"
| "beaten-hardcore"
| "beaten-softcore"
| null;
highestAwardKind?: AwardKind | null;
highestAwardDate?: string;
}
5 changes: 5 additions & 0 deletions src/utils/public/models/award-kind.model.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export type AwardKind =
| "beaten-softcore"
| "beaten-hardcore"
| "completed"
| "mastered";
1 change: 1 addition & 0 deletions src/utils/public/models/index.ts
Original file line number Diff line number Diff line change
@@ -1 +1,2 @@
export * from "./auth-object.model";
export * from "./award-kind.model";

0 comments on commit c3fe412

Please sign in to comment.