package v1 import ( "bytes" "encoding/json" "net/http" "net/http/httptest" "os" "path/filepath" "testing" "github.com/wild-cloud/wild-central/internal/config" "github.com/wild-cloud/wild-central/internal/storage" "gopkg.in/yaml.v3" ) func setupTestDnsmasq(t *testing.T) (*API, string) { tmpDir := t.TempDir() dnsmasqConfigPath := filepath.Join(tmpDir, "dnsmasq.conf") t.Setenv("WILD_CENTRAL_DNSMASQ_CONFIG_PATH", dnsmasqConfigPath) api, err := NewAPI(tmpDir, "", nil) if err != nil { t.Fatalf("Failed to create test API: %v", err) } return api, tmpDir } func TestDnsmasqGenerate(t *testing.T) { api, tmpDir := setupTestDnsmasq(t) globalConfig := config.State{} globalConfig.Cloud.Central.Domain = "central.example.com" configPath := filepath.Join(tmpDir, "state.yaml") configData, _ := yaml.Marshal(globalConfig) if err := storage.WriteFile(configPath, configData, 0644); err != nil { t.Fatal(err) } req := httptest.NewRequest("POST", "/api/v1/dnsmasq/generate", nil) w := httptest.NewRecorder() api.DnsmasqGenerate(w, req) if w.Code != http.StatusOK { t.Fatalf("Expected status 200, got %d: %s", w.Code, w.Body.String()) } var resp map[string]any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("failed to unmarshal response: %v", err) } if cfg, ok := resp["config"].(string); !ok || cfg == "" { t.Fatal("Expected generated config in response") } } func TestDnsmasqWriteConfig(t *testing.T) { api, _ := setupTestDnsmasq(t) customConfig := `# Custom dnsmasq config interface=wlan0 listen-address=192.168.2.1 ` reqBody := map[string]string{ "content": customConfig, } reqData, _ := json.Marshal(reqBody) req := httptest.NewRequest("PUT", "/api/v1/dnsmasq/config", bytes.NewBuffer(reqData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() api.DnsmasqWriteConfig(w, req) if w.Code != http.StatusOK { t.Fatalf("Expected status 200, got %d: %s", w.Code, w.Body.String()) } configPath := api.dnsmasq.GetConfigPath() content, err := os.ReadFile(configPath) if err != nil { t.Fatalf("Failed to read written config: %v", err) } if string(content) != customConfig { t.Fatalf("Config content mismatch.\nExpected:\n%s\nGot:\n%s", customConfig, string(content)) } } func TestDnsmasqWriteConfig_EmptyContent(t *testing.T) { api, _ := setupTestDnsmasq(t) reqBody := map[string]string{ "content": "", } reqData, _ := json.Marshal(reqBody) req := httptest.NewRequest("PUT", "/api/v1/dnsmasq/config", bytes.NewBuffer(reqData)) req.Header.Set("Content-Type", "application/json") w := httptest.NewRecorder() api.DnsmasqWriteConfig(w, req) if w.Code != http.StatusBadRequest { t.Fatalf("Expected status 400, got %d", w.Code) } } func TestDnsmasqGetConfig(t *testing.T) { api, _ := setupTestDnsmasq(t) configPath := api.dnsmasq.GetConfigPath() testConfig := "# Test config\ninterface=eth0\n" if err := os.MkdirAll(filepath.Dir(configPath), 0755); err != nil { t.Fatal(err) } if err := os.WriteFile(configPath, []byte(testConfig), 0644); err != nil { t.Fatal(err) } req := httptest.NewRequest("GET", "/api/v1/dnsmasq/config", nil) w := httptest.NewRecorder() api.DnsmasqGetConfig(w, req) if w.Code != http.StatusOK { t.Fatalf("Expected status 200, got %d: %s", w.Code, w.Body.String()) } var resp map[string]any if err := json.Unmarshal(w.Body.Bytes(), &resp); err != nil { t.Fatalf("failed to unmarshal response: %v", err) } content, ok := resp["content"].(string) if !ok || content != testConfig { t.Fatalf("Expected config content: %s, got: %s", testConfig, content) } }