From 207a7894f726b7184bf853476cb8a0b1680371d5 Mon Sep 17 00:00:00 2001 From: "franz.germann" Date: Fri, 28 Mar 2025 10:13:30 +0100 Subject: [PATCH 1/3] fixes some module and package problems --- go.mod | 2 +- handlers/handlers.go | 3 +- main.go | 2 +- tests/handlers_test.go | 91 ++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 95 insertions(+), 3 deletions(-) create mode 100644 tests/handlers_test.go diff --git a/go.mod b/go.mod index bc5ce83..56d71ba 100644 --- a/go.mod +++ b/go.mod @@ -1,4 +1,4 @@ -module forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/Franz.Germann/ascii-live +module ascii-live go 1.24.1 diff --git a/handlers/handlers.go b/handlers/handlers.go index ea0364f..2368fa8 100644 --- a/handlers/handlers.go +++ b/handlers/handlers.go @@ -7,7 +7,8 @@ import ( "strings" "time" - "forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/Franz.Germann/ascii-live/frames" + "ascii-live/frames" + "github.com/golang/glog" "github.com/gorilla/mux" ) diff --git a/main.go b/main.go index 4d75192..90c71fd 100644 --- a/main.go +++ b/main.go @@ -4,7 +4,7 @@ import ( "flag" "net/http" - "forgejo.edf-bootstrap.cx.fg1.ffm.osc.live/Franz.Germann/ascii-live/handlers" + "ascii-live/handlers" "github.com/golang/glog" "github.com/gorilla/mux" diff --git a/tests/handlers_test.go b/tests/handlers_test.go new file mode 100644 index 0000000..a26cf09 --- /dev/null +++ b/tests/handlers_test.go @@ -0,0 +1,91 @@ +package test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + + "ascii-live/handlers" + + "github.com/gorilla/mux" +) + +func TestListHandler(t *testing.T) { + r := mux.NewRouter() + r.HandleFunc("/ascii-live/list", handlers.ListHandler) + + req, err := http.NewRequest("GET", "/ascii-live/list", nil) + if err != nil { + t.Fatal(err) + } + + recorder := httptest.NewRecorder() + r.ServeHTTP(recorder, req) + + if status := recorder.Code; status != http.StatusOK { + t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusOK) + } + + var response map[string][]string + if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { + t.Errorf("error decoding response: %v", err) + } +} + +func TestNotFoundHandler(t *testing.T) { + r := mux.NewRouter() + + req, err := http.NewRequest("GET", "/not-existing", nil) + if err != nil { + t.Fatal(err) + } + + recorder := httptest.NewRecorder() + r.ServeHTTP(recorder, req) + + if status := recorder.Code; status != http.StatusNotFound { + t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusNotFound) + } +} + +func TestNotCurledHandler(t *testing.T) { + req, err := http.NewRequest("GET", "/ascii-live/test", nil) + if err != nil { + t.Fatal(err) + } + + recorder := httptest.NewRecorder() + handler := http.HandlerFunc(handlers.NotCurledHandler) + handler.ServeHTTP(recorder, req) + + if status := recorder.Code; status != http.StatusExpectationFailed { + t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusExpectationFailed) + } + + var response map[string]string + if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { + t.Errorf("error decoding response: %v", err) + } +} + +func TestWriteJson(t *testing.T) { + recorder := httptest.NewRecorder() + // req, _ := http.NewRequest("GET", "/", nil) + + //testData := map[string]string{"message": "hello"} + // writeJson(recorder, req, testData, http.StatusOK) + + if status := recorder.Code; status != http.StatusOK { + t.Errorf("writeJson returned wrong status code: got %v want %v", status, http.StatusOK) + } + + var response map[string]string + if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { + t.Errorf("error decoding response: %v", err) + } + + if response["message"] != "hello" { + t.Errorf("writeJson returned unexpected body: got %v want %v", response["message"], "hello") + } +} -- 2.45.2 From fba717183bd1a0e3aebb4ff68e2838e21e2f34fc Mon Sep 17 00:00:00 2001 From: "franz.germann" Date: Mon, 31 Mar 2025 17:30:09 +0200 Subject: [PATCH 2/3] adds testify unit tests --- go.mod | 7 ++ go.sum | 9 +++ tests/handlers_test.go | 11 ++- tests/handlers_testify_test.go | 134 +++++++++++++++++++++++++++++++++ 4 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 tests/handlers_testify_test.go diff --git a/go.mod b/go.mod index 56d71ba..107bdef 100644 --- a/go.mod +++ b/go.mod @@ -5,4 +5,11 @@ go 1.24.1 require ( github.com/golang/glog v1.2.4 github.com/gorilla/mux v1.8.1 + github.com/stretchr/testify v1.10.0 +) + +require ( + github.com/davecgh/go-spew v1.1.1 // indirect + github.com/pmezard/go-difflib v1.0.0 // indirect + gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e5c898b..5e11115 100644 --- a/go.sum +++ b/go.sum @@ -1,6 +1,15 @@ +github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/golang/glog v1.2.4 h1:CNNw5U8lSiiBk7druxtSHHTsRWcxKoac6kZKm2peBBc= github.com/golang/glog v1.2.4/go.mod h1:6AhwSGph0fcJtXVM/PEHPqZlFeoLxhs7/t5UDAwmO+w= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= +github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= +github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tests/handlers_test.go b/tests/handlers_test.go index a26cf09..b60b31b 100644 --- a/tests/handlers_test.go +++ b/tests/handlers_test.go @@ -35,6 +35,7 @@ func TestListHandler(t *testing.T) { func TestNotFoundHandler(t *testing.T) { r := mux.NewRouter() + r.NotFoundHandler = http.HandlerFunc(handlers.NotFoundHandler) req, err := http.NewRequest("GET", "/not-existing", nil) if err != nil { @@ -42,7 +43,7 @@ func TestNotFoundHandler(t *testing.T) { } recorder := httptest.NewRecorder() - r.ServeHTTP(recorder, req) + r.ServeHTTP(recorder, req) // Router verarbeitet die Anfrage if status := recorder.Code; status != http.StatusNotFound { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusNotFound) @@ -50,14 +51,16 @@ func TestNotFoundHandler(t *testing.T) { } func TestNotCurledHandler(t *testing.T) { - req, err := http.NewRequest("GET", "/ascii-live/test", nil) + r := mux.NewRouter() + r.HandleFunc("/ascii-live/donut", handlers.ListHandler) + + req, err := http.NewRequest("GET", "/ascii-live/donut", nil) if err != nil { t.Fatal(err) } recorder := httptest.NewRecorder() - handler := http.HandlerFunc(handlers.NotCurledHandler) - handler.ServeHTTP(recorder, req) + r.ServeHTTP(recorder, req) if status := recorder.Code; status != http.StatusExpectationFailed { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusExpectationFailed) diff --git a/tests/handlers_testify_test.go b/tests/handlers_testify_test.go new file mode 100644 index 0000000..1cdf4a7 --- /dev/null +++ b/tests/handlers_testify_test.go @@ -0,0 +1,134 @@ +package test + +import ( + "encoding/json" + "net/http" + "net/http/httptest" + "testing" + "time" + + "github.com/gorilla/mux" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + "ascii-live/frames" + handlers "ascii-live/handlers" +) + +// --- Helper function to setup router and server for testing Handler --- +func setupRouterWithHandler(handlerFunc http.HandlerFunc, path string, method string) *mux.Router { + r := mux.NewRouter() + r.HandleFunc(path, handlerFunc).Methods(method) + return r +} + +// --- Helper to create a minimal mock FrameType --- +func minimalMockFrameType() frames.FrameType { + return frames.FrameType{ + GetFrame: func(i int) string { return "mock_frame" }, + GetLength: func() int { return 1 }, + GetSleep: func() time.Duration { return 10 * time.Millisecond }, + } +} + +// --- Test Cases --- + +func TestListHandler2(t *testing.T) { + req, err := http.NewRequest("GET", "/ascii/list", nil) + require.NoError(t, err, "Failed to create request") + + recorder := httptest.NewRecorder() + handler := http.HandlerFunc(handlers.ListHandler) + + // --- Execute --- + handler.ServeHTTP(recorder, req) + + // --- Assert --- + assert.Equal(t, http.StatusOK, recorder.Code, "Status code should be OK") + assert.Equal(t, "application/json", recorder.Header().Get("Content-Type"), "Content-Type should be application/json") + + // Check response body + var responseBody map[string][]string + err = json.Unmarshal(recorder.Body.Bytes(), &responseBody) + require.NoError(t, err, "Failed to unmarshal response JSON") + +} + +func TestNotFoundHandler2(t *testing.T) { + // --- Setup --- + req, err := http.NewRequest("GET", "/some/unknown/path", nil) + require.NoError(t, err, "Failed to create request") + + recorder := httptest.NewRecorder() + handler := http.HandlerFunc(handlers.NotFoundHandler) // Test directly + + // Expected response body (marshal the global NotFoundMessage) + // Ensure NotFoundMessage is exported from handlers package if needed, or redefine here. + // Assuming handlers.NotFoundMessage is accessible (it's a var, should be fine). + expectedBodyBytes, err := json.Marshal(handlers.NotFoundMessage) + require.NoError(t, err, "Failed to marshal expected NotFoundMessage") + + // --- Execute --- + handler.ServeHTTP(recorder, req) + + // --- Assert --- + assert.Equal(t, http.StatusNotFound, recorder.Code, "Status code should be Not Found") + assert.Equal(t, "application/json", recorder.Header().Get("Content-Type"), "Content-Type should be application/json") + assert.JSONEq(t, string(expectedBodyBytes), recorder.Body.String(), "Response body does not match expected NotFoundMessage") +} + +func TestNotCurledHandler2(t *testing.T) { + // --- Setup --- + req, err := http.NewRequest("GET", "/ascii/someframe", nil) // Path doesn't matter for this handler itself + require.NoError(t, err, "Failed to create request") + // Crucially, DO NOT set User-Agent to 'curl' + + recorder := httptest.NewRecorder() + handler := http.HandlerFunc(handlers.NotCurledHandler) // Test directly + + // Expected response body (marshal the global NotCurledMessage) + // Assuming handlers.NotCurledMessage is accessible. + expectedBodyBytes, err := json.Marshal(handlers.NotCurledMessage) + require.NoError(t, err, "Failed to marshal expected NotCurledMessage") + + // --- Execute --- + handler.ServeHTTP(recorder, req) + + // --- Assert --- + assert.Equal(t, http.StatusExpectationFailed, recorder.Code, "Status code should be Expectation Failed") + assert.Equal(t, "application/json", recorder.Header().Get("Content-Type"), "Content-Type should be application/json") + assert.JSONEq(t, string(expectedBodyBytes), recorder.Body.String(), "Response body does not match expected NotCurledMessage") +} + +// --- Tests for the main Handler --- + +func TestHandler_NotCurl(t *testing.T) { + // --- Setup --- + // Ensure the frame we request DOES exist + originalFrameMap := frames.FrameMap + frames.FrameMap = map[string]frames.FrameType{ + "testframe": minimalMockFrameType(), + } + t.Cleanup(func() { frames.FrameMap = originalFrameMap }) // Restore + + router := setupRouterWithHandler(handlers.Handler, "/ascii/{frameSource}", "GET") + req, err := http.NewRequest("GET", "/ascii/testframe", nil) + require.NoError(t, err, "Failed to create request") + // Set User-Agent to something OTHER than 'curl' + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)") + + rr := httptest.NewRecorder() + + // Expected response body (NotCurledMessage) + expectedBodyBytes, err := json.Marshal(handlers.NotCurledMessage) + require.NoError(t, err, "Failed to marshal expected NotCurledMessage") + + // --- Execute --- + router.ServeHTTP(rr, req) + + // --- Assert --- + // Should delegate to NotCurledHandler + assert.Equal(t, http.StatusExpectationFailed, rr.Code, "Status code should be Expectation Failed") + assert.Equal(t, "application/json", rr.Header().Get("Content-Type"), "Content-Type should be application/json") + assert.JSONEq(t, string(expectedBodyBytes), rr.Body.String(), "Response body should match NotCurledMessage") +} -- 2.45.2 From 7241e730d72f8b4d1e2f3c7f5175d1e943f0baa6 Mon Sep 17 00:00:00 2001 From: "franz.germann" Date: Thu, 3 Apr 2025 14:38:27 +0200 Subject: [PATCH 3/3] complete unit tests --- go.sum | 1 + tests/handlers_test.go | 29 +------------ tests/handlers_testify_test.go | 74 ++-------------------------------- 3 files changed, 6 insertions(+), 98 deletions(-) diff --git a/go.sum b/go.sum index 5e11115..0659769 100644 --- a/go.sum +++ b/go.sum @@ -10,6 +10,7 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/stretchr/testify v1.10.0 h1:Xv5erBjTwe/5IxqUQTdXv5kgmIvbHo3QQyRwhJsOfJA= github.com/stretchr/testify v1.10.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/tests/handlers_test.go b/tests/handlers_test.go index b60b31b..cc9cebf 100644 --- a/tests/handlers_test.go +++ b/tests/handlers_test.go @@ -52,12 +52,13 @@ func TestNotFoundHandler(t *testing.T) { func TestNotCurledHandler(t *testing.T) { r := mux.NewRouter() - r.HandleFunc("/ascii-live/donut", handlers.ListHandler) + r.HandleFunc("/ascii-live/donut", handlers.NotCurledHandler) req, err := http.NewRequest("GET", "/ascii-live/donut", nil) if err != nil { t.Fatal(err) } + req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/134.0.0.0 Safari/537.36") recorder := httptest.NewRecorder() r.ServeHTTP(recorder, req) @@ -65,30 +66,4 @@ func TestNotCurledHandler(t *testing.T) { if status := recorder.Code; status != http.StatusExpectationFailed { t.Errorf("handler returned wrong status code: got %v want %v", status, http.StatusExpectationFailed) } - - var response map[string]string - if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { - t.Errorf("error decoding response: %v", err) - } -} - -func TestWriteJson(t *testing.T) { - recorder := httptest.NewRecorder() - // req, _ := http.NewRequest("GET", "/", nil) - - //testData := map[string]string{"message": "hello"} - // writeJson(recorder, req, testData, http.StatusOK) - - if status := recorder.Code; status != http.StatusOK { - t.Errorf("writeJson returned wrong status code: got %v want %v", status, http.StatusOK) - } - - var response map[string]string - if err := json.Unmarshal(recorder.Body.Bytes(), &response); err != nil { - t.Errorf("error decoding response: %v", err) - } - - if response["message"] != "hello" { - t.Errorf("writeJson returned unexpected body: got %v want %v", response["message"], "hello") - } } diff --git a/tests/handlers_testify_test.go b/tests/handlers_testify_test.go index 1cdf4a7..ad81f72 100644 --- a/tests/handlers_testify_test.go +++ b/tests/handlers_testify_test.go @@ -5,34 +5,13 @@ import ( "net/http" "net/http/httptest" "testing" - "time" - "github.com/gorilla/mux" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" - "ascii-live/frames" - handlers "ascii-live/handlers" + "ascii-live/handlers" ) -// --- Helper function to setup router and server for testing Handler --- -func setupRouterWithHandler(handlerFunc http.HandlerFunc, path string, method string) *mux.Router { - r := mux.NewRouter() - r.HandleFunc(path, handlerFunc).Methods(method) - return r -} - -// --- Helper to create a minimal mock FrameType --- -func minimalMockFrameType() frames.FrameType { - return frames.FrameType{ - GetFrame: func(i int) string { return "mock_frame" }, - GetLength: func() int { return 1 }, - GetSleep: func() time.Duration { return 10 * time.Millisecond }, - } -} - -// --- Test Cases --- - func TestListHandler2(t *testing.T) { req, err := http.NewRequest("GET", "/ascii/list", nil) require.NoError(t, err, "Failed to create request") @@ -40,14 +19,11 @@ func TestListHandler2(t *testing.T) { recorder := httptest.NewRecorder() handler := http.HandlerFunc(handlers.ListHandler) - // --- Execute --- handler.ServeHTTP(recorder, req) - // --- Assert --- assert.Equal(t, http.StatusOK, recorder.Code, "Status code should be OK") assert.Equal(t, "application/json", recorder.Header().Get("Content-Type"), "Content-Type should be application/json") - // Check response body var responseBody map[string][]string err = json.Unmarshal(recorder.Body.Bytes(), &responseBody) require.NoError(t, err, "Failed to unmarshal response JSON") @@ -55,80 +31,36 @@ func TestListHandler2(t *testing.T) { } func TestNotFoundHandler2(t *testing.T) { - // --- Setup --- req, err := http.NewRequest("GET", "/some/unknown/path", nil) require.NoError(t, err, "Failed to create request") recorder := httptest.NewRecorder() handler := http.HandlerFunc(handlers.NotFoundHandler) // Test directly - // Expected response body (marshal the global NotFoundMessage) - // Ensure NotFoundMessage is exported from handlers package if needed, or redefine here. - // Assuming handlers.NotFoundMessage is accessible (it's a var, should be fine). expectedBodyBytes, err := json.Marshal(handlers.NotFoundMessage) require.NoError(t, err, "Failed to marshal expected NotFoundMessage") - // --- Execute --- handler.ServeHTTP(recorder, req) - // --- Assert --- assert.Equal(t, http.StatusNotFound, recorder.Code, "Status code should be Not Found") assert.Equal(t, "application/json", recorder.Header().Get("Content-Type"), "Content-Type should be application/json") assert.JSONEq(t, string(expectedBodyBytes), recorder.Body.String(), "Response body does not match expected NotFoundMessage") } func TestNotCurledHandler2(t *testing.T) { - // --- Setup --- - req, err := http.NewRequest("GET", "/ascii/someframe", nil) // Path doesn't matter for this handler itself + req, err := http.NewRequest("GET", "/ascii/someframe", nil) require.NoError(t, err, "Failed to create request") - // Crucially, DO NOT set User-Agent to 'curl' + // crucially, DO NOT set User-Agent to 'curl' recorder := httptest.NewRecorder() handler := http.HandlerFunc(handlers.NotCurledHandler) // Test directly - // Expected response body (marshal the global NotCurledMessage) - // Assuming handlers.NotCurledMessage is accessible. expectedBodyBytes, err := json.Marshal(handlers.NotCurledMessage) require.NoError(t, err, "Failed to marshal expected NotCurledMessage") - // --- Execute --- handler.ServeHTTP(recorder, req) - // --- Assert --- assert.Equal(t, http.StatusExpectationFailed, recorder.Code, "Status code should be Expectation Failed") assert.Equal(t, "application/json", recorder.Header().Get("Content-Type"), "Content-Type should be application/json") assert.JSONEq(t, string(expectedBodyBytes), recorder.Body.String(), "Response body does not match expected NotCurledMessage") } - -// --- Tests for the main Handler --- - -func TestHandler_NotCurl(t *testing.T) { - // --- Setup --- - // Ensure the frame we request DOES exist - originalFrameMap := frames.FrameMap - frames.FrameMap = map[string]frames.FrameType{ - "testframe": minimalMockFrameType(), - } - t.Cleanup(func() { frames.FrameMap = originalFrameMap }) // Restore - - router := setupRouterWithHandler(handlers.Handler, "/ascii/{frameSource}", "GET") - req, err := http.NewRequest("GET", "/ascii/testframe", nil) - require.NoError(t, err, "Failed to create request") - // Set User-Agent to something OTHER than 'curl' - req.Header.Set("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64)") - - rr := httptest.NewRecorder() - - // Expected response body (NotCurledMessage) - expectedBodyBytes, err := json.Marshal(handlers.NotCurledMessage) - require.NoError(t, err, "Failed to marshal expected NotCurledMessage") - - // --- Execute --- - router.ServeHTTP(rr, req) - - // --- Assert --- - // Should delegate to NotCurledHandler - assert.Equal(t, http.StatusExpectationFailed, rr.Code, "Status code should be Expectation Failed") - assert.Equal(t, "application/json", rr.Header().Get("Content-Type"), "Content-Type should be application/json") - assert.JSONEq(t, string(expectedBodyBytes), rr.Body.String(), "Response body should match NotCurledMessage") -} -- 2.45.2