Repository: mailgun/mailgun-go (go)

Issue:
missing `result` in email validation response
Based on this documentation, the result field available in v4 API
https://documentation.mailgun.com/en/latest/api-email-validation.html#request-examples

```
{
    "address": "existingemail@realdomain.com",
    "is_disposable_address": false,
    "is_role_address": false,
    "reason": [],
    "result": "deliverable",
    "risk": "low"
}
```

but missing in EmailVerification struct in https://github.com/mailgun/mailgun-go/blob/master/email_validation.go

Pull request description:
Added result to v4 validation response
Fixes #263 

Patch:
diff --git a/email_validation.go b/email_validation.go
index b6dddb2..b4964ec 100644
--- a/email_validation.go
+++ b/email_validation.go
@@ -47,6 +47,8 @@ type EmailVerification struct {
 	Reasons []string
 	// Risk assessment for the provided email.
 	Risk string `json:"risk"`
+	// Result
+	Result string `json:"result"`
 }
 
 type v4EmailValidationResp struct {
@@ -59,6 +61,7 @@ type v4EmailValidationResp struct {
 	IsRoleAddress       bool                   `json:"is_role_address"`
 	Reason              []string               `json:"reason"`
 	Risk                string                 `json:"risk"`
+	Result              string                 `json:"result"`
 }
 
 type addressParseResult struct {
@@ -198,6 +201,7 @@ func (m *EmailValidatorImpl) validateV4(ctx context.Context, email string, mailB
 		IsDisposableAddress: res.IsDisposableAddress,
 		IsRoleAddress:       res.IsRoleAddress,
 		Reasons:             res.Reason,
+		Result:              res.Result,
 		Risk:                res.Risk}, nil
 }
 
diff --git a/examples/examples.go b/examples/examples.go
index d928b04..75b2eb7 100644
--- a/examples/examples.go
+++ b/examples/examples.go
@@ -101,20 +101,6 @@ func CreateUnsubscribe(domain, apiKey string) error {
 	return mg.CreateUnsubscribe(ctx, "bob@example.com", "*")
 }
 
-func CreateUnsubscribes(domain, apiKey string) error {
-	mg := mailgun.NewMailgun(domain, apiKey)
-
-	ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
-	defer cancel()
-
-	unsubscribes := []mailgun.Unsubscribe{
-		{Address: "alice@example.com"},
-		{Address: "bob@example.com", Tags: []string{"tag1"}},
-	}
-
-	return mg.CreateUnsubscribes(ctx, unsubscribes)
-}
-
 func CreateUnsubscribeWithTag(domain, apiKey string) error {
 	mg := mailgun.NewMailgun(domain, apiKey)
 
diff --git a/httphelpers.go b/httphelpers.go
index 382659b..a74adc6 100644
--- a/httphelpers.go
+++ b/httphelpers.go
@@ -68,10 +68,6 @@ type urlEncodedPayload struct {
 	Values []keyValuePair
 }
 
-type jsonEncodedPayload struct {
-	payload interface{}
-}
-
 func newHTTPRequest(url string) *httpRequest {
 	return &httpRequest{URL: url, Client: http.DefaultClient}
 }
@@ -92,27 +88,6 @@ func (r *httpRequest) setBasicAuth(user, password string) {
 	r.BasicAuthPassword = password
 }
 
-func newJSONEncodedPayload(payload interface{}) *jsonEncodedPayload {
-	return &jsonEncodedPayload{payload: payload}
-}
-
-func (j *jsonEncodedPayload) getPayloadBuffer() (*bytes.Buffer, error) {
-	b, err := json.Marshal(j.payload)
-	if err != nil {
-		return nil, err
-	}
-
-	return bytes.NewBuffer(b), nil
-}
-
-func (j *jsonEncodedPayload) getContentType() string {
-	return "application/json"
-}
-
-func (j *jsonEncodedPayload) getValues() []keyValuePair {
-	return nil
-}
-
 func newUrlEncodedPayload() *urlEncodedPayload {
 	return &urlEncodedPayload{}
 }
@@ -347,16 +322,8 @@ func (r *httpRequest) curlString(req *http.Request, p payload) string {
 	//parts = append(parts, fmt.Sprintf(" --user '%s:%s'", r.BasicAuthUser, r.BasicAuthPassword))
 
 	if p != nil {
-		if p.getContentType() == "application/json" {
-			b, err := p.getPayloadBuffer()
-			if err != nil {
-				return "Unable to get payload buffer: " + err.Error()
-			}
-			parts = append(parts, fmt.Sprintf("--data '%s'", b.String()))
-		} else {
-			for _, param := range p.getValues() {
-				parts = append(parts, fmt.Sprintf(" -F %s='%s'", param.key, param.value))
-			}
+		for _, param := range p.getValues() {
+			parts = append(parts, fmt.Sprintf(" -F %s='%s'", param.key, param.value))
 		}
 	}
 	return strings.Join(parts, " ")
diff --git a/mailgun.go b/mailgun.go
index 16be275..f4bc7ea 100644
--- a/mailgun.go
+++ b/mailgun.go
@@ -171,7 +171,6 @@ type Mailgun interface {
 	ListUnsubscribes(opts *ListOptions) *UnsubscribesIterator
 	GetUnsubscribe(ctx context.Context, address string) (Unsubscribe, error)
 	CreateUnsubscribe(ctx context.Context, address, tag string) error
-	CreateUnsubscribes(ctx context.Context, unsubscribes []Unsubscribe) error
 	DeleteUnsubscribe(ctx context.Context, address string) error
 	DeleteUnsubscribeWithTag(ctx context.Context, a, t string) error
 
diff --git a/mock_validation.go b/mock_validation.go
index de48f96..6299b2c 100644
--- a/mock_validation.go
+++ b/mock_validation.go
@@ -33,6 +33,7 @@ func (ms *mockServer) validateEmailV4(w http.ResponseWriter, r *http.Request) {
 	}
 	results.Reason = []string{"no-reason"}
 	results.Risk = "unknown"
+	results.Result = "deliverable"
 	toJSON(w, results)
 }
 
diff --git a/unsubscribes.go b/unsubscribes.go
index 5e6e7f1..fd81a07 100644
--- a/unsubscribes.go
+++ b/unsubscribes.go
@@ -6,9 +6,9 @@ import (
 )
 
 type Unsubscribe struct {
-	CreatedAt RFC2822Time `json:"created_at,omitempty"`
-	Tags      []string    `json:"tags,omitempty"`
-	ID        string      `json:"id,omitempty"`
+	CreatedAt RFC2822Time `json:"created_at"`
+	Tags      []string    `json:"tags"`
+	ID        string      `json:"id"`
 	Address   string      `json:"address"`
 }
 
@@ -157,18 +157,6 @@ func (mg *MailgunImpl) CreateUnsubscribe(ctx context.Context, address, tag strin
 	return err
 }
 
-// CreateUnsubscribes adds multiple e-mail addresses to the domain's unsubscription table.
-func (mg *MailgunImpl) CreateUnsubscribes(ctx context.Context, unsubscribes []Unsubscribe) error {
-	r := newHTTPRequest(generateApiUrl(mg, unsubscribesEndpoint))
-	r.setClient(mg.Client())
-	r.setBasicAuth(basicAuthUser, mg.APIKey())
-	r.addHeader("Content-Type", "application/json")
-
-	p := newJSONEncodedPayload(unsubscribes)
-	_, err := makePostRequest(ctx, r, p)
-	return err
-}
-
 // DeleteUnsubscribe removes the e-mail address given from the domain's unsubscription table.
 // If passing in an ID (discoverable from, e.g., ListUnsubscribes()), the e-mail address associated
 // with the given ID will be removed.


Test patch:
diff --git a/email_validation_test.go b/email_validation_test.go
index 8547456..30af83f 100644
--- a/email_validation_test.go
+++ b/email_validation_test.go
@@ -50,6 +50,7 @@ func TestEmailValidationV4(t *testing.T) {
 	ensure.True(t, len(ev.Reasons) != 0)
 	ensure.DeepEqual(t, ev.Reasons[0], "no-reason")
 	ensure.DeepEqual(t, ev.Risk, "unknown")
+	ensure.DeepEqual(t, ev.Result, "deliverable")
 }
 
 func TestParseAddresses(t *testing.T) {
diff --git a/unsubscribes_test.go b/unsubscribes_test.go
index ecb4a1f..4a918f4 100644
--- a/unsubscribes_test.go
+++ b/unsubscribes_test.go
@@ -22,28 +22,6 @@ func TestCreateUnsubscriber(t *testing.T) {
 	ensure.Nil(t, mg.CreateUnsubscribe(ctx, email, "*"))
 }
 
-func TestCreateUnsubscribes(t *testing.T) {
-	if reason := SkipNetworkTest(); reason != "" {
-		t.Skip(reason)
-	}
-
-	unsubscribes := []Unsubscribe{
-		{
-			Address: randomEmail("unsubcribe", os.Getenv("MG_DOMAIN")),
-		},
-		{
-			Address: randomEmail("unsubcribe", os.Getenv("MG_DOMAIN")),
-			Tags:    []string{"tag1"},
-		},
-	}
-	mg, err := NewMailgunFromEnv()
-	ensure.Nil(t, err)
-	ctx := context.Background()
-
-	// Create unsubscription records
-	ensure.Nil(t, mg.CreateUnsubscribes(ctx, unsubscribes))
-}
-
 func TestListUnsubscribes(t *testing.T) {
 	if reason := SkipNetworkTest(); reason != "" {
 		t.Skip(reason)