From 91b7639977683b3a8a518e18242e211d31b41f24 Mon Sep 17 00:00:00 2001 From: Joshua Raphael Date: Mon, 18 Nov 2024 22:51:12 -0700 Subject: [PATCH] add GetUserWantToPlayList --- README.md | 3 +- .../getuserwanttoplaylist.go | 28 ++++ models/user.go | 27 ++++ user.go | 25 ++++ user_test.go | 140 ++++++++++++++++++ 5 files changed, 222 insertions(+), 1 deletion(-) create mode 100644 examples/user/getuserwanttoplaylist/getuserwanttoplaylist.go diff --git a/README.md b/README.md index d7fe648..359ac55 100644 --- a/README.md +++ b/README.md @@ -36,7 +36,7 @@ you can now use the client to call any of the available endpoints, for example: ```go profile, err := client.GetUserProfile(models.GetUserProfileParameters{ - Username: "jamiras", + Username: "jamiras", }) ``` @@ -63,6 +63,7 @@ For convenience, the API docs and examples can be found in the tables below |`GetUserRecentlyPlayedGames()`|Get a list of games a user has recently played.|[docs](https://api-docs.retroachievements.org/v1/get-user-recently-played-games.html) \| [example](examples/user/getuserrecentlyplayedgames/getuserrecentlyplayedgames.go)| |`GetUserSummary()`|Get a user's profile metadata.|[docs](https://api-docs.retroachievements.org/v1/get-user-summary.html) \| [example](examples/user/getusersummary/getusersummary.go)| |`GetUserCompletedGames()`|[Deprecated] Get hardcore and softcore completion metadata about games a user has played.|[docs](https://api-docs.retroachievements.org/v1/get-user-completed-games.html) \| [example](examples/user/getusercompletedgames/getusercompletedgames.go)| +|`GetUserWantToPlayList()`|Get a user's "Want to Play Games" list.|[docs](https://api-docs.retroachievements.org/v1/get-user-want-to-play-list.html) \| [example](examples/user/getuserwanttoplaylist/getuserwanttoplaylist.go)|

Game

diff --git a/examples/user/getuserwanttoplaylist/getuserwanttoplaylist.go b/examples/user/getuserwanttoplaylist/getuserwanttoplaylist.go new file mode 100644 index 0000000..2c2cf44 --- /dev/null +++ b/examples/user/getuserwanttoplaylist/getuserwanttoplaylist.go @@ -0,0 +1,28 @@ +// Package getuserwanttoplaylist provides an example for a users "Want to Play Games" list +package main + +import ( + "fmt" + "os" + + "github.com/joshraphael/go-retroachievements" + "github.com/joshraphael/go-retroachievements/models" +) + +/* +Test script, add RA_API_KEY to your env and use `go run getuserwanttoplaylist.go` +*/ +func main() { + secret := os.Getenv("RA_API_KEY") + + client := retroachievements.NewClient(secret) + + resp, err := client.GetUserWantToPlayList(models.GetUserWantToPlayListParameters{ + Username: "jamiras", + }) + if err != nil { + panic(err) + } + + fmt.Printf("%+v\n", resp) +} diff --git a/models/user.go b/models/user.go index 294ee0a..ef5f469 100644 --- a/models/user.go +++ b/models/user.go @@ -579,3 +579,30 @@ type GetUserCompletedGames struct { PctWon string `json:"PctWon"` HardcoreMode string `json:"HardcoreMode"` } + +type GetUserWantToPlayListParameters struct { + // The target username + Username string + + // [Optional] The number of records to return (default: 100, max: 500). + Count *int + + // [Optional] The number of entries to skip (default: 0). + Offset *int +} + +type GetUserWantToPlayList struct { + Count int `json:"Count"` + Total int `json:"Total"` + Results []GetUserWantToPlayListResult `json:"Results"` +} + +type GetUserWantToPlayListResult struct { + ID int `json:"ID"` + Title string `json:"Title"` + ImageIcon string `json:"ImageIcon"` + ConsoleID int `json:"ConsoleID"` + ConsoleName string `json:"ConsoleName"` + PointsTotal int `json:"PointsTotal"` + AchievementsPublished int `json:"AchievementsPublished"` +} diff --git a/user.go b/user.go index d5efb12..3947d1b 100644 --- a/user.go +++ b/user.go @@ -287,3 +287,28 @@ func (c *Client) GetUserCompletedGames(params models.GetUserCompletedGamesParame } return games, nil } + +// GetUserWantToPlayList gets a given user's "Want to Play Games" list. +func (c *Client) GetUserWantToPlayList(params models.GetUserWantToPlayListParameters) (*models.GetUserWantToPlayList, error) { + details := []raHttp.RequestDetail{ + raHttp.Method(http.MethodGet), + raHttp.Path("/API/API_GetUserWantToPlayList.php"), + raHttp.APIToken(c.Secret), + raHttp.Username(params.Username), + } + if params.Count != nil { + details = append(details, raHttp.Count(*params.Count)) + } + if params.Offset != nil { + details = append(details, raHttp.Offset(*params.Offset)) + } + resp, err := c.do(details...) + if err != nil { + return nil, fmt.Errorf("calling endpoint: %w", err) + } + results, err := raHttp.ResponseObject[models.GetUserWantToPlayList](resp) + if err != nil { + return nil, fmt.Errorf("parsing response object: %w", err) + } + return results, nil +} diff --git a/user_test.go b/user_test.go index 866332a..a53e679 100644 --- a/user_test.go +++ b/user_test.go @@ -2351,3 +2351,143 @@ func TestGetUserCompletedGames(tt *testing.T) { }) } } + +func TestGetUserWantToPlayList(tt *testing.T) { + count := 10 + offset := 23 + tests := []struct { + name string + params models.GetUserWantToPlayListParameters + modifyURL func(url string) string + responseCode int + responseMessage models.GetUserWantToPlayList + responseError models.ErrorResponse + response func(messageBytes []byte, errorBytes []byte) []byte + assert func(t *testing.T, resp *models.GetUserWantToPlayList, err error) + }{ + { + name: "fail to call endpoint", + params: models.GetUserWantToPlayListParameters{ + Username: "Test", + Count: &count, + Offset: &offset, + }, + modifyURL: func(url string) string { + return "" + }, + responseCode: http.StatusUnauthorized, + responseError: models.ErrorResponse{ + Message: "test", + Errors: []models.ErrorDetail{ + { + Status: http.StatusUnauthorized, + Code: "unauthorized", + Title: "Not Authorized", + }, + }, + }, + response: func(messageBytes []byte, errorBytes []byte) []byte { + return errorBytes + }, + assert: func(t *testing.T, resp *models.GetUserWantToPlayList, err error) { + require.Nil(t, resp) + require.EqualError(t, err, "calling endpoint: Get \"/API/API_GetUserWantToPlayList.php?c=10&o=23&u=Test&y=some_secret\": unsupported protocol scheme \"\"") + }, + }, + { + name: "error response", + params: models.GetUserWantToPlayListParameters{ + Username: "Test", + Count: &count, + Offset: &offset, + }, + modifyURL: func(url string) string { + return url + }, + responseCode: http.StatusUnauthorized, + responseError: models.ErrorResponse{ + Message: "test", + Errors: []models.ErrorDetail{ + { + Status: http.StatusUnauthorized, + Code: "unauthorized", + Title: "Not Authorized", + }, + }, + }, + response: func(messageBytes []byte, errorBytes []byte) []byte { + return errorBytes + }, + assert: func(t *testing.T, resp *models.GetUserWantToPlayList, err error) { + require.Nil(t, resp) + require.EqualError(t, err, "parsing response object: error responses: [401] Not Authorized") + }, + }, + { + name: "success", + params: models.GetUserWantToPlayListParameters{ + Username: "Test", + Count: &count, + Offset: &offset, + }, + modifyURL: func(url string) string { + return url + }, + responseCode: http.StatusOK, + responseMessage: models.GetUserWantToPlayList{ + Count: 1, + Total: 1, + Results: []models.GetUserWantToPlayListResult{ + { + ID: 189, + Title: "Super Mario Galaxy", + ConsoleID: 19, + ConsoleName: "Wii", + ImageIcon: "/Images/079076.png", + PointsTotal: 0, + AchievementsPublished: 0, + }, + }, + }, + response: func(messageBytes []byte, errorBytes []byte) []byte { + return messageBytes + }, + assert: func(t *testing.T, resp *models.GetUserWantToPlayList, err error) { + require.NoError(t, err) + require.Equal(t, 1, resp.Count) + require.Equal(t, 1, resp.Total) + require.Len(t, resp.Results, 1) + require.Equal(t, 189, resp.Results[0].ID) + require.Equal(t, "Super Mario Galaxy", resp.Results[0].Title) + require.Equal(t, 19, resp.Results[0].ConsoleID) + require.Equal(t, "Wii", resp.Results[0].ConsoleName) + require.Equal(t, "/Images/079076.png", resp.Results[0].ImageIcon) + require.Equal(t, 0, resp.Results[0].PointsTotal) + require.Equal(t, 0, resp.Results[0].AchievementsPublished) + }, + }, + } + for _, test := range tests { + tt.Run(test.name, func(t *testing.T) { + server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + expectedPath := "/API/API_GetUserWantToPlayList.php" + if r.URL.Path != expectedPath { + t.Errorf("Expected to request '%s', got: %s", expectedPath, r.URL.Path) + } + w.WriteHeader(test.responseCode) + responseMessage, err := json.Marshal(test.responseMessage) + require.NoError(t, err) + errBytes, err := json.Marshal(test.responseError) + require.NoError(t, err) + resp := test.response(responseMessage, errBytes) + num, err := w.Write(resp) + require.NoError(t, err) + require.Equal(t, num, len(resp)) + })) + defer server.Close() + client := retroachievements.New(test.modifyURL(server.URL), "some_secret") + resp, err := client.GetUserWantToPlayList(test.params) + test.assert(t, resp, err) + }) + } +}