195 lines
3.9 KiB
Go
195 lines
3.9 KiB
Go
|
package mailgun
|
||
|
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
"net/http"
|
||
|
"net/http/httptest"
|
||
|
"net/mail"
|
||
|
"net/url"
|
||
|
"strconv"
|
||
|
"strings"
|
||
|
|
||
|
"github.com/go-chi/chi"
|
||
|
)
|
||
|
|
||
|
// A mailgun api mock suitable for testing
|
||
|
type MockServer struct {
|
||
|
srv *httptest.Server
|
||
|
|
||
|
domainIPS []string
|
||
|
domainList []domainContainer
|
||
|
exportList []Export
|
||
|
mailingList []mailingListContainer
|
||
|
routeList []Route
|
||
|
events []Event
|
||
|
webhooks WebHooksListResponse
|
||
|
}
|
||
|
|
||
|
// Create a new instance of the mailgun API mock server
|
||
|
func NewMockServer() MockServer {
|
||
|
ms := MockServer{}
|
||
|
|
||
|
// Add all our handlers
|
||
|
r := chi.NewRouter()
|
||
|
|
||
|
r.Route("/v3", func(r chi.Router) {
|
||
|
ms.addIPRoutes(r)
|
||
|
ms.addExportRoutes(r)
|
||
|
ms.addDomainRoutes(r)
|
||
|
ms.addMailingListRoutes(r)
|
||
|
ms.addEventRoutes(r)
|
||
|
ms.addMessagesRoutes(r)
|
||
|
ms.addValidationRoutes(r)
|
||
|
ms.addRoutes(r)
|
||
|
ms.addWebhookRoutes(r)
|
||
|
})
|
||
|
|
||
|
// Start the server
|
||
|
ms.srv = httptest.NewServer(r)
|
||
|
return ms
|
||
|
}
|
||
|
|
||
|
// Stop the server
|
||
|
func (ms *MockServer) Stop() {
|
||
|
ms.srv.Close()
|
||
|
}
|
||
|
|
||
|
// URL returns the URL used to connect to the mock server
|
||
|
func (ms *MockServer) URL() string {
|
||
|
return ms.srv.URL + "/v3"
|
||
|
}
|
||
|
|
||
|
func toJSON(w http.ResponseWriter, obj interface{}) {
|
||
|
if err := json.NewEncoder(w).Encode(obj); err != nil {
|
||
|
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||
|
}
|
||
|
w.Header().Set("Content-Type", "application/json")
|
||
|
}
|
||
|
|
||
|
func stringToBool(v string) bool {
|
||
|
lower := strings.ToLower(v)
|
||
|
if lower == "yes" || lower == "no" {
|
||
|
return lower == "yes"
|
||
|
}
|
||
|
|
||
|
if v == "" {
|
||
|
return false
|
||
|
}
|
||
|
|
||
|
result, err := strconv.ParseBool(v)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func stringToInt(v string) int {
|
||
|
if v == "" {
|
||
|
return 0
|
||
|
}
|
||
|
|
||
|
result, err := strconv.ParseInt(v, 10, 64)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return int(result)
|
||
|
}
|
||
|
|
||
|
func stringToMap(v string) map[string]interface{} {
|
||
|
if v == "" {
|
||
|
return nil
|
||
|
}
|
||
|
|
||
|
result := make(map[string]interface{})
|
||
|
err := json.Unmarshal([]byte(v), &result)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return result
|
||
|
}
|
||
|
|
||
|
func parseAddress(v string) string {
|
||
|
if v == "" {
|
||
|
return ""
|
||
|
}
|
||
|
e, err := mail.ParseAddress(v)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
return e.Address
|
||
|
}
|
||
|
|
||
|
// Given the page direction, pivot value and limit, calculate the offsets for the slice
|
||
|
func pageOffsets(pivotIdx []string, pivotDir, pivotVal string, limit int) (int, int) {
|
||
|
switch pivotDir {
|
||
|
case "first":
|
||
|
if limit < len(pivotIdx) {
|
||
|
return 0, limit
|
||
|
}
|
||
|
return 0, len(pivotIdx)
|
||
|
case "last":
|
||
|
if limit < len(pivotIdx) {
|
||
|
return len(pivotIdx) - limit, len(pivotIdx)
|
||
|
}
|
||
|
return 0, len(pivotIdx)
|
||
|
case "next":
|
||
|
for i, item := range pivotIdx {
|
||
|
if item == pivotVal {
|
||
|
offset := i + 1 + limit
|
||
|
if offset > len(pivotIdx) {
|
||
|
offset = len(pivotIdx)
|
||
|
}
|
||
|
return i + 1, offset
|
||
|
}
|
||
|
}
|
||
|
return 0, 0
|
||
|
case "prev":
|
||
|
for i, item := range pivotIdx {
|
||
|
if item == pivotVal {
|
||
|
if i == 0 {
|
||
|
return 0, 0
|
||
|
}
|
||
|
|
||
|
offset := i - limit
|
||
|
if offset < 0 {
|
||
|
offset = 0
|
||
|
}
|
||
|
return offset, i
|
||
|
}
|
||
|
}
|
||
|
return 0, 0
|
||
|
}
|
||
|
|
||
|
if limit > len(pivotIdx) {
|
||
|
return 0, len(pivotIdx)
|
||
|
}
|
||
|
return 0, limit
|
||
|
}
|
||
|
|
||
|
func getPageURL(r *http.Request, params url.Values) string {
|
||
|
if r.FormValue("limit") != "" {
|
||
|
params.Add("limit", r.FormValue("limit"))
|
||
|
}
|
||
|
return "http://" + r.Host + r.URL.EscapedPath() + "?" + params.Encode()
|
||
|
}
|
||
|
|
||
|
// randomString generates a string of given length, but random content.
|
||
|
// All content will be within the ASCII graphic character set.
|
||
|
// (Implementation from Even Shaw's contribution on
|
||
|
// http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
|
||
|
func randomString(n int, prefix string) string {
|
||
|
const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||
|
var bytes = make([]byte, n)
|
||
|
rand.Read(bytes)
|
||
|
for i, b := range bytes {
|
||
|
bytes[i] = alphanum[b%byte(len(alphanum))]
|
||
|
}
|
||
|
return prefix + string(bytes)
|
||
|
}
|
||
|
|
||
|
func randomEmail(prefix, domain string) string {
|
||
|
return strings.ToLower(fmt.Sprintf("%s@%s", randomString(20, prefix), domain))
|
||
|
}
|