chore: 初始化仓库,排除二进制文件和覆盖率文件
This commit is contained in:
350
internal/service/yggdrasil_service_test.go
Normal file
350
internal/service/yggdrasil_service_test.go
Normal file
@@ -0,0 +1,350 @@
|
||||
package service
|
||||
|
||||
import (
|
||||
"net"
|
||||
"strings"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestYggdrasilService_Constants 测试Yggdrasil服务常量
|
||||
func TestYggdrasilService_Constants(t *testing.T) {
|
||||
if SessionKeyPrefix != "Join_" {
|
||||
t.Errorf("SessionKeyPrefix = %s, want 'Join_'", SessionKeyPrefix)
|
||||
}
|
||||
|
||||
if SessionTTL != 15*time.Minute {
|
||||
t.Errorf("SessionTTL = %v, want 15 minutes", SessionTTL)
|
||||
}
|
||||
}
|
||||
|
||||
// TestSessionData_Structure 测试SessionData结构
|
||||
func TestSessionData_Structure(t *testing.T) {
|
||||
data := SessionData{
|
||||
AccessToken: "test-token",
|
||||
UserName: "TestUser",
|
||||
SelectedProfile: "test-profile-uuid",
|
||||
IP: "127.0.0.1",
|
||||
}
|
||||
|
||||
if data.AccessToken == "" {
|
||||
t.Error("AccessToken should not be empty")
|
||||
}
|
||||
|
||||
if data.UserName == "" {
|
||||
t.Error("UserName should not be empty")
|
||||
}
|
||||
|
||||
if data.SelectedProfile == "" {
|
||||
t.Error("SelectedProfile should not be empty")
|
||||
}
|
||||
}
|
||||
|
||||
// TestJoinServer_InputValidation 测试JoinServer输入验证逻辑
|
||||
func TestJoinServer_InputValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
serverId string
|
||||
accessToken string
|
||||
selectedProfile string
|
||||
wantErr bool
|
||||
errContains string
|
||||
}{
|
||||
{
|
||||
name: "所有参数有效",
|
||||
serverId: "test-server-123",
|
||||
accessToken: "test-token",
|
||||
selectedProfile: "test-profile",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "serverId为空",
|
||||
serverId: "",
|
||||
accessToken: "test-token",
|
||||
selectedProfile: "test-profile",
|
||||
wantErr: true,
|
||||
errContains: "参数不能为空",
|
||||
},
|
||||
{
|
||||
name: "accessToken为空",
|
||||
serverId: "test-server",
|
||||
accessToken: "",
|
||||
selectedProfile: "test-profile",
|
||||
wantErr: true,
|
||||
errContains: "参数不能为空",
|
||||
},
|
||||
{
|
||||
name: "selectedProfile为空",
|
||||
serverId: "test-server",
|
||||
accessToken: "test-token",
|
||||
selectedProfile: "",
|
||||
wantErr: true,
|
||||
errContains: "参数不能为空",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
hasError := tt.serverId == "" || tt.accessToken == "" || tt.selectedProfile == ""
|
||||
if hasError != tt.wantErr {
|
||||
t.Errorf("Input validation failed: got %v, want %v", hasError, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestJoinServer_ServerIDValidation 测试服务器ID格式验证
|
||||
func TestJoinServer_ServerIDValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
serverId string
|
||||
wantValid bool
|
||||
}{
|
||||
{
|
||||
name: "有效的serverId",
|
||||
serverId: "test-server-123",
|
||||
wantValid: true,
|
||||
},
|
||||
{
|
||||
name: "serverId过长",
|
||||
serverId: strings.Repeat("a", 101),
|
||||
wantValid: false,
|
||||
},
|
||||
{
|
||||
name: "serverId包含危险字符<",
|
||||
serverId: "test<server",
|
||||
wantValid: false,
|
||||
},
|
||||
{
|
||||
name: "serverId包含危险字符>",
|
||||
serverId: "test>server",
|
||||
wantValid: false,
|
||||
},
|
||||
{
|
||||
name: "serverId包含危险字符\"",
|
||||
serverId: "test\"server",
|
||||
wantValid: false,
|
||||
},
|
||||
{
|
||||
name: "serverId包含危险字符'",
|
||||
serverId: "test'server",
|
||||
wantValid: false,
|
||||
},
|
||||
{
|
||||
name: "serverId包含危险字符&",
|
||||
serverId: "test&server",
|
||||
wantValid: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
isValid := len(tt.serverId) <= 100 && !strings.ContainsAny(tt.serverId, "<>\"'&")
|
||||
if isValid != tt.wantValid {
|
||||
t.Errorf("ServerID validation failed: got %v, want %v", isValid, tt.wantValid)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestJoinServer_IPValidation 测试IP地址验证逻辑
|
||||
func TestJoinServer_IPValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
ip string
|
||||
wantValid bool
|
||||
}{
|
||||
{
|
||||
name: "有效的IPv4地址",
|
||||
ip: "127.0.0.1",
|
||||
wantValid: true,
|
||||
},
|
||||
{
|
||||
name: "有效的IPv6地址",
|
||||
ip: "::1",
|
||||
wantValid: true,
|
||||
},
|
||||
{
|
||||
name: "无效的IP地址",
|
||||
ip: "invalid-ip",
|
||||
wantValid: false,
|
||||
},
|
||||
{
|
||||
name: "空IP地址(可选)",
|
||||
ip: "",
|
||||
wantValid: true, // 空IP是允许的
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var isValid bool
|
||||
if tt.ip == "" {
|
||||
isValid = true // 空IP是允许的
|
||||
} else {
|
||||
isValid = net.ParseIP(tt.ip) != nil
|
||||
}
|
||||
if isValid != tt.wantValid {
|
||||
t.Errorf("IP validation failed: got %v, want %v (ip=%s)", isValid, tt.wantValid, tt.ip)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestHasJoinedServer_InputValidation 测试HasJoinedServer输入验证
|
||||
func TestHasJoinedServer_InputValidation(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
serverId string
|
||||
username string
|
||||
wantErr bool
|
||||
}{
|
||||
{
|
||||
name: "所有参数有效",
|
||||
serverId: "test-server",
|
||||
username: "TestUser",
|
||||
wantErr: false,
|
||||
},
|
||||
{
|
||||
name: "serverId为空",
|
||||
serverId: "",
|
||||
username: "TestUser",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "username为空",
|
||||
serverId: "test-server",
|
||||
username: "",
|
||||
wantErr: true,
|
||||
},
|
||||
{
|
||||
name: "两者都为空",
|
||||
serverId: "",
|
||||
username: "",
|
||||
wantErr: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
hasError := tt.serverId == "" || tt.username == ""
|
||||
if hasError != tt.wantErr {
|
||||
t.Errorf("Input validation failed: got %v, want %v", hasError, tt.wantErr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestHasJoinedServer_UsernameMatching 测试用户名匹配逻辑
|
||||
func TestHasJoinedServer_UsernameMatching(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sessionUser string
|
||||
requestUser string
|
||||
wantMatch bool
|
||||
}{
|
||||
{
|
||||
name: "用户名匹配",
|
||||
sessionUser: "TestUser",
|
||||
requestUser: "TestUser",
|
||||
wantMatch: true,
|
||||
},
|
||||
{
|
||||
name: "用户名不匹配",
|
||||
sessionUser: "TestUser",
|
||||
requestUser: "OtherUser",
|
||||
wantMatch: false,
|
||||
},
|
||||
{
|
||||
name: "大小写敏感",
|
||||
sessionUser: "TestUser",
|
||||
requestUser: "testuser",
|
||||
wantMatch: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
matches := tt.sessionUser == tt.requestUser
|
||||
if matches != tt.wantMatch {
|
||||
t.Errorf("Username matching failed: got %v, want %v", matches, tt.wantMatch)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestHasJoinedServer_IPMatching 测试IP地址匹配逻辑
|
||||
func TestHasJoinedServer_IPMatching(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
sessionIP string
|
||||
requestIP string
|
||||
wantMatch bool
|
||||
shouldCheck bool
|
||||
}{
|
||||
{
|
||||
name: "IP匹配",
|
||||
sessionIP: "127.0.0.1",
|
||||
requestIP: "127.0.0.1",
|
||||
wantMatch: true,
|
||||
shouldCheck: true,
|
||||
},
|
||||
{
|
||||
name: "IP不匹配",
|
||||
sessionIP: "127.0.0.1",
|
||||
requestIP: "192.168.1.1",
|
||||
wantMatch: false,
|
||||
shouldCheck: true,
|
||||
},
|
||||
{
|
||||
name: "请求IP为空时不检查",
|
||||
sessionIP: "127.0.0.1",
|
||||
requestIP: "",
|
||||
wantMatch: true,
|
||||
shouldCheck: false,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
var matches bool
|
||||
if tt.requestIP == "" {
|
||||
matches = true // 空IP不检查
|
||||
} else {
|
||||
matches = tt.sessionIP == tt.requestIP
|
||||
}
|
||||
if matches != tt.wantMatch {
|
||||
t.Errorf("IP matching failed: got %v, want %v", matches, tt.wantMatch)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// TestJoinServer_SessionKey 测试会话键生成
|
||||
func TestJoinServer_SessionKey(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
serverId string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "生成正确的会话键",
|
||||
serverId: "test-server-123",
|
||||
expected: "Join_test-server-123",
|
||||
},
|
||||
{
|
||||
name: "空serverId",
|
||||
serverId: "",
|
||||
expected: "Join_",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
sessionKey := SessionKeyPrefix + tt.serverId
|
||||
if sessionKey != tt.expected {
|
||||
t.Errorf("Session key = %s, want %s", sessionKey, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user