Skip to content

Commit

Permalink
Merge branch 'main' into issue-template-config
Browse files Browse the repository at this point in the history
  • Loading branch information
luchaos authored Feb 25, 2024
2 parents d4e2edb + 711818b commit 08249aa
Show file tree
Hide file tree
Showing 20 changed files with 418 additions and 460 deletions.
15 changes: 2 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,8 @@ Click the function names to open their complete docs on the docs site.
- [`getUserProgress()`](https://api-docs.retroachievements.org/v1/users/get-user-progress.html) - Get a user's progress on a list of specified games.
- [`getUserRecentAchievements()`](https://api-docs.retroachievements.org/v1/users/get-user-recent-achievements.html) - Get a list of achievements recently earned by the user.
- [`getUserRecentlyPlayedGames()`](https://api-docs.retroachievements.org/v1/users/get-user-recently-played-games.html) - Get a list of games a user has recently played.
- [`getUserSummary()`](https://api-docs.retroachievements.org/v1/users/get-user-summary.html) - Get a user's profile metadata.
- [`getUserSummary()`](https://api-docs.retroachievements.org/v1/users/get-user-summary.html) - Get a user's exhaustive profile metadata.
- [`getUserProfile()`](https://api-docs.retroachievements.org/v1/users/users/profile.html) - Get a thin subset of a user's profile metadata.

### Games

Expand Down Expand Up @@ -133,15 +134,3 @@ Let us know about yours by [opening an issue](https://github.com/RetroAchievemen
## How to Contribute

Check out [CONTRIBUTING.md](https://github.com/RetroAchievements/api-js/blob/main/CONTRIBUTING.md) for how to get started.

## Contributors

<!-- prettier-ignore-start -->
<!-- markdownlint-disable -->
<table>
<tbody>
<tr>
<td align="center"><a href="https://github.com/wescopeland"><img src="https://avatars.githubusercontent.com/u/3984985?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Wes Copeland</b></sub></a><br /><a href="https://github.com/achievements-app/psn-api/commits?author=wescopeland" title="Code">💻</a> <a href="#example-wescopeland" title="Examples">💡</a> <a href="https://github.com/achievements-app/psn-api/commits?author=wescopeland" title="Documentation">📖</a></td>
</tr>
</tbody>
</table>
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
"raweb",
"retro gaming"
],
"version": "1.3.0",
"version": "1.4.0",
"typings": "dist/index.d.ts",
"exports": {
".": {
Expand Down
2 changes: 1 addition & 1 deletion src/game/getGame.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ describe("Function: getGame", () => {
publisher: "Activision ",
developer: "David Crane",
genre: "Racing",
released: 1980,
released: "1980",
gameTitle: "Dragster",
console: "Atari 2600"
});
Expand Down
10 changes: 2 additions & 8 deletions src/game/getGame.ts
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ import type { Game, GetGameResponse } from "./models";
* publisher: "Activision",
* developer: "David Crane",
* genre: "Racing",
* released: 1980,
* released: "1980",
* gameTitle: "Dragster",
* console: "Atari 2600"
* }
Expand All @@ -64,12 +64,6 @@ export const getGame = async (
const rawResponse = await call<GetGameResponse>({ url });

return serializeProperties(rawResponse, {
shouldCastToNumbers: [
"ID",
"ForumTopicID",
"ConsoleID",
"Flags",
"Released"
]
shouldCastToNumbers: ["ID", "ForumTopicID", "ConsoleID", "Flags"]
});
};
2 changes: 1 addition & 1 deletion src/game/getGameExtended.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ describe("Function: getGameExtended", () => {
publisher: "Activision ",
developer: "David Crane",
genre: "Racing",
released: 1980,
released: "1980",
isFinal: false,
consoleName: "Atari 2600",
richPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
Expand Down
21 changes: 13 additions & 8 deletions src/game/getGameExtended.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ import type { GameExtended, GetGameExtendedResponse } from "./models";
* publisher: "Activision",
* developer: "David Crane",
* genre: "Racing",
* released: 1980,
* released: "1980",
* isFinal: false,
* consoleName: "Atari 2600",
* richPresencePatch: "2b92fa1bf9635c303b3b7f8feea3ed3c",
Expand Down Expand Up @@ -73,17 +73,23 @@ import type { GameExtended, GetGameExtendedResponse } from "./models";
*/
export const getGameExtended = async (
authorization: AuthObject,
payload: { gameId: ID }
payload: { gameId: ID; isRequestingUnofficialAchievements: boolean }
): Promise<GameExtended> => {
const { gameId } = payload;
const { gameId, isRequestingUnofficialAchievements } = payload;

const params: Record<string, string | number> = {
i: gameId
};

if (isRequestingUnofficialAchievements) {
params["f"] = 5;
}

const url = buildRequestUrl(
apiBaseUrl,
"/API_GetGameExtended.php",
authorization,
{
i: gameId
}
params
);

const rawResponse = await call<GetGameExtendedResponse>({ url });
Expand All @@ -97,8 +103,7 @@ export const getGameExtended = async (
"TrueRatio",
"DisplayOrder",
"NumDistinctPlayersCasual",
"NumDistinctPlayersHardcore",
"Released"
"NumDistinctPlayersHardcore"
]
});
};
2 changes: 1 addition & 1 deletion src/game/models/game-extended.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export interface GameExtended {
publisher: string;
developer: string;
genre: string;
released: number;
released: string;
isFinal: boolean;
consoleName: string;
richPresencePatch: string;
Expand Down
2 changes: 1 addition & 1 deletion src/game/models/game.model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface Game {
publisher: string;
developer: string;
genre: string;
released: number;
released: string;
gameTitle: string;
console: string;
}
81 changes: 81 additions & 0 deletions src/user/getUserCompletionProgress.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";

import { apiBaseUrl } from "../utils/internal";
import { buildAuthorization } from "../utils/public";
import { getUserCompletionProgress } from "./getUserCompletionProgress";
import type { GetUserCompletionProgressResponse } from "./models";

const server = setupServer();

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

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

it("retrieves completion progress by username", async () => {
// ARRANGE
const authorization = buildAuthorization({
userName: "mockUserName",
webApiKey: "mockWebApiKey"
});

const mockResponse: GetUserCompletionProgressResponse = {
Count: 1,
Total: 1,
Results: [
{
GameID: 680,
Title: "Game & Watch Gallery",
ImageIcon: "/Images/042952.png",
ConsoleID: 4,
ConsoleName: "Game Boy",
MaxPossible: 27,
NumAwarded: 8,
NumAwardedHardcore: 8,
MostRecentAwardedDate: "2022-07-26T23:56:15+00:00",
HighestAwardKind: null,
HighestAwardDate: null
}
]
};

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

// ACT
const response = await getUserCompletionProgress(authorization, {
userName: "xelnia"
});

// ASSERT
expect(response).toEqual({
count: 1,
total: 1,
results: [
{
gameId: 680,
title: "Game & Watch Gallery",
imageIcon: "/Images/042952.png",
consoleId: 4,
consoleName: "Game Boy",
maxPossible: 27,
numAwarded: 8,
numAwardedHardcore: 8,
mostRecentAwardedDate: "2022-07-26T23:56:15+00:00",
highestAwardKind: null,
highestAwardDate: null
}
]
});
});
});
83 changes: 83 additions & 0 deletions src/user/getUserCompletionProgress.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import {
apiBaseUrl,
buildRequestUrl,
call,
serializeProperties
} from "../utils/internal";
import type { AuthObject } from "../utils/public";
import type {
GetUserCompletionProgressResponse,
UserCompletionProgress
} from "./models";

/**
* A call to this function will retrieve a given user's completion
* progress, targeted by their username.
*
* @param authorization An object containing your userName and webApiKey.
* This can be constructed with `buildAuthorization()`.
*
* @param payload.userName The user for which to retrieve the progress for.
*
* @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 userCompletionProgress = await getUserCompletionProgress(
* authorization,
* { userName: "xelnia" }
* );
* ```
*
* @returns
* ```
* {
* "count": 100,
* "total": 752,
* "results": [
* {
gameId: 11406,
title: 'Mortal Kombat 4',
imageIcon: '/Images/042133.png',
consoleId: 12,
consoleName: 'PlayStation',
maxPossible: 131,
numAwarded: 131,
numAwardedHardcore: 131,
mostRecentAwardedDate: '2022-08-07T18:24:44+00:00',
highestAwardKind: 'mastered',
highestAwardDate: '2022-08-07T18:24:44+00:00'
* }
* ]
* }
* ```
*/
export const getUserCompletionProgress = async (
authorization: AuthObject,
payload: { userName: string; offset?: number; count?: number }
): Promise<UserCompletionProgress> => {
const { userName, offset, count } = payload;

const params: Record<string, string | number> = {
u: userName
};
if (offset) {
params["o"] = offset;
}
if (count) {
params["c"] = count;
}

const url = buildRequestUrl(
apiBaseUrl,
"/API_GetUserCompletionProgress.php",
authorization,
params
);

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

return serializeProperties(rawResponse);
};
79 changes: 79 additions & 0 deletions src/user/getUserProfile.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
import { http, HttpResponse } from "msw";
import { setupServer } from "msw/node";

import { apiBaseUrl } from "../utils/internal";
import { buildAuthorization } from "../utils/public";
import { getUserProfile } from "./getUserProfile";
import type { GetUserProfileResponse } from "./models";

const server = setupServer();

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

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

it("given a username, retrieves minimal user profile information about the user", async () => {
// ARRANGE
const authorization = buildAuthorization({
userName: "mockUserName",
webApiKey: "mockWebApiKey"
});

const mockResponse: GetUserProfileResponse = {
User: "MaxMilyin",
UserPic: "/UserPic/MaxMilyin.png",
MemberSince: "2016-01-02 00:43:04",
RichPresenceMsg:
"Playing ~Hack~ 11th Annual Vanilla Level Design Contest, The",
LastGameID: 19_504,
ContribCount: 0,
ContribYield: 0,
TotalPoints: 399_597,
TotalSoftcorePoints: 0,
TotalTruePoints: 1_599_212,
Permissions: 1,
Untracked: 0,
ID: 16_446,
UserWallActive: 1,
Motto: "Join me on Twitch! GameSquadSquad for live RA"
};

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

// ACT
const response = await getUserProfile(authorization, {
userName: "WCopeland"
});

// ASSERT
expect(response).toEqual({
user: "MaxMilyin",
userPic: "/UserPic/MaxMilyin.png",
memberSince: "2016-01-02 00:43:04",
richPresenceMsg:
"Playing ~Hack~ 11th Annual Vanilla Level Design Contest, The",
lastGameId: 19_504,
contribCount: 0,
contribYield: 0,
totalPoints: 399_597,
totalSoftcorePoints: 0,
totalTruePoints: 1_599_212,
permissions: 1,
untracked: false,
id: 16_446,
userWallActive: true,
motto: "Join me on Twitch! GameSquadSquad for live RA"
});
});
});
Loading

0 comments on commit 08249aa

Please sign in to comment.