package clientpolicy import ( "errors" "slices" "testing" ) func TestValidate(t *testing.T) { t.Parallel() tests := []struct { name string policy Policy wantErr bool }{ {name: "empty policy", policy: Policy{}}, {name: "bounded policy", policy: Policy{ MaxExtractCount: 10, RequestsPerMinute: 600, MaxConcurrentConnections: 3, AllowedUpstreams: []string{"provider-a", "provider-b"}, AllowedRegions: []string{"shanghai", "beijing"}, AllowedRoutings: []string{"checkout", "catalog"}, }}, {name: "negative max count", policy: Policy{MaxExtractCount: -1}, wantErr: true}, {name: "negative request rate", policy: Policy{RequestsPerMinute: -1}, wantErr: true}, {name: "negative concurrency", policy: Policy{MaxConcurrentConnections: -1}, wantErr: true}, {name: "empty upstream", policy: Policy{AllowedUpstreams: []string{""}}, wantErr: true}, {name: "whitespace upstream", policy: Policy{AllowedUpstreams: []string{" provider-a"}}, wantErr: true}, {name: "duplicate upstream", policy: Policy{AllowedUpstreams: []string{"provider-a", "provider-a"}}, wantErr: true}, {name: "empty region", policy: Policy{AllowedRegions: []string{""}}, wantErr: true}, {name: "duplicate region", policy: Policy{AllowedRegions: []string{"shanghai", "shanghai"}}, wantErr: true}, {name: "duplicate routing", policy: Policy{AllowedRoutings: []string{"checkout", "checkout"}}, wantErr: true}, } for _, test := range tests { test := test t.Run(test.name, func(t *testing.T) { t.Parallel() err := test.policy.Validate() if test.wantErr && !errors.Is(err, ErrInvalidPolicy) { t.Fatalf("Validate() error = %v, want ErrInvalidPolicy", err) } if !test.wantErr && err != nil { t.Fatalf("Validate() error = %v", err) } }) } } func TestPolicyRestrictsExtractInputs(t *testing.T) { t.Parallel() policy := Policy{ MaxExtractCount: 5, AllowedUpstreams: []string{"provider-a", "provider-b"}, AllowedRegions: []string{"shanghai"}, } if !policy.AllowsExtractCount(5) || policy.AllowsExtractCount(6) { t.Fatal("max extract count restriction was not applied") } upstreams, ok := policy.RestrictUpstreams(nil) if !ok || !slices.Equal(upstreams, []string{"provider-a", "provider-b"}) { t.Fatalf("RestrictUpstreams(nil) = (%v, %v)", upstreams, ok) } upstreams, ok = policy.RestrictUpstreams([]string{"provider-b"}) if !ok || !slices.Equal(upstreams, []string{"provider-b"}) { t.Fatalf("RestrictUpstreams(subset) = (%v, %v)", upstreams, ok) } if _, ok = policy.RestrictUpstreams([]string{"provider-c"}); ok { t.Fatal("RestrictUpstreams() allowed an unauthorized upstream") } regions, ok := policy.RestrictRegions(nil) if !ok || !slices.Equal(regions, []string{"shanghai"}) { t.Fatalf("RestrictRegions(nil) = (%v, %v)", regions, ok) } if _, ok = policy.RestrictRegions([]string{"beijing"}); ok { t.Fatal("RestrictRegions() allowed an unauthorized region") } } func TestPolicyWithoutRestrictionsPreservesRequestAndClones(t *testing.T) { t.Parallel() policy := Policy{} requested := []string{"provider-a"} effective, ok := policy.RestrictUpstreams(requested) if !ok || !slices.Equal(effective, requested) { t.Fatalf("RestrictUpstreams() = (%v, %v)", effective, ok) } effective[0] = "changed" if requested[0] != "provider-a" { t.Fatal("RestrictUpstreams() aliases caller input") } } func TestPolicyRestrictsGatewayRoutings(t *testing.T) { t.Parallel() policy := Policy{AllowedRoutings: []string{"checkout"}} if !policy.AllowsRouting("checkout") { t.Fatal("AllowsRouting() rejected the configured routing") } if policy.AllowsRouting("catalog") { t.Fatal("AllowsRouting() accepted a routing outside the credential policy") } if !(Policy{}).AllowsRouting("catalog") { t.Fatal("empty policy must preserve legacy gateway access") } }