package transport import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestCalculateExchangeCost_ResourceExchange(t *testing.T) { tests := []struct { name string params ExchangeParams expected ExchangeCost hasError bool }{ { name: "waste-to-resource exchange", params: ExchangeParams{ DistanceKm: 5.0, Value: 100000, // €100k annual value Volume: 1000, // 1000 units SymbiosisType: SymbiosisWasteToResource, Complexity: "medium", RiskLevel: "medium", OperatingHours: 8000, }, expected: ExchangeCost{ CapitalCost: 65325, // €50,250 × 1.3 complexity = €65,325 AnnualOpexCost: 130, // €100 × 1.3 complexity = €130 PlatformFee: 5000, // €100k × 5% RegulatoryCost: 3000, // €100k × 3% RiskMitigationCost: 2500, // €100k × 2.5% TotalAnnualCost: 7449, // (€100 + €2,500 + €3,000) × 1.3 = €7,449 CostPerUnit: 7.449, // Total annual / volume Feasibility: "medium", }, hasError: false, }, { name: "digital data sharing (low cost)", params: ExchangeParams{ DistanceKm: 0.0, // Digital - no distance Value: 50000, Volume: 1000, SymbiosisType: SymbiosisDataSharing, Complexity: "low", RiskLevel: "low", OperatingHours: 8000, }, expected: ExchangeCost{ CapitalCost: 5000, // €5k base × 1.0 (low complexity) AnnualOpexCost: 2000, // €50k × 4% = €2k × 1.0 PlatformFee: 2500, // €50k × 5% RegulatoryCost: 25, // €50k × 0.05% RiskMitigationCost: 500, // €50k × 1% TotalAnnualCost: 3025, // (€2,000 + €500 + €25) × 1.0 = €3,025 CostPerUnit: 3.025, // Total annual / volume Feasibility: "high", }, hasError: false, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { result, err := CalculateExchangeCost(tt.params) if tt.hasError { assert.Error(t, err) return } require.NoError(t, err) assert.Equal(t, tt.expected.Feasibility, result.Feasibility) // Allow some tolerance for cost calculations assert.InDelta(t, tt.expected.CapitalCost, result.CapitalCost, tt.expected.CapitalCost*0.1) assert.InDelta(t, tt.expected.PlatformFee, result.PlatformFee, 100) }) } } func TestCalculateExchangeCost_InvalidParams(t *testing.T) { tests := []struct { name string params ExchangeParams hasError bool }{ { name: "negative value", params: ExchangeParams{ Value: -1000, SymbiosisType: SymbiosisDataSharing, }, hasError: true, }, { name: "empty symbiosis type", params: ExchangeParams{ Value: 10000, }, hasError: true, }, { name: "unsupported symbiosis type", params: ExchangeParams{ Value: 10000, SymbiosisType: SymbiosisType("unsupported"), }, hasError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { _, err := CalculateExchangeCost(tt.params) if tt.hasError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } func TestValidateExchangeParams(t *testing.T) { tests := []struct { name string params ExchangeParams hasError bool }{ { name: "valid parameters", params: ExchangeParams{ Value: 10000, Volume: 100, DistanceKm: 5.0, SymbiosisType: SymbiosisDataSharing, }, hasError: false, }, { name: "negative value", params: ExchangeParams{ Value: -1000, SymbiosisType: SymbiosisDataSharing, }, hasError: true, }, { name: "negative volume", params: ExchangeParams{ Value: 10000, Volume: -100, SymbiosisType: SymbiosisDataSharing, }, hasError: true, }, { name: "empty symbiosis type", params: ExchangeParams{ Value: 10000, }, hasError: true, }, } for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { err := ValidateExchangeParams(tt.params) if tt.hasError { assert.Error(t, err) } else { assert.NoError(t, err) } }) } } func TestGetComplexityMultiplier(t *testing.T) { tests := []struct { complexity string expected float64 }{ {"low", 1.0}, {"medium", 1.3}, {"high", 1.8}, {"unknown", 1.3}, // defaults to medium } for _, tt := range tests { result := getComplexityMultiplier(tt.complexity) assert.Equal(t, tt.expected, result) } } func TestCalculateRiskMitigationCost(t *testing.T) { tests := []struct { value float64 riskLevel string expected float64 }{ {100000, "low", 1000}, // 1% of €100k {100000, "medium", 2500}, // 2.5% of €100k {100000, "high", 5000}, // 5% of €100k } for _, tt := range tests { result := calculateRiskMitigationCost(tt.value, tt.riskLevel) assert.Equal(t, tt.expected, result) } } func TestCalculateRegulatoryCost(t *testing.T) { tests := []struct { symbiosisType SymbiosisType value float64 expected float64 }{ {SymbiosisWasteToResource, 100000, 3000}, // 3% for waste handling {SymbiosisDataSharing, 100000, 50}, // 0.05% for data sharing {SymbiosisKnowledgeSharing, 100000, 1000}, // 1% for knowledge sharing } for _, tt := range tests { result := calculateRegulatoryCost(tt.symbiosisType, tt.value) assert.Equal(t, tt.expected, result) } } func TestAssessExchangeFeasibility(t *testing.T) { tests := []struct { params ExchangeParams expected string }{ { params: ExchangeParams{ DistanceKm: 1.0, Complexity: "low", RiskLevel: "low", SymbiosisType: SymbiosisDataSharing, }, expected: "high", }, { params: ExchangeParams{ DistanceKm: 10.0, Complexity: "medium", RiskLevel: "medium", SymbiosisType: SymbiosisWasteToResource, }, expected: "medium", }, { params: ExchangeParams{ DistanceKm: 50.0, Complexity: "high", RiskLevel: "high", SymbiosisType: SymbiosisWasteToResource, }, expected: "low", }, } for _, tt := range tests { result := assessExchangeFeasibility(tt.params) assert.Equal(t, tt.expected, result) } }