Files

87 lines
2.8 KiB
Go
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package acme
import (
"context"
"net/http"
"net/http/httptest"
"strings"
"testing"
)
// withEndpoint 把 ZeroSSL 端点指向本地测试服务(用完恢复)。
func withEndpoint(t *testing.T, handler http.HandlerFunc) {
t.Helper()
server := httptest.NewServer(handler)
previous := zeroSSLEABEndpoint
zeroSSLEABEndpoint = server.URL
t.Cleanup(func() {
zeroSSLEABEndpoint = previous
server.Close()
})
}
func TestZeroSSLEABCredentialsSuccess(t *testing.T) {
withEndpoint(t, func(w http.ResponseWriter, r *http.Request) {
if got := r.URL.Query().Get("access_key"); got != "good-key" {
t.Fatalf("access_key 应原样传出,实际 %q", got)
}
_, _ = w.Write([]byte(`{"success":1,"eab_kid":"kid-1","eab_hmac_key":"hmac-1"}`))
})
kid, hmac, err := zerosslEABCredentials(context.Background(), "good-key")
if err != nil {
t.Fatalf("不应报错:%v", err)
}
if kid != "kid-1" || hmac != "hmac-1" {
t.Fatalf("凭据解析错误:kid=%q hmac=%q", kid, hmac)
}
}
// 422 时要把 ZeroSSL 给的错误类型带出来,而不是只回一个状态码让用户猜
func TestZeroSSLEABCredentialsSurfacesErrorType(t *testing.T) {
withEndpoint(t, func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusUnprocessableEntity)
_, _ = w.Write([]byte(`{"success":false,"error":{"code":2902,"type":"invalid_api_key"}}`))
})
_, _, err := zerosslEABCredentials(context.Background(), "bad-key")
if err == nil {
t.Fatal("期望报错")
}
if !strings.Contains(err.Error(), "422") || !strings.Contains(err.Error(), "invalid_api_key") {
t.Fatalf("错误里应含状态码与错误类型,实际:%v", err)
}
}
// 非 JSON 的失败响应:退回截断正文,便于定位(例如网关返回的 HTML)
func TestZeroSSLEABCredentialsFallsBackToBodySnippet(t *testing.T) {
withEndpoint(t, func(w http.ResponseWriter, _ *http.Request) {
w.WriteHeader(http.StatusBadGateway)
_, _ = w.Write([]byte("<html><body>\n 502 Bad Gateway\n</body></html>"))
})
_, _, err := zerosslEABCredentials(context.Background(), "any")
if err == nil || !strings.Contains(err.Error(), "502 Bad Gateway") {
t.Fatalf("应带上响应正文摘要,实际:%v", err)
}
}
// 网络错误必须脱敏:url.Error 的字符串里带 access_key,泄漏进日志等于泄密
func TestZeroSSLEABCredentialsDoesNotLeakKey(t *testing.T) {
const key = "SUPERSECRETACCESSKEY"
server := httptest.NewServer(http.HandlerFunc(func(http.ResponseWriter, *http.Request) {}))
server.Close() // 立刻关掉,制造连接失败
previous := zeroSSLEABEndpoint
zeroSSLEABEndpoint = server.URL
t.Cleanup(func() { zeroSSLEABEndpoint = previous })
_, _, err := zerosslEABCredentials(context.Background(), key)
if err == nil {
t.Fatal("期望请求失败")
}
if strings.Contains(err.Error(), key) {
t.Fatalf("错误信息里泄露了 API Key:%v", err)
}
}