Files
backend/internal/service/yggdrasil_service_test.go
lan 4b4980820f
Some checks failed
SonarQube Analysis / sonarqube (push) Has been cancelled
Test / test (push) Has been cancelled
Test / lint (push) Has been cancelled
Test / build (push) Has been cancelled
chore: 初始化仓库,排除二进制文件和覆盖率文件
2025-11-28 23:30:49 +08:00

351 lines
7.6 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 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)
}
})
}
}