package mcp import ( "os" "path/filepath" "testing" ) func TestLoadEnvFile(t *testing.T) { tests := []struct { name string content string expected map[string]string expectErr bool }{ { name: "basic env file", content: `API_KEY=secret123 DATABASE_URL=postgres://localhost/db PORT=8080`, expected: map[string]string{ "API_KEY": "secret123", "DATABASE_URL": "postgres://localhost/db", "PORT": "8080", }, expectErr: false, }, { name: "with comments and empty lines", content: `# This is a comment API_KEY=secret123 # Another comment DATABASE_URL=postgres://localhost/db PORT=8080`, expected: map[string]string{ "API_KEY": "secret123", "DATABASE_URL": "postgres://localhost/db", "PORT": "8080", }, expectErr: false, }, { name: "with quoted values", content: `API_KEY="secret with spaces" NAME='single quoted' PLAIN=no-quotes`, expected: map[string]string{ "API_KEY": "secret with spaces", "NAME": "single quoted", "PLAIN": "no-quotes", }, expectErr: false, }, { name: "with spaces around equals", content: `API_KEY = secret123 DATABASE_URL= postgres://localhost/db PORT =8080`, expected: map[string]string{ "API_KEY": "secret123", "DATABASE_URL": "postgres://localhost/db", "PORT": "8080", }, expectErr: false, }, { name: "invalid format - no equals", content: `INVALID_LINE`, expectErr: true, }, { name: "empty file", content: ``, expected: map[string]string{}, expectErr: false, }, { name: "only comments", content: `# Comment 1 # Comment 2`, expected: map[string]string{}, expectErr: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { tmpDir := t.TempDir() envFile := filepath.Join(tmpDir, ".env") if err := os.WriteFile(envFile, []byte(tt.content), 0644); err != nil { t.Fatalf("Failed to create test file: %v", err) } result, err := loadEnvFile(envFile) if tt.expectErr { if err == nil { t.Errorf("Expected error but got none") } return } if err != nil { t.Errorf("Unexpected error: %v", err) return } if len(result) != len(tt.expected) { t.Errorf("Expected %d variables, got %d", len(tt.expected), len(result)) } for key, expectedValue := range tt.expected { if actualValue, ok := result[key]; !ok { t.Errorf("Expected key %s not found", key) } else if actualValue != expectedValue { t.Errorf("For key %s: expected %q, got %q", key, expectedValue, actualValue) } } }) } } func TestLoadEnvFileNotFound(t *testing.T) { _, err := loadEnvFile("/nonexistent/file.env") if err == nil { t.Error("Expected error for nonexistent file") } } func TestEnvFilePriority(t *testing.T) { // Create a temporary .env file tmpDir := t.TempDir() envFile := filepath.Join(tmpDir, ".env") envContent := `API_KEY=from_file DATABASE_URL=from_file SHARED_VAR=from_file` if err := os.WriteFile(envFile, []byte(envContent), 0644); err != nil { t.Fatalf("Failed to create .env file: %v", err) } // Load envFile envVars, err := loadEnvFile(envFile) if err != nil { t.Fatalf("Failed to load env file: %v", err) } // Verify envFile variables if envVars["API_KEY"] != "from_file" { t.Errorf("Expected API_KEY=from_file, got %s", envVars["API_KEY"]) } // Simulate config.Env overriding envFile configEnv := map[string]string{ "SHARED_VAR": "from_config", "NEW_VAR": "from_config", } // Merge: envFile first, then config overrides merged := make(map[string]string) for k, v := range envVars { merged[k] = v } for k, v := range configEnv { merged[k] = v } // Verify priority: config.Env should override envFile if merged["SHARED_VAR"] != "from_config" { t.Errorf("Expected SHARED_VAR=from_config (config should override file), got %s", merged["SHARED_VAR"]) } if merged["API_KEY"] != "from_file" { t.Errorf("Expected API_KEY=from_file, got %s", merged["API_KEY"]) } if merged["NEW_VAR"] != "from_config" { t.Errorf("Expected NEW_VAR=from_config, got %s", merged["NEW_VAR"]) } }