Files
whatismyip/internal/setting/app_test.go
T
dcarrillo 2e32a20f60 refactor: dependency injection instead of package globals (#57)
* refactor: export Settings type, Setup returns value

* refactor: resolver.Setup takes explicit Settings struct

* refactor: GetHeadersWithoutTrustedHeaders takes explicit header params

* refactor: server constructors take narrow config

* refactor: Router struct with handler methods, remove geoSvc global

* refactor: wire DI through main, remove setting.App references

* refactor: remove App global, use returned Settings

* refactor: update router tests for DI

* chore: fix lint issues — rename ServerTimeouts to Timeouts, fix shadowed variables
2026-07-21 18:37:21 +02:00

218 lines
4.3 KiB
Go

package setting
import (
"flag"
"reflect"
"strings"
"testing"
"time"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
func TestParseMandatoryFlags(t *testing.T) {
mandatoryFlags := []struct {
args []string
}{
{
[]string{
"-geoip2-city", "my-city-path",
},
},
{
[]string{
"-geoip2-asn", "my-asn-path",
},
},
{
[]string{
"-tls-bind", ":9000",
},
},
{
[]string{
"-tls-bind", ":9000", "-tls-crt", "/crt-path",
},
},
{
[]string{
"-tls-bind", ":9000", "-tls-key", "/key-path",
},
},
{
[]string{
"-enable-http3",
},
},
{
[]string{
"-bind", ":8000", "-trusted-port-header", "port-header",
},
},
}
for _, tt := range mandatoryFlags {
t.Run(strings.Join(tt.args, " "), func(t *testing.T) {
_, _, err := Setup(tt.args)
require.Error(t, err)
assert.Contains(t, err.Error(), "mandatory")
})
}
}
func TestParseFlags(t *testing.T) {
flags := []struct {
args []string
conf Settings
}{
{
[]string{},
Settings{
BindAddress: ":8080",
Server: serverSettings{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
},
},
{
[]string{"-disable-scan"},
Settings{
BindAddress: ":8080",
Server: serverSettings{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
DisableTCPScan: true,
},
},
{
[]string{"-bind", ":8001", "-geoip2-city", "/city-path", "-geoip2-asn", "/asn-path"},
Settings{
GeodbPath: geodbConf{
City: "/city-path",
ASN: "/asn-path",
},
BindAddress: ":8001",
Server: serverSettings{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
},
},
{
[]string{
"-geoip2-city", "/city-path", "-geoip2-asn", "/asn-path", "-tls-bind", ":9000",
"-tls-crt", "/crt-path", "-tls-key", "/key-path",
},
Settings{
GeodbPath: geodbConf{
City: "/city-path",
ASN: "/asn-path",
},
BindAddress: ":8080",
TLSAddress: ":9000",
TLSCrtPath: "/crt-path",
TLSKeyPath: "/key-path",
Server: serverSettings{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
},
},
{
[]string{
"-geoip2-city", "/city-path", "-geoip2-asn", "/asn-path",
"-trusted-header", "header", "-trusted-port-header", "port-header",
},
Settings{
GeodbPath: geodbConf{
City: "/city-path",
ASN: "/asn-path",
},
BindAddress: ":8080",
TrustedHeader: "header",
TrustedPortHeader: "port-header",
Server: serverSettings{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
},
},
{
[]string{
"-geoip2-city", "/city-path", "-geoip2-asn", "/asn-path",
"-trusted-header", "header", "-enable-secure-headers",
},
Settings{
GeodbPath: geodbConf{
City: "/city-path",
ASN: "/asn-path",
},
BindAddress: ":8080",
TrustedHeader: "header",
EnableSecureHeaders: true,
Server: serverSettings{
ReadTimeout: 10 * time.Second,
WriteTimeout: 10 * time.Second,
},
},
},
}
for _, tt := range flags {
t.Run(strings.Join(tt.args, " "), func(t *testing.T) {
cfg, _, err := Setup(tt.args)
require.Nil(t, err)
assert.True(t, reflect.DeepEqual(cfg, tt.conf))
})
}
}
func TestParseFlagsUsage(t *testing.T) {
usageArgs := []string{"-help", "-h", "--help"}
for _, arg := range usageArgs {
t.Run(arg, func(t *testing.T) {
_, output, err := Setup([]string{arg})
assert.ErrorIs(t, err, flag.ErrHelp)
assert.Contains(t, output, "Usage of")
})
}
}
func TestParseFlagVersion(t *testing.T) {
_, output, err := Setup([]string{"-version"})
assert.ErrorIs(t, err, ErrVersion)
assert.Contains(t, output, "whatismyip version")
}
func TestParseFlagTemplate(t *testing.T) {
testCases := []struct {
name string
flags []string
errMsg string
}{
{
name: "Invalid template path",
flags: []string{"-template", "/template-path"},
errMsg: "no such file or directory",
},
{
name: "Template path is a directory",
flags: []string{"-template", "/"},
errMsg: "must be a file",
},
}
for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
_, _, err := Setup(tc.flags)
require.Error(t, err)
assert.Contains(t, err.Error(), tc.errMsg)
})
}
}