Files
cmroubao/backend-api/internal/config/config_test.go
T

182 lines
4.2 KiB
Go

package config
import (
"path/filepath"
"testing"
"time"
)
func TestLoadUsesSafeDefaults(t *testing.T) {
cfg, err := Load(emptyEnvironment)
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if cfg.HTTPAddress != "127.0.0.1:8080" {
t.Fatalf("HTTPAddress = %q", cfg.HTTPAddress)
}
if cfg.DatabasePath != filepath.FromSlash("var/cmroubao.db") {
t.Fatalf("DatabasePath = %q", cfg.DatabasePath)
}
if cfg.AssetDirectory != filepath.FromSlash("var/assets") {
t.Fatalf("AssetDirectory = %q", cfg.AssetDirectory)
}
if cfg.ReadHeaderTimeout <= 0 ||
cfg.ReadTimeout <= 0 ||
cfg.WriteTimeout <= 0 ||
cfg.IdleTimeout <= 0 ||
cfg.ShutdownTimeout <= 0 ||
cfg.MaxHeaderBytes <= 0 {
t.Fatal("server safety limits must all be positive")
}
if cfg.ShutdownTimeout > 30*time.Second {
t.Fatalf("ShutdownTimeout = %s", cfg.ShutdownTimeout)
}
}
func TestLoadAcceptsExplicitConfiguration(t *testing.T) {
values := map[string]string{
HTTPAddressEnvironment: "192.0.2.10:9090",
DatabasePathEnvironment: "tmp/test.db",
AssetDirectoryEnvironment: "tmp/assets",
TLSCertificateEnvironment: "tmp/server.crt",
TLSPrivateKeyEnvironment: "tmp/server.key",
}
cfg, err := Load(mapEnvironment(values))
if err != nil {
t.Fatalf("Load() error = %v", err)
}
if cfg.HTTPAddress != values[HTTPAddressEnvironment] {
t.Fatalf("HTTPAddress = %q", cfg.HTTPAddress)
}
if cfg.DatabasePath != filepath.Clean(values[DatabasePathEnvironment]) {
t.Fatalf("DatabasePath = %q", cfg.DatabasePath)
}
if cfg.AssetDirectory != filepath.Clean(values[AssetDirectoryEnvironment]) {
t.Fatalf("AssetDirectory = %q", cfg.AssetDirectory)
}
if cfg.TLSCertificate != filepath.Clean(values[TLSCertificateEnvironment]) ||
cfg.TLSPrivateKey != filepath.Clean(values[TLSPrivateKeyEnvironment]) {
t.Fatalf(
"TLS files = %q / %q",
cfg.TLSCertificate,
cfg.TLSPrivateKey,
)
}
}
func TestLoadRejectsUnsafeOrInvalidValues(t *testing.T) {
tests := []struct {
name string
values map[string]string
}{
{
name: "blank explicit address",
values: map[string]string{
HTTPAddressEnvironment: " ",
},
},
{
name: "address without host",
values: map[string]string{
HTTPAddressEnvironment: ":8080",
},
},
{
name: "invalid port",
values: map[string]string{
HTTPAddressEnvironment: "127.0.0.1:70000",
},
},
{
name: "memory database",
values: map[string]string{
DatabasePathEnvironment: ":memory:",
},
},
{
name: "database DSN",
values: map[string]string{
DatabasePathEnvironment: "file:test.db?mode=memory",
},
},
{
name: "database directory",
values: map[string]string{
DatabasePathEnvironment: "./",
},
},
{
name: "non SQLite extension",
values: map[string]string{
DatabasePathEnvironment: "var/database.txt",
},
},
{
name: "asset root directory",
values: map[string]string{
AssetDirectoryEnvironment: string(filepath.Separator),
},
},
{
name: "asset current directory",
values: map[string]string{
AssetDirectoryEnvironment: ".",
},
},
{
name: "non loopback without TLS",
values: map[string]string{
HTTPAddressEnvironment: "0.0.0.0:8080",
},
},
{
name: "TLS certificate without key",
values: map[string]string{
TLSCertificateEnvironment: "tmp/server.crt",
},
},
{
name: "blank TLS key",
values: map[string]string{
TLSCertificateEnvironment: "tmp/server.crt",
TLSPrivateKeyEnvironment: " ",
},
},
}
for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
if _, err := Load(mapEnvironment(test.values)); err == nil {
t.Fatal("Load() error = nil")
}
})
}
}
func TestLoadDatabasePathIgnoresHTTPConfiguration(t *testing.T) {
path, err := LoadDatabasePath(mapEnvironment(map[string]string{
HTTPAddressEnvironment: "invalid",
DatabasePathEnvironment: "tmp/migration.sqlite",
}))
if err != nil {
t.Fatalf("LoadDatabasePath() error = %v", err)
}
if path != filepath.Clean("tmp/migration.sqlite") {
t.Fatalf("path = %q", path)
}
}
func emptyEnvironment(string) (string, bool) {
return "", false
}
func mapEnvironment(values map[string]string) LookupEnvironment {
return func(name string) (string, bool) {
value, exists := values[name]
return value, exists
}
}