Repository: nicklaw5/helix
Pull request #64 (2020-11-24 12:19:20)

Get drops entitlements
Introduce the functionality to query for entitlements given to users by the Twitch Drops product offering.

More specifically: https://dev.twitch.tv/docs/api/reference#get-drops-entitlements



Patch:
diff --git a/drops.go b/drops.go
new file mode 100644
index 0000000..d787c7b
--- /dev/null
+++ b/drops.go
@@ -0,0 +1,56 @@
+package helix
+
+// GetDropEntitlementsParams ...
+type GetDropEntitlementsParams struct {
+	ID string `query:"id"`
+	UserID        string `query:"user_id"`
+	GameID        string `query:"game_id"`
+	After         string `query:"after"`
+	First         int    `query:"first,20"` // Limit 100
+}
+
+// Entitlement ...
+type Entitlement struct {
+	ID string `json:"id"`
+	BenefitID     string `json:"benefit_id"`
+	Timestamp     Time   `json:"timestamp"`
+	UserID        string `json:"user_id"`
+	GameID        string `json:"game_id"`
+}
+
+// ManyEntitlements ...
+type ManyEntitlements struct {
+	Entitlements []Entitlement `json:"data"`
+}
+
+// ManyEntitlementsWithPagination ...
+type ManyEntitlementsWithPagination struct {
+	ManyEntitlements
+	Pagination `json:"pagination"`
+}
+
+// GetDropsEntitlementsResponse ...
+type GetDropsEntitlementsResponse struct {
+	ResponseCommon
+	Data ManyEntitlementsWithPagination
+}
+
+// GetDropsEntitlements returns a list of entitlements, which have been awarded to users by your organization.
+// Filtering by UserID returns all of the entitlements related to that specific user.
+// Filtering by GameID returns all of the entitlements related to that game.
+// Filtering by GameID and UserID returns all of the entitlements related to that game and that user.
+// Entitlements are digital items that users are entitled to use. Twitch entitlements are granted based on viewership
+// engagement with a content creator, based on the game developers' campaign.
+func (c *Client) GetDropsEntitlements(params *GetDropEntitlementsParams) (*GetDropsEntitlementsResponse, error) {
+	resp, err := c.get("/entitlements/drops", &ManyEntitlementsWithPagination{}, params)
+	if err != nil {
+		return nil, err
+	}
+
+	entitlements := &GetDropsEntitlementsResponse{}
+	resp.HydrateResponseCommon(&entitlements.ResponseCommon)
+	entitlements.Data.Entitlements = resp.Data.(*ManyEntitlementsWithPagination).Entitlements
+	entitlements.Data.Pagination = resp.Data.(*ManyEntitlementsWithPagination).Pagination
+
+	return entitlements, nil
+}


Test patch:
diff --git a/drops_test.go b/drops_test.go
new file mode 100644
index 0000000..bb5a16e
--- /dev/null
+++ b/drops_test.go
@@ -0,0 +1,86 @@
+package helix
+
+import (
+	"net/http"
+	"strings"
+	"testing"
+)
+
+func TestGetDropsEntitlements(t *testing.T) {
+	t.Parallel()
+
+	testCases := []struct {
+		statusCode      int
+		options         *Options
+		gameID          string
+		respBody        string
+		expectedErrMsg  string
+	}{
+		{
+			http.StatusUnauthorized,
+			&Options{
+				ClientID:       "valid-client-id",
+				AppAccessToken: "invalid-app-access-token", // invalid app access token
+			},
+			"1337",
+			`{"error":"Unauthorized","status":401,"message":"Must provide valid app token."}`,
+			"Must provide valid app token.",
+		},
+		{
+			http.StatusForbidden,
+			&Options{
+				ClientID:       "valid-client-id",
+				AppAccessToken: "valid-app-access-token", // invalid app access token
+			},
+			"1337",
+			`{"error":"Forbidden","status":403,"message":"game not managed by this organization."}`,
+			"game not managed by this organization.",
+		},
+		{
+			http.StatusOK,
+			&Options{
+				ClientID:       "valid-client-id",
+				AppAccessToken: "valid-app-access-token",
+			},
+			"33214",
+			`{"data": [ { "id": "fb78259e-fb81-4d1b-8333-34a06ffc24c0", "benefit_id": "74c52265-e214-48a6-91b9-23b6014e8041", "timestamp": "2019-01-28T04:17:53.325Z", "user_id": "25009227", "game_id": "33214" }, { "id": "862750a5-265e-4ab6-9f0a-c64df3d54dd0", "benefit_id": "74c52265-e214-48a6-91b9-23b6014e8041", "timestamp": "2019-01-28T04:16:53.325Z", "user_id": "25009227", "game_id": "33214" }, { "id": "d8879baa-3966-4d10-8856-15fdd62cce02", "benefit_id": "cdfdc5c3-65a2-43bc-8767-fde06eb4ab2c", "timestamp": "2019-01-28T04:15:53.325Z", "user_id": "25009227", "game_id": "33214" }] }`,
+			"",
+		},
+	}
+
+	for _, testCase := range testCases {
+		c := newMockClient(testCase.options, newMockHandler(testCase.statusCode, testCase.respBody, nil))
+
+		resp, err := c.GetDropsEntitlements(&GetDropEntitlementsParams{GameID: testCase.gameID})
+		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)
+		}
+
+		// Test error cases
+		if resp.StatusCode != http.StatusOK {
+			if resp.ErrorStatus != testCase.statusCode {
+				t.Errorf("expected error status to be \"%d\", got \"%d\"", testCase.statusCode, resp.ErrorStatus)
+			}
+
+			if resp.ErrorMessage != testCase.expectedErrMsg {
+				t.Errorf("expected error message to be \"%s\", got \"%s\"", testCase.expectedErrMsg, resp.ErrorMessage)
+			}
+
+			continue
+		}
+
+		// Test success case
+		if len(resp.Data.Entitlements) < 1 {
+			t.Errorf("Expected the number of entitlements to be a positive number")
+		}
+
+		if !strings.EqualFold(resp.Data.Entitlements[0].GameID, testCase.gameID) {
+			t.Errorf("Expected the Entitlement's GameID to be the same as the requested GameID - wanted \"%s\", got \"%s\"",
+				resp.Data.Entitlements[0].GameID, testCase.gameID)
+		}
+	}
+}