359 lines
8.5 KiB
Go
359 lines
8.5 KiB
Go
package service
|
||
|
||
import (
|
||
"crypto/rand"
|
||
"crypto/rsa"
|
||
"strings"
|
||
"testing"
|
||
"time"
|
||
|
||
"go.uber.org/zap/zaptest"
|
||
)
|
||
|
||
// TestSignatureService_Constants 测试签名服务相关常量
|
||
func TestSignatureService_Constants(t *testing.T) {
|
||
if RSAKeySize != 4096 {
|
||
t.Errorf("RSAKeySize = %d, want 4096", RSAKeySize)
|
||
}
|
||
|
||
if PrivateKeyRedisKey == "" {
|
||
t.Error("PrivateKeyRedisKey should not be empty")
|
||
}
|
||
|
||
if PublicKeyRedisKey == "" {
|
||
t.Error("PublicKeyRedisKey should not be empty")
|
||
}
|
||
|
||
if KeyExpirationTime != 24*7*time.Hour {
|
||
t.Errorf("KeyExpirationTime = %v, want 7 days", KeyExpirationTime)
|
||
}
|
||
|
||
if CertificateRefreshInterval != 24*time.Hour {
|
||
t.Errorf("CertificateRefreshInterval = %v, want 24 hours", CertificateRefreshInterval)
|
||
}
|
||
|
||
if CertificateExpirationPeriod != 24*7*time.Hour {
|
||
t.Errorf("CertificateExpirationPeriod = %v, want 7 days", CertificateExpirationPeriod)
|
||
}
|
||
}
|
||
|
||
// TestSignatureService_DataValidation 测试签名数据验证逻辑
|
||
func TestSignatureService_DataValidation(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
data string
|
||
wantValid bool
|
||
}{
|
||
{
|
||
name: "非空数据有效",
|
||
data: "test data",
|
||
wantValid: true,
|
||
},
|
||
{
|
||
name: "空数据无效",
|
||
data: "",
|
||
wantValid: false,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
isValid := tt.data != ""
|
||
if isValid != tt.wantValid {
|
||
t.Errorf("Data validation failed: got %v, want %v", isValid, tt.wantValid)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestPlayerCertificate_Structure 测试PlayerCertificate结构
|
||
func TestPlayerCertificate_Structure(t *testing.T) {
|
||
cert := PlayerCertificate{
|
||
ExpiresAt: "2025-01-01T00:00:00Z",
|
||
RefreshedAfter: "2025-01-01T00:00:00Z",
|
||
PublicKeySignature: "signature",
|
||
PublicKeySignatureV2: "signaturev2",
|
||
}
|
||
|
||
// 验证结构体字段
|
||
if cert.ExpiresAt == "" {
|
||
t.Error("ExpiresAt should not be empty")
|
||
}
|
||
|
||
if cert.RefreshedAfter == "" {
|
||
t.Error("RefreshedAfter should not be empty")
|
||
}
|
||
|
||
// PublicKeySignature是可选的
|
||
if cert.PublicKeySignature == "" {
|
||
t.Log("PublicKeySignature is optional")
|
||
}
|
||
}
|
||
|
||
// TestWrapString 测试字符串换行函数
|
||
func TestWrapString(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
str string
|
||
width int
|
||
expected string
|
||
}{
|
||
{
|
||
name: "正常换行",
|
||
str: "1234567890",
|
||
width: 5,
|
||
expected: "12345\n67890",
|
||
},
|
||
{
|
||
name: "字符串长度等于width",
|
||
str: "12345",
|
||
width: 5,
|
||
expected: "12345",
|
||
},
|
||
{
|
||
name: "字符串长度小于width",
|
||
str: "123",
|
||
width: 5,
|
||
expected: "123",
|
||
},
|
||
{
|
||
name: "width为0,返回原字符串",
|
||
str: "1234567890",
|
||
width: 0,
|
||
expected: "1234567890",
|
||
},
|
||
{
|
||
name: "width为负数,返回原字符串",
|
||
str: "1234567890",
|
||
width: -1,
|
||
expected: "1234567890",
|
||
},
|
||
{
|
||
name: "空字符串",
|
||
str: "",
|
||
width: 5,
|
||
expected: "",
|
||
},
|
||
{
|
||
name: "width为1",
|
||
str: "12345",
|
||
width: 1,
|
||
expected: "1\n2\n3\n4\n5",
|
||
},
|
||
{
|
||
name: "长字符串多次换行",
|
||
str: "123456789012345",
|
||
width: 5,
|
||
expected: "12345\n67890\n12345",
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
result := WrapString(tt.str, tt.width)
|
||
if result != tt.expected {
|
||
t.Errorf("WrapString(%q, %d) = %q, want %q", tt.str, tt.width, result, tt.expected)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestWrapString_LineCount 测试换行后的行数
|
||
func TestWrapString_LineCount(t *testing.T) {
|
||
tests := []struct {
|
||
name string
|
||
str string
|
||
width int
|
||
wantLines int
|
||
}{
|
||
{
|
||
name: "10个字符,width=5,应该2行",
|
||
str: "1234567890",
|
||
width: 5,
|
||
wantLines: 2,
|
||
},
|
||
{
|
||
name: "15个字符,width=5,应该3行",
|
||
str: "123456789012345",
|
||
width: 5,
|
||
wantLines: 3,
|
||
},
|
||
{
|
||
name: "5个字符,width=5,应该1行",
|
||
str: "12345",
|
||
width: 5,
|
||
wantLines: 1,
|
||
},
|
||
{
|
||
name: "width为0,应该1行",
|
||
str: "1234567890",
|
||
width: 0,
|
||
wantLines: 1,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
result := WrapString(tt.str, tt.width)
|
||
lines := strings.Count(result, "\n") + 1
|
||
if lines != tt.wantLines {
|
||
t.Errorf("Line count = %d, want %d (result: %q)", lines, tt.wantLines, result)
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestWrapString_NoTrailingNewline 测试末尾不换行
|
||
func TestWrapString_NoTrailingNewline(t *testing.T) {
|
||
str := "1234567890"
|
||
result := WrapString(str, 5)
|
||
|
||
// 验证末尾没有换行符
|
||
if strings.HasSuffix(result, "\n") {
|
||
t.Error("Result should not end with newline")
|
||
}
|
||
|
||
// 验证包含换行符(除了最后一行)
|
||
if !strings.Contains(result, "\n") {
|
||
t.Error("Result should contain newline for multi-line output")
|
||
}
|
||
}
|
||
|
||
// TestEncodePrivateKeyToPEM_ActualCall 实际调用EncodePrivateKeyToPEM函数
|
||
func TestEncodePrivateKeyToPEM_ActualCall(t *testing.T) {
|
||
// 生成测试用的RSA私钥
|
||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||
if err != nil {
|
||
t.Fatalf("生成RSA私钥失败: %v", err)
|
||
}
|
||
|
||
tests := []struct {
|
||
name string
|
||
keyType []string
|
||
wantError bool
|
||
}{
|
||
{
|
||
name: "默认类型",
|
||
keyType: []string{},
|
||
wantError: false,
|
||
},
|
||
{
|
||
name: "RSA类型",
|
||
keyType: []string{"RSA"},
|
||
wantError: false,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
pemBytes, err := EncodePrivateKeyToPEM(privateKey, tt.keyType...)
|
||
if (err != nil) != tt.wantError {
|
||
t.Errorf("EncodePrivateKeyToPEM() error = %v, wantError %v", err, tt.wantError)
|
||
return
|
||
}
|
||
if !tt.wantError {
|
||
if len(pemBytes) == 0 {
|
||
t.Error("EncodePrivateKeyToPEM() 返回的PEM字节不应为空")
|
||
}
|
||
pemStr := string(pemBytes)
|
||
// 验证PEM格式
|
||
if !strings.Contains(pemStr, "BEGIN") || !strings.Contains(pemStr, "END") {
|
||
t.Error("EncodePrivateKeyToPEM() 返回的PEM格式不正确")
|
||
}
|
||
// 验证类型
|
||
if len(tt.keyType) > 0 && tt.keyType[0] == "RSA" {
|
||
if !strings.Contains(pemStr, "RSA PRIVATE KEY") {
|
||
t.Error("EncodePrivateKeyToPEM() 应包含 'RSA PRIVATE KEY'")
|
||
}
|
||
} else {
|
||
if !strings.Contains(pemStr, "PRIVATE KEY") {
|
||
t.Error("EncodePrivateKeyToPEM() 应包含 'PRIVATE KEY'")
|
||
}
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestEncodePublicKeyToPEM_ActualCall 实际调用EncodePublicKeyToPEM函数
|
||
func TestEncodePublicKeyToPEM_ActualCall(t *testing.T) {
|
||
logger := zaptest.NewLogger(t)
|
||
|
||
// 生成测试用的RSA密钥对
|
||
privateKey, err := rsa.GenerateKey(rand.Reader, 2048)
|
||
if err != nil {
|
||
t.Fatalf("生成RSA密钥对失败: %v", err)
|
||
}
|
||
publicKey := &privateKey.PublicKey
|
||
|
||
tests := []struct {
|
||
name string
|
||
keyType []string
|
||
wantError bool
|
||
}{
|
||
{
|
||
name: "默认类型",
|
||
keyType: []string{},
|
||
wantError: false,
|
||
},
|
||
{
|
||
name: "RSA类型",
|
||
keyType: []string{"RSA"},
|
||
wantError: false,
|
||
},
|
||
}
|
||
|
||
for _, tt := range tests {
|
||
t.Run(tt.name, func(t *testing.T) {
|
||
pemBytes, err := EncodePublicKeyToPEM(logger, publicKey, tt.keyType...)
|
||
if (err != nil) != tt.wantError {
|
||
t.Errorf("EncodePublicKeyToPEM() error = %v, wantError %v", err, tt.wantError)
|
||
return
|
||
}
|
||
if !tt.wantError {
|
||
if len(pemBytes) == 0 {
|
||
t.Error("EncodePublicKeyToPEM() 返回的PEM字节不应为空")
|
||
}
|
||
pemStr := string(pemBytes)
|
||
// 验证PEM格式
|
||
if !strings.Contains(pemStr, "BEGIN") || !strings.Contains(pemStr, "END") {
|
||
t.Error("EncodePublicKeyToPEM() 返回的PEM格式不正确")
|
||
}
|
||
// 验证类型
|
||
if len(tt.keyType) > 0 && tt.keyType[0] == "RSA" {
|
||
if !strings.Contains(pemStr, "RSA PUBLIC KEY") {
|
||
t.Error("EncodePublicKeyToPEM() 应包含 'RSA PUBLIC KEY'")
|
||
}
|
||
} else {
|
||
if !strings.Contains(pemStr, "PUBLIC KEY") {
|
||
t.Error("EncodePublicKeyToPEM() 应包含 'PUBLIC KEY'")
|
||
}
|
||
}
|
||
}
|
||
})
|
||
}
|
||
}
|
||
|
||
// TestEncodePublicKeyToPEM_NilKey 测试nil公钥
|
||
func TestEncodePublicKeyToPEM_NilKey(t *testing.T) {
|
||
logger := zaptest.NewLogger(t)
|
||
_, err := EncodePublicKeyToPEM(logger, nil)
|
||
if err == nil {
|
||
t.Error("EncodePublicKeyToPEM() 对于nil公钥应返回错误")
|
||
}
|
||
}
|
||
|
||
// TestNewSignatureService 测试创建SignatureService
|
||
func TestNewSignatureService(t *testing.T) {
|
||
logger := zaptest.NewLogger(t)
|
||
// 注意:这里需要实际的redis client,但我们只测试结构体创建
|
||
// 在实际测试中,可以使用mock redis client
|
||
service := NewSignatureService(logger, nil)
|
||
if service == nil {
|
||
t.Error("NewSignatureService() 不应返回nil")
|
||
}
|
||
if service.logger != logger {
|
||
t.Error("NewSignatureService() logger 设置不正确")
|
||
}
|
||
}
|