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 }