Skip to content

Commit 5e9fa03

Browse files
authored
feat(getUserCompletionProgress): add function (#64)
1 parent 13562f4 commit 5e9fa03

7 files changed

+219
-0
lines changed
Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
import { http, HttpResponse } from "msw";
2+
import { setupServer } from "msw/node";
3+
4+
import { apiBaseUrl } from "../utils/internal";
5+
import { buildAuthorization } from "../utils/public";
6+
import { getUserCompletionProgress } from "./getUserCompletionProgress";
7+
import type { GetUserCompletionProgressResponse } from "./models";
8+
9+
const server = setupServer();
10+
11+
describe("Function: getUserCompletionProgress", () => {
12+
// MSW Setup
13+
beforeAll(() => server.listen());
14+
afterEach(() => server.resetHandlers());
15+
afterAll(() => server.close());
16+
17+
it("is defined #sanity", () => {
18+
// ASSERT
19+
expect(getUserCompletionProgress).toBeDefined();
20+
});
21+
22+
it("retrieves completion progress by username", async () => {
23+
// ARRANGE
24+
const authorization = buildAuthorization({
25+
userName: "mockUserName",
26+
webApiKey: "mockWebApiKey"
27+
});
28+
29+
const mockResponse: GetUserCompletionProgressResponse = {
30+
Count: 1,
31+
Total: 1,
32+
Results: [
33+
{
34+
GameID: 680,
35+
Title: "Game & Watch Gallery",
36+
ImageIcon: "/Images/042952.png",
37+
ConsoleID: 4,
38+
ConsoleName: "Game Boy",
39+
MaxPossible: 27,
40+
NumAwarded: 8,
41+
NumAwardedHardcore: 8,
42+
MostRecentAwardedDate: "2022-07-26T23:56:15+00:00",
43+
HighestAwardKind: null,
44+
HighestAwardDate: null
45+
}
46+
]
47+
};
48+
49+
server.use(
50+
http.get(`${apiBaseUrl}/API_GetUserCompletionProgress.php`, () =>
51+
HttpResponse.json(mockResponse)
52+
)
53+
);
54+
55+
// ACT
56+
const response = await getUserCompletionProgress(authorization, {
57+
userName: "xelnia"
58+
});
59+
60+
// ASSERT
61+
expect(response).toEqual({
62+
count: 1,
63+
total: 1,
64+
results: [
65+
{
66+
gameId: 680,
67+
title: "Game & Watch Gallery",
68+
imageIcon: "/Images/042952.png",
69+
consoleId: 4,
70+
consoleName: "Game Boy",
71+
maxPossible: 27,
72+
numAwarded: 8,
73+
numAwardedHardcore: 8,
74+
mostRecentAwardedDate: "2022-07-26T23:56:15+00:00",
75+
highestAwardKind: null,
76+
highestAwardDate: null
77+
}
78+
]
79+
});
80+
});
81+
});

src/user/getUserCompletionProgress.ts

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
import {
2+
apiBaseUrl,
3+
buildRequestUrl,
4+
call,
5+
serializeProperties
6+
} from "../utils/internal";
7+
import type { AuthObject } from "../utils/public";
8+
import type {
9+
GetUserCompletionProgressResponse,
10+
UserCompletionProgress
11+
} from "./models";
12+
13+
/**
14+
* A call to this function will retrieve a given user's completion
15+
* progress, targeted by their username.
16+
*
17+
* @param authorization An object containing your userName and webApiKey.
18+
* This can be constructed with `buildAuthorization()`.
19+
*
20+
* @param payload.userName The user for which to retrieve the progress for.
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 userCompletionProgress = await getUserCompletionProgress(
29+
* authorization,
30+
* { userName: "xelnia" }
31+
* );
32+
* ```
33+
*
34+
* @returns
35+
* ```
36+
* {
37+
* "count": 100,
38+
* "total": 752,
39+
* "results": [
40+
* {
41+
gameId: 11406,
42+
title: 'Mortal Kombat 4',
43+
imageIcon: '/Images/042133.png',
44+
consoleId: 12,
45+
consoleName: 'PlayStation',
46+
maxPossible: 131,
47+
numAwarded: 131,
48+
numAwardedHardcore: 131,
49+
mostRecentAwardedDate: '2022-08-07T18:24:44+00:00',
50+
highestAwardKind: 'mastered',
51+
highestAwardDate: '2022-08-07T18:24:44+00:00'
52+
* }
53+
* ]
54+
* }
55+
* ```
56+
*/
57+
export const getUserCompletionProgress = async (
58+
authorization: AuthObject,
59+
payload: { userName: string; offset?: number; count?: number }
60+
): Promise<UserCompletionProgress> => {
61+
const { userName, offset, count } = payload;
62+
63+
const params: Record<string, string | number> = {
64+
u: userName
65+
};
66+
if (offset) {
67+
params["o"] = offset;
68+
}
69+
if (count) {
70+
params["c"] = count;
71+
}
72+
73+
const url = buildRequestUrl(
74+
apiBaseUrl,
75+
"/API_GetUserCompletionProgress.php",
76+
authorization,
77+
params
78+
);
79+
80+
const rawResponse = await call<GetUserCompletionProgressResponse>({ url });
81+
82+
return serializeProperties(rawResponse);
83+
};

src/user/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ export * from "./getGameInfoAndUserProgress";
44
export * from "./getUserAwards";
55
export * from "./getUserClaims";
66
export * from "./getUserCompletedGames";
7+
export * from "./getUserCompletionProgress";
78
export * from "./getUserGameRankAndScore";
89
export * from "./getUserPoints";
910
export * from "./getUserProgress";
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
interface RawUserCompletionProgressEntity {
2+
GameID: number;
3+
Title: string;
4+
ImageIcon: string;
5+
ConsoleID: number;
6+
ConsoleName: string;
7+
MaxPossible: number;
8+
NumAwarded: number;
9+
NumAwardedHardcore: number;
10+
11+
MostRecentAwardedDate?: string;
12+
HighestAwardKind?:
13+
| "mastered"
14+
| "completed"
15+
| "beaten-hardcore"
16+
| "beaten-softcore"
17+
| null;
18+
HighestAwardDate?: string | null;
19+
}
20+
21+
export interface GetUserCompletionProgressResponse {
22+
Count: number;
23+
Total: number;
24+
Results: RawUserCompletionProgressEntity[];
25+
}

src/user/models/index.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ export * from "./game-info-and-user-progress.model";
55
export * from "./get-game-info-and-user-progress-response.model";
66
export * from "./get-user-awards-response.model";
77
export * from "./get-user-completed-games-response.model";
8+
export * from "./get-user-completion-progress-response.model";
89
export * from "./get-user-game-rank-and-score-response.model";
910
export * from "./get-user-points-response.model";
1011
export * from "./get-user-progress-response.model";
@@ -15,6 +16,8 @@ export * from "./user-awards.model";
1516
export * from "./user-claims.model";
1617
export * from "./user-claims-response.model";
1718
export * from "./user-completed-games.model";
19+
export * from "./user-completion-progress.model";
20+
export * from "./user-completion-progress-entity.model";
1821
export * from "./user-game-rank-and-score.model";
1922
export * from "./user-points.model";
2023
export * from "./user-progress.model";
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
export interface UserCompletionProgressEntity {
2+
gameId: number;
3+
title: string;
4+
imageIcon: string;
5+
consoleId: number;
6+
consoleName: string;
7+
maxPossible: number;
8+
numAwarded: number;
9+
numAwardedHardcore: number;
10+
11+
mostRecentAwardedDate?: string;
12+
highestAwardKind?:
13+
| "mastered"
14+
| "completed"
15+
| "beaten-hardcore"
16+
| "beaten-softcore"
17+
| null;
18+
highestAwardDate?: string;
19+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import type { UserCompletionProgressEntity } from "./user-completion-progress-entity.model";
2+
3+
export interface UserCompletionProgress {
4+
count: number;
5+
total: number;
6+
results: UserCompletionProgressEntity[];
7+
}

0 commit comments

Comments
 (0)