package config import ( "os" "path/filepath" "strings" "testing" "time" ) // TestLoad 验证 gateway-service 的本地 config.yaml 能被正常读取。 func TestLoad(t *testing.T) { cfg, err := Load("../../configs/config.yaml") if err != nil { t.Fatalf("Load failed: %v", err) } if cfg.HTTPAddr != ":13000" { t.Fatalf("unexpected http addr: %s", cfg.HTTPAddr) } if cfg.RoomServiceAddr != "127.0.0.1:13001" { t.Fatalf("unexpected room addr: %s", cfg.RoomServiceAddr) } if cfg.GRPCClient.DefaultTimeout != 5*time.Second || cfg.GRPCClient.RetryMaxAttempts != 2 || len(cfg.GRPCClient.RetryableStatusCodes) != 1 || cfg.GRPCClient.RetryableStatusCodes[0] != "UNAVAILABLE" { t.Fatalf("unexpected grpc client policy: %+v", cfg.GRPCClient) } if cfg.AppConfig.MySQLDSN == "" || !strings.Contains(cfg.AppConfig.MySQLDSN, "hyapp_admin") { t.Fatalf("gateway app config mysql dsn must point to admin config db: %+v", cfg.AppConfig) } if !cfg.AuthRateLimit.Enabled || cfg.AuthRateLimit.RedisAddr != "127.0.0.1:13379" { t.Fatalf("local auth rate redis config mismatch: %+v", cfg.AuthRateLimit) } if cfg.AuthRateLimit.KeyPrefix != "gateway:auth:rate:" { t.Fatalf("unexpected auth rate key prefix: %q", cfg.AuthRateLimit.KeyPrefix) } if !cfg.TencentRTC.Enabled || cfg.TencentRTC.SDKAppID == 0 || cfg.TencentRTC.SecretKey == "" { t.Fatalf("local tencent rtc config must be explicit: %+v", cfg.TencentRTC) } if cfg.TencentRTC.UserSigTTL != 2*time.Hour || cfg.TencentRTC.RoomIDType != "string" || cfg.TencentRTC.AppScene != "voice_chat_room" { t.Fatalf("unexpected local tencent rtc policy: %+v", cfg.TencentRTC) } if !cfg.TencentCOS.Enabled || cfg.TencentCOS.SecretID == "" || cfg.TencentCOS.SecretKey == "" || cfg.TencentCOS.BucketName == "" || cfg.TencentCOS.Region == "" || cfg.TencentCOS.AccessURL == "" { t.Fatalf("local tencent cos config must be explicit") } if cfg.TencentCOS.AccessURL != "https://media.haiyihy.com" { t.Fatalf("unexpected local tencent cos access url: %q", cfg.TencentCOS.AccessURL) } } // TestLoadTencentExample 验证腾讯云 IM 线上模板字段能被 gateway 正确解析。 func TestLoadTencentExample(t *testing.T) { cfg, err := Load("../../configs/config.tencent.example.yaml") if err != nil { t.Fatalf("Load tencent example failed: %v", err) } if cfg.TencentIM.SDKAppID == 0 { t.Fatalf("sdk_app_id template must be present") } if cfg.TencentIM.SecretKey == "" || cfg.TencentIM.CallbackAuthToken == "" { t.Fatalf("secret and callback token templates must be present") } if cfg.TencentIM.CallbackURL == "" { t.Fatalf("callback_url template must be present") } if cfg.AppConfig.MySQLDSN == "" || !strings.Contains(cfg.AppConfig.MySQLDSN, "hyapp_admin") { t.Fatalf("tencent app config mysql dsn template must be explicit: %+v", cfg.AppConfig) } if cfg.TencentIM.UserSigTTL != 24*time.Hour { t.Fatalf("unexpected usersig ttl: %s", cfg.TencentIM.UserSigTTL) } if !cfg.AuthRateLimit.Enabled || cfg.AuthRateLimit.RedisAddr == "" || cfg.AuthRateLimit.RedisPassword == "" { t.Fatalf("tencent auth rate redis template must be explicit: %+v", cfg.AuthRateLimit) } if !cfg.TencentRTC.Enabled || cfg.TencentRTC.SDKAppID == 0 || cfg.TencentRTC.SecretKey == "" { t.Fatalf("tencent rtc template must be explicit: %+v", cfg.TencentRTC) } if cfg.TencentRTC.UserSigTTL != 2*time.Hour || cfg.TencentRTC.RoomIDType != "string" || cfg.TencentRTC.AppScene != "voice_chat_room" { t.Fatalf("unexpected tencent rtc policy: %+v", cfg.TencentRTC) } if !cfg.TencentCOS.Enabled || cfg.TencentCOS.SecretID == "" || cfg.TencentCOS.SecretKey == "" || cfg.TencentCOS.BucketName == "" || cfg.TencentCOS.Region == "" || cfg.TencentCOS.AccessURL == "" { t.Fatalf("tencent cos template must be explicit") } } // TestLoadRejectsUnsupportedRTCRoomIDType protects the string strRoomId policy at startup. func TestLoadRejectsUnsupportedRTCRoomIDType(t *testing.T) { path := filepath.Join(t.TempDir(), "config.yaml") if err := os.WriteFile(path, []byte(`tencent_rtc: enabled: true sdk_app_id: 1400000000 secret_key: "secret" user_sig_ttl: "2h" room_id_type: "number" app_scene: "voice_chat_room" `), 0o600); err != nil { t.Fatalf("write temp config failed: %v", err) } if _, err := Load(path); err == nil { t.Fatalf("Load should reject unsupported tencent_rtc.room_id_type") } } func TestLoadRejectsIncompleteTencentCOSConfigWhenEnabled(t *testing.T) { path := filepath.Join(t.TempDir(), "config.yaml") if err := os.WriteFile(path, []byte(`tencent-cos: enabled: true secret-id: "secret-id" secret-key: "" bucket-name: "bucket" region: "me-saudi-arabia" access-url: "https://media.example.com" `), 0o600); err != nil { t.Fatalf("write temp config failed: %v", err) } if _, err := Load(path); err == nil { t.Fatalf("Load should reject incomplete enabled tencent-cos config") } }