github.com/vnpaycloud-console/gophercloud/v2@v2.0.5/testhelper/http_responses.go (about) 1 package testhelper 2 3 import ( 4 "encoding/json" 5 "fmt" 6 "io" 7 "net" 8 "net/http" 9 "net/http/httptest" 10 "net/url" 11 "reflect" 12 "strings" 13 "testing" 14 ) 15 16 var ( 17 // Mux is a multiplexer that can be used to register handlers. 18 Mux *http.ServeMux 19 20 // Server is an in-memory HTTP server for testing. 21 Server *httptest.Server 22 ) 23 24 // SetupPersistentPortHTTP prepares the Mux and Server listening specific port. 25 func SetupPersistentPortHTTP(t *testing.T, port int) { 26 l, err := net.Listen("tcp", fmt.Sprintf("127.0.0.1:%d", port)) 27 if err != nil { 28 t.Errorf("Failed to listen to 127.0.0.1:%d: %s", port, err) 29 } 30 Mux = http.NewServeMux() 31 Server = httptest.NewUnstartedServer(Mux) 32 Server.Listener = l 33 Server.Start() 34 } 35 36 // SetupHTTP prepares the Mux and Server. 37 func SetupHTTP() { 38 Mux = http.NewServeMux() 39 Server = httptest.NewServer(Mux) 40 } 41 42 // TeardownHTTP releases HTTP-related resources. 43 func TeardownHTTP() { 44 Server.Close() 45 } 46 47 // Endpoint returns a fake endpoint that will actually target the Mux. 48 func Endpoint() string { 49 return Server.URL + "/" 50 } 51 52 // Serves a static content at baseURL/relPath 53 func ServeFile(t *testing.T, baseURL, relPath, contentType, content string) string { 54 rawURL := strings.Join([]string{baseURL, relPath}, "/") 55 parsedURL, err := url.Parse(rawURL) 56 AssertNoErr(t, err) 57 Mux.HandleFunc(parsedURL.Path, func(w http.ResponseWriter, r *http.Request) { 58 TestMethod(t, r, "GET") 59 w.Header().Set("Content-Type", contentType) 60 w.WriteHeader(http.StatusOK) 61 fmt.Fprint(w, content) 62 }) 63 64 return rawURL 65 } 66 67 // TestFormValues ensures that all the URL parameters given to the http.Request are the same as values. 68 func TestFormValues(t *testing.T, r *http.Request, values map[string]string) { 69 want := url.Values{} 70 for k, v := range values { 71 want.Add(k, v) 72 } 73 74 if err := r.ParseForm(); err != nil { 75 t.Errorf("Failed to parse request form %v", r) 76 } 77 if !reflect.DeepEqual(want, r.Form) { 78 t.Errorf("Request parameters = %v, want %v", r.Form, want) 79 } 80 } 81 82 // TestMethod checks that the Request has the expected method (e.g. GET, POST). 83 func TestMethod(t *testing.T, r *http.Request, expected string) { 84 if expected != r.Method { 85 t.Errorf("Request method = %v, expected %v", r.Method, expected) 86 } 87 } 88 89 // TestHeader checks that the header on the http.Request matches the expected value. 90 func TestHeader(t *testing.T, r *http.Request, header string, expected string) { 91 if len(r.Header.Values(header)) == 0 { 92 t.Errorf("Header %s not found, expected %q", header, expected) 93 return 94 } 95 for _, actual := range r.Header.Values(header) { 96 if expected != actual { 97 t.Errorf("Header %s = %q, expected %q", header, actual, expected) 98 } 99 } 100 } 101 102 // TestHeaderUnset checks that the header on the http.Request doesn't exist. 103 func TestHeaderUnset(t *testing.T, r *http.Request, header string) { 104 if len(r.Header.Values(header)) > 0 { 105 t.Errorf("Header %s is not expected", header) 106 } 107 } 108 109 // TestBody verifies that the request body matches an expected body. 110 func TestBody(t *testing.T, r *http.Request, expected string) { 111 b, err := io.ReadAll(r.Body) 112 if err != nil { 113 t.Errorf("Unable to read body: %v", err) 114 } 115 str := string(b) 116 if expected != str { 117 t.Errorf("Body = %s, expected %s", str, expected) 118 } 119 } 120 121 // TestJSONRequest verifies that the JSON payload of a request matches an expected structure, without asserting things about 122 // whitespace or ordering. 123 func TestJSONRequest(t *testing.T, r *http.Request, expected string) { 124 b, err := io.ReadAll(r.Body) 125 if err != nil { 126 t.Errorf("Unable to read request body: %v", err) 127 } 128 129 var actualJSON any 130 err = json.Unmarshal(b, &actualJSON) 131 if err != nil { 132 t.Errorf("Unable to parse request body as JSON: %v", err) 133 } 134 135 CheckJSONEquals(t, expected, actualJSON) 136 }