mirror of
https://github.com/DeBrosOfficial/orama.git
synced 2026-03-17 13:56:57 +00:00
406 lines
9.9 KiB
Go
406 lines
9.9 KiB
Go
package gateway
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestValidateListenAddr(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
addr string
|
|
wantErr bool
|
|
errSubstr string
|
|
}{
|
|
{"valid :8080", ":8080", false, ""},
|
|
{"valid 0.0.0.0:443", "0.0.0.0:443", false, ""},
|
|
{"valid 127.0.0.1:6001", "127.0.0.1:6001", false, ""},
|
|
{"valid :80", ":80", false, ""},
|
|
{"valid high port", ":65535", false, ""},
|
|
{"invalid no colon", "8080", true, "invalid format"},
|
|
{"invalid port zero", ":0", true, "port must be a number"},
|
|
{"invalid port too high", ":99999", true, "port must be a number"},
|
|
{"invalid non-numeric port", ":abc", true, "port must be a number"},
|
|
{"empty string", "", true, "invalid format"},
|
|
{"invalid negative port", ":-1", true, "port must be a number"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validateListenAddr(tt.addr)
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Errorf("validateListenAddr(%q) = nil, want error containing %q", tt.addr, tt.errSubstr)
|
|
} else if tt.errSubstr != "" && !strings.Contains(err.Error(), tt.errSubstr) {
|
|
t.Errorf("validateListenAddr(%q) error = %q, want error containing %q", tt.addr, err.Error(), tt.errSubstr)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("validateListenAddr(%q) = %v, want nil", tt.addr, err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateRQLiteDSN(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
dsn string
|
|
wantErr bool
|
|
errSubstr string
|
|
}{
|
|
{"valid http localhost", "http://localhost:4001", false, ""},
|
|
{"valid https", "https://db.example.com", false, ""},
|
|
{"valid http with path", "http://192.168.1.1:4001/db", false, ""},
|
|
{"valid https with port", "https://db.example.com:4001", false, ""},
|
|
{"invalid scheme ftp", "ftp://localhost", true, "scheme must be http or https"},
|
|
{"invalid scheme tcp", "tcp://localhost:4001", true, "scheme must be http or https"},
|
|
{"missing host", "http://", true, "host must not be empty"},
|
|
{"no scheme", "localhost:4001", true, "scheme must be http or https"},
|
|
{"empty string", "", true, "scheme must be http or https"},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
err := validateRQLiteDSN(tt.dsn)
|
|
if tt.wantErr {
|
|
if err == nil {
|
|
t.Errorf("validateRQLiteDSN(%q) = nil, want error containing %q", tt.dsn, tt.errSubstr)
|
|
} else if tt.errSubstr != "" && !strings.Contains(err.Error(), tt.errSubstr) {
|
|
t.Errorf("validateRQLiteDSN(%q) error = %q, want error containing %q", tt.dsn, err.Error(), tt.errSubstr)
|
|
}
|
|
} else {
|
|
if err != nil {
|
|
t.Errorf("validateRQLiteDSN(%q) = %v, want nil", tt.dsn, err)
|
|
}
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIsValidDomainName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
domain string
|
|
want bool
|
|
}{
|
|
{"valid example.com", "example.com", true},
|
|
{"valid sub.domain.co.uk", "sub.domain.co.uk", true},
|
|
{"valid with numbers", "host123.example.com", true},
|
|
{"valid with hyphen", "my-host.example.com", true},
|
|
{"valid uppercase", "Example.COM", true},
|
|
{"invalid starts with hyphen", "-example.com", false},
|
|
{"invalid ends with hyphen", "example.com-", false},
|
|
{"invalid starts with dot", ".example.com", false},
|
|
{"invalid ends with dot", "example.com.", false},
|
|
{"invalid special chars", "exam!ple.com", false},
|
|
{"invalid underscore", "my_host.example.com", false},
|
|
{"invalid space", "example .com", false},
|
|
{"empty string", "", false},
|
|
{"no dot", "localhost", false},
|
|
{"single char domain", "a.b", true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := isValidDomainName(tt.domain)
|
|
if got != tt.want {
|
|
t.Errorf("isValidDomainName(%q) = %v, want %v", tt.domain, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractTCPPort_Gateway(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
multiaddr string
|
|
want string
|
|
}{
|
|
{
|
|
"standard multiaddr",
|
|
"/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWExample",
|
|
"4001",
|
|
},
|
|
{
|
|
"no tcp component",
|
|
"/ip4/127.0.0.1/udp/4001",
|
|
"",
|
|
},
|
|
{
|
|
"multiple tcp segments uses last",
|
|
"/ip4/127.0.0.1/tcp/4001/tcp/5001/p2p/12D3KooWExample",
|
|
"5001",
|
|
},
|
|
{
|
|
"tcp port at end",
|
|
"/ip4/0.0.0.0/tcp/8080",
|
|
"8080",
|
|
},
|
|
{
|
|
"empty string",
|
|
"",
|
|
"",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := extractTCPPort(tt.multiaddr)
|
|
if got != tt.want {
|
|
t.Errorf("extractTCPPort(%q) = %q, want %q", tt.multiaddr, got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_Empty(t *testing.T) {
|
|
cfg := &Config{}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
if len(errs) == 0 {
|
|
t.Fatal("empty config should produce validation errors")
|
|
}
|
|
|
|
// Should have errors for listen_addr and client_namespace at minimum
|
|
var foundListenAddr, foundClientNamespace bool
|
|
for _, err := range errs {
|
|
msg := err.Error()
|
|
if strings.Contains(msg, "listen_addr") {
|
|
foundListenAddr = true
|
|
}
|
|
if strings.Contains(msg, "client_namespace") {
|
|
foundClientNamespace = true
|
|
}
|
|
}
|
|
|
|
if !foundListenAddr {
|
|
t.Error("expected validation error for listen_addr, got none")
|
|
}
|
|
if !foundClientNamespace {
|
|
t.Error("expected validation error for client_namespace, got none")
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_ValidMinimal(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":8080",
|
|
ClientNamespace: "default",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
if len(errs) > 0 {
|
|
t.Errorf("valid minimal config should not produce errors, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_DuplicateBootstrapPeers(t *testing.T) {
|
|
peer := "/ip4/127.0.0.1/tcp/4001/p2p/12D3KooWHbcFcrGPXKUrHcxvd8MXEeUzRYyvY8fQcpEBxncSUwhj"
|
|
cfg := &Config{
|
|
ListenAddr: ":8080",
|
|
ClientNamespace: "default",
|
|
BootstrapPeers: []string{peer, peer},
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
var foundDuplicate bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "duplicate") {
|
|
foundDuplicate = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundDuplicate {
|
|
t.Error("expected duplicate bootstrap peer error, got none")
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_InvalidMultiaddr(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":8080",
|
|
ClientNamespace: "default",
|
|
BootstrapPeers: []string{"not-a-multiaddr"},
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
if len(errs) == 0 {
|
|
t.Fatal("invalid multiaddr should produce validation error")
|
|
}
|
|
|
|
var foundInvalid bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "invalid multiaddr") {
|
|
foundInvalid = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundInvalid {
|
|
t.Errorf("expected 'invalid multiaddr' error, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_MissingP2PComponent(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":8080",
|
|
ClientNamespace: "default",
|
|
BootstrapPeers: []string{"/ip4/127.0.0.1/tcp/4001"},
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
var foundMissingP2P bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "missing /p2p/") {
|
|
foundMissingP2P = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundMissingP2P {
|
|
t.Errorf("expected 'missing /p2p/' error, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_InvalidListenAddr(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: "not-valid",
|
|
ClientNamespace: "default",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
if len(errs) == 0 {
|
|
t.Fatal("invalid listen_addr should produce validation error")
|
|
}
|
|
|
|
var foundListenAddr bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "listen_addr") {
|
|
foundListenAddr = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundListenAddr {
|
|
t.Errorf("expected listen_addr error, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_InvalidRQLiteDSN(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":8080",
|
|
ClientNamespace: "default",
|
|
RQLiteDSN: "ftp://invalid",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
var foundDSN bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "rqlite_dsn") {
|
|
foundDSN = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundDSN {
|
|
t.Errorf("expected rqlite_dsn error, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_HTTPSWithoutDomain(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":443",
|
|
ClientNamespace: "default",
|
|
EnableHTTPS: true,
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
var foundDomain bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "domain_name") {
|
|
foundDomain = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundDomain {
|
|
t.Errorf("expected domain_name error when HTTPS enabled without domain, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_HTTPSWithInvalidDomain(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":443",
|
|
ClientNamespace: "default",
|
|
EnableHTTPS: true,
|
|
DomainName: "-invalid",
|
|
TLSCacheDir: "/tmp/tls",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
var foundDomain bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "domain_name") && strings.Contains(err.Error(), "invalid domain") {
|
|
foundDomain = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundDomain {
|
|
t.Errorf("expected invalid domain_name error, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_HTTPSWithoutTLSCacheDir(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":443",
|
|
ClientNamespace: "default",
|
|
EnableHTTPS: true,
|
|
DomainName: "example.com",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
var foundTLS bool
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "tls_cache_dir") {
|
|
foundTLS = true
|
|
break
|
|
}
|
|
}
|
|
|
|
if !foundTLS {
|
|
t.Errorf("expected tls_cache_dir error when HTTPS enabled without TLS cache dir, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_ValidHTTPS(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":443",
|
|
ClientNamespace: "default",
|
|
EnableHTTPS: true,
|
|
DomainName: "example.com",
|
|
TLSCacheDir: "/tmp/tls",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
if len(errs) > 0 {
|
|
t.Errorf("valid HTTPS config should not produce errors, got: %v", errs)
|
|
}
|
|
}
|
|
|
|
func TestValidateConfig_EmptyRQLiteDSNSkipped(t *testing.T) {
|
|
cfg := &Config{
|
|
ListenAddr: ":8080",
|
|
ClientNamespace: "default",
|
|
RQLiteDSN: "",
|
|
}
|
|
errs := cfg.ValidateConfig()
|
|
|
|
for _, err := range errs {
|
|
if strings.Contains(err.Error(), "rqlite_dsn") {
|
|
t.Errorf("empty rqlite_dsn should not produce error, got: %v", err)
|
|
}
|
|
}
|
|
}
|