package utils import ( "bytes" "encoding/json" "io" "net/http" "strings" "testing" "github.com/stretchr/testify/assert" "edge-infra.dev/pkg/edge/api/graph/model" ) const login = "/login" func TestNewMockHTTPTestServer(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) } func TestAddTestServer(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) } func TestNotAllowedContentType(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) route := &Route{ Name: "Login", Method: http.MethodPost, Path: login, Callback: func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("login route")) }, } mockServer.AddAllowedContentType("application/xml") mockServer.AddRoute(route) assert.Equal(t, len(mockServer.Routes), 1) resp, err := http.Post(mockServer.Server.URL+login, "application/json", nil) assert.NoError(t, err) assert.Equal(t, resp.StatusCode, http.StatusBadRequest) defer resp.Body.Close() _, err = io.ReadAll(resp.Body) assert.NoError(t, err) } func TestAddRoute(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) route := &Route{ Name: "Login", Method: http.MethodPost, Path: login, Callback: func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("login route")) }, } mockServer.AddAllowedContentType("application/json") mockServer.AddRoute(route) assert.Equal(t, len(mockServer.Routes), 1) resp, err := http.Post(mockServer.Server.URL+login, "application/json", nil) assert.NoError(t, err) defer resp.Body.Close() body, err := io.ReadAll(resp.Body) assert.NoError(t, err) assert.Equal(t, string(body), "login route") } func TestPost(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) mockServer.AddAllowedContentType("application/json") mockServer.AddNotFound(NotFound) mockServer.Post("Login", login, func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("login route")) }, nil) assert.Equal(t, len(mockServer.Routes), 1) resp, err := http.Post(mockServer.Server.URL+login, "application/json", nil) assert.NoError(t, err) defer resp.Body.Close() body, err := io.ReadAll(resp.Body) assert.NoError(t, err) assert.Equal(t, string(body), "login route") } func TestGet(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) mockServer.AddAllowedContentType("application/json") mockServer.AddNotFound(NotFound) mockServer.Get("Get User", "/user", func(w http.ResponseWriter, _ *http.Request) { user := &model.User{ Username: "Test", FamilyName: "John", GivenName: "Doe", } data, err := json.Marshal(user) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(nil)) return } w.WriteHeader(http.StatusOK) _, err = w.Write(data) assert.NoError(t, err) }, nil) assert.Equal(t, len(mockServer.Routes), 1) client := &http.Client{} req, err := http.NewRequest(http.MethodGet, mockServer.Server.URL+"/user", nil) req.Header.Add("Content-Type", "application/json") assert.NoError(t, err) resp, err := client.Do(req) assert.NoError(t, err) defer resp.Body.Close() assert.NoError(t, err) body, err := io.ReadAll(resp.Body) assert.NoError(t, err) userResp := &model.User{} err = json.Unmarshal(body, userResp) assert.NoError(t, err) assert.Equal(t, userResp.Username, "Test") assert.Equal(t, userResp.GivenName, "Doe") assert.Equal(t, userResp.FamilyName, "John") } func TestPut(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) mockServer.AddAllowedContentType("application/json") mockServer.AddNotFound(NotFound) actualUser := &model.User{ Username: "Test", FamilyName: "John", GivenName: "Doe", } mockServer.Put("Get User", "/update-user", func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() requestBody, err := io.ReadAll(r.Body) assert.NoError(t, err) requestUser := &model.User{} err = json.Unmarshal(requestBody, requestUser) assert.NoError(t, err) actualUser.Username = requestUser.Username actualUser.FamilyName = "" actualUser.GivenName = "" data, err := json.Marshal(actualUser) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(nil)) return } w.WriteHeader(http.StatusOK) _, err = w.Write(data) assert.NoError(t, err) }, nil) assert.Equal(t, len(mockServer.Routes), 1) requestBuffer := &bytes.Buffer{} requestUser := &model.User{ Username: "Test 1", } err := json.NewEncoder(requestBuffer).Encode(requestUser) assert.NoError(t, err) client := &http.Client{} req, err := http.NewRequest(http.MethodPut, mockServer.Server.URL+"/update-user", requestBuffer) req.Header.Add("Content-Type", "application/json") assert.NoError(t, err) resp, err := client.Do(req) assert.NoError(t, err) defer resp.Body.Close() assert.NoError(t, err) body, err := io.ReadAll(resp.Body) assert.NoError(t, err) userResp := &model.User{} err = json.Unmarshal(body, userResp) assert.NoError(t, err) assert.Equal(t, userResp.Username, "Test 1") assert.Equal(t, userResp.GivenName, "") assert.Equal(t, userResp.FamilyName, "") } func TestPatch(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) mockServer.AddAllowedContentType("application/json") mockServer.AddNotFound(NotFound) actualUser := &model.User{ Username: "Test", FamilyName: "John", GivenName: "Doe", } mockServer.Patch("Get User", "/update-user", func(w http.ResponseWriter, r *http.Request) { defer r.Body.Close() requestBody, err := io.ReadAll(r.Body) assert.NoError(t, err) requestUser := &model.User{} err = json.Unmarshal(requestBody, requestUser) assert.NoError(t, err) actualUser.Username = requestUser.Username data, err := json.Marshal(actualUser) if err != nil { w.WriteHeader(http.StatusBadRequest) _, _ = w.Write([]byte(nil)) return } w.WriteHeader(http.StatusOK) _, err = w.Write(data) assert.NoError(t, err) }, nil) assert.Equal(t, len(mockServer.Routes), 1) requestBuffer := &bytes.Buffer{} requestUser := &model.User{ Username: "Test 1", } err := json.NewEncoder(requestBuffer).Encode(requestUser) assert.NoError(t, err) client := &http.Client{} req, err := http.NewRequest(http.MethodPatch, mockServer.Server.URL+"/update-user", requestBuffer) req.Header.Add("Content-Type", "application/json") assert.NoError(t, err) resp, err := client.Do(req) assert.NoError(t, err) defer resp.Body.Close() assert.NoError(t, err) body, err := io.ReadAll(resp.Body) assert.NoError(t, err) userResp := &model.User{} err = json.Unmarshal(body, userResp) assert.NoError(t, err) assert.Equal(t, userResp.Username, "Test 1") assert.Equal(t, userResp.GivenName, actualUser.GivenName) assert.Equal(t, userResp.FamilyName, actualUser.FamilyName) } func TestAny(t *testing.T) { mockServer := NewMockHTTPTestServer() assert.NotNil(t, mockServer) defer mockServer.Close() assert.NotNil(t, mockServer.Server) mockServer.AddAllowedContentType("application/json") mockServer.AddNotFound(NotFound) mockServer.Any("Get User Profile", func(w http.ResponseWriter, _ *http.Request) { w.WriteHeader(http.StatusOK) _, _ = w.Write([]byte("login route")) }, func(_ http.ResponseWriter, r *http.Request) bool { return strings.HasPrefix(r.URL.String(), "/user/profile/") }) assert.Equal(t, len(mockServer.Routes), 1) assert.Equal(t, len(mockServer.Routes), 1) client := &http.Client{} req, err := http.NewRequest(http.MethodGet, mockServer.Server.URL+"/user/profile/2355", nil) req.Header.Add("Content-Type", "application/json") assert.NoError(t, err) resp, err := client.Do(req) assert.NoError(t, err) defer resp.Body.Close() assert.NoError(t, err) body, err := io.ReadAll(resp.Body) assert.NoError(t, err) assert.Equal(t, string(body), "login route") } func TestReadFormData(t *testing.T) { resp := make(map[string]string, 0) err := readFormData([]byte("token=test-okta-access-token&token_type_hint=access_token"), resp) assert.NoError(t, err) assert.Equal(t, resp["token"], "test-okta-access-token") assert.Equal(t, resp["token_type_hint"], "access_token") }