package sign import ( "encoding/hex" "net/url" "strings" "testing" "time" "git.misaka.ren/M1saka/zhanlu_proxy/internal/auth" ) const testPublicKeyPEM = `-----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAhxudxTewPgljUHEZHkusP7m3I+zA4/RGvuUMt6TtII/m4zwUOm/Y31zHBTmkCCt8k5vj9y+AmO0TsGmHooNQuMebakdmEWdcA5h7YAHHFbF2w5LcxIXjib08vgVpA+m3R5xPbLK+vfHe2aAX36b5nHReDNncY5vAl3U4CgIEBGPqyG67vJytRWqP+sfEdw5+m192Rf4SCGyiBzRmjiVlH3zeEBjdbOrkAnzKOVz6AHBl2q7LPLJKIzxjoAyhEp5qnDjHUFo5VZUgFwUOt83A/jbGMyzmjRoxBuvKcs9tBuorZyUwIsZN6E+rtQk2YqMPj4RkDsZ7LRmj6on8sN2rHQIDAQAB -----END PUBLIC KEY-----` func TestBuildOpURLStructure(t *testing.T) { pub, err := auth.ParsePublicKey(testPublicKeyPEM) if err != nil { t.Fatal(err) } now := time.Date(2026, 8, 5, 2, 30, 0, 0, time.UTC) s := Signer{ PublicKey: pub, Now: func() time.Time { return now }, Nonce: func() string { return "fixed-nonce-1234567890" }, } creds := auth.Credentials{AccessKey: "AK123", SecretKey: "SK456", Token: "TOK789"} u, err := s.BuildOpURL("/api/acepilot/zhanlu/v1/login", creds, "https://ecloud.10086.cn", "POST") if err != nil { t.Fatal(err) } if !strings.HasPrefix(u, "https://ecloud.10086.cn/api/acepilot/zhanlu/v1/login?") { t.Fatalf("url = %s", u) } parsed, err := url.Parse(u) if err != nil { t.Fatal(err) } q := parsed.Query() if q.Get("AccessKey") != "AK123" { t.Errorf("AccessKey = %q", q.Get("AccessKey")) } if q.Get("SignatureMethod") != "HmacSHA1" { t.Errorf("SignatureMethod = %q", q.Get("SignatureMethod")) } if q.Get("SignatureVersion") != "V2.0" { t.Errorf("SignatureVersion = %q", q.Get("SignatureVersion")) } if q.Get("Version") != "2016-12-05" { t.Errorf("Version = %q", q.Get("Version")) } // Beijing time (UTC+8) formatted with Z suffix, matching the plugin's yE9. if q.Get("Timestamp") != "2026-08-05T10:30:00Z" { t.Errorf("Timestamp = %q, want 2026-08-05T10:30:00Z (Beijing time)", q.Get("Timestamp")) } if q.Get("Signature") == "" { t.Error("Signature is empty") } if _, err := hex.DecodeString(q.Get("Signature")); err != nil { t.Errorf("Signature is not hex: %v", err) } authz := q.Get("authorization") if authz == "" { t.Error("authorization is empty") } } func TestBuildOpURLMissingCreds(t *testing.T) { s := Signer{} if _, err := s.BuildOpURL("/x", auth.Credentials{}, "http://x", "POST"); err == nil { t.Fatal("expected error for missing credentials") } }