From 7fa857563762c3efa09051d474549264fe270668 Mon Sep 17 00:00:00 2001 From: Dave Gray Date: Tue, 15 Nov 2016 09:44:52 -0700 Subject: [PATCH] support for webhook event documentation endpoint --- event_docs.go | 68 ++++++++++++++++++++++++++++++++++++++++------ event_docs_test.go | 68 +++++++++++++++++++++++++++++++++++++++++++--- 2 files changed, 123 insertions(+), 13 deletions(-) diff --git a/event_docs.go b/event_docs.go index a2853f2..0dd834f 100644 --- a/event_docs.go +++ b/event_docs.go @@ -1,23 +1,73 @@ package gosparkpost -var eventDocumentationFormat = "/api/v%d/webhooks/events/documentation" +import ( + "encoding/json" + "fmt" -type EventDocumentationResponse struct { - Results map[string]*EventGroup `json:"results,omitempty"` -} + "github.com/pkg/errors" +) + +var eventDocumentationFormat = "/api/v%d/webhooks/events/documentation" type EventGroup struct { Name string - Events map[string]EventField + Events map[string]EventMeta Description string `json:"description"` DisplayName string `json:"display_name"` } +type EventMeta struct { + Name string + Fields map[string]EventField `json:"event"` + Description string `json:"description"` + DisplayName string `json:"display_name"` +} + type EventField struct { - Description string `json:"description"` - SampleValue string `json:"sampleValue"` + Description string `json:"description"` + SampleValue interface{} `json:"sampleValue"` } -func (c *Client) EventDocumentation() (g *EventGroup, res *Response, err error) { - return nil, nil, nil +func (c *Client) EventDocumentation() (g map[string]*EventGroup, res *Response, err error) { + path := fmt.Sprintf(eventDocumentationFormat, c.Config.ApiVersion) + res, err = c.HttpGet(c.Config.BaseUrl + path) + if err != nil { + return nil, nil, err + } + + if err = res.AssertJson(); err != nil { + return nil, res, err + } + + if res.HTTP.StatusCode == 200 { + var body []byte + var ok bool + body, err = res.ReadBody() + if err != nil { + return nil, res, err + } + + var results map[string]map[string]*EventGroup + var groups map[string]*EventGroup + if err = json.Unmarshal(body, &results); err != nil { + return nil, res, err + } else if groups, ok = results["results"]; ok { + return groups, res, err + } + return nil, res, errors.New("Unexpected response format") + } else { + err = res.ParseResponse() + if err != nil { + return nil, res, err + } + if len(res.Errors) > 0 { + err = res.PrettyError("EventDocumentation", "retrieve") + if err != nil { + return nil, res, err + } + } + return nil, res, errors.Errorf("%d: %s", res.HTTP.StatusCode, string(res.Body)) + } + + return nil, res, err } diff --git a/event_docs_test.go b/event_docs_test.go index d669243..83d071d 100644 --- a/event_docs_test.go +++ b/event_docs_test.go @@ -10,9 +10,42 @@ import ( const eventDocumentationFile = "test/event-docs.json" var eventDocumentationBytes []byte +var eventGroups = []string{"track", "gen", "unsubscribe", "relay", "message"} +var eventGroupMap = map[string]map[string]int{ + "track_event": { + "click": 22, + "open": 20, + }, + "gen_event": { + "generation_failure": 21, + "generation_rejection": 23, + }, + "unsubscribe_event": { + "list_unsubscribe": 18, + "link_unsubscribe": 19, + }, + "relay_event": { + "relay_permfail": 15, + "relay_injection": 12, + "relay_rejection": 14, + "relay_delivery": 12, + "relay_tempfail": 15, + }, + "message_event": { + "spam_complaint": 24, + "out_of_band": 21, + "policy_rejection": 23, + "delay": 38, + "bounce": 37, + "delivery": 36, + "injection": 31, + "sms_status": 22, + }, +} func init() { - eventDocumentationBytes, err := ioutil.ReadFile(eventDocumentationFile) + var err error + eventDocumentationBytes, err = ioutil.ReadFile(eventDocumentationFile) if err != nil { panic(err) } @@ -31,7 +64,7 @@ func TestEventDocs_Get_parse(t *testing.T) { }) // hit our local handler - w, res, err := testClient.EventDocumentation() + groups, res, err := testClient.EventDocumentation() if err != nil { t.Errorf("EventDocumentation GET returned error: %v", err) for _, e := range res.Verbose { @@ -41,7 +74,34 @@ func TestEventDocs_Get_parse(t *testing.T) { } // basic content test - if w.Results == nil { - t.Error("EventDocumentation GET returned nil Results") + if len(groups) == 0 { + testFailVerbose(t, res, "EventDocumentation GET returned 0 EventGroups") + } else { + // check the top level event data + eventGroupsSeen := make(map[string]bool, len(eventGroups)) + for _, etype := range eventGroups { + eventGroupsSeen[etype+"_event"] = false + } + + for gname, v := range groups { + eventGroupsSeen[gname] = true + if _, ok := eventGroupMap[gname]; !ok { + t.Fatalf("expected group [%s] not present in response", gname) + } + for ename, efields := range v.Events { + if fieldCount, ok := eventGroupMap[gname][ename]; !ok { + t.Fatalf("expected event [%s] not present in [%s]", ename, gname) + if fieldCount != len(efields.Fields) { + t.Fatalf("saw %d fields for %s, expected %d", len(efields.Fields), ename, fieldCount) + } + } + } + } + + for gname, seen := range eventGroupsSeen { + if !seen { + t.Fatalf("expected message type [%s] not returned", gname) + } + } } }