Skip to content

Commit

Permalink
add GetUserPoints endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
joshraphael committed Aug 21, 2024
1 parent c0119cd commit a126d36
Show file tree
Hide file tree
Showing 5 changed files with 177 additions and 2 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@ For convenience, the API docs and examples can be found in the tables below
|`GetUserAwards(string)`|Get a list of a user's site awards/badges.|[docs](https://api-docs.retroachievements.org/v1/get-user-awards.html) \| [example](examples/user/getuserawards/getuserawards.go)|
|`GetUserClaims(string)`|Get a list of set development claims made over the lifetime of a user.|[docs](https://api-docs.retroachievements.org/v1/get-user-claims.html) \| [example](examples/user/getuserclaims/getuserclaims.go)|
|`GetUserGameRankAndScore(string,int)`|Get metadata about how a user has performed on a given game.|[docs](https://api-docs.retroachievements.org/v1/get-user-game-rank-and-score.html) \| [example](examples/user/getusergamerankandscore/getusergamerankandscore.go)|
|`GetUserPoints(string)`|Get a user's total hardcore and softcore points.|[docs](https://api-docs.retroachievements.org/v1/get-user-points.html) \| [example](examples/user/getuserpoints/getuserpoints.go)|

<h3>Game</h3>

Expand Down
25 changes: 25 additions & 0 deletions examples/user/getuserpoints/getuserpoints.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// Package getuserpoints get a user's total hardcore and softcore points.
package main

import (
"fmt"
"os"

"github.com/joshraphael/go-retroachievements"
)

/*
Test script, add RA_API_KEY to your env and use `go run getuserpoints.go`
*/
func main() {
secret := os.Getenv("RA_API_KEY")

client := retroachievements.NewClient(secret)

resp, err := client.GetUserPoints("joshraphael")
if err != nil {
panic(err)
}

fmt.Printf("%+v\n", resp)
}
5 changes: 5 additions & 0 deletions models/awards.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,8 @@ type Award struct {
Flags *int `json:"Flags"`
ImageIcon *string `json:"ImageIcon"`
}

type Points struct {
Points int `json:"Points"`
SoftcorePoints int `json:"SoftcorePoints"`
}
22 changes: 20 additions & 2 deletions user.go
Original file line number Diff line number Diff line change
Expand Up @@ -86,13 +86,13 @@ func (c *Client) GetAchievementsEarnedOnDay(username string, date time.Time) ([]
}

// GetGameInfoAndUserProgress get metadata about a game as well as a user's progress on that game.
func (c *Client) GetGameInfoAndUserProgress(username string, game int, includeAwardMetadata bool) (*models.UserGameProgress, error) {
func (c *Client) GetGameInfoAndUserProgress(username string, gameId int, includeAwardMetadata bool) (*models.UserGameProgress, error) {
resp, err := c.do(
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetGameInfoAndUserProgress.php"),
raHttp.APIToken(c.Secret),
raHttp.Username(username),
raHttp.GameID(game),
raHttp.GameID(gameId),
raHttp.AwardMetadata(includeAwardMetadata),
)
if err != nil {
Expand Down Expand Up @@ -177,3 +177,21 @@ func (c *Client) GetUserGameRankAndScore(username string, gameId int) ([]models.
}
return userGameRankScore, nil
}

// GetUserPoints get a user's total hardcore and softcore points.
func (c *Client) GetUserPoints(username string) (*models.Points, error) {
resp, err := c.do(
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetUserPoints.php"),
raHttp.APIToken(c.Secret),
raHttp.Username(username),
)
if err != nil {
return nil, fmt.Errorf("calling endpoint: %w", err)
}
points, err := raHttp.ResponseObject[models.Points](resp)
if err != nil {
return nil, fmt.Errorf("parsing response object: %w", err)
}
return points, nil
}
126 changes: 126 additions & 0 deletions user_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1237,6 +1237,23 @@ func TestGetUserClaims(tt *testing.T) {
assert: func(t *testing.T, userClaims []models.UserClaims, err error) {
require.NotNil(t, userClaims)
require.Len(t, userClaims, 1)
require.Equal(t, 13657, userClaims[0].ID)
require.Equal(t, "joshraphael", userClaims[0].User)
require.Equal(t, 4111, userClaims[0].GameID)
require.Equal(t, "Monster Max", userClaims[0].GameTitle)
require.Equal(t, "/Images/059373.png", userClaims[0].GameIcon)
require.Equal(t, 4, userClaims[0].ConsoleID)
require.Equal(t, "Game Boy", userClaims[0].ConsoleName)
require.Equal(t, 0, userClaims[0].ClaimType)
require.Equal(t, 0, userClaims[0].SetType)
require.Equal(t, 0, userClaims[0].Status)
require.Equal(t, 0, userClaims[0].Extension)
require.Equal(t, 0, userClaims[0].Special)
require.Equal(t, created, userClaims[0].Created.Time)
require.Equal(t, done, userClaims[0].DoneTime.Time)
require.Equal(t, created, userClaims[0].Updated.Time)
require.Equal(t, 1, userClaims[0].UserIsJrDev)
require.Equal(t, 87089, userClaims[0].MinutesLeft)
require.NoError(t, err)
},
},
Expand Down Expand Up @@ -1387,3 +1404,112 @@ func TestGetUserGameRankAndScore(tt *testing.T) {
})
}
}

func TestGetUserPoints(tt *testing.T) {
tests := []struct {
name string
username string
modifyURL func(url string) string
responseCode int
responseMessage models.Points
responseError models.ErrorResponse
response func(messageBytes []byte, errorBytes []byte) []byte
assert func(t *testing.T, points *models.Points, err error)
}{
{
name: "fail to call endpoint",
username: "Test",
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, points *models.Points, err error) {
require.Nil(t, points)
require.EqualError(t, err, "calling endpoint: Get \"/API/API_GetUserPoints.php?u=Test&y=some_secret\": unsupported protocol scheme \"\"")
},
},
{
name: "error response",
username: "Test",
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, points *models.Points, err error) {
require.Nil(t, points)
require.EqualError(t, err, "parsing response object: error responses: [401] Not Authorized")
},
},
{
name: "success",
username: "Test",
modifyURL: func(url string) string {
return url
},
responseCode: http.StatusOK,
responseMessage: models.Points{
Points: 230,
SoftcorePoints: 342,
},
response: func(messageBytes []byte, errorBytes []byte) []byte {
return messageBytes
},
assert: func(t *testing.T, points *models.Points, err error) {
require.NotNil(t, points)
require.Equal(t, 230, points.Points)
require.Equal(t, 342, points.SoftcorePoints)
require.NoError(t, err)
},
},
}
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_GetUserPoints.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")
points, err := client.GetUserPoints(test.username)
test.assert(t, points, err)
})
}
}

0 comments on commit a126d36

Please sign in to comment.