-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
70e2bf4
commit dda99b7
Showing
6 changed files
with
254 additions
and
4 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
28 changes: 28 additions & 0 deletions
28
examples/leaderboards/getgameleaderboards/getgameleaderboards.go
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
// Package getgameleaderboards provides an example for getting a given games's list of leaderboards. | ||
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 getgameleaderboards.go` | ||
*/ | ||
func main() { | ||
secret := os.Getenv("RA_API_KEY") | ||
|
||
client := retroachievements.NewClient(secret) | ||
|
||
resp, err := client.GetGameLeaderboards(models.GetGameLeaderboardsParameters{ | ||
GameID: 1, | ||
}) | ||
if err != nil { | ||
panic(err) | ||
} | ||
|
||
fmt.Printf("%+v\n", resp) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
package retroachievements | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
raHttp "github.com/joshraphael/go-retroachievements/http" | ||
"github.com/joshraphael/go-retroachievements/models" | ||
) | ||
|
||
// GetGameLeaderboards gets a given games's list of leaderboards. | ||
func (c *Client) GetGameLeaderboards(params models.GetGameLeaderboardsParameters) (*models.GetGameLeaderboards, error) { | ||
details := []raHttp.RequestDetail{ | ||
raHttp.Method(http.MethodGet), | ||
raHttp.Path("/API/API_GetGameLeaderboards.php"), | ||
raHttp.APIToken(c.Secret), | ||
raHttp.IDs([]int{params.GameID}), | ||
} | ||
if params.Count != nil { | ||
details = append(details, raHttp.Count(*params.Count)) | ||
} | ||
if params.Offset != nil { | ||
details = append(details, raHttp.Offset(*params.Offset)) | ||
} | ||
r, err := c.do(details...) | ||
if err != nil { | ||
return nil, fmt.Errorf("calling endpoint: %w", err) | ||
} | ||
resp, err := raHttp.ResponseObject[models.GetGameLeaderboards](r) | ||
if err != nil { | ||
return nil, fmt.Errorf("parsing response object: %w", err) | ||
} | ||
return resp, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,149 @@ | ||
package retroachievements_test | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
|
||
"github.com/joshraphael/go-retroachievements" | ||
"github.com/joshraphael/go-retroachievements/models" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGetGameLeaderboards(tt *testing.T) { | ||
count := 10 | ||
offset := 10 | ||
tests := []struct { | ||
name string | ||
params models.GetGameLeaderboardsParameters | ||
modifyURL func(url string) string | ||
responseCode int | ||
responseMessage models.GetGameLeaderboards | ||
responseError models.ErrorResponse | ||
response func(messageBytes []byte, errorBytes []byte) []byte | ||
assert func(t *testing.T, resp *models.GetGameLeaderboards, err error) | ||
}{ | ||
{ | ||
name: "fail to call endpoint", | ||
params: models.GetGameLeaderboardsParameters{ | ||
GameID: 14402, | ||
Count: &count, | ||
Offset: &offset, | ||
}, | ||
modifyURL: func(url string) string { | ||
return "" | ||
}, | ||
responseCode: http.StatusOK, | ||
response: func(messageBytes []byte, errorBytes []byte) []byte { | ||
return messageBytes | ||
}, | ||
assert: func(t *testing.T, resp *models.GetGameLeaderboards, err error) { | ||
require.Nil(t, resp) | ||
require.EqualError(t, err, "calling endpoint: Get \"/API/API_GetGameLeaderboards.php?c=10&i=14402&o=10&y=some_secret\": unsupported protocol scheme \"\"") | ||
}, | ||
}, | ||
{ | ||
name: "error response", | ||
params: models.GetGameLeaderboardsParameters{ | ||
GameID: 14402, | ||
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.GetGameLeaderboards, err error) { | ||
require.Nil(t, resp) | ||
require.EqualError(t, err, "parsing response object: error responses: [401] Not Authorized") | ||
}, | ||
}, | ||
{ | ||
name: "success", | ||
params: models.GetGameLeaderboardsParameters{ | ||
GameID: 14402, | ||
Count: &count, | ||
Offset: &offset, | ||
}, | ||
modifyURL: func(url string) string { | ||
return url | ||
}, | ||
responseCode: http.StatusOK, | ||
responseMessage: models.GetGameLeaderboards{ | ||
Count: 1, | ||
Total: 2, | ||
Results: []models.GetGameLeaderboardsResult{ | ||
{ | ||
ID: 114798, | ||
RankAsc: true, | ||
Title: "Speedrun Monster Max", | ||
Description: "Complete the game from start to finish as fast as possible without using passwords", | ||
Format: "TIME", | ||
TopEntry: &models.GetGameLeaderboardsTopEntry{ | ||
User: "joshraphael", | ||
Score: 2267, | ||
FormattedScore: "0:37.78", | ||
}, | ||
}, | ||
}, | ||
}, | ||
response: func(messageBytes []byte, errorBytes []byte) []byte { | ||
return messageBytes | ||
}, | ||
assert: func(t *testing.T, resp *models.GetGameLeaderboards, err error) { | ||
require.NotNil(t, resp) | ||
require.Equal(t, 1, resp.Count) | ||
require.Equal(t, 2, resp.Total) | ||
require.Len(t, resp.Results, 1) | ||
require.Equal(t, 114798, resp.Results[0].ID) | ||
require.True(t, resp.Results[0].RankAsc) | ||
require.Equal(t, "Speedrun Monster Max", resp.Results[0].Title) | ||
require.Equal(t, "Complete the game from start to finish as fast as possible without using passwords", resp.Results[0].Description) | ||
require.Equal(t, "TIME", resp.Results[0].Format) | ||
require.NotNil(t, resp.Results[0].TopEntry) | ||
require.Equal(t, "joshraphael", resp.Results[0].TopEntry.User) | ||
require.Equal(t, 2267, resp.Results[0].TopEntry.Score) | ||
require.Equal(t, "0:37.78", resp.Results[0].TopEntry.FormattedScore) | ||
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_GetGameLeaderboards.php" | ||
if r.URL.Path != expectedPath { | ||
t.Errorf("Expected to request '%s', got: %s", expectedPath, r.URL.Path) | ||
} | ||
w.WriteHeader(test.responseCode) | ||
messageBytes, err := json.Marshal(test.responseMessage) | ||
require.NoError(t, err) | ||
errBytes, err := json.Marshal(test.responseError) | ||
require.NoError(t, err) | ||
resp := test.response(messageBytes, 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.GetGameLeaderboards(test.params) | ||
test.assert(t, resp, err) | ||
}) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
package models | ||
|
||
type GetGameLeaderboardsParameters struct { | ||
// The target game ID | ||
GameID int | ||
|
||
// [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 GetGameLeaderboards struct { | ||
Count int `json:"Count"` | ||
Total int `json:"Total"` | ||
Results []GetGameLeaderboardsResult `json:"Results"` | ||
} | ||
|
||
type GetGameLeaderboardsResult struct { | ||
ID int `json:"ID"` | ||
RankAsc bool `json:"RankAsc"` | ||
Title string `json:"Title"` | ||
Description string `json:"Description"` | ||
Format string `json:"Format"` | ||
TopEntry *GetGameLeaderboardsTopEntry `json:"TopEntry"` | ||
} | ||
|
||
type GetGameLeaderboardsTopEntry struct { | ||
User string `json:"User"` | ||
Score int `json:"Score"` | ||
FormattedScore string `json:"FormattedScore"` | ||
} |