diff --git a/main.go b/main.go index 5fe8ea5..6ec165d 100644 --- a/main.go +++ b/main.go @@ -2,12 +2,18 @@ package main import ( "bytes" + "encoding/json" "fmt" + "io" "log" "log/slog" "net/http" ) +type UserData struct { + Name string +} + func main() { mux := http.NewServeMux() @@ -16,6 +22,7 @@ func main() { mux.HandleFunc("/hello/", handleHelloParameterized) mux.HandleFunc("/responses/{user}/hello/", handleUserResponsesHello) mux.HandleFunc("/user/hello", handleHelloHeader) + mux.HandleFunc("/json", handleJSON) fmt.Println("Listening on port 4000") @@ -89,6 +96,38 @@ func handleHelloNoHeader(w http.ResponseWriter, r *http.Request) { handleHello(w, username) } +func handleJSON(w http.ResponseWriter, r *http.Request) { + fmt.Println("Requested Path: ", r.URL.Path) + + byteData, err := io.ReadAll(r.Body) + if err != nil { + slog.Error("error reading request body", "err: ", err) + http.Error(w, "bad request body", http.StatusBadRequest) + return + } + + if len(byteData) == 0 { + http.Error(w, "empty request body", http.StatusBadRequest) + return + } + + var reqData UserData + err = json.Unmarshal(byteData, &reqData) + if err != nil { + slog.Error("error unmarshalling request body", "err", err) + http.Error(w, "error parsing request body", http.StatusBadRequest) + return + } + + if reqData.Name == "" { + http.Error(w, "invalid request body!", http.StatusBadRequest) + return + } + + handleHello(w, reqData.Name) + +} + func handleHello(w http.ResponseWriter, username string) { var output bytes.Buffer diff --git a/main_test.go b/main_test.go index a54c89f..4b67931 100644 --- a/main_test.go +++ b/main_test.go @@ -2,6 +2,7 @@ package main import ( "bytes" + "encoding/json" "net/http" "net/http/httptest" "testing" @@ -160,3 +161,81 @@ func TestHandleHelloNoHeader(t *testing.T) { string(expectedMessage), string(w.Body.Bytes()), w.Body.String()) } } + +func TestHandleJSON(t *testing.T) { + testRequest := UserData{ + Name: "human", + } + + marshalledRequestBody, err := json.Marshal(testRequest) + if err != nil { + t.Fatal("error marshalling testRequest data:", err) + } + + req := httptest.NewRequest(http.MethodPost, "/josn", bytes.NewBuffer(marshalledRequestBody)) + + w := httptest.NewRecorder() + + handleJSON(w, req) + + desiredCode := http.StatusOK + if w.Code != desiredCode { + t.Errorf("bad response code: expected %v got %v\nbody: %s\n", + desiredCode, w.Code, w.Body.String()) + } + + expectedMessage := []byte("Hello human!\n") + if !bytes.Equal(w.Body.Bytes(), expectedMessage) { + t.Errorf("bad response body: expected %s, got %s\nbody: %s\n", + string(expectedMessage), string(w.Body.Bytes()), w.Body.String()) + } +} + +func TestHandleJSONEmptyBody(t *testing.T) { + req := httptest.NewRequest(http.MethodPost, "/json", nil) + + w := httptest.NewRecorder() + + handleJSON(w, req) + + desiredCode := http.StatusBadRequest + if w.Code != desiredCode { + t.Errorf("bad response code: expected %v got %v\nbody: %s\n", + desiredCode, w.Code, w.Body.String()) + } + + expectedMessage := []byte("empty request body\n") + if !bytes.Equal(w.Body.Bytes(), expectedMessage) { + t.Errorf("bad response body: expected %s, got %s\nbody: %s\n", + string(expectedMessage), string(w.Body.Bytes()), w.Body.String()) + } +} + +func TestHandleJSONEmptyNameFeild(t *testing.T) { + testRequest := UserData{ + Name: "", + } + + marshalledRequestBody, err := json.Marshal(testRequest) + if err != nil { + t.Fatal("error marshalling testRequest data:", err) + } + + req := httptest.NewRequest(http.MethodPost, "/json", bytes.NewBuffer(marshalledRequestBody)) + + w := httptest.NewRecorder() + + handleJSON(w, req) + + desiredCode := http.StatusBadRequest + if w.Code != desiredCode { + t.Errorf("bad response code: expected %v got %v\nbody: %s\n", + desiredCode, w.Code, w.Body.String()) + } + + expectedMessage := []byte("invalid request body!\n") + if !bytes.Equal(w.Body.Bytes(), expectedMessage) { + t.Errorf("bad response body: expected %s, got %s\nbody: %s\n", + string(expectedMessage), string(w.Body.Bytes()), w.Body.String()) + } +}