package hws_test import ( "bytes" "context" "net/http" "net/http/httptest" "testing" "git.haelnorr.com/h/golib/hws" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func Test_Server_Addr(t *testing.T) { server, err := hws.NewServer(&hws.Config{ Host: "192.168.1.1", Port: 8080, }) require.NoError(t, err) addr := server.Addr() assert.Equal(t, "192.168.1.1:8080", addr) } func Test_Server_Handler(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) // Add routes first handler := testHandler err := server.AddRoutes(hws.Route{ Path: "/test", Method: hws.MethodGET, Handler: handler, }) require.NoError(t, err) // Get the handler h := server.Handler() require.NotNil(t, h) // Test the handler directly with httptest req := httptest.NewRequest("GET", "/test", nil) rr := httptest.NewRecorder() h.ServeHTTP(rr, req) assert.Equal(t, 200, rr.Code) assert.Equal(t, "hello world", rr.Body.String()) } func Test_LoggerIgnorePaths_Integration(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) // Add routes err := server.AddRoutes(hws.Route{ Path: "/test", Method: hws.MethodGET, Handler: testHandler, }, hws.Route{ Path: "/ignore", Method: hws.MethodGET, Handler: testHandler, }) require.NoError(t, err) // Set paths to ignore server.LoggerIgnorePaths("/ignore", "/healthz") err = server.AddMiddleware() require.NoError(t, err) // Test that ignored path doesn't generate logs buf.Reset() req := httptest.NewRequest("GET", "/ignore", nil) rr := httptest.NewRecorder() server.Handler().ServeHTTP(rr, req) // Buffer should be empty for ignored path assert.Empty(t, buf.String()) // Test that non-ignored path generates logs buf.Reset() req = httptest.NewRequest("GET", "/test", nil) rr = httptest.NewRecorder() server.Handler().ServeHTTP(rr, req) // Buffer should have logs for non-ignored path assert.NotEmpty(t, buf.String()) } func Test_WrappedWriter(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) // Add routes with different status codes err := server.AddRoutes( hws.Route{ Path: "/ok", Method: hws.MethodGET, Handler: testHandler, }, hws.Route{ Path: "/created", Method: hws.MethodPOST, Handler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(201) w.Write([]byte("created")) }), }, ) require.NoError(t, err) err = server.AddMiddleware() require.NoError(t, err) // Test OK status req := httptest.NewRequest("GET", "/ok", nil) rr := httptest.NewRecorder() server.Handler().ServeHTTP(rr, req) assert.Equal(t, 200, rr.Code) // Test Created status req = httptest.NewRequest("POST", "/created", nil) rr = httptest.NewRecorder() server.Handler().ServeHTTP(rr, req) assert.Equal(t, 201, rr.Code) } func Test_Start_Errors(t *testing.T) { t.Run("Start fails when AddRoutes not called", func(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) err := server.Start(t.Context()) assert.Error(t, err) assert.Contains(t, err.Error(), "Server.AddRoutes must be run before starting the server") }) t.Run("Start fails with nil context", func(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) err := server.AddRoutes(hws.Route{ Path: "/test", Method: hws.MethodGET, Handler: testHandler, }) require.NoError(t, err) err = server.Start(t.Context()) assert.Error(t, err) assert.Contains(t, err.Error(), "Context cannot be nil") }) } func Test_Shutdown_Errors(t *testing.T) { t.Run("Shutdown fails with nil context", func(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) startTestServer(t, server) <-server.Ready() err := server.Shutdown(t.Context()) assert.Error(t, err) assert.Contains(t, err.Error(), "Context cannot be nil") // Clean up server.Shutdown(t.Context()) }) t.Run("Shutdown fails when server not running", func(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) err := server.Shutdown(t.Context()) assert.Error(t, err) assert.Contains(t, err.Error(), "Server isn't running") }) } func Test_WaitUntilReady_ContextCancelled(t *testing.T) { t.Run("Context cancelled before server ready", func(t *testing.T) { var buf bytes.Buffer server := createTestServer(t, &buf) err := server.AddRoutes(hws.Route{ Path: "/test", Method: hws.MethodGET, Handler: testHandler, }) require.NoError(t, err) // Create a context with a very short timeout ctx, cancel := context.WithTimeout(t.Context(), 1) defer cancel() // Start should return with context error since timeout is so short err = server.Start(ctx) // The error could be nil if server started very quickly, or context.DeadlineExceeded // This tests the ctx.Err() path in waitUntilReady if err != nil { assert.Equal(t, context.DeadlineExceeded, err) } }) }