- Add end-to-end tests for complete workflow validation - Include integration tests for API and database interactions - Add unit tests for all major components and utilities - Include performance tests for payload handling - Add CLI API integration tests - Include Podman container integration tests - Add WebSocket and queue execution tests - Include shell script tests for setup validation Provides comprehensive test coverage ensuring platform reliability and functionality across all components and interactions.
212 lines
5.5 KiB
Go
212 lines
5.5 KiB
Go
package config
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
|
|
"github.com/jfraeys/fetch_ml/internal/config"
|
|
)
|
|
|
|
// MockValidator implements the Validator interface for testing
|
|
type MockValidator struct {
|
|
shouldFail bool
|
|
errorMsg string
|
|
}
|
|
|
|
func (m *MockValidator) Validate() error {
|
|
if m.shouldFail {
|
|
return fmt.Errorf("validation error: %s", m.errorMsg)
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func TestValidateConfig(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test with valid validator
|
|
validValidator := &MockValidator{shouldFail: false}
|
|
err := config.ValidateConfig(validValidator)
|
|
if err != nil {
|
|
t.Errorf("Expected no error for valid validator, got %v", err)
|
|
}
|
|
|
|
// Test with invalid validator
|
|
invalidValidator := &MockValidator{shouldFail: true, errorMsg: "validation failed"}
|
|
err = config.ValidateConfig(invalidValidator)
|
|
if err == nil {
|
|
t.Error("Expected error for invalid validator")
|
|
}
|
|
if err.Error() != "validation error: validation failed" {
|
|
t.Errorf("Expected error message 'validation error: validation failed', got %s", err.Error())
|
|
}
|
|
}
|
|
|
|
func TestValidatePort(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test valid ports
|
|
validPorts := []int{1, 22, 80, 443, 6379, 65535}
|
|
for _, port := range validPorts {
|
|
err := config.ValidatePort(port)
|
|
if err != nil {
|
|
t.Errorf("Expected no error for valid port %d, got %v", port, err)
|
|
}
|
|
}
|
|
|
|
// Test invalid ports
|
|
invalidPorts := []int{0, -1, 65536, 100000}
|
|
for _, port := range invalidPorts {
|
|
err := config.ValidatePort(port)
|
|
if err == nil {
|
|
t.Errorf("Expected error for invalid port %d", port)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateDirectory(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test empty path
|
|
err := config.ValidateDirectory("")
|
|
if err == nil {
|
|
t.Error("Expected error for empty path")
|
|
}
|
|
|
|
// Test non-existent directory
|
|
err = config.ValidateDirectory("/nonexistent/directory")
|
|
if err == nil {
|
|
t.Error("Expected error for non-existent directory")
|
|
}
|
|
|
|
// Test existing directory
|
|
tempDir := t.TempDir()
|
|
err = config.ValidateDirectory(tempDir)
|
|
if err != nil {
|
|
t.Errorf("Expected no error for existing directory %s, got %v", tempDir, err)
|
|
}
|
|
|
|
// Test file instead of directory
|
|
tempFile := filepath.Join(tempDir, "test_file")
|
|
err = os.WriteFile(tempFile, []byte("test"), 0644)
|
|
if err != nil {
|
|
t.Fatalf("Failed to create test file: %v", err)
|
|
}
|
|
|
|
err = config.ValidateDirectory(tempFile)
|
|
if err == nil {
|
|
t.Error("Expected error for file path")
|
|
}
|
|
|
|
// Test directory with environment variable expansion
|
|
os.Setenv("TEST_DIR", tempDir)
|
|
defer os.Unsetenv("TEST_DIR")
|
|
|
|
err = config.ValidateDirectory("$TEST_DIR")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for expanded directory path, got %v", err)
|
|
}
|
|
|
|
// Test directory with tilde expansion (if home directory is available)
|
|
home, err := os.UserHomeDir()
|
|
if err == nil {
|
|
// Create a test directory in home
|
|
testHomeDir := filepath.Join(home, "test_fetch_ml")
|
|
err = os.MkdirAll(testHomeDir, 0755)
|
|
if err == nil {
|
|
defer os.RemoveAll(testHomeDir)
|
|
|
|
err = config.ValidateDirectory("~/test_fetch_ml")
|
|
if err != nil {
|
|
t.Errorf("Expected no error for tilde expanded path, got %v", err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateRedisAddr(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test valid Redis addresses
|
|
validAddrs := []string{
|
|
"localhost:6379",
|
|
"127.0.0.1:6379",
|
|
"redis.example.com:6379",
|
|
"10.0.0.1:6380",
|
|
"[::1]:6379", // IPv6
|
|
}
|
|
|
|
for _, addr := range validAddrs {
|
|
err := config.ValidateRedisAddr(addr)
|
|
if err != nil {
|
|
t.Errorf("Expected no error for valid Redis address %s, got %v", addr, err)
|
|
}
|
|
}
|
|
|
|
// Test invalid Redis addresses
|
|
invalidAddrs := []string{
|
|
"", // empty
|
|
"localhost", // missing port
|
|
":6379", // missing host
|
|
"localhost:", // missing port number
|
|
"localhost:abc", // non-numeric port
|
|
"localhost:-1", // negative port
|
|
"localhost:0", // port too low
|
|
"localhost:65536", // port too high
|
|
"localhost:999999", // port way too high
|
|
"multiple:colons:6379", // too many colons
|
|
}
|
|
|
|
for _, addr := range invalidAddrs {
|
|
err := config.ValidateRedisAddr(addr)
|
|
if err == nil {
|
|
t.Errorf("Expected error for invalid Redis address %s", addr)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidateRedisAddrEdgeCases(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test edge case ports
|
|
edgeCases := []struct {
|
|
addr string
|
|
shouldErr bool
|
|
}{
|
|
{"localhost:1", false}, // minimum valid port
|
|
{"localhost:65535", false}, // maximum valid port
|
|
{"localhost:0", true}, // below minimum
|
|
{"localhost:65536", true}, // above maximum
|
|
}
|
|
|
|
for _, tc := range edgeCases {
|
|
err := config.ValidateRedisAddr(tc.addr)
|
|
if tc.shouldErr && err == nil {
|
|
t.Errorf("Expected error for Redis address %s", tc.addr)
|
|
}
|
|
if !tc.shouldErr && err != nil {
|
|
t.Errorf("Expected no error for Redis address %s, got %v", tc.addr, err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestValidatorInterface(t *testing.T) {
|
|
t.Parallel() // Enable parallel execution
|
|
|
|
// Test that our mock properly implements the interface
|
|
var _ config.Validator = &MockValidator{}
|
|
|
|
// Test that the interface works as expected
|
|
validator := &MockValidator{shouldFail: false}
|
|
err := validator.Validate()
|
|
if err != nil {
|
|
t.Errorf("MockValidator should not fail when shouldFail is false")
|
|
}
|
|
|
|
validator = &MockValidator{shouldFail: true, errorMsg: "test error"}
|
|
err = validator.Validate()
|
|
if err == nil {
|
|
t.Error("MockValidator should fail when shouldFail is true")
|
|
}
|
|
}
|