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))
 | |
| }
 |