edge-connect-client/internal/adapters/driving/cli/app_test.go
Stephan Lo 8e2e61d61e feat: implement dependency injection with proper hexagonal architecture
 Features:
- Simple dependency inversion following SOLID principles
- Clean constructor injection without complex DI containers
- Proper hexagonal architecture with driving/driven separation
- Presentation layer moved to cmd/cli for correct application structure

🏗️ Architecture Changes:
- Driving Adapters (Inbound): internal/adapters/driving/cli/
- Driven Adapters (Outbound): internal/adapters/driven/edgeconnect/
- Core Services: Dependency-injected via interface parameters
- main.go relocated from root to cmd/cli/main.go

📦 Application Flow:
1. cmd/cli/main.go - Entry point and dependency wiring
   └── Creates EdgeConnect client based on environment
   └── Instantiates services with injected repositories
   └── Executes CLI with properly wired dependencies

2. internal/adapters/driving/cli/ - User interface layer
   └── Receives user commands and input validation
   └── Delegates to core services via driving ports
   └── Handles presentation logic and output formatting

3. internal/core/services/ - Business logic layer
   └── NewAppService(appRepo, instanceRepo) - Constructor injection
   └── NewAppInstanceService(instanceRepo) - Interface dependencies
   └── NewCloudletService(cloudletRepo) - Clean separation

4. internal/adapters/driven/edgeconnect/ - Infrastructure layer
   └── Implements repository interfaces for external API
   └── Handles HTTP communication and data persistence
   └── Provides concrete implementations of driven ports

🔧 Build & Deployment:
- CLI Binary: make build → bin/edge-connect-cli
- Usage: ./bin/edge-connect-cli --help
- Tests: make test (all passing)
- Clean: make clean (updated paths)

💡 Benefits:
- Simple and maintainable dependency management
- Testable architecture with clear boundaries
- SOLID principles compliance without overengineering
- Proper separation of concerns in hexagonal structure
2025-10-08 18:15:26 +02:00

100 lines
1.9 KiB
Go

package cli
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestValidateBaseURL(t *testing.T) {
tests := []struct {
name string
input string
expectError bool
}{
{
name: "valid URL",
input: "https://hub.edge.de",
expectError: false,
},
{
name: "valid URL with slash",
input: "https://hub.edge.de/",
expectError: false,
},
{
name: "no schema",
input: "hub.edge.de",
expectError: true,
},
{
name: "user set",
input: "https://user@hub.edge.de",
expectError: true,
},
{
name: "user and password set",
input: "https://user:password@hub.edge.de/",
expectError: true,
},
{
name: "contains path and query",
input: "http://hub.edge.de/index.html?a=b",
expectError: true,
},
{
name: "contains query",
input: "http://hub.edge.de/?a=b",
expectError: true,
},
{
name: "contains path and fragment",
input: "http://hub.edge.de/index.html#abc",
expectError: true,
},
{
name: "contains fragment",
input: "http://hub.edge.de/#abc",
expectError: true,
},
{
name: "contains path, query and fragment",
input: "http://hub.edge.de/index.html?a=b#abc",
expectError: true,
},
{
name: "contains query and fragment",
input: "http://hub.edge.de/?a=b#abc",
expectError: true,
},
{
name: "contains path, fragment and query",
input: "http://hub.edge.de/index.html#abc?a=b",
expectError: true,
},
{
name: "contains fragment and query",
input: "http://hub.edge.de/#abc?a=b",
expectError: true,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := validateBaseURL(tt.input)
// Verify results
if tt.expectError {
assert.Error(t, err)
} else {
assert.NoError(t, err)
}
})
}
}