package handlers import ( "encoding/json" "net/http" "net/http/httptest" "testing" ) // TestRespondErrorProducesValidJSON 错误信息含引号/换行时输出仍须是合法 JSON func TestRespondErrorProducesValidJSON(t *testing.T) { w := httptest.NewRecorder() respondError(w, "上游返回了 \"引号\" 和\n换行", false) var body map[string]interface{} if err := json.Unmarshal(w.Body.Bytes(), &body); err != nil { t.Fatalf("非法 JSON: %v, body: %s", err, w.Body.String()) } if body["code"].(float64) != -1 { t.Errorf("code 应为 -1, got %v", body["code"]) } if w.Code != 500 { t.Errorf("服务端错误应返回 500, got %d", w.Code) } } // TestRespondErrorClientErr 客户端错误应返回 400 func TestRespondErrorClientErr(t *testing.T) { w := httptest.NewRecorder() respondError(w, "缺少 book_id 参数", true) if w.Code != 400 { t.Errorf("客户端错误应返回 400, got %d", w.Code) } } // TestHandleDetailMissingParam 缺少必需参数返回 400 而非透传到上游 func TestHandleDetailMissingParam(t *testing.T) { w := httptest.NewRecorder() HandleDetail(w, httptest.NewRequest("GET", "/detail", nil)) if w.Code != 400 { t.Errorf("缺参应返回 400, got %d, body: %s", w.Code, w.Body.String()) } } // TestOptionalAccessKeyDisabled protect_all 未启用(或配置未加载)时直接放行 func TestOptionalAccessKeyDisabled(t *testing.T) { called := false h := OptionalAccessKey(func(w http.ResponseWriter, r *http.Request) { called = true }) h(httptest.NewRecorder(), httptest.NewRequest("GET", "/search?query=x", nil)) if !called { t.Error("protect_all 未启用时应直接放行") } } // TestHandleHealth 存活探针返回 200 ok func TestHandleHealth(t *testing.T) { w := httptest.NewRecorder() HandleHealth(w, httptest.NewRequest("GET", "/healthz", nil)) if w.Code != 200 || w.Body.String() != "ok" { t.Errorf("应返回 200 ok, got %d %q", w.Code, w.Body.String()) } }