package handlers import ( "bytes" "log/slog" "net/http" "net/http/httptest" "net/url" "strings" "testing" "sneak.berlin/go/pixa/internal/clientip" "sneak.berlin/go/pixa/internal/config" ) // TestFailedLoginLogsResolvedClientIP verifies the failed-login record // carries the resolved client IP from the request context, not the raw // proxy peer address. func TestFailedLoginLogsResolvedClientIP(t *testing.T) { t.Parallel() var buf bytes.Buffer h := &Handlers{ log: slog.New(slog.NewJSONHandler(&buf, nil)), config: &config.Config{SigningKey: testSigningKey}, } form := url.Values{loginKeyField: {"wrong-key"}} req := httptest.NewRequestWithContext( t.Context(), http.MethodPost, "/", strings.NewReader(form.Encode())) req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req = req.WithContext(clientip.WithClientIP(req.Context(), "203.0.113.7")) h.handleLoginPost(httptest.NewRecorder(), req) if !strings.Contains(buf.String(), `"remote_addr":"203.0.113.7"`) { t.Errorf("failed-login log missing resolved client IP; got %q", buf.String()) } }