Skip to content

Commit

Permalink
Merge pull request #113 from jackmcguire1/hype-trains
Browse files Browse the repository at this point in the history
Add Get HypeTrainEvents
  • Loading branch information
nicklaw5 authored Jul 27, 2021
2 parents 343474f + 0e3a803 commit cbfb165
Show file tree
Hide file tree
Showing 3 changed files with 149 additions and 1 deletion.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ If you are looking for the Twitch API docs, see the [Twitch Developer website](h
- [x] Create / Remove / List EventSub Subscriptions
- [x] Get Top Games
- [x] Get Games
- [ ] Get Hype Train Events
- [x] Get Hype Train Events
- [ ] Check AutoMod Status
- [x] Manage Held AutoMod Messages
- [ ] Get Banned Events
Expand Down
60 changes: 60 additions & 0 deletions hype_train.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
package helix

type HypeTrainContribuition struct {
Total int64 `json:"total"`
Type string `json:"type"`
User string `json:"user"`
}

type HypeTrainEvent struct {
ID string `json:"id"`
EventType string `json:"event_type"`
EventTimestamp Time `json:"event_timestamp"`
Version string `json:"version"`
Event HypeTrainEventData `json:"event_data"`
}

type HypeTrainEventData struct {
ID string `json:"id"`
BroadcasterID string `json:"broadcaster_id"`
CooldownEndTime Time `json:"cooldown_end_time"`
ExpiresAt Time `json:"expires_at"`
Goal int64 `json:"goal"`
LastContribution HypeTrainContribuition `json:"last_contribution"`
Level int64 `json:"level"`
StartedAt Time `json:"started_at"`
TopContributions []HypeTrainContribuition `json:"top_contributions"`
Total int64 `json:"total"`
}

type ManyHypeTrainEvents struct {
Events []HypeTrainEvent `json:"data"`
Pagination Pagination `json:"pagination"`
}

type HypeTrainEventsResponse struct {
ResponseCommon
Data ManyHypeTrainEvents
}

type HypeTrainEventsParams struct {
BroadcasterID string `query:"broadcaster_id"`
After string `query:"after"`
First int `query:"first,20"` // Limit 100
ID string `query:"id"`
}

// Required scope: channel:read:hype_train
func (c *Client) GetHypeTrainEvents(params *HypeTrainEventsParams) (*HypeTrainEventsResponse, error) {
resp, err := c.get("/hypetrain/events", &ManyHypeTrainEvents{}, params)
if err != nil {
return nil, err
}

events := &HypeTrainEventsResponse{}
resp.HydrateResponseCommon(&events.ResponseCommon)
events.Data.Events = resp.Data.(*ManyHypeTrainEvents).Events
events.Data.Pagination = resp.Data.(*ManyHypeTrainEvents).Pagination

return events, nil
}
88 changes: 88 additions & 0 deletions hype_train_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package helix

import (
"net/http"
"testing"
)

func TestGetHypeTrainEvents(t *testing.T) {
t.Parallel()

testCases := []struct {
statusCode int
options *Options
PollsParams *HypeTrainEventsParams
respBody string
}{
{
http.StatusBadRequest,
&Options{ClientID: "my-client-id"},
&HypeTrainEventsParams{BroadcasterID: ""},
`{"error":"Bad Request","status":400,"message":"Missing required parameter \"broadcaster_id\""}`,
},
{
http.StatusOK,
&Options{ClientID: "my-client-id"},
&HypeTrainEventsParams{BroadcasterID: "121445595"},
`{"data":[{"id":"1vsv0LoqZEl1YVRUKehGesQJQFY","event_type":"hypetrain.progression","event_timestamp":"2021-07-27T05:23:06Z","version":"1.0","event_data":{"broadcaster_id":"32043018","cooldown_end_time":"2021-07-27T06:27:11Z","expires_at":"2021-07-27T05:27:11Z","goal":1600,"id":"207ab35e-26f3-4b3a-b4c5-0c9025079906","last_contribution":{"total":100,"type":"BITS","user":"36099963"},"level":1,"started_at":"2021-07-27T05:22:11Z","top_contributions":[{"total":100,"type":"BITS","user":"86228897"},{"total":500,"type":"SUBS","user":"36099963"}],"total":1300}},{"id":"1vsuvsQkf1dFPbOXcxvlS3NiAum","event_type":"hypetrain.progression","event_timestamp":"2021-07-27T05:22:30Z","version":"1.0","event_data":{"broadcaster_id":"32043018","cooldown_end_time":"2021-07-27T06:27:11Z","expires_at":"2021-07-27T05:27:11Z","goal":1600,"id":"207ab35e-26f3-4b3a-b4c5-0c9025079906","last_contribution":{"total":100,"type":"BITS","user":"44526173"},"level":1,"started_at":"2021-07-27T05:22:11Z","top_contributions":[{"total":100,"type":"BITS","user":"86228897"},{"total":500,"type":"SUBS","user":"36099963"}],"total":1200}},{"id":"1vsutOWymap8tfJMTuihbwzBQHC","event_type":"hypetrain.progression","event_timestamp":"2021-07-27T05:22:11Z","version":"1.0","event_data":{"broadcaster_id":"32043018","cooldown_end_time":"2021-07-27T06:27:11Z","expires_at":"2021-07-27T05:27:11Z","goal":1600,"id":"207ab35e-26f3-4b3a-b4c5-0c9025079906","last_contribution":{"total":500,"type":"SUBS","user":"158357643"},"level":1,"started_at":"2021-07-27T05:22:11Z","top_contributions":[{"total":100,"type":"BITS","user":"86228897"},{"total":500,"type":"SUBS","user":"36099963"}],"total":1100}},{"id":"1vsutUYGOAFjhD3U8d0NbG4BbxA","event_type":"hypetrain.progression","event_timestamp":"2021-07-27T05:22:11Z","version":"1.0","event_data":{"broadcaster_id":"32043018","cooldown_end_time":"2021-07-27T06:27:11Z","expires_at":"2021-07-27T05:27:11Z","goal":1600,"id":"207ab35e-26f3-4b3a-b4c5-0c9025079906","last_contribution":{"total":500,"type":"SUBS","user":"158357643"},"level":1,"started_at":"2021-07-27T05:22:11Z","top_contributions":[{"total":500,"type":"SUBS","user":"36099963"}],"total":1100}},{"id":"1vsutTHkvLoRBbRpIPNuu6SGZzd","event_type":"hypetrain.progression","event_timestamp":"2021-07-27T05:22:11Z","version":"1.0","event_data":{"broadcaster_id":"32043018","cooldown_end_time":"2021-07-27T06:27:11Z","expires_at":"2021-07-27T05:27:11Z","goal":1600,"id":"207ab35e-26f3-4b3a-b4c5-0c9025079906","last_contribution":{"total":500,"type":"SUBS","user":"158357643"},"level":1,"started_at":"2021-07-27T05:22:11Z","top_contributions":[{"total":500,"type":"SUBS","user":"36099963"}],"total":1100}}],"pagination":null}`,
},
}

for _, testCase := range testCases {
c := newMockClient(testCase.options, newMockHandler(testCase.statusCode, testCase.respBody, nil))

resp, err := c.GetHypeTrainEvents(testCase.PollsParams)
if err != nil {
t.Error(err)
}

if resp.StatusCode != testCase.statusCode {
t.Errorf("expected status code to be %d, got %d", testCase.statusCode, resp.StatusCode)
}

if resp.StatusCode == http.StatusBadRequest {
if resp.Error != "Bad Request" {
t.Errorf("expected error to be %s, got %s", "Bad Request", resp.Error)
}

if resp.ErrorStatus != http.StatusBadRequest {
t.Errorf("expected error status to be %d, got %d", http.StatusBadRequest, resp.ErrorStatus)
}

expectedErrMsg := "Missing required parameter \"broadcaster_id\""
if resp.ErrorMessage != expectedErrMsg {
t.Errorf("expected error message to be %s, got %s", expectedErrMsg, resp.ErrorMessage)
}

continue
}

if len(resp.Data.Events) != 5 {
t.Errorf("expected hype train events len to be 5, got %d", len(resp.Data.Events))
}

if len(resp.Data.Events[0].Event.TopContributions) != 2 {
t.Errorf("expected hype train event top contributors len to be 2, got %d", len(resp.Data.Events[0].Event.TopContributions))
}
}

// Test with HTTP Failure
options := &Options{
ClientID: "my-client-id",
HTTPClient: &badMockHTTPClient{
newMockHandler(0, "", nil),
},
}
c := &Client{
opts: options,
}

_, err := c.GetHypeTrainEvents(&HypeTrainEventsParams{})
if err == nil {
t.Error("expected error but got nil")
}

if err.Error() != "Failed to execute API request: Oops, that's bad :(" {
t.Error("expected error does match return error")
}
}

0 comments on commit cbfb165

Please sign in to comment.