Skip to content

Commit

Permalink
add GetComments endpoint
Browse files Browse the repository at this point in the history
  • Loading branch information
joshraphael committed Nov 23, 2024
1 parent fcc6efc commit 92c8288
Show file tree
Hide file tree
Showing 19 changed files with 416 additions and 72 deletions.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,10 @@ For convenience, the API docs and examples can be found in the tables below

|Function|Description|Links|
|-|-|-|
|`GetAchievementUnlocks()`|Gets a list of users who have earned an achievement.|[docs](https://api-docs.retroachievements.org/v1/get-achievement-unlocks.html) \| [example](examples/achievement/getachievementunlocks/getachievementunlocks.go)|
|`GetAchievementUnlocks()`|Gets a list of users who have earned an achievement.|[docs](https://api-docs.retroachievements.org/v1/get-achievement-unlocks.html) \| [example](examples/achievement/getachievementunlocks/getachievementunlocks.go)|

<h3>Comment</h3>

|Function|Description|Links|
|-|-|-|
|`GetComments()`|Gets comments of a specified kind: game, achievement, or user.|[docs](https://api-docs.retroachievements.org/v1/get-comments.html) \| [example](examples/comment/getcomments/getcomments.go)|
2 changes: 1 addition & 1 deletion achievement_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ func TestGetAchievementUnlocks(tt *testing.T) {
},
assert: func(t *testing.T, resp *models.GetAchievementUnlocks, err error) {
require.Nil(t, resp)
require.EqualError(t, err, "parsing response object: error responses: [401] Not Authorized")
require.EqualError(t, err, "parsing response object: error code 401 returned: {\"message\":\"test\",\"errors\":[{\"status\":401,\"code\":\"unauthorized\",\"title\":\"Not Authorized\"}]}")
},
},
{
Expand Down
46 changes: 46 additions & 0 deletions comment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
package retroachievements

import (
"fmt"
"net/http"
"strconv"

raHttp "github.com/joshraphael/go-retroachievements/http"
"github.com/joshraphael/go-retroachievements/models"
)

// GetComments gets comments of a specified kind: game, achievement, or user.
func (c *Client) GetComments(params models.GetCommentsParameters) (*models.GetComments, error) {
details := []raHttp.RequestDetail{
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetComments.php"),
raHttp.APIToken(c.Secret),
raHttp.T(params.Type.GetCommentsType()),
}
switch params.Type.(type) {
case models.GetCommentsGame:
game := params.Type.(models.GetCommentsGame)
details = append(details, raHttp.I([]string{strconv.Itoa(game.GameID)}))
case models.GetCommentsAchievement:
achievement := params.Type.(models.GetCommentsAchievement)
details = append(details, raHttp.I([]string{strconv.Itoa(achievement.AchievementID)}))
case models.GetCommentsUser:
user := params.Type.(models.GetCommentsUser)
details = append(details, raHttp.I([]string{user.Username}))
}
if params.Count != nil {
details = append(details, raHttp.C(*params.Count))
}
if params.Offset != nil {
details = append(details, raHttp.O(*params.Offset))
}
r, err := c.do(details...)
if err != nil {
return nil, fmt.Errorf("calling endpoint: %w", err)
}
resp, err := raHttp.ResponseObject[models.GetComments](r)
if err != nil {
return nil, fmt.Errorf("parsing response object: %w", err)
}
return resp, nil
}
220 changes: 220 additions & 0 deletions comment_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
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 TestGetComments(tt *testing.T) {
count := 10
offset := 12
submitted, err := time.Parse(time.RFC3339Nano, "2013-04-08T12:37:12.000000Z")
require.NoError(tt, err)
tests := []struct {
name string
params models.GetCommentsParameters
modifyURL func(url string) string
responseCode int
responseMessage models.GetComments
responseError models.ErrorResponse
response func(messageBytes []byte, errorBytes []byte) []byte
assert func(t *testing.T, resp *models.GetComments, err error)
}{
{
name: "fail to call endpoint",
params: models.GetCommentsParameters{
Type: models.GetCommentsUser{
Username: "jamiras",
},
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.GetComments, err error) {
require.Nil(t, resp)
require.EqualError(t, err, "calling endpoint: Get \"/API/API_GetComments.php?c=10&i=jamiras&o=12&t=3&y=some_secret\": unsupported protocol scheme \"\"")
},
},
{
name: "error response",
params: models.GetCommentsParameters{
Type: models.GetCommentsUser{
Username: "jamiras",
},
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.GetComments, 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 - game",
params: models.GetCommentsParameters{
Type: models.GetCommentsGame{
GameID: 123,
},
Count: &count,
Offset: &offset,
},
modifyURL: func(url string) string {
return url
},
responseCode: http.StatusOK,
responseMessage: models.GetComments{
Count: 1,
Total: 1,
Results: []models.GetCommentsResult{
{
User: "Scott",
Submitted: submitted,
CommentText: "Next I think we should have leaderboards/time trials for each act...",
},
},
},
response: func(messageBytes []byte, errorBytes []byte) []byte {
return messageBytes
},
assert: func(t *testing.T, resp *models.GetComments, err error) {
require.NotNil(t, resp)
require.Equal(t, 1, resp.Count)
require.Equal(t, 1, resp.Total)
require.Len(t, resp.Results, 1)
require.Equal(t, "Scott", resp.Results[0].User)
require.Equal(t, submitted, resp.Results[0].Submitted)
require.Equal(t, "Next I think we should have leaderboards/time trials for each act...", resp.Results[0].CommentText)
require.NoError(t, err)
},
},
{
name: "success - achievement",
params: models.GetCommentsParameters{
Type: models.GetCommentsAchievement{
AchievementID: 123,
},
Count: &count,
Offset: &offset,
},
modifyURL: func(url string) string {
return url
},
responseCode: http.StatusOK,
responseMessage: models.GetComments{
Count: 1,
Total: 1,
Results: []models.GetCommentsResult{
{
User: "Scott",
Submitted: submitted,
CommentText: "Next I think we should have leaderboards/time trials for each act...",
},
},
},
response: func(messageBytes []byte, errorBytes []byte) []byte {
return messageBytes
},
assert: func(t *testing.T, resp *models.GetComments, err error) {
require.NotNil(t, resp)
require.Equal(t, 1, resp.Count)
require.Equal(t, 1, resp.Total)
require.Len(t, resp.Results, 1)
require.Equal(t, "Scott", resp.Results[0].User)
require.Equal(t, submitted, resp.Results[0].Submitted)
require.Equal(t, "Next I think we should have leaderboards/time trials for each act...", resp.Results[0].CommentText)
require.NoError(t, err)
},
},
{
name: "success - achievement",
params: models.GetCommentsParameters{
Type: models.GetCommentsUser{
Username: "123",
},
Count: &count,
Offset: &offset,
},
modifyURL: func(url string) string {
return url
},
responseCode: http.StatusOK,
responseMessage: models.GetComments{
Count: 1,
Total: 1,
Results: []models.GetCommentsResult{
{
User: "Scott",
Submitted: submitted,
CommentText: "Next I think we should have leaderboards/time trials for each act...",
},
},
},
response: func(messageBytes []byte, errorBytes []byte) []byte {
return messageBytes
},
assert: func(t *testing.T, resp *models.GetComments, err error) {
require.NotNil(t, resp)
require.Equal(t, 1, resp.Count)
require.Equal(t, 1, resp.Total)
require.Len(t, resp.Results, 1)
require.Equal(t, "Scott", resp.Results[0].User)
require.Equal(t, submitted, resp.Results[0].Submitted)
require.Equal(t, "Next I think we should have leaderboards/time trials for each act...", resp.Results[0].CommentText)
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_GetComments.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.GetComments(test.params)
test.assert(t, resp, err)
})
}
}
30 changes: 30 additions & 0 deletions examples/comment/getcomments/getcomments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
// Package getcomments provides an example for getting comments of a specified kind: game, achievement, or user.
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 getcomments.go`
*/
func main() {
secret := os.Getenv("RA_API_KEY")

client := retroachievements.NewClient(secret)

resp, err := client.GetComments(models.GetCommentsParameters{
Type: models.GetCommentsUser{
Username: "123",
},
})
if err != nil {
panic(err)
}

fmt.Printf("%+v\n", resp)
}
11 changes: 6 additions & 5 deletions game.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package retroachievements
import (
"fmt"
"net/http"
"strconv"

raHttp "github.com/joshraphael/go-retroachievements/http"
"github.com/joshraphael/go-retroachievements/models"
Expand All @@ -14,7 +15,7 @@ func (c *Client) GetGame(params models.GetGameParameters) (*models.GetGame, erro
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetGame.php"),
raHttp.APIToken(c.Secret),
raHttp.I([]int{params.GameID}),
raHttp.I([]string{strconv.Itoa(params.GameID)}),
)
if err != nil {
return nil, fmt.Errorf("calling endpoint: %w", err)
Expand All @@ -32,7 +33,7 @@ func (c *Client) GetGameExtended(params models.GetGameExtentedParameters) (*mode
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetGameExtended.php"),
raHttp.APIToken(c.Secret),
raHttp.I([]int{params.GameID}),
raHttp.I([]string{strconv.Itoa(params.GameID)}),
}
if params.Unofficial != nil {
f := 3
Expand All @@ -58,7 +59,7 @@ func (c *Client) GetGameHashes(params models.GetGameHashesParameters) (*models.G
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetGameHashes.php"),
raHttp.APIToken(c.Secret),
raHttp.I([]int{params.GameID}),
raHttp.I([]string{strconv.Itoa(params.GameID)}),
)
if err != nil {
return nil, fmt.Errorf("calling endpoint: %w", err)
Expand All @@ -76,7 +77,7 @@ func (c *Client) GetAchievementCount(params models.GetAchievementCountParameters
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetAchievementCount.php"),
raHttp.APIToken(c.Secret),
raHttp.I([]int{params.GameID}),
raHttp.I([]string{strconv.Itoa(params.GameID)}),
)
if err != nil {
return nil, fmt.Errorf("calling endpoint: %w", err)
Expand All @@ -94,7 +95,7 @@ func (c *Client) GetAchievementDistribution(params models.GetAchievementDistribu
raHttp.Method(http.MethodGet),
raHttp.Path("/API/API_GetAchievementDistribution.php"),
raHttp.APIToken(c.Secret),
raHttp.I([]int{params.GameID}),
raHttp.I([]string{strconv.Itoa(params.GameID)}),
}
if params.Unofficial != nil {
f := 3
Expand Down
Loading

0 comments on commit 92c8288

Please sign in to comment.