mirror of
https://tangled.org/evan.jarrett.net/at-container-registry
synced 2026-09-02 00:06:58 +00:00
971 lines
21 KiB
Go
971 lines
21 KiB
Go
package appview
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
|
|
"github.com/distribution/distribution/v3/configuration"
|
|
)
|
|
|
|
func TestGetEnvOrDefault(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
key string
|
|
defaultValue string
|
|
envValue string
|
|
setEnv bool
|
|
want string
|
|
}{
|
|
{
|
|
name: "env var not set",
|
|
key: "TEST_VAR_NOT_SET",
|
|
defaultValue: "default",
|
|
setEnv: false,
|
|
want: "default",
|
|
},
|
|
{
|
|
name: "env var set to value",
|
|
key: "TEST_VAR_SET",
|
|
defaultValue: "default",
|
|
envValue: "custom",
|
|
setEnv: true,
|
|
want: "custom",
|
|
},
|
|
{
|
|
name: "env var set to empty string",
|
|
key: "TEST_VAR_EMPTY",
|
|
defaultValue: "default",
|
|
envValue: "",
|
|
setEnv: true,
|
|
want: "default",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setEnv {
|
|
t.Setenv(tt.key, tt.envValue)
|
|
}
|
|
|
|
got := GetEnvOrDefault(tt.key, tt.defaultValue)
|
|
if got != tt.want {
|
|
t.Errorf("GetEnvOrDefault() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetBaseURL(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
httpAddr string
|
|
envBaseURL string
|
|
setEnv bool
|
|
want string
|
|
}{
|
|
{
|
|
name: "env var set",
|
|
httpAddr: ":5000",
|
|
envBaseURL: "https://registry.example.com",
|
|
setEnv: true,
|
|
want: "https://registry.example.com",
|
|
},
|
|
{
|
|
name: "port only - auto detect localhost",
|
|
httpAddr: ":5000",
|
|
setEnv: false,
|
|
want: "http://127.0.0.1:5000",
|
|
},
|
|
{
|
|
name: "full address",
|
|
httpAddr: "0.0.0.0:5000",
|
|
setEnv: false,
|
|
want: "http://0.0.0.0:5000",
|
|
},
|
|
{
|
|
name: "custom port",
|
|
httpAddr: ":8080",
|
|
setEnv: false,
|
|
want: "http://127.0.0.1:8080",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setEnv {
|
|
t.Setenv("ATCR_BASE_URL", tt.envBaseURL)
|
|
} else {
|
|
os.Unsetenv("ATCR_BASE_URL")
|
|
}
|
|
|
|
got := GetBaseURL(tt.httpAddr)
|
|
if got != tt.want {
|
|
t.Errorf("GetBaseURL() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func Test_getServiceName(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
baseURL string
|
|
envService string
|
|
setEnv bool
|
|
want string
|
|
}{
|
|
{
|
|
name: "env var set",
|
|
baseURL: "http://127.0.0.1:5000",
|
|
envService: "custom.registry.io",
|
|
setEnv: true,
|
|
want: "custom.registry.io",
|
|
},
|
|
{
|
|
name: "localhost - use default",
|
|
baseURL: "http://localhost:5000",
|
|
setEnv: false,
|
|
want: "atcr.io",
|
|
},
|
|
{
|
|
name: "127.0.0.1 - use default",
|
|
baseURL: "http://127.0.0.1:5000",
|
|
setEnv: false,
|
|
want: "atcr.io",
|
|
},
|
|
{
|
|
name: "custom domain",
|
|
baseURL: "https://registry.example.com",
|
|
setEnv: false,
|
|
want: "registry.example.com",
|
|
},
|
|
{
|
|
name: "domain with port",
|
|
baseURL: "https://registry.example.com:443",
|
|
setEnv: false,
|
|
want: "registry.example.com",
|
|
},
|
|
{
|
|
name: "invalid URL - use default",
|
|
baseURL: "://invalid",
|
|
setEnv: false,
|
|
want: "atcr.io",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setEnv {
|
|
t.Setenv("ATCR_SERVICE_NAME", tt.envService)
|
|
} else {
|
|
os.Unsetenv("ATCR_SERVICE_NAME")
|
|
}
|
|
|
|
got := getServiceName(tt.baseURL)
|
|
if got != tt.want {
|
|
t.Errorf("getServiceName() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildLogConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
envLevel string
|
|
envFormatter string
|
|
setLevel bool
|
|
setFormatter bool
|
|
wantLevel configuration.Loglevel
|
|
wantFormatter string
|
|
}{
|
|
{
|
|
name: "defaults",
|
|
setLevel: false,
|
|
setFormatter: false,
|
|
wantLevel: "info",
|
|
wantFormatter: "text",
|
|
},
|
|
{
|
|
name: "custom level",
|
|
envLevel: "debug",
|
|
setLevel: true,
|
|
setFormatter: false,
|
|
wantLevel: "debug",
|
|
wantFormatter: "text",
|
|
},
|
|
{
|
|
name: "custom formatter",
|
|
envLevel: "info",
|
|
envFormatter: "json",
|
|
setLevel: true,
|
|
setFormatter: true,
|
|
wantLevel: "info",
|
|
wantFormatter: "json",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setLevel {
|
|
t.Setenv("ATCR_LOG_LEVEL", tt.envLevel)
|
|
} else {
|
|
os.Unsetenv("ATCR_LOG_LEVEL")
|
|
}
|
|
|
|
if tt.setFormatter {
|
|
t.Setenv("ATCR_LOG_FORMATTER", tt.envFormatter)
|
|
} else {
|
|
os.Unsetenv("ATCR_LOG_FORMATTER")
|
|
}
|
|
|
|
got := buildLogConfig()
|
|
if got.Level != tt.wantLevel {
|
|
t.Errorf("buildLogConfig().Level = %v, want %v", got.Level, tt.wantLevel)
|
|
}
|
|
if got.Formatter != tt.wantFormatter {
|
|
t.Errorf("buildLogConfig().Formatter = %v, want %v", got.Formatter, tt.wantFormatter)
|
|
}
|
|
if got.Fields["service"] != "atcr-appview" {
|
|
t.Errorf("buildLogConfig().Fields[service] = %v, want atcr-appview", got.Fields["service"])
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildHTTPConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
envAddr string
|
|
envDebugAddr string
|
|
envSecret string
|
|
setAddr bool
|
|
setDebugAddr bool
|
|
setSecret bool
|
|
wantAddr string
|
|
wantDebug string
|
|
wantSecret string // empty means "should be generated"
|
|
}{
|
|
{
|
|
name: "defaults",
|
|
setAddr: false,
|
|
wantAddr: ":5000",
|
|
wantDebug: ":5001",
|
|
wantSecret: "", // generated
|
|
},
|
|
{
|
|
name: "custom addr",
|
|
envAddr: ":8080",
|
|
setAddr: true,
|
|
setDebugAddr: false,
|
|
wantAddr: ":8080",
|
|
wantDebug: ":5001",
|
|
wantSecret: "",
|
|
},
|
|
{
|
|
name: "custom debug addr",
|
|
envDebugAddr: ":9001",
|
|
setAddr: false,
|
|
setDebugAddr: true,
|
|
wantAddr: ":5000",
|
|
wantDebug: ":9001",
|
|
wantSecret: "",
|
|
},
|
|
{
|
|
name: "custom secret",
|
|
envSecret: "my-custom-secret",
|
|
setAddr: false,
|
|
setSecret: true,
|
|
wantAddr: ":5000",
|
|
wantDebug: ":5001",
|
|
wantSecret: "my-custom-secret",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setAddr {
|
|
t.Setenv("ATCR_HTTP_ADDR", tt.envAddr)
|
|
} else {
|
|
os.Unsetenv("ATCR_HTTP_ADDR")
|
|
}
|
|
|
|
if tt.setDebugAddr {
|
|
t.Setenv("ATCR_DEBUG_ADDR", tt.envDebugAddr)
|
|
} else {
|
|
os.Unsetenv("ATCR_DEBUG_ADDR")
|
|
}
|
|
|
|
if tt.setSecret {
|
|
t.Setenv("REGISTRY_HTTP_SECRET", tt.envSecret)
|
|
} else {
|
|
os.Unsetenv("REGISTRY_HTTP_SECRET")
|
|
}
|
|
|
|
got, err := buildHTTPConfig()
|
|
if err != nil {
|
|
t.Fatalf("buildHTTPConfig() error = %v", err)
|
|
}
|
|
|
|
if got.Addr != tt.wantAddr {
|
|
t.Errorf("buildHTTPConfig().Addr = %v, want %v", got.Addr, tt.wantAddr)
|
|
}
|
|
|
|
if got.Debug.Addr != tt.wantDebug {
|
|
t.Errorf("buildHTTPConfig().Debug.Addr = %v, want %v", got.Debug.Addr, tt.wantDebug)
|
|
}
|
|
|
|
if tt.wantSecret == "" {
|
|
// Should be generated (64 hex chars = 32 bytes)
|
|
if len(got.Secret) != 64 {
|
|
t.Errorf("buildHTTPConfig().Secret length = %v, want 64", len(got.Secret))
|
|
}
|
|
} else {
|
|
if got.Secret != tt.wantSecret {
|
|
t.Errorf("buildHTTPConfig().Secret = %v, want %v", got.Secret, tt.wantSecret)
|
|
}
|
|
}
|
|
|
|
// Verify headers
|
|
if got.Headers["X-Content-Type-Options"][0] != "nosniff" {
|
|
t.Error("buildHTTPConfig() missing X-Content-Type-Options header")
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildStorageConfig(t *testing.T) {
|
|
got := buildStorageConfig()
|
|
|
|
// Verify inmemory driver exists
|
|
if _, ok := got["inmemory"]; !ok {
|
|
t.Error("buildStorageConfig() missing inmemory driver")
|
|
}
|
|
|
|
// Verify maintenance config
|
|
maintenance, ok := got["maintenance"]
|
|
if !ok {
|
|
t.Fatal("buildStorageConfig() missing maintenance config")
|
|
}
|
|
|
|
uploadPurging, ok := maintenance["uploadpurging"]
|
|
if !ok {
|
|
t.Fatal("buildStorageConfig() missing uploadpurging config")
|
|
}
|
|
|
|
// Verify uploadpurging is map[any]any (for distribution validation)
|
|
purging, ok := uploadPurging.(map[any]any)
|
|
if !ok {
|
|
t.Fatalf("uploadpurging is %T, want map[any]any", uploadPurging)
|
|
}
|
|
|
|
if purging["enabled"] != false {
|
|
t.Error("uploadpurging enabled should be false")
|
|
}
|
|
}
|
|
|
|
func TestBuildMiddlewareConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
defaultHoldDID string
|
|
baseURL string
|
|
testMode bool
|
|
setTestMode bool
|
|
wantTestMode bool
|
|
}{
|
|
{
|
|
name: "normal mode",
|
|
defaultHoldDID: "did:web:hold01.atcr.io",
|
|
baseURL: "https://atcr.io",
|
|
setTestMode: false,
|
|
wantTestMode: false,
|
|
},
|
|
{
|
|
name: "test mode enabled",
|
|
defaultHoldDID: "did:web:hold01.atcr.io",
|
|
baseURL: "https://atcr.io",
|
|
testMode: true,
|
|
setTestMode: true,
|
|
wantTestMode: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setTestMode {
|
|
t.Setenv("TEST_MODE", "true")
|
|
} else {
|
|
os.Unsetenv("TEST_MODE")
|
|
}
|
|
|
|
got := buildMiddlewareConfig(tt.defaultHoldDID, tt.baseURL)
|
|
|
|
registryMW, ok := got["registry"]
|
|
if !ok {
|
|
t.Fatal("buildMiddlewareConfig() missing registry middleware")
|
|
}
|
|
|
|
if len(registryMW) != 1 {
|
|
t.Fatalf("buildMiddlewareConfig() registry middleware count = %v, want 1", len(registryMW))
|
|
}
|
|
|
|
mw := registryMW[0]
|
|
if mw.Name != "atproto-resolver" {
|
|
t.Errorf("middleware name = %v, want atproto-resolver", mw.Name)
|
|
}
|
|
|
|
if mw.Options["default_hold_did"] != tt.defaultHoldDID {
|
|
t.Errorf("default_hold_did = %v, want %v", mw.Options["default_hold_did"], tt.defaultHoldDID)
|
|
}
|
|
|
|
if mw.Options["base_url"] != tt.baseURL {
|
|
t.Errorf("base_url = %v, want %v", mw.Options["base_url"], tt.baseURL)
|
|
}
|
|
|
|
if mw.Options["test_mode"] != tt.wantTestMode {
|
|
t.Errorf("test_mode = %v, want %v", mw.Options["test_mode"], tt.wantTestMode)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildAuthConfig(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
baseURL string
|
|
envKeyPath string
|
|
envCertPath string
|
|
envExpiration string
|
|
setKeyPath bool
|
|
setCertPath bool
|
|
setExpiration bool
|
|
wantKeyPath string
|
|
wantCertPath string
|
|
wantExpiration int
|
|
wantRealm string
|
|
wantService string
|
|
wantError bool
|
|
}{
|
|
{
|
|
name: "defaults",
|
|
baseURL: "http://127.0.0.1:5000",
|
|
setKeyPath: false,
|
|
setCertPath: false,
|
|
setExpiration: false,
|
|
wantKeyPath: "/var/lib/atcr/auth/private-key.pem",
|
|
wantCertPath: "/var/lib/atcr/auth/private-key.crt",
|
|
wantExpiration: 300,
|
|
wantRealm: "http://127.0.0.1:5000/auth/token",
|
|
wantService: "atcr.io",
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "custom values",
|
|
baseURL: "https://registry.example.com",
|
|
envKeyPath: "/custom/key.pem",
|
|
envCertPath: "/custom/cert.crt",
|
|
envExpiration: "600",
|
|
setKeyPath: true,
|
|
setCertPath: true,
|
|
setExpiration: true,
|
|
wantKeyPath: "/custom/key.pem",
|
|
wantCertPath: "/custom/cert.crt",
|
|
wantExpiration: 600,
|
|
wantRealm: "https://registry.example.com/auth/token",
|
|
wantService: "registry.example.com",
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "invalid expiration",
|
|
baseURL: "http://127.0.0.1:5000",
|
|
envExpiration: "not-a-number",
|
|
setExpiration: true,
|
|
wantError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setKeyPath {
|
|
t.Setenv("ATCR_AUTH_KEY_PATH", tt.envKeyPath)
|
|
} else {
|
|
os.Unsetenv("ATCR_AUTH_KEY_PATH")
|
|
}
|
|
|
|
if tt.setCertPath {
|
|
t.Setenv("ATCR_AUTH_CERT_PATH", tt.envCertPath)
|
|
} else {
|
|
os.Unsetenv("ATCR_AUTH_CERT_PATH")
|
|
}
|
|
|
|
if tt.setExpiration {
|
|
t.Setenv("ATCR_TOKEN_EXPIRATION", tt.envExpiration)
|
|
} else {
|
|
os.Unsetenv("ATCR_TOKEN_EXPIRATION")
|
|
}
|
|
|
|
// Clear service name env var
|
|
os.Unsetenv("ATCR_SERVICE_NAME")
|
|
|
|
got, err := buildAuthConfig(tt.baseURL)
|
|
if (err != nil) != tt.wantError {
|
|
t.Errorf("buildAuthConfig() error = %v, wantError %v", err, tt.wantError)
|
|
return
|
|
}
|
|
|
|
if tt.wantError {
|
|
return
|
|
}
|
|
|
|
tokenParams, ok := got["token"]
|
|
if !ok {
|
|
t.Fatal("buildAuthConfig() missing token params")
|
|
}
|
|
|
|
if tokenParams["privatekey"] != tt.wantKeyPath {
|
|
t.Errorf("privatekey = %v, want %v", tokenParams["privatekey"], tt.wantKeyPath)
|
|
}
|
|
|
|
if tokenParams["rootcertbundle"] != tt.wantCertPath {
|
|
t.Errorf("rootcertbundle = %v, want %v", tokenParams["rootcertbundle"], tt.wantCertPath)
|
|
}
|
|
|
|
if tokenParams["expiration"] != tt.wantExpiration {
|
|
t.Errorf("expiration = %v, want %v", tokenParams["expiration"], tt.wantExpiration)
|
|
}
|
|
|
|
if tokenParams["realm"] != tt.wantRealm {
|
|
t.Errorf("realm = %v, want %v", tokenParams["realm"], tt.wantRealm)
|
|
}
|
|
|
|
if tokenParams["service"] != tt.wantService {
|
|
t.Errorf("service = %v, want %v", tokenParams["service"], tt.wantService)
|
|
}
|
|
|
|
if tokenParams["issuer"] != tt.wantService {
|
|
t.Errorf("issuer = %v, want %v", tokenParams["issuer"], tt.wantService)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestBuildHealthConfig(t *testing.T) {
|
|
got := buildHealthConfig()
|
|
|
|
if !got.StorageDriver.Enabled {
|
|
t.Error("buildHealthConfig().StorageDriver.Enabled = false, want true")
|
|
}
|
|
|
|
if got.StorageDriver.Interval.Seconds() != 10 {
|
|
t.Errorf("buildHealthConfig().StorageDriver.Interval = %v, want 10s", got.StorageDriver.Interval)
|
|
}
|
|
|
|
if got.StorageDriver.Threshold != 3 {
|
|
t.Errorf("buildHealthConfig().StorageDriver.Threshold = %v, want 3", got.StorageDriver.Threshold)
|
|
}
|
|
}
|
|
|
|
func TestGetStringParam(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
params configuration.Parameters
|
|
key string
|
|
defaultValue string
|
|
want string
|
|
}{
|
|
{
|
|
name: "string value exists",
|
|
params: configuration.Parameters{
|
|
"foo": "bar",
|
|
},
|
|
key: "foo",
|
|
defaultValue: "default",
|
|
want: "bar",
|
|
},
|
|
{
|
|
name: "key does not exist",
|
|
params: configuration.Parameters{},
|
|
key: "foo",
|
|
defaultValue: "default",
|
|
want: "default",
|
|
},
|
|
{
|
|
name: "value is not a string",
|
|
params: configuration.Parameters{
|
|
"foo": 123,
|
|
},
|
|
key: "foo",
|
|
defaultValue: "default",
|
|
want: "default",
|
|
},
|
|
{
|
|
name: "empty string value",
|
|
params: configuration.Parameters{
|
|
"foo": "",
|
|
},
|
|
key: "foo",
|
|
defaultValue: "default",
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := GetStringParam(tt.params, tt.key, tt.defaultValue)
|
|
if got != tt.want {
|
|
t.Errorf("GetStringParam() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestGetIntParam(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
params configuration.Parameters
|
|
key string
|
|
defaultValue int
|
|
want int
|
|
}{
|
|
{
|
|
name: "int value exists",
|
|
params: configuration.Parameters{
|
|
"foo": 42,
|
|
},
|
|
key: "foo",
|
|
defaultValue: 100,
|
|
want: 42,
|
|
},
|
|
{
|
|
name: "key does not exist",
|
|
params: configuration.Parameters{},
|
|
key: "foo",
|
|
defaultValue: 100,
|
|
want: 100,
|
|
},
|
|
{
|
|
name: "value is not an int",
|
|
params: configuration.Parameters{
|
|
"foo": "not-an-int",
|
|
},
|
|
key: "foo",
|
|
defaultValue: 100,
|
|
want: 100,
|
|
},
|
|
{
|
|
name: "zero value",
|
|
params: configuration.Parameters{
|
|
"foo": 0,
|
|
},
|
|
key: "foo",
|
|
defaultValue: 100,
|
|
want: 0,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := GetIntParam(tt.params, tt.key, tt.defaultValue)
|
|
if got != tt.want {
|
|
t.Errorf("GetIntParam() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractDefaultHoldDID(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
config *configuration.Configuration
|
|
want string
|
|
}{
|
|
{
|
|
name: "valid config with hold DID",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"default_hold_did": "did:web:hold01.atcr.io",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "did:web:hold01.atcr.io",
|
|
},
|
|
{
|
|
name: "no registry middleware",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{},
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "no atproto-resolver middleware",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "other-middleware",
|
|
Options: configuration.Parameters{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "atproto-resolver without default_hold_did",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"other_option": "value",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "default_hold_did is not a string",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"default_hold_did": 123,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
},
|
|
{
|
|
name: "nil options",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: nil,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: "",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ExtractDefaultHoldDID(tt.config)
|
|
if got != tt.want {
|
|
t.Errorf("ExtractDefaultHoldDID() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestExtractTestMode(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
config *configuration.Configuration
|
|
want bool
|
|
}{
|
|
{
|
|
name: "test mode enabled",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"test_mode": true,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: true,
|
|
},
|
|
{
|
|
name: "test mode disabled",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"test_mode": false,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no registry middleware",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "no atproto-resolver middleware",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "other-middleware",
|
|
Options: configuration.Parameters{
|
|
"foo": "bar",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "atproto-resolver without test_mode",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"other_option": "value",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "test_mode is not a bool",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: configuration.Parameters{
|
|
"test_mode": "true",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
{
|
|
name: "nil options",
|
|
config: &configuration.Configuration{
|
|
Middleware: map[string][]configuration.Middleware{
|
|
"registry": {
|
|
{
|
|
Name: "atproto-resolver",
|
|
Options: nil,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
want: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got := ExtractTestMode(tt.config)
|
|
if got != tt.want {
|
|
t.Errorf("ExtractTestMode() = %v, want %v", got, tt.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestLoadConfigFromEnv(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
envHoldDID string
|
|
setHoldDID bool
|
|
wantError bool
|
|
}{
|
|
{
|
|
name: "valid config",
|
|
envHoldDID: "did:web:hold01.atcr.io",
|
|
setHoldDID: true,
|
|
wantError: false,
|
|
},
|
|
{
|
|
name: "missing default hold DID",
|
|
setHoldDID: false,
|
|
wantError: true,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
if tt.setHoldDID {
|
|
t.Setenv("ATCR_DEFAULT_HOLD_DID", tt.envHoldDID)
|
|
} else {
|
|
os.Unsetenv("ATCR_DEFAULT_HOLD_DID")
|
|
}
|
|
|
|
// Clear other env vars to use defaults
|
|
os.Unsetenv("ATCR_BASE_URL")
|
|
os.Unsetenv("ATCR_SERVICE_NAME")
|
|
|
|
got, err := LoadConfigFromEnv()
|
|
if (err != nil) != tt.wantError {
|
|
t.Errorf("LoadConfigFromEnv() error = %v, wantError %v", err, tt.wantError)
|
|
return
|
|
}
|
|
|
|
if tt.wantError {
|
|
return
|
|
}
|
|
|
|
// Verify config structure
|
|
if got.Version.Major() != 0 || got.Version.Minor() != 1 {
|
|
t.Errorf("version = %v, want 0.1", got.Version)
|
|
}
|
|
|
|
if got.Log.Level != "info" {
|
|
t.Errorf("log level = %v, want info", got.Log.Level)
|
|
}
|
|
|
|
if got.HTTP.Addr != ":5000" {
|
|
t.Errorf("HTTP addr = %v, want :5000", got.HTTP.Addr)
|
|
}
|
|
|
|
if _, ok := got.Storage["inmemory"]; !ok {
|
|
t.Error("storage missing inmemory driver")
|
|
}
|
|
|
|
if _, ok := got.Middleware["registry"]; !ok {
|
|
t.Error("middleware missing registry")
|
|
}
|
|
|
|
if _, ok := got.Auth["token"]; !ok {
|
|
t.Error("auth missing token config")
|
|
}
|
|
|
|
if !got.Health.StorageDriver.Enabled {
|
|
t.Error("health storage driver not enabled")
|
|
}
|
|
})
|
|
}
|
|
}
|