Skip to content

Commit aeb43a0

Browse files
authored
Merge pull request #8 from joshraphael/issue-2
issue-2 -- add GetUsersIFollow endpoint
2 parents 3732a9f + 4a41a2d commit aeb43a0

File tree

5 files changed

+210
-0
lines changed

5 files changed

+210
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@ For convenience, the API docs and examples can be found in the tables below
7070
|`GetUserSummary()`|Get a user's profile metadata.|[docs](https://api-docs.retroachievements.org/v1/get-user-summary.html) \| [example](examples/user/getusersummary/getusersummary.go)|
7171
|`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)|
7272
|`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)|
73+
|`GetUsersIFollow()`|Get the caller's "Following" users list.|[docs](https://api-docs.retroachievements.org/v1/get-users-i-follow.html) \| [example](examples/user/getusersifollow/getusersifollow.go)|
7374
|`GetUserSetRequests()`|Get a user's list of set requests.|[docs](https://api-docs.retroachievements.org/v1/get-user-set-requests.html) \| [example](examples/user/getusersetrequests/getusersetrequests.go)|
7475

7576
<h3>Game</h3>
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Package getusersifollow provides an example for the caller's "Following" users list.
2+
package main
3+
4+
import (
5+
"fmt"
6+
"os"
7+
8+
"github.com/joshraphael/go-retroachievements"
9+
"github.com/joshraphael/go-retroachievements/models"
10+
)
11+
12+
/*
13+
Test script, add RA_API_KEY to your env and use `go run getusersifollow.go`
14+
*/
15+
func main() {
16+
secret := os.Getenv("RA_API_KEY")
17+
18+
client := retroachievements.NewClient(secret)
19+
20+
count := 1
21+
offset := 1
22+
resp, err := client.GetUsersIFollow(models.GetUsersIFollowParameters{
23+
Count: &count,
24+
Offset: &offset,
25+
})
26+
if err != nil {
27+
panic(err)
28+
}
29+
30+
fmt.Printf("%+v\n", resp)
31+
}

models/user.go

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -605,6 +605,27 @@ type GetUserWantToPlayListResult struct {
605605
AchievementsPublished int `json:"AchievementsPublished"`
606606
}
607607

608+
type GetUsersIFollowParameters struct {
609+
// [Optional] The number of records to return (default: 100, max: 500).
610+
Count *int
611+
612+
// [Optional] The number of entries to skip (default: 0).
613+
Offset *int
614+
}
615+
616+
type GetUsersIFollow struct {
617+
Count int `json:"Count"`
618+
Total int `json:"Total"`
619+
Results []GetUsersIFollowResult `json:"Results"`
620+
}
621+
622+
type GetUsersIFollowResult struct {
623+
User string `json:"User"`
624+
Points int `json:"Points"`
625+
PointsSoftcore int `json:"PointsSoftcore"`
626+
IsFollowingMe bool `json:"IsFollowingMe"`
627+
}
628+
608629
type GetUserSetRequestsParameters struct {
609630
// The target username.
610631
Username string

user.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,31 @@ func (c *Client) GetUserWantToPlayList(params models.GetUserWantToPlayListParame
338338
return resp, nil
339339
}
340340

341+
// GetUsersIFollow gets the caller's "Following" users list.
342+
func (c *Client) GetUsersIFollow(params models.GetUsersIFollowParameters) (*models.GetUsersIFollow, error) {
343+
details := []raHttp.RequestDetail{
344+
raHttp.Method(http.MethodGet),
345+
raHttp.UserAgent(c.UserAgent),
346+
raHttp.Path("/API/API_GetUsersIFollow.php"),
347+
raHttp.APIToken(c.Secret),
348+
}
349+
if params.Count != nil {
350+
details = append(details, raHttp.C(*params.Count))
351+
}
352+
if params.Offset != nil {
353+
details = append(details, raHttp.O(*params.Offset))
354+
}
355+
r, err := c.do(details...)
356+
if err != nil {
357+
return nil, fmt.Errorf("calling endpoint: %w", err)
358+
}
359+
resp, err := raHttp.ResponseObject[models.GetUsersIFollow](r)
360+
if err != nil {
361+
return nil, fmt.Errorf("parsing response object: %w", err)
362+
}
363+
return resp, nil
364+
}
365+
341366
// GetUserSetRequests gets a user's list of set requests.
342367
func (c *Client) GetUserSetRequests(params models.GetUserSetRequestsParameters) (*models.GetUserSetRequests, error) {
343368
details := []raHttp.RequestDetail{

user_test.go

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2478,6 +2478,138 @@ func TestGetUserWantToPlayList(tt *testing.T) {
24782478
}
24792479
}
24802480

2481+
func TestGetUsersIFollow(tt *testing.T) {
2482+
count := 10
2483+
offset := 23
2484+
tests := []struct {
2485+
name string
2486+
params models.GetUsersIFollowParameters
2487+
modifyURL func(url string) string
2488+
responseCode int
2489+
responseMessage models.GetUsersIFollow
2490+
responseError models.ErrorResponse
2491+
response func(messageBytes []byte, errorBytes []byte) []byte
2492+
assert func(t *testing.T, resp *models.GetUsersIFollow, err error)
2493+
}{
2494+
{
2495+
name: "fail to call endpoint",
2496+
params: models.GetUsersIFollowParameters{
2497+
Count: &count,
2498+
Offset: &offset,
2499+
},
2500+
modifyURL: func(url string) string {
2501+
return ""
2502+
},
2503+
responseCode: http.StatusUnauthorized,
2504+
responseError: models.ErrorResponse{
2505+
Message: "test",
2506+
Errors: []models.ErrorDetail{
2507+
{
2508+
Status: http.StatusUnauthorized,
2509+
Code: "unauthorized",
2510+
Title: "Not Authorized",
2511+
},
2512+
},
2513+
},
2514+
response: func(messageBytes []byte, errorBytes []byte) []byte {
2515+
return errorBytes
2516+
},
2517+
assert: func(t *testing.T, resp *models.GetUsersIFollow, err error) {
2518+
require.Nil(t, resp)
2519+
require.EqualError(t, err, "calling endpoint: Get \"/API/API_GetUsersIFollow.php?c=10&o=23&y=some_secret\": unsupported protocol scheme \"\"")
2520+
},
2521+
},
2522+
{
2523+
name: "error response",
2524+
params: models.GetUsersIFollowParameters{
2525+
Count: &count,
2526+
Offset: &offset,
2527+
},
2528+
modifyURL: func(url string) string {
2529+
return url
2530+
},
2531+
responseCode: http.StatusUnauthorized,
2532+
responseError: models.ErrorResponse{
2533+
Message: "test",
2534+
Errors: []models.ErrorDetail{
2535+
{
2536+
Status: http.StatusUnauthorized,
2537+
Code: "unauthorized",
2538+
Title: "Not Authorized",
2539+
},
2540+
},
2541+
},
2542+
response: func(messageBytes []byte, errorBytes []byte) []byte {
2543+
return errorBytes
2544+
},
2545+
assert: func(t *testing.T, resp *models.GetUsersIFollow, err error) {
2546+
require.Nil(t, resp)
2547+
require.EqualError(t, err, "parsing response object: error code 401 returned: {\"message\":\"test\",\"errors\":[{\"status\":401,\"code\":\"unauthorized\",\"title\":\"Not Authorized\"}]}")
2548+
},
2549+
},
2550+
{
2551+
name: "success",
2552+
params: models.GetUsersIFollowParameters{
2553+
Count: &count,
2554+
Offset: &offset,
2555+
},
2556+
modifyURL: func(url string) string {
2557+
return url
2558+
},
2559+
responseCode: http.StatusOK,
2560+
responseMessage: models.GetUsersIFollow{
2561+
Count: 20,
2562+
Total: 120,
2563+
Results: []models.GetUsersIFollowResult{
2564+
{
2565+
User: "zuliman92",
2566+
Points: 1882,
2567+
PointsSoftcore: 258,
2568+
IsFollowingMe: true,
2569+
},
2570+
},
2571+
},
2572+
response: func(messageBytes []byte, errorBytes []byte) []byte {
2573+
return messageBytes
2574+
},
2575+
assert: func(t *testing.T, resp *models.GetUsersIFollow, err error) {
2576+
require.NotNil(t, resp)
2577+
require.Equal(t, 20, resp.Count)
2578+
require.Equal(t, 120, resp.Total)
2579+
require.Len(t, resp.Results, 1)
2580+
require.Equal(t, "zuliman92", resp.Results[0].User)
2581+
require.Equal(t, 1882, resp.Results[0].Points)
2582+
require.Equal(t, 258, resp.Results[0].PointsSoftcore)
2583+
require.True(t, resp.Results[0].IsFollowingMe)
2584+
require.NoError(t, err)
2585+
},
2586+
},
2587+
}
2588+
for _, test := range tests {
2589+
tt.Run(test.name, func(t *testing.T) {
2590+
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
2591+
expectedPath := "/API/API_GetUsersIFollow.php"
2592+
if r.URL.Path != expectedPath {
2593+
t.Errorf("Expected to request '%s', got: %s", expectedPath, r.URL.Path)
2594+
}
2595+
w.WriteHeader(test.responseCode)
2596+
responseMessage, err := json.Marshal(test.responseMessage)
2597+
require.NoError(t, err)
2598+
errBytes, err := json.Marshal(test.responseError)
2599+
require.NoError(t, err)
2600+
resp := test.response(responseMessage, errBytes)
2601+
num, err := w.Write(resp)
2602+
require.NoError(t, err)
2603+
require.Equal(t, num, len(resp))
2604+
}))
2605+
defer server.Close()
2606+
client := retroachievements.New(test.modifyURL(server.URL), "go-retroachievements/v0.0.0", "some_secret")
2607+
resp, err := client.GetUsersIFollow(test.params)
2608+
test.assert(t, resp, err)
2609+
})
2610+
}
2611+
}
2612+
24812613
func TestGetUserSetRequests(tt *testing.T) {
24822614
all := true
24832615
tests := []struct {

0 commit comments

Comments
 (0)