-
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
92c8288
commit aa05227
Showing
7 changed files
with
315 additions
and
1 deletion.
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
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,26 @@ | ||
// Package getrecentgameawards provides an example for getting all recently granted game awards across the site's userbase. | ||
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 getrecentgameawards.go` | ||
*/ | ||
func main() { | ||
secret := os.Getenv("RA_API_KEY") | ||
|
||
client := retroachievements.NewClient(secret) | ||
|
||
resp, err := client.GetRecentGameAwards(models.GetRecentGameAwardsParameters{}) | ||
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
package retroachievements | ||
|
||
import ( | ||
"fmt" | ||
"net/http" | ||
|
||
raHttp "github.com/joshraphael/go-retroachievements/http" | ||
"github.com/joshraphael/go-retroachievements/models" | ||
) | ||
|
||
// GetRecentGameAwards gets all recently granted game awards across the site's userbase. | ||
func (c *Client) GetRecentGameAwards(params models.GetRecentGameAwardsParameters) (*models.GetRecentGameAwards, error) { | ||
details := []raHttp.RequestDetail{ | ||
raHttp.Method(http.MethodGet), | ||
raHttp.Path("/API/API_GetRecentGameAwards.php"), | ||
raHttp.APIToken(c.Secret), | ||
} | ||
if params.StartingDate != nil { | ||
details = append(details, raHttp.D(*params.StartingDate)) | ||
} | ||
if params.Count != nil { | ||
details = append(details, raHttp.C(*params.Count)) | ||
} | ||
if params.Offset != nil { | ||
details = append(details, raHttp.O(*params.Offset)) | ||
} | ||
if params.IncludePartialAwards != nil { | ||
beatenSoftcore := params.IncludePartialAwards.BeatenSoftcore | ||
beatenHardcore := params.IncludePartialAwards.BeatenHardcore | ||
completed := params.IncludePartialAwards.Completed | ||
mastered := params.IncludePartialAwards.Mastered | ||
if beatenSoftcore || beatenHardcore || completed || mastered { | ||
k := []string{} | ||
if beatenSoftcore { | ||
k = append(k, "beaten-softcore") | ||
} | ||
if beatenHardcore { | ||
k = append(k, "beaten-hardcore") | ||
} | ||
if beatenHardcore { | ||
k = append(k, "completed") | ||
} | ||
if beatenHardcore { | ||
k = append(k, "mastered") | ||
} | ||
details = append(details, raHttp.K(k)) | ||
} | ||
} | ||
r, err := c.do(details...) | ||
if err != nil { | ||
return nil, fmt.Errorf("calling endpoint: %w", err) | ||
} | ||
resp, err := raHttp.ResponseObject[models.GetRecentGameAwards](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,168 @@ | ||
package retroachievements_test | ||
|
||
import ( | ||
"encoding/json" | ||
"net/http" | ||
"net/http/httptest" | ||
"testing" | ||
"time" | ||
|
||
"github.com/joshraphael/go-retroachievements" | ||
"github.com/joshraphael/go-retroachievements/models" | ||
"github.com/stretchr/testify/require" | ||
) | ||
|
||
func TestGetRecentGameAwards(tt *testing.T) { | ||
count := 10 | ||
offset := 10 | ||
startingDate, err := time.Parse(models.RFC3339NumColonTZFormat, "2024-10-05T18:30:59+00:00") | ||
require.NoError(tt, err) | ||
awardDate, err := time.Parse(models.RFC3339NumColonTZFormat, "2024-11-23T13:39:21+00:00") | ||
require.NoError(tt, err) | ||
tests := []struct { | ||
name string | ||
params models.GetRecentGameAwardsParameters | ||
modifyURL func(url string) string | ||
responseCode int | ||
responseMessage models.GetRecentGameAwards | ||
responseError models.ErrorResponse | ||
response func(messageBytes []byte, errorBytes []byte) []byte | ||
assert func(t *testing.T, resp *models.GetRecentGameAwards, err error) | ||
}{ | ||
{ | ||
name: "fail to call endpoint", | ||
params: models.GetRecentGameAwardsParameters{ | ||
StartingDate: &startingDate, | ||
Count: &count, | ||
Offset: &offset, | ||
IncludePartialAwards: &models.GetRecentGameAwardsParametersPartialAwards{ | ||
BeatenSoftcore: true, | ||
BeatenHardcore: true, | ||
Completed: true, | ||
Mastered: true, | ||
}, | ||
}, | ||
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.GetRecentGameAwards, err error) { | ||
require.Nil(t, resp) | ||
require.EqualError(t, err, "calling endpoint: Get \"/API/API_GetRecentGameAwards.php?c=10&d=2024-10-05&k=beaten-softcore%2Cbeaten-hardcore%2Ccompleted%2Cmastered&o=10&y=some_secret\": unsupported protocol scheme \"\"") | ||
}, | ||
}, | ||
{ | ||
name: "error response", | ||
params: models.GetRecentGameAwardsParameters{ | ||
StartingDate: &startingDate, | ||
Count: &count, | ||
Offset: &offset, | ||
IncludePartialAwards: &models.GetRecentGameAwardsParametersPartialAwards{ | ||
BeatenSoftcore: true, | ||
BeatenHardcore: true, | ||
Completed: true, | ||
Mastered: true, | ||
}, | ||
}, | ||
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.GetRecentGameAwards, err error) { | ||
require.Nil(t, resp) | ||
require.EqualError(t, err, "parsing response object: error code 401 returned: {\"message\":\"test\",\"errors\":[{\"status\":401,\"code\":\"unauthorized\",\"title\":\"Not Authorized\"}]}") | ||
}, | ||
}, | ||
{ | ||
name: "success", | ||
params: models.GetRecentGameAwardsParameters{ | ||
StartingDate: &startingDate, | ||
Count: &count, | ||
Offset: &offset, | ||
IncludePartialAwards: &models.GetRecentGameAwardsParametersPartialAwards{ | ||
BeatenSoftcore: true, | ||
BeatenHardcore: true, | ||
Completed: true, | ||
Mastered: true, | ||
}, | ||
}, | ||
modifyURL: func(url string) string { | ||
return url | ||
}, | ||
responseCode: http.StatusOK, | ||
responseMessage: models.GetRecentGameAwards{ | ||
Total: 2, | ||
Count: 1, | ||
Results: []models.GetRecentGameAwardsResult{ | ||
{ | ||
User: "spoony", | ||
AwardKind: "mastered", | ||
AwardDate: models.RFC3339NumColonTZ{ | ||
Time: awardDate, | ||
}, | ||
GameID: 7317, | ||
GameTitle: "~Hack~ Pokémon Brown Version", | ||
ConsoleID: 4, | ||
ConsoleName: "Game Boy", | ||
}, | ||
}, | ||
}, | ||
response: func(messageBytes []byte, errorBytes []byte) []byte { | ||
return messageBytes | ||
}, | ||
assert: func(t *testing.T, resp *models.GetRecentGameAwards, err error) { | ||
require.NotNil(t, resp) | ||
require.Equal(t, 2, resp.Total) | ||
require.Equal(t, 1, resp.Count) | ||
require.Len(t, resp.Results, 1) | ||
require.Equal(t, "spoony", resp.Results[0].User) | ||
require.Equal(t, "mastered", resp.Results[0].AwardKind) | ||
require.Equal(t, awardDate, resp.Results[0].AwardDate.Time) | ||
require.Equal(t, 7317, resp.Results[0].GameID) | ||
require.Equal(t, "~Hack~ Pokémon Brown Version", resp.Results[0].GameTitle) | ||
require.Equal(t, 4, resp.Results[0].ConsoleID) | ||
require.Equal(t, "Game Boy", resp.Results[0].ConsoleName) | ||
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_GetRecentGameAwards.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), "go-retroachievements/v0.0.0", "some_secret") | ||
resp, err := client.GetRecentGameAwards(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
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,47 @@ | ||
package models | ||
|
||
import "time" | ||
|
||
type GetRecentGameAwardsParameters struct { | ||
// [Optional] Starting date (YYYY-MM-DD) (default: now). | ||
StartingDate *time.Time | ||
|
||
// [Optional] The number of records to return (default: 100, max: 500). | ||
Count *int | ||
|
||
// [Optional] The number of entries to skip (default: 0). | ||
Offset *int | ||
|
||
// [Optional] Return partial list of awards based on type (default: return everything). | ||
IncludePartialAwards *GetRecentGameAwardsParametersPartialAwards | ||
} | ||
|
||
type GetRecentGameAwardsParametersPartialAwards struct { | ||
// Include beaten softcore awards | ||
BeatenSoftcore bool | ||
|
||
// Include beaten hardcore awards | ||
BeatenHardcore bool | ||
|
||
// Include completed game awards | ||
Completed bool | ||
|
||
// Include mastered game awards | ||
Mastered bool | ||
} | ||
|
||
type GetRecentGameAwards struct { | ||
Count int `json:"Count"` | ||
Total int `json:"Total"` | ||
Results []GetRecentGameAwardsResult `json:"Results"` | ||
} | ||
|
||
type GetRecentGameAwardsResult struct { | ||
User string `json:"User"` | ||
AwardKind string `json:"AwardKind"` | ||
AwardDate RFC3339NumColonTZ `json:"AwardDate"` | ||
GameID int `json:"GameID"` | ||
GameTitle string `json:"GameTitle"` | ||
ConsoleID int `json:"ConsoleID"` | ||
ConsoleName string `json:"ConsoleName"` | ||
} |