From c47af1162f90c214a5a200fbb69d8cb30add0ac8 Mon Sep 17 00:00:00 2001 From: Wes Copeland Date: Sun, 14 Jan 2024 12:23:32 -0500 Subject: [PATCH] feat(getUserProfile): add function --- README.md | 15 +--- src/user/getUserProfile.test.ts | 79 +++++++++++++++++++ src/user/getUserProfile.ts | 55 +++++++++++++ src/user/index.ts | 1 + .../models/get-user-profile-response.model.ts | 17 ++++ src/user/models/index.ts | 2 + src/user/models/user-profile.model.ts | 17 ++++ 7 files changed, 173 insertions(+), 13 deletions(-) create mode 100644 src/user/getUserProfile.test.ts create mode 100644 src/user/getUserProfile.ts create mode 100644 src/user/models/get-user-profile-response.model.ts create mode 100644 src/user/models/user-profile.model.ts diff --git a/README.md b/README.md index c0cc20a..a78d48b 100644 --- a/README.md +++ b/README.md @@ -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 @@ -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 - - - - - - - - - -

Wes Copeland

💻 💡 📖
diff --git a/src/user/getUserProfile.test.ts b/src/user/getUserProfile.test.ts new file mode 100644 index 0000000..142b070 --- /dev/null +++ b/src/user/getUserProfile.test.ts @@ -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" + }); + }); +}); diff --git a/src/user/getUserProfile.ts b/src/user/getUserProfile.ts new file mode 100644 index 0000000..83a7470 --- /dev/null +++ b/src/user/getUserProfile.ts @@ -0,0 +1,55 @@ +import { + apiBaseUrl, + buildRequestUrl, + call, + serializeProperties +} from "../utils/internal"; +import type { AuthObject } from "../utils/public"; +import type { GetUserProfileResponse, UserProfile } from "./models"; + +/** + * A call to this function will retrieve summary information about + * a given user, targeted by 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 summary for. + * + * @example + * ``` + * const userSummary = await getUserProfile( + * authorization, + * { userName: "xelnia" } + * ); + * ``` + * + * @returns An object containing profile summary metadata about a target user. + */ +export const getUserProfile = async ( + authorization: AuthObject, + payload: { + userName: string; + } +): Promise => { + const { userName } = payload; + + const url = buildRequestUrl( + apiBaseUrl, + "/API_GetUserProfile.php", + authorization, + { u: userName } + ); + + const rawResponse = await call({ url }); + + return serializeProperties(rawResponse, { + shouldCastToNumbers: [ + "TotalPoints", + "TotalSoftcorePoints", + "TotalTruePoints", + "Permissions" + ], + shouldMapToBooleans: ["Untracked", "UserWallActive"] + }); +}; diff --git a/src/user/index.ts b/src/user/index.ts index 08c853e..e6c1e38 100644 --- a/src/user/index.ts +++ b/src/user/index.ts @@ -7,6 +7,7 @@ export * from "./getUserCompletedGames"; export * from "./getUserCompletionProgress"; export * from "./getUserGameRankAndScore"; export * from "./getUserPoints"; +export * from "./getUserProfile"; export * from "./getUserProgress"; export * from "./getUserRecentAchievements"; export * from "./getUserRecentlyPlayedGames"; diff --git a/src/user/models/get-user-profile-response.model.ts b/src/user/models/get-user-profile-response.model.ts new file mode 100644 index 0000000..e85c787 --- /dev/null +++ b/src/user/models/get-user-profile-response.model.ts @@ -0,0 +1,17 @@ +export interface GetUserProfileResponse { + User: string; + UserPic: string; + MemberSince: string; + RichPresenceMsg: string; + LastGameID: number; + ContribCount: number; + ContribYield: number; + TotalPoints: number; + TotalSoftcorePoints: number; + TotalTruePoints: number; + Permissions: number; + Untracked: number; + ID: number; + UserWallActive: number; + Motto: string; +} diff --git a/src/user/models/index.ts b/src/user/models/index.ts index 8c623a3..b0f5ab6 100644 --- a/src/user/models/index.ts +++ b/src/user/models/index.ts @@ -8,6 +8,7 @@ export * from "./get-user-completed-games-response.model"; export * from "./get-user-completion-progress-response.model"; export * from "./get-user-game-rank-and-score-response.model"; export * from "./get-user-points-response.model"; +export * from "./get-user-profile-response.model"; export * from "./get-user-progress-response.model"; export * from "./get-user-recent-achievements-response.model"; export * from "./get-user-recently-played-games-response.model"; @@ -20,6 +21,7 @@ export * from "./user-completion-progress.model"; export * from "./user-completion-progress-entity.model"; export * from "./user-game-rank-and-score.model"; export * from "./user-points.model"; +export * from "./user-profile.model"; export * from "./user-progress.model"; export * from "./user-recent-achievement.model"; export * from "./user-recently-played-games.model"; diff --git a/src/user/models/user-profile.model.ts b/src/user/models/user-profile.model.ts new file mode 100644 index 0000000..b447260 --- /dev/null +++ b/src/user/models/user-profile.model.ts @@ -0,0 +1,17 @@ +export interface UserProfile { + user: string; + userPic: string; + memberSince: string; + richPresenceMsg: string; + lastGameId: number; + contribCount: number; + contribYield: number; + totalPoints: number; + totalSoftcorePoints: number; + totalTruePoints: number; + permissions: number; + untracked: boolean; + id: number; + userWallActive: boolean; + motto: string; +}