Skip to content

Commit b8f4457

Browse files
committed
feat: add more test cases
1 parent 09213bc commit b8f4457

File tree

6 files changed

+1564
-0
lines changed

6 files changed

+1564
-0
lines changed
Lines changed: 395 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,395 @@
1+
package provider
2+
3+
import (
4+
"path/filepath"
5+
"testing"
6+
7+
"github.com/TimothyYe/godns/internal/settings"
8+
"github.com/TimothyYe/godns/internal/utils"
9+
)
10+
11+
func TestConfigurationFiles(t *testing.T) {
12+
testDataDir := filepath.Join("..", "..", "testdata")
13+
14+
t.Run("SingleProviderConfigFile", func(t *testing.T) {
15+
configPath := filepath.Join(testDataDir, "config_test_single.json")
16+
config := &settings.Settings{}
17+
18+
// Load configuration from file
19+
err := settings.LoadSettings(configPath, config)
20+
if err != nil {
21+
t.Fatalf("Failed to load single provider config: %v", err)
22+
}
23+
24+
// Validate configuration
25+
if err := utils.CheckSettings(config); err != nil {
26+
t.Fatalf("Single provider configuration validation failed: %v", err)
27+
}
28+
29+
// Test provider creation
30+
providers, err := GetProviders(config)
31+
if err != nil {
32+
t.Fatalf("Failed to create providers from single config: %v", err)
33+
}
34+
35+
if len(providers) != 1 {
36+
t.Errorf("Expected 1 provider for single config, got %d", len(providers))
37+
}
38+
39+
if _, exists := providers["DNSPod"]; !exists {
40+
t.Error("DNSPod provider not found in single config")
41+
}
42+
43+
// Test domain resolution
44+
for _, domain := range config.Domains {
45+
providerName := config.GetDomainProvider(&domain)
46+
if providerName != "DNSPod" {
47+
t.Errorf("Expected DNSPod for domain %s, got %s", domain.DomainName, providerName)
48+
}
49+
50+
provider, err := GetProviderForDomain(&domain, providers, config)
51+
if err != nil {
52+
t.Errorf("Failed to get provider for domain %s: %v", domain.DomainName, err)
53+
}
54+
if provider == nil {
55+
t.Errorf("Provider is nil for domain %s", domain.DomainName)
56+
}
57+
}
58+
59+
t.Logf("Single provider config test passed with %d domains", len(config.Domains))
60+
})
61+
62+
t.Run("MultiProviderConfigFile", func(t *testing.T) {
63+
configPath := filepath.Join(testDataDir, "config_test_multi.json")
64+
config := &settings.Settings{}
65+
66+
// Load configuration from file
67+
err := settings.LoadSettings(configPath, config)
68+
if err != nil {
69+
t.Fatalf("Failed to load multi provider config: %v", err)
70+
}
71+
72+
// Validate configuration
73+
if err := utils.CheckSettings(config); err != nil {
74+
t.Fatalf("Multi provider configuration validation failed: %v", err)
75+
}
76+
77+
// Test provider creation
78+
providers, err := GetProviders(config)
79+
if err != nil {
80+
t.Fatalf("Failed to create providers from multi config: %v", err)
81+
}
82+
83+
if len(providers) != 4 {
84+
t.Errorf("Expected 4 providers for multi config, got %d", len(providers))
85+
}
86+
87+
expectedProviders := []string{"Cloudflare", "DNSPod", "DigitalOcean", "DuckDNS"}
88+
for _, expectedProvider := range expectedProviders {
89+
if _, exists := providers[expectedProvider]; !exists {
90+
t.Errorf("%s provider not found in multi config", expectedProvider)
91+
}
92+
}
93+
94+
// Test domain resolution with expected mappings
95+
expectedMappings := map[string]string{
96+
"cloudflare-test.com": "Cloudflare",
97+
"dnspod-test.com": "DNSPod",
98+
"digitalocean-test.com": "DigitalOcean",
99+
"duckdns-test.org": "DuckDNS",
100+
}
101+
102+
for _, domain := range config.Domains {
103+
expectedProvider := expectedMappings[domain.DomainName]
104+
providerName := config.GetDomainProvider(&domain)
105+
106+
if providerName != expectedProvider {
107+
t.Errorf("Expected %s for domain %s, got %s", expectedProvider, domain.DomainName, providerName)
108+
}
109+
110+
provider, err := GetProviderForDomain(&domain, providers, config)
111+
if err != nil {
112+
t.Errorf("Failed to get provider for domain %s: %v", domain.DomainName, err)
113+
}
114+
if provider == nil {
115+
t.Errorf("Provider is nil for domain %s", domain.DomainName)
116+
}
117+
}
118+
119+
t.Logf("Multi provider config test passed with %d providers and %d domains", len(providers), len(config.Domains))
120+
})
121+
122+
t.Run("MixedProviderConfigFile", func(t *testing.T) {
123+
configPath := filepath.Join(testDataDir, "config_test_mixed.json")
124+
config := &settings.Settings{}
125+
126+
// Load configuration from file
127+
err := settings.LoadSettings(configPath, config)
128+
if err != nil {
129+
t.Fatalf("Failed to load mixed provider config: %v", err)
130+
}
131+
132+
// Validate configuration
133+
if err := utils.CheckSettings(config); err != nil {
134+
t.Fatalf("Mixed provider configuration validation failed: %v", err)
135+
}
136+
137+
// Test provider creation
138+
providers, err := GetProviders(config)
139+
if err != nil {
140+
t.Fatalf("Failed to create providers from mixed config: %v", err)
141+
}
142+
143+
if len(providers) != 3 {
144+
t.Errorf("Expected 3 providers for mixed config, got %d", len(providers))
145+
}
146+
147+
// Should have global DNSPod + specific providers
148+
expectedProviders := []string{"DNSPod", "Cloudflare", "DigitalOcean"}
149+
for _, expectedProvider := range expectedProviders {
150+
if _, exists := providers[expectedProvider]; !exists {
151+
t.Errorf("%s provider not found in mixed config", expectedProvider)
152+
}
153+
}
154+
155+
// Test domain resolution with expected mappings
156+
expectedMappings := map[string]string{
157+
"legacy-domain.com": "DNSPod", // Uses global provider
158+
"cloudflare-mixed.com": "Cloudflare", // Uses specific provider
159+
"digitalocean-mixed.com": "DigitalOcean", // Uses specific provider
160+
"another-legacy.net": "DNSPod", // Uses global provider
161+
}
162+
163+
for _, domain := range config.Domains {
164+
expectedProvider := expectedMappings[domain.DomainName]
165+
providerName := config.GetDomainProvider(&domain)
166+
167+
if providerName != expectedProvider {
168+
t.Errorf("Expected %s for domain %s, got %s", expectedProvider, domain.DomainName, providerName)
169+
}
170+
171+
provider, err := GetProviderForDomain(&domain, providers, config)
172+
if err != nil {
173+
t.Errorf("Failed to get provider for domain %s: %v", domain.DomainName, err)
174+
}
175+
if provider == nil {
176+
t.Errorf("Provider is nil for domain %s", domain.DomainName)
177+
}
178+
}
179+
180+
t.Logf("Mixed provider config test passed with %d providers and %d domains", len(providers), len(config.Domains))
181+
})
182+
}
183+
184+
func TestConfigurationModeDetection(t *testing.T) {
185+
testDataDir := filepath.Join("..", "..", "testdata")
186+
187+
testCases := []struct {
188+
name string
189+
configFile string
190+
expectedMode string
191+
expectedMulti bool
192+
}{
193+
{
194+
name: "Single Provider Mode",
195+
configFile: "config_test_single.json",
196+
expectedMode: "single",
197+
expectedMulti: false,
198+
},
199+
{
200+
name: "Multi Provider Mode",
201+
configFile: "config_test_multi.json",
202+
expectedMode: "multi",
203+
expectedMulti: true,
204+
},
205+
{
206+
name: "Mixed Provider Mode",
207+
configFile: "config_test_mixed.json",
208+
expectedMode: "mixed",
209+
expectedMulti: true,
210+
},
211+
}
212+
213+
for _, tc := range testCases {
214+
t.Run(tc.name, func(t *testing.T) {
215+
configPath := filepath.Join(testDataDir, tc.configFile)
216+
config := &settings.Settings{}
217+
218+
err := settings.LoadSettings(configPath, config)
219+
if err != nil {
220+
t.Fatalf("Failed to load config %s: %v", tc.configFile, err)
221+
}
222+
223+
isMulti := config.IsMultiProvider()
224+
if isMulti != tc.expectedMulti {
225+
t.Errorf("Expected IsMultiProvider() to be %v for %s, got %v", tc.expectedMulti, tc.name, isMulti)
226+
}
227+
228+
// Additional checks based on mode
229+
switch tc.expectedMode {
230+
case "single":
231+
if config.Provider == "" {
232+
t.Error("Single provider mode should have Provider field set")
233+
}
234+
if len(config.Providers) > 0 {
235+
t.Error("Single provider mode should not have Providers map")
236+
}
237+
238+
case "multi":
239+
if config.Provider != "" {
240+
t.Error("Pure multi provider mode should not have global Provider field set")
241+
}
242+
if len(config.Providers) == 0 {
243+
t.Error("Multi provider mode should have Providers map")
244+
}
245+
246+
case "mixed":
247+
if config.Provider == "" {
248+
t.Error("Mixed provider mode should have global Provider field set")
249+
}
250+
if len(config.Providers) == 0 {
251+
t.Error("Mixed provider mode should have Providers map")
252+
}
253+
}
254+
255+
t.Logf("%s detected correctly: IsMultiProvider=%v", tc.name, isMulti)
256+
})
257+
}
258+
}
259+
260+
func TestRealWorldScenarios(t *testing.T) {
261+
t.Run("MigrationScenario", func(t *testing.T) {
262+
// Simulate a user migrating from single to mixed to multi provider
263+
264+
// Step 1: Start with single provider
265+
singleConfig := &settings.Settings{
266+
Provider: "DNSPod",
267+
LoginToken: "dnspod-token",
268+
Domains: []settings.Domain{
269+
{DomainName: "example.com", SubDomains: []string{"www"}},
270+
},
271+
}
272+
273+
if err := utils.CheckSettings(singleConfig); err != nil {
274+
t.Fatalf("Single config validation failed: %v", err)
275+
}
276+
277+
providers1, err := GetProviders(singleConfig)
278+
if err != nil {
279+
t.Fatalf("Single config provider creation failed: %v", err)
280+
}
281+
if len(providers1) != 1 {
282+
t.Errorf("Expected 1 provider in single mode, got %d", len(providers1))
283+
}
284+
285+
// Step 2: Add new provider while keeping old (mixed mode)
286+
mixedConfig := &settings.Settings{
287+
Provider: "DNSPod",
288+
LoginToken: "dnspod-token",
289+
Providers: map[string]*settings.ProviderConfig{
290+
"Cloudflare": {
291+
LoginToken: "cf-token",
292+
},
293+
},
294+
Domains: []settings.Domain{
295+
{DomainName: "example.com", SubDomains: []string{"www"}}, // Uses global DNSPod
296+
{DomainName: "newsite.com", SubDomains: []string{"www"}, Provider: "Cloudflare"},
297+
},
298+
}
299+
300+
if err := utils.CheckSettings(mixedConfig); err != nil {
301+
t.Fatalf("Mixed config validation failed: %v", err)
302+
}
303+
304+
providers2, err := GetProviders(mixedConfig)
305+
if err != nil {
306+
t.Fatalf("Mixed config provider creation failed: %v", err)
307+
}
308+
if len(providers2) != 2 {
309+
t.Errorf("Expected 2 providers in mixed mode, got %d", len(providers2))
310+
}
311+
312+
// Step 3: Convert to full multi-provider mode
313+
multiConfig := &settings.Settings{
314+
Providers: map[string]*settings.ProviderConfig{
315+
"DNSPod": {
316+
LoginToken: "dnspod-token",
317+
},
318+
"Cloudflare": {
319+
LoginToken: "cf-token",
320+
},
321+
},
322+
Domains: []settings.Domain{
323+
{DomainName: "example.com", SubDomains: []string{"www"}, Provider: "DNSPod"},
324+
{DomainName: "newsite.com", SubDomains: []string{"www"}, Provider: "Cloudflare"},
325+
},
326+
}
327+
328+
if err := utils.CheckSettings(multiConfig); err != nil {
329+
t.Fatalf("Multi config validation failed: %v", err)
330+
}
331+
332+
providers3, err := GetProviders(multiConfig)
333+
if err != nil {
334+
t.Fatalf("Multi config provider creation failed: %v", err)
335+
}
336+
if len(providers3) != 2 {
337+
t.Errorf("Expected 2 providers in multi mode, got %d", len(providers3))
338+
}
339+
340+
t.Log("Migration scenario test passed: single -> mixed -> multi")
341+
})
342+
343+
t.Run("LargeScaleDeployment", func(t *testing.T) {
344+
// Test a large-scale deployment with many providers and domains
345+
config := &settings.Settings{
346+
Providers: map[string]*settings.ProviderConfig{
347+
"Cloudflare": {LoginToken: "cf-token"},
348+
"DNSPod": {LoginToken: "dnspod-token"},
349+
"DigitalOcean": {LoginToken: "do-token"},
350+
"DuckDNS": {LoginToken: "duck-token"},
351+
"Google": {Email: "[email protected]", Password: "google-pass"},
352+
"AliDNS": {Email: "[email protected]", Password: "ali-pass"},
353+
},
354+
Domains: []settings.Domain{
355+
{DomainName: "site1.com", SubDomains: []string{"www", "api", "mail"}, Provider: "Cloudflare"},
356+
{DomainName: "site2.com", SubDomains: []string{"www", "blog"}, Provider: "DNSPod"},
357+
{DomainName: "site3.org", SubDomains: []string{"www"}, Provider: "DigitalOcean"},
358+
{DomainName: "home.duckdns.org", SubDomains: []string{"myhouse"}, Provider: "DuckDNS"},
359+
{DomainName: "corp.com", SubDomains: []string{"www", "intranet"}, Provider: "Google"},
360+
{DomainName: "china.cn", SubDomains: []string{"www", "api"}, Provider: "AliDNS"},
361+
},
362+
}
363+
364+
if err := utils.CheckSettings(config); err != nil {
365+
t.Fatalf("Large scale config validation failed: %v", err)
366+
}
367+
368+
providers, err := GetProviders(config)
369+
if err != nil {
370+
t.Fatalf("Large scale provider creation failed: %v", err)
371+
}
372+
373+
if len(providers) != 6 {
374+
t.Errorf("Expected 6 providers in large scale deployment, got %d", len(providers))
375+
}
376+
377+
// Test all domains resolve correctly
378+
for _, domain := range config.Domains {
379+
providerName := config.GetDomainProvider(&domain)
380+
if providerName != domain.Provider {
381+
t.Errorf("Domain %s: expected provider %s, got %s", domain.DomainName, domain.Provider, providerName)
382+
}
383+
384+
provider, err := GetProviderForDomain(&domain, providers, config)
385+
if err != nil {
386+
t.Errorf("Failed to get provider for domain %s: %v", domain.DomainName, err)
387+
}
388+
if provider == nil {
389+
t.Errorf("Provider is nil for domain %s", domain.DomainName)
390+
}
391+
}
392+
393+
t.Logf("Large scale deployment test passed with %d providers and %d domains", len(providers), len(config.Domains))
394+
})
395+
}

0 commit comments

Comments
 (0)