package middleware import ( "errors" "testing" "time" "git.sendico.io/tech/sxchnge/bff/pkg/merrors" ) func TestResolveLoginRateLimitsUsesSecureDefaults(t *testing.T) { got, err := (&Config{}).ResolveLoginRateLimits() if err != nil { t.Fatalf("resolve defaults: %v", err) } if got.PerAccount.Limit != 5 || got.PerAccount.Window != 15*time.Minute { t.Fatalf("unexpected account defaults: %+v", got.PerAccount) } if got.PerIP.Limit != 50 || got.PerIP.Window != 15*time.Minute { t.Fatalf("unexpected IP defaults: %+v", got.PerIP) } } func TestResolveLoginRateLimitsRejectsUnsafeConfiguration(t *testing.T) { tests := []struct { name string cfg *LoginRateLimitsConfig }{ { name: "zero account threshold", cfg: &LoginRateLimitsConfig{ PerAccount: LoginRateLimitWindowConfig{Window: "15m"}, PerIP: LoginRateLimitWindowConfig{Limit: 50, Window: "15m"}, }, }, { name: "invalid IP window", cfg: &LoginRateLimitsConfig{ PerAccount: LoginRateLimitWindowConfig{Limit: 5, Window: "15m"}, PerIP: LoginRateLimitWindowConfig{Limit: 50, Window: "forever"}, }, }, { name: "excessive account window", cfg: &LoginRateLimitsConfig{ PerAccount: LoginRateLimitWindowConfig{Limit: 5, Window: "25h"}, PerIP: LoginRateLimitWindowConfig{Limit: 50, Window: "15m"}, }, }, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { _, err := (&Config{LoginRateLimits: test.cfg}).ResolveLoginRateLimits() if !errors.Is(err, merrors.ErrInvalidArg) { t.Fatalf("expected invalid argument, got %v", err) } }) } }