package web import ( "crypto/tls" "net/http" "net/http/httptest" "testing" "time" "github.com/gin-gonic/gin" ) func TestSafeNext只允许本站绝对路径(t *testing.T) { for _, test := range []struct { raw string want string }{ {"/pdd?status=pending", "/pdd?status=pending"}, {"", "/shopee"}, {"https://example.com", "/shopee"}, {"//example.com/path", "/shopee"}, {"pdd", "/shopee"}, } { if got := safeNext(test.raw); got != test.want { t.Errorf("safeNext(%q) = %q,期望 %q", test.raw, got, test.want) } } } func TestPasswordReturnPath移除改密反馈参数(t *testing.T) { got := passwordReturnPath("/pdd?q=shoe&change_password=1&password_error=bad&password_field=new_password") if got != "/pdd?q=shoe" { t.Fatalf("passwordReturnPath = %q,期望保留业务筛选并移除改密参数", got) } if got := passwordReturnPath("https://example.com"); got != "/shopee" { t.Fatalf("外部返回地址应回退到 /shopee,实际 %q", got) } } func TestAuthCookie安全属性(t *testing.T) { gin.SetMode(gin.TestMode) for _, test := range []struct { name string tls bool secure bool }{ {"HTTP", false, false}, {"HTTPS", true, true}, } { t.Run(test.name, func(t *testing.T) { response := httptest.NewRecorder() request := httptest.NewRequest(http.MethodGet, "/login", nil) if test.tls { request.TLS = &tls.ConnectionState{} } context, _ := gin.CreateTestContext(response) context.Request = request setAuthCookie(context, "raw-token", time.Now().Add(12*time.Hour)) cookies := response.Result().Cookies() if len(cookies) != 1 { t.Fatalf("Set-Cookie 数量 = %d,期望 1", len(cookies)) } cookie := cookies[0] if cookie.Name != authCookieName || cookie.Value != "raw-token" || cookie.Path != "/" { t.Errorf("Cookie 名称、值或 Path 不正确: %#v", cookie) } if !cookie.HttpOnly || cookie.SameSite != http.SameSiteLaxMode || cookie.Secure != test.secure { t.Errorf("Cookie 安全属性不正确: %#v", cookie) } if cookie.MaxAge != 12*60*60 { t.Errorf("Cookie MaxAge = %d,期望 43200", cookie.MaxAge) } }) } }