github.com/mailgun/mailgun-go/v3@v3.6.4/messages_test.go (about) 1 package mailgun 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "net/http" 8 "net/http/httptest" 9 "os" 10 "strings" 11 "testing" 12 "time" 13 14 "github.com/facebookgo/ensure" 15 ) 16 17 const ( 18 fromUser = "=?utf-8?q?Katie_Brewer=2C_CFP=C2=AE?= <joe@example.com>" 19 exampleSubject = "Mailgun-go Example Subject" 20 exampleText = "Testing some Mailgun awesomeness!" 21 exampleHtml = "<html><head /><body><p>Testing some <a href=\"http://google.com?q=abc&r=def&s=ghi\">Mailgun HTML awesomeness!</a> at www.kc5tja@yahoo.com</p></body></html>" 22 23 exampleMime = `Content-Type: text/plain; charset="ascii" 24 Subject: Joe's Example Subject 25 From: Joe Example <joe@example.com> 26 To: BARGLEGARF <sam.falvo@rackspace.com> 27 Content-Transfer-Encoding: 7bit 28 Date: Thu, 6 Mar 2014 00:37:52 +0000 29 30 Testing some Mailgun MIME awesomeness! 31 ` 32 templateText = "Greetings %recipient.name%! Your reserved seat is at table %recipient.table%." 33 exampleDomain = "testDomain" 34 exampleAPIKey = "testAPIKey" 35 ) 36 37 func TestSendMGPlain(t *testing.T) { 38 if reason := SkipNetworkTest(); reason != "" { 39 t.Skip(reason) 40 } 41 42 spendMoney(t, func() { 43 toUser := os.Getenv("MG_EMAIL_TO") 44 mg, err := NewMailgunFromEnv() 45 ensure.Nil(t, err) 46 47 ctx := context.Background() 48 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 49 msg, id, err := mg.Send(ctx, m) 50 ensure.Nil(t, err) 51 t.Log("TestSendPlain:MSG(" + msg + "),ID(" + id + ")") 52 }) 53 } 54 55 func TestSendMGPlainWithTracking(t *testing.T) { 56 if reason := SkipNetworkTest(); reason != "" { 57 t.Skip(reason) 58 } 59 60 spendMoney(t, func() { 61 toUser := os.Getenv("MG_EMAIL_TO") 62 mg, err := NewMailgunFromEnv() 63 ensure.Nil(t, err) 64 65 ctx := context.Background() 66 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 67 m.SetTracking(true) 68 msg, id, err := mg.Send(ctx, m) 69 ensure.Nil(t, err) 70 t.Log("TestSendPlainWithTracking:MSG(" + msg + "),ID(" + id + ")") 71 }) 72 } 73 74 func TestSendMGPlainAt(t *testing.T) { 75 if reason := SkipNetworkTest(); reason != "" { 76 t.Skip(reason) 77 } 78 79 spendMoney(t, func() { 80 toUser := os.Getenv("MG_EMAIL_TO") 81 mg, err := NewMailgunFromEnv() 82 ensure.Nil(t, err) 83 84 ctx := context.Background() 85 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 86 m.SetDeliveryTime(time.Now().Add(5 * time.Minute)) 87 msg, id, err := mg.Send(ctx, m) 88 ensure.Nil(t, err) 89 t.Log("TestSendPlainAt:MSG(" + msg + "),ID(" + id + ")") 90 }) 91 } 92 93 func TestSendMGHtml(t *testing.T) { 94 if reason := SkipNetworkTest(); reason != "" { 95 t.Skip(reason) 96 } 97 98 spendMoney(t, func() { 99 toUser := os.Getenv("MG_EMAIL_TO") 100 mg, err := NewMailgunFromEnv() 101 ensure.Nil(t, err) 102 103 ctx := context.Background() 104 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 105 m.SetHtml(exampleHtml) 106 msg, id, err := mg.Send(ctx, m) 107 ensure.Nil(t, err) 108 t.Log("TestSendHtml:MSG(" + msg + "),ID(" + id + ")") 109 }) 110 } 111 112 func TestSendMGTracking(t *testing.T) { 113 if reason := SkipNetworkTest(); reason != "" { 114 t.Skip(reason) 115 } 116 117 spendMoney(t, func() { 118 toUser := os.Getenv("MG_EMAIL_TO") 119 mg, err := NewMailgunFromEnv() 120 ensure.Nil(t, err) 121 122 ctx := context.Background() 123 m := mg.NewMessage(fromUser, exampleSubject, exampleText+"Tracking!\n", toUser) 124 m.SetTracking(false) 125 msg, id, err := mg.Send(ctx, m) 126 ensure.Nil(t, err) 127 t.Log("TestSendTracking:MSG(" + msg + "),ID(" + id + ")") 128 }) 129 } 130 131 func TestSendMGTag(t *testing.T) { 132 if reason := SkipNetworkTest(); reason != "" { 133 t.Skip(reason) 134 } 135 136 spendMoney(t, func() { 137 toUser := os.Getenv("MG_EMAIL_TO") 138 mg, err := NewMailgunFromEnv() 139 ensure.Nil(t, err) 140 141 ctx := context.Background() 142 m := mg.NewMessage(fromUser, exampleSubject, exampleText+"Tags Galore!\n", toUser) 143 m.AddTag("FooTag") 144 m.AddTag("BarTag") 145 m.AddTag("BlortTag") 146 msg, id, err := mg.Send(ctx, m) 147 ensure.Nil(t, err) 148 t.Log("TestSendTag:MSG(" + msg + "),ID(" + id + ")") 149 }) 150 } 151 152 func TestSendMGMIME(t *testing.T) { 153 if reason := SkipNetworkTest(); reason != "" { 154 t.Skip(reason) 155 } 156 157 spendMoney(t, func() { 158 toUser := os.Getenv("MG_EMAIL_TO") 159 mg, err := NewMailgunFromEnv() 160 ensure.Nil(t, err) 161 162 ctx := context.Background() 163 m := mg.NewMIMEMessage(ioutil.NopCloser(strings.NewReader(exampleMime)), toUser) 164 msg, id, err := mg.Send(ctx, m) 165 ensure.Nil(t, err) 166 t.Log("TestSendMIME:MSG(" + msg + "),ID(" + id + ")") 167 }) 168 } 169 170 func TestSendMGBatchFailRecipients(t *testing.T) { 171 if reason := SkipNetworkTest(); reason != "" { 172 t.Skip(reason) 173 } 174 175 spendMoney(t, func() { 176 toUser := os.Getenv("MG_EMAIL_TO") 177 mg, err := NewMailgunFromEnv() 178 ensure.Nil(t, err) 179 180 m := mg.NewMessage(fromUser, exampleSubject, exampleText+"Batch\n") 181 for i := 0; i < MaxNumberOfRecipients; i++ { 182 m.AddRecipient("") // We expect this to indicate a failure at the API 183 } 184 err = m.AddRecipientAndVariables(toUser, nil) 185 // In case of error the SDK didn't send the message, 186 // OR the API didn't check for empty To: headers. 187 ensure.NotNil(t, err) 188 }) 189 } 190 191 func TestSendMGBatchRecipientVariables(t *testing.T) { 192 if reason := SkipNetworkTest(); reason != "" { 193 t.Skip(reason) 194 } 195 196 spendMoney(t, func() { 197 toUser := os.Getenv("MG_EMAIL_TO") 198 mg, err := NewMailgunFromEnv() 199 ensure.Nil(t, err) 200 201 ctx := context.Background() 202 m := mg.NewMessage(fromUser, exampleSubject, templateText) 203 err = m.AddRecipientAndVariables(toUser, map[string]interface{}{ 204 "name": "Joe Cool Example", 205 "table": 42, 206 }) 207 ensure.Nil(t, err) 208 _, _, err = mg.Send(ctx, m) 209 ensure.Nil(t, err) 210 }) 211 } 212 213 func TestSendMGOffline(t *testing.T) { 214 const ( 215 exampleDomain = "testDomain" 216 exampleAPIKey = "testAPIKey" 217 toUser = "test@test.com" 218 exampleMessage = "Queue. Thank you" 219 exampleID = "<20111114174239.25659.5817@samples.mailgun.org>" 220 ) 221 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 222 ensure.DeepEqual(t, req.Method, http.MethodPost) 223 ensure.DeepEqual(t, req.URL.Path, fmt.Sprintf("/v3/%s/messages", exampleDomain)) 224 ensure.DeepEqual(t, req.FormValue("from"), fromUser) 225 ensure.DeepEqual(t, req.FormValue("subject"), exampleSubject) 226 ensure.DeepEqual(t, req.FormValue("text"), exampleText) 227 ensure.DeepEqual(t, req.FormValue("to"), toUser) 228 rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID) 229 fmt.Fprint(w, rsp) 230 })) 231 defer srv.Close() 232 233 mg := NewMailgun(exampleDomain, exampleAPIKey) 234 mg.SetAPIBase(srv.URL + "/v3") 235 ctx := context.Background() 236 237 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 238 msg, id, err := mg.Send(ctx, m) 239 ensure.Nil(t, err) 240 ensure.DeepEqual(t, msg, exampleMessage) 241 ensure.DeepEqual(t, id, exampleID) 242 } 243 244 func TestSendMGSeparateDomain(t *testing.T) { 245 const ( 246 exampleDomain = "testDomain" 247 signingDomain = "signingDomain" 248 249 exampleAPIKey = "testAPIKey" 250 toUser = "test@test.com" 251 exampleMessage = "Queue. Thank you" 252 exampleID = "<20111114174239.25659.5817@samples.mailgun.org>" 253 ) 254 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 255 ensure.DeepEqual(t, req.Method, http.MethodPost) 256 ensure.DeepEqual(t, req.URL.Path, fmt.Sprintf("/v3/%s/messages", signingDomain)) 257 ensure.DeepEqual(t, req.FormValue("from"), fromUser) 258 ensure.DeepEqual(t, req.FormValue("subject"), exampleSubject) 259 ensure.DeepEqual(t, req.FormValue("text"), exampleText) 260 ensure.DeepEqual(t, req.FormValue("to"), toUser) 261 rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID) 262 fmt.Fprint(w, rsp) 263 })) 264 defer srv.Close() 265 266 mg := NewMailgun(exampleDomain, exampleAPIKey) 267 mg.SetAPIBase(srv.URL + "/v3") 268 269 ctx := context.Background() 270 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 271 m.AddDomain(signingDomain) 272 273 msg, id, err := mg.Send(ctx, m) 274 ensure.Nil(t, err) 275 ensure.DeepEqual(t, msg, exampleMessage) 276 ensure.DeepEqual(t, id, exampleID) 277 } 278 279 func TestSendMGMessageVariables(t *testing.T) { 280 const ( 281 exampleDomain = "testDomain" 282 exampleAPIKey = "testAPIKey" 283 toUser = "test@test.com" 284 exampleMessage = "Queue. Thank you" 285 exampleID = "<20111114174239.25659.5820@samples.mailgun.org>" 286 exampleStrVarKey = "test-str-key" 287 exampleStrVarVal = "test-str-val" 288 exampleBoolVarKey = "test-bool-key" 289 exampleBoolVarVal = "false" 290 exampleMapVarKey = "test-map-key" 291 exampleMapVarStrVal = `{"test":"123"}` 292 exampleTemplateStrVal = `{"templateVariable":{"key":{"nested":"yes","status":"test"}}}` 293 ) 294 var ( 295 exampleMapVarVal = map[string]string{"test": "123"} 296 exampleTemplateVariable = map[string]interface{}{ 297 "key": map[string]string{ 298 "nested": "yes", 299 "status": "test", 300 }, 301 } 302 ) 303 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 304 ensure.DeepEqual(t, req.Method, http.MethodPost) 305 ensure.DeepEqual(t, req.URL.Path, fmt.Sprintf("/v3/%s/messages", exampleDomain)) 306 307 ensure.DeepEqual(t, req.FormValue("from"), fromUser) 308 ensure.DeepEqual(t, req.FormValue("subject"), exampleSubject) 309 ensure.DeepEqual(t, req.FormValue("text"), exampleText) 310 ensure.DeepEqual(t, req.FormValue("to"), toUser) 311 ensure.DeepEqual(t, req.FormValue("v:"+exampleMapVarKey), exampleMapVarStrVal) 312 ensure.DeepEqual(t, req.FormValue("v:"+exampleBoolVarKey), exampleBoolVarVal) 313 ensure.DeepEqual(t, req.FormValue("v:"+exampleStrVarKey), exampleStrVarVal) 314 ensure.DeepEqual(t, req.FormValue("h:X-Mailgun-Variables"), exampleTemplateStrVal) 315 rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID) 316 fmt.Fprint(w, rsp) 317 })) 318 defer srv.Close() 319 320 mg := NewMailgun(exampleDomain, exampleAPIKey) 321 mg.SetAPIBase(srv.URL + "/v3") 322 323 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 324 m.AddVariable(exampleStrVarKey, exampleStrVarVal) 325 m.AddVariable(exampleBoolVarKey, false) 326 m.AddVariable(exampleMapVarKey, exampleMapVarVal) 327 m.AddTemplateVariable("templateVariable", exampleTemplateVariable) 328 329 msg, id, err := mg.Send(context.Background(), m) 330 ensure.Nil(t, err) 331 ensure.DeepEqual(t, msg, exampleMessage) 332 ensure.DeepEqual(t, id, exampleID) 333 } 334 335 func TestAddRecipientsError(t *testing.T) { 336 337 mg := NewMailgun(exampleDomain, exampleAPIKey) 338 m := mg.NewMessage(fromUser, exampleSubject, exampleText) 339 340 for i := 0; i < 1000; i++ { 341 recipient := fmt.Sprintf("recipient_%d@example.com", i) 342 ensure.Nil(t, m.AddRecipient(recipient)) 343 } 344 345 err := m.AddRecipient("recipient_1001@example.com") 346 ensure.NotNil(t, err) 347 ensure.DeepEqual(t, err.Error(), "recipient limit exceeded (max 1000)") 348 } 349 350 func TestAddRecipientAndVariablesError(t *testing.T) { 351 var err error 352 353 mg := NewMailgun(exampleDomain, exampleAPIKey) 354 m := mg.NewMessage(fromUser, exampleSubject, exampleText) 355 356 for i := 0; i < 1000; i++ { 357 recipient := fmt.Sprintf("recipient_%d@example.com", i) 358 err = m.AddRecipientAndVariables(recipient, map[string]interface{}{"id": i}) 359 ensure.Nil(t, err) 360 } 361 362 err = m.AddRecipientAndVariables("recipient_1001@example.com", map[string]interface{}{"id": 1001}) 363 ensure.DeepEqual(t, err.Error(), "recipient limit exceeded (max 1000)") 364 } 365 366 func TestSendEOFError(t *testing.T) { 367 const ( 368 exampleDomain = "testDomain" 369 exampleAPIKey = "testAPIKey" 370 toUser = "test@test.com" 371 ) 372 373 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 374 panic("") 375 return 376 })) 377 defer srv.Close() 378 379 mg := NewMailgun(exampleDomain, exampleAPIKey) 380 mg.SetAPIBase(srv.URL + "/v3") 381 382 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 383 _, _, err := mg.Send(context.Background(), m) 384 ensure.NotNil(t, err) 385 ensure.StringContains(t, err.Error(), "remote server prematurely closed connection: Post ") 386 ensure.StringContains(t, err.Error(), "/messages: EOF") 387 } 388 389 func TestHasRecipient(t *testing.T) { 390 const ( 391 exampleDomain = "testDomain" 392 exampleAPIKey = "testAPIKey" 393 recipient = "test@test.com" 394 ) 395 396 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 397 ensure.DeepEqual(t, req.Method, http.MethodPost) 398 ensure.DeepEqual(t, req.URL.Path, fmt.Sprintf("/v3/%s/messages", exampleDomain)) 399 fmt.Fprint(w, `{"message":"Queued, Thank you", "id":"<20111114174239.25659.5820@samples.mailgun.org>"}`) 400 })) 401 defer srv.Close() 402 403 mg := NewMailgun(exampleDomain, exampleAPIKey) 404 mg.SetAPIBase(srv.URL + "/v3") 405 406 // No recipient 407 m := mg.NewMessage(fromUser, exampleSubject, exampleText) 408 _, _, err := mg.Send(context.Background(), m) 409 ensure.NotNil(t, err) 410 ensure.DeepEqual(t, err.Error(), "message not valid") 411 412 // Provided Bcc 413 m = mg.NewMessage(fromUser, exampleSubject, exampleText) 414 m.AddBCC(recipient) 415 _, _, err = mg.Send(context.Background(), m) 416 ensure.Nil(t, err) 417 418 // Provided cc 419 m = mg.NewMessage(fromUser, exampleSubject, exampleText) 420 m.AddCC(recipient) 421 _, _, err = mg.Send(context.Background(), m) 422 ensure.Nil(t, err) 423 } 424 425 func TestResendStored(t *testing.T) { 426 const ( 427 exampleDomain = "testDomain" 428 exampleAPIKey = "testAPIKey" 429 toUser = "test@test.com" 430 exampleMessage = "Queue. Thank you" 431 exampleID = "<20111114174239.25659.5820@samples.mailgun.org>" 432 ) 433 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 434 ensure.DeepEqual(t, req.Method, http.MethodPost) 435 ensure.DeepEqual(t, req.URL.Path, "/v3/some-url") 436 ensure.DeepEqual(t, req.FormValue("to"), toUser) 437 438 rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID) 439 fmt.Fprint(w, rsp) 440 })) 441 defer srv.Close() 442 443 mg := NewMailgun(exampleDomain, exampleAPIKey) 444 mg.SetAPIBase(srv.URL + "/v3") 445 446 msg, id, err := mg.ReSend(context.Background(), srv.URL+"/v3/some-url") 447 ensure.NotNil(t, err) 448 ensure.DeepEqual(t, err.Error(), "must provide at least one recipient") 449 450 msg, id, err = mg.ReSend(context.Background(), srv.URL+"/v3/some-url", toUser) 451 ensure.Nil(t, err) 452 ensure.DeepEqual(t, msg, exampleMessage) 453 ensure.DeepEqual(t, id, exampleID) 454 } 455 456 func TestSendTLSOptions(t *testing.T) { 457 const ( 458 exampleDomain = "testDomain" 459 exampleAPIKey = "testAPIKey" 460 toUser = "test@test.com" 461 exampleMessage = "Queue. Thank you" 462 exampleID = "<20111114174239.25659.5817@samples.mailgun.org>" 463 ) 464 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 465 ensure.DeepEqual(t, req.Method, http.MethodPost) 466 ensure.DeepEqual(t, req.URL.Path, fmt.Sprintf("/v3/%s/messages", exampleDomain)) 467 ensure.DeepEqual(t, req.FormValue("from"), fromUser) 468 ensure.DeepEqual(t, req.FormValue("subject"), exampleSubject) 469 ensure.DeepEqual(t, req.FormValue("text"), exampleText) 470 ensure.DeepEqual(t, req.FormValue("to"), toUser) 471 ensure.DeepEqual(t, req.FormValue("o:require-tls"), "true") 472 ensure.DeepEqual(t, req.FormValue("o:skip-verification"), "true") 473 rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID) 474 fmt.Fprint(w, rsp) 475 })) 476 defer srv.Close() 477 478 mg := NewMailgun(exampleDomain, exampleAPIKey) 479 mg.SetAPIBase(srv.URL + "/v3") 480 ctx := context.Background() 481 482 m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser) 483 m.SetRequireTLS(true) 484 m.SetSkipVerification(true) 485 486 msg, id, err := mg.Send(ctx, m) 487 ensure.Nil(t, err) 488 ensure.DeepEqual(t, msg, exampleMessage) 489 ensure.DeepEqual(t, id, exampleID) 490 } 491 492 func TestSendTemplate(t *testing.T) { 493 const ( 494 exampleDomain = "testDomain" 495 exampleAPIKey = "testAPIKey" 496 toUser = "test@test.com" 497 exampleMessage = "Queue. Thank you" 498 exampleID = "<20111114174239.25659.5817@samples.mailgun.org>" 499 templateName = "my-template" 500 ) 501 srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) { 502 ensure.DeepEqual(t, req.FormValue("template"), templateName) 503 rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID) 504 fmt.Fprint(w, rsp) 505 })) 506 defer srv.Close() 507 508 mg := NewMailgun(exampleDomain, exampleAPIKey) 509 mg.SetAPIBase(srv.URL + "/v3") 510 ctx := context.Background() 511 512 m := mg.NewMessage(fromUser, exampleSubject, "", toUser) 513 m.SetTemplate(templateName) 514 515 msg, id, err := mg.Send(ctx, m) 516 ensure.Nil(t, err) 517 ensure.DeepEqual(t, msg, exampleMessage) 518 ensure.DeepEqual(t, id, exampleID) 519 }