github.com/mailgun/mailgun-go/v3@v3.6.4/mock.go (about)

     1  package mailgun
     2  
     3  import (
     4  	"crypto/rand"
     5  	"encoding/json"
     6  	"fmt"
     7  	"net/http"
     8  	"net/http/httptest"
     9  	"net/mail"
    10  	"net/url"
    11  	"strconv"
    12  	"strings"
    13  
    14  	"github.com/go-chi/chi"
    15  )
    16  
    17  // A mailgun api mock suitable for testing
    18  type MockServer struct {
    19  	srv *httptest.Server
    20  
    21  	domainIPS   []string
    22  	domainList  []domainContainer
    23  	exportList  []Export
    24  	mailingList []mailingListContainer
    25  	routeList   []Route
    26  	events      []Event
    27  	webhooks    WebHooksListResponse
    28  }
    29  
    30  // Create a new instance of the mailgun API mock server
    31  func NewMockServer() MockServer {
    32  	ms := MockServer{}
    33  
    34  	// Add all our handlers
    35  	r := chi.NewRouter()
    36  
    37  	r.Route("/v3", func(r chi.Router) {
    38  		ms.addIPRoutes(r)
    39  		ms.addExportRoutes(r)
    40  		ms.addDomainRoutes(r)
    41  		ms.addMailingListRoutes(r)
    42  		ms.addEventRoutes(r)
    43  		ms.addMessagesRoutes(r)
    44  		ms.addValidationRoutes(r)
    45  		ms.addRoutes(r)
    46  		ms.addWebhookRoutes(r)
    47  	})
    48  
    49  	// Start the server
    50  	ms.srv = httptest.NewServer(r)
    51  	return ms
    52  }
    53  
    54  // Stop the server
    55  func (ms *MockServer) Stop() {
    56  	ms.srv.Close()
    57  }
    58  
    59  // URL returns the URL used to connect to the mock server
    60  func (ms *MockServer) URL() string {
    61  	return ms.srv.URL + "/v3"
    62  }
    63  
    64  func toJSON(w http.ResponseWriter, obj interface{}) {
    65  	if err := json.NewEncoder(w).Encode(obj); err != nil {
    66  		http.Error(w, err.Error(), http.StatusInternalServerError)
    67  	}
    68  	w.Header().Set("Content-Type", "application/json")
    69  }
    70  
    71  func stringToBool(v string) bool {
    72  	lower := strings.ToLower(v)
    73  	if lower == "yes" || lower == "no" {
    74  		return lower == "yes"
    75  	}
    76  
    77  	if v == "" {
    78  		return false
    79  	}
    80  
    81  	result, err := strconv.ParseBool(v)
    82  	if err != nil {
    83  		panic(err)
    84  	}
    85  	return result
    86  }
    87  
    88  func stringToInt(v string) int {
    89  	if v == "" {
    90  		return 0
    91  	}
    92  
    93  	result, err := strconv.ParseInt(v, 10, 64)
    94  	if err != nil {
    95  		panic(err)
    96  	}
    97  	return int(result)
    98  }
    99  
   100  func stringToMap(v string) map[string]interface{} {
   101  	if v == "" {
   102  		return nil
   103  	}
   104  
   105  	result := make(map[string]interface{})
   106  	err := json.Unmarshal([]byte(v), &result)
   107  	if err != nil {
   108  		panic(err)
   109  	}
   110  	return result
   111  }
   112  
   113  func parseAddress(v string) string {
   114  	if v == "" {
   115  		return ""
   116  	}
   117  	e, err := mail.ParseAddress(v)
   118  	if err != nil {
   119  		panic(err)
   120  	}
   121  	return e.Address
   122  }
   123  
   124  // Given the page direction, pivot value and limit, calculate the offsets for the slice
   125  func pageOffsets(pivotIdx []string, pivotDir, pivotVal string, limit int) (int, int) {
   126  	switch pivotDir {
   127  	case "first":
   128  		if limit < len(pivotIdx) {
   129  			return 0, limit
   130  		}
   131  		return 0, len(pivotIdx)
   132  	case "last":
   133  		if limit < len(pivotIdx) {
   134  			return len(pivotIdx) - limit, len(pivotIdx)
   135  		}
   136  		return 0, len(pivotIdx)
   137  	case "next":
   138  		for i, item := range pivotIdx {
   139  			if item == pivotVal {
   140  				offset := i + 1 + limit
   141  				if offset > len(pivotIdx) {
   142  					offset = len(pivotIdx)
   143  				}
   144  				return i + 1, offset
   145  			}
   146  		}
   147  		return 0, 0
   148  	case "prev":
   149  		for i, item := range pivotIdx {
   150  			if item == pivotVal {
   151  				if i == 0 {
   152  					return 0, 0
   153  				}
   154  
   155  				offset := i - limit
   156  				if offset < 0 {
   157  					offset = 0
   158  				}
   159  				return offset, i
   160  			}
   161  		}
   162  		return 0, 0
   163  	}
   164  
   165  	if limit > len(pivotIdx) {
   166  		return 0, len(pivotIdx)
   167  	}
   168  	return 0, limit
   169  }
   170  
   171  func getPageURL(r *http.Request, params url.Values) string {
   172  	if r.FormValue("limit") != "" {
   173  		params.Add("limit", r.FormValue("limit"))
   174  	}
   175  	return "http://" + r.Host + r.URL.EscapedPath() + "?" + params.Encode()
   176  }
   177  
   178  // randomString generates a string of given length, but random content.
   179  // All content will be within the ASCII graphic character set.
   180  // (Implementation from Even Shaw's contribution on
   181  // http://stackoverflow.com/questions/12771930/what-is-the-fastest-way-to-generate-a-long-random-string-in-go).
   182  func randomString(n int, prefix string) string {
   183  	const alphanum = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
   184  	var bytes = make([]byte, n)
   185  	rand.Read(bytes)
   186  	for i, b := range bytes {
   187  		bytes[i] = alphanum[b%byte(len(alphanum))]
   188  	}
   189  	return prefix + string(bytes)
   190  }
   191  
   192  func randomEmail(prefix, domain string) string {
   193  	return strings.ToLower(fmt.Sprintf("%s@%s", randomString(20, prefix), domain))
   194  }