From c57eca66d1fb9fca149d61c5aabeedf28b4de275 Mon Sep 17 00:00:00 2001 From: Kenzo Tanaka Date: Mon, 15 May 2023 16:06:58 +0900 Subject: [PATCH] Support rate limit API Support backlog API the below: - GET /api/v2/rateLimit ref: https://developer.nulab.com/ja/docs/backlog/rate-limit/ --- rate_limit.go | 46 ++++++++++++++++++++++ rate_limit_test.go | 96 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 142 insertions(+) create mode 100644 rate_limit.go create mode 100644 rate_limit_test.go diff --git a/rate_limit.go b/rate_limit.go new file mode 100644 index 0000000..8c79247 --- /dev/null +++ b/rate_limit.go @@ -0,0 +1,46 @@ +package backlog + +import ( + "context" +) + +// LimitStatus : limit status +type LimitStatus struct { + Limit *int `json:"limit,omitempty"` + Remaining *int `json:"remaining,omitempty"` + Reset *int `json:"reset,omitempty"` +} + +// RateLimit : rate limit +type RateLimit struct { + Read *LimitStatus `json:"read,omitempty"` + Update *LimitStatus `json:"update,omitempty"` + Search *LimitStatus `json:"search,omitempty"` + Icon *LimitStatus `json:"icon,omitempty"` +} + +// ResponseRateLimit : rate limit API response +type ResponseRateLimit struct { + RateLimit *RateLimit `json:"rateLimit,omitempty"` +} + +// GetRateLimit returns the rate limit +func (c *Client) GetRateLimit() (*RateLimit, error) { + return c.GetRateLimitContext(context.Background()) +} + +// GetRateLimitContext returns the rate limit +func (c *Client) GetRateLimitContext(ctx context.Context) (*RateLimit, error) { + u := "/api/v2/rateLimit" + + req, err := c.NewRequest("GET", u, nil) + if err != nil { + return nil, err + } + + responseRateLimit := new(ResponseRateLimit) + if err := c.Do(ctx, req, &responseRateLimit); err != nil { + return nil, err + } + return responseRateLimit.RateLimit, nil +} diff --git a/rate_limit_test.go b/rate_limit_test.go new file mode 100644 index 0000000..a0578f1 --- /dev/null +++ b/rate_limit_test.go @@ -0,0 +1,96 @@ +package backlog + +import ( + "fmt" + "net/http" + "reflect" + "testing" +) + +const testJSONRateLimit string = `{ + "rateLimit": { + "read": { + "limit": 600, + "remaining": 600, + "reset": 1603881873 + }, + "update": { + "limit": 150, + "remaining": 150, + "reset": 1603881873 + }, + "search": { + "limit": 150, + "remaining": 150, + "reset": 1603881873 + }, + "icon": { + "limit": 60, + "remaining": 60, + "reset": 1603881873 + } + } + }` + +func getTestRateLimit() *ResponseRateLimit { + return &ResponseRateLimit{ + RateLimit: &RateLimit{ + Read: &LimitStatus{ + Limit: Int(600), + Remaining: Int(600), + Reset: Int(1603881873), + }, + Update: &LimitStatus{ + Limit: Int(150), + Remaining: Int(150), + Reset: Int(1603881873), + }, + Search: &LimitStatus{ + Limit: Int(150), + Remaining: Int(150), + Reset: Int(1603881873), + }, + Icon: &LimitStatus{ + Limit: Int(60), + Remaining: Int(60), + Reset: Int(1603881873), + }, + }, + } +} + +func TestGetRateLimit(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/rateLimit", func(w http.ResponseWriter, r *http.Request) { + if _, err := fmt.Fprint(w, testJSONRateLimit); err != nil { + t.Fatal(err) + } + }) + + expected, err := client.GetRateLimit() + if err != nil { + t.Errorf("Unexpected error: %s", err) + return + } + + r := getTestRateLimit() + want := r.RateLimit + if !reflect.DeepEqual(want, expected) { + t.Fatal(ErrIncorrectResponse) + } +} + +func TestGetRateLimitFailed(t *testing.T) { + client, mux, _, teardown := setup() + defer teardown() + + mux.HandleFunc("/rateLimit", func(w http.ResponseWriter, r *http.Request) { + w.WriteHeader(http.StatusInternalServerError) + }) + + if _, err := client.GetRateLimit(); err == nil { + t.Fatal("expected an error but got none") + } +}