package host import ( "context" "testing" "time" ) type fakeRoleScopePolicyRepository struct { policy RoleScopePolicy found bool err error } func (r *fakeRoleScopePolicyRepository) GetRoleScopePolicy(context.Context, string) (RoleScopePolicy, bool, error) { return r.policy, r.found, r.err } func (r *fakeRoleScopePolicyRepository) UpsertRoleScopePolicies(_ context.Context, policies []RoleScopePolicy, updatedAtMS int64) ([]RoleScopePolicy, error) { for index := range policies { policies[index].UpdatedAtMS = updatedAtMS } return policies, r.err } func TestResolveRoleScopePolicyUsesOwnerConfigOrGenericDefault(t *testing.T) { tests := []struct { name string repository *fakeRoleScopePolicyRepository baseScope RoleScope configurable bool expanded RoleScope }{ { name: "new app uses generic default", repository: &fakeRoleScopePolicyRepository{}, baseScope: RoleScopeCountry, configurable: true, expanded: RoleScopeRegion, }, { name: "stored owner config is authoritative", repository: &fakeRoleScopePolicyRepository{found: true, policy: RoleScopePolicy{ Scene: RoleScopeSceneManagerOperations, BaseScope: RoleScopeGlobal, ExpandedScope: RoleScopeGlobal, }}, baseScope: RoleScopeGlobal, expanded: RoleScopeGlobal, }, } for _, testCase := range tests { t.Run(testCase.name, func(t *testing.T) { policy, err := ResolveRoleScopePolicy(context.Background(), testCase.repository, RoleScopeSceneManagerOperations) if err != nil { t.Fatalf("resolve policy: %v", err) } if policy.BaseScope != testCase.baseScope || policy.RegionExpansionConfigurable != testCase.configurable { t.Fatalf("policy mismatch: %+v", policy) } if got := policy.EffectiveScope(true); got != testCase.expanded { t.Fatalf("expanded scope = %q, want %q", got, testCase.expanded) } }) } } func TestDefaultRoleScopePolicyKeepsLegacyManagerSceneCompatible(t *testing.T) { policy, err := DefaultRoleScopePolicy(RoleScopeSceneManagerAddBDLeader) if err != nil { t.Fatalf("resolve legacy manager scene: %v", err) } if policy.Scene != RoleScopeSceneManagerOperations || policy.ExpandedScope != RoleScopeRegion { t.Fatalf("legacy scene must resolve to general manager policy: %+v", policy) } } func TestUpdateRoleScopePoliciesRejectsPartialOrNarrowerSnapshots(t *testing.T) { svc := New(nil, WithClock(func() time.Time { return time.UnixMilli(123).UTC() })) svc.roleScopePolicyRepository = &fakeRoleScopePolicyRepository{} if _, err := svc.UpdateRoleScopePolicies(context.Background(), []RoleScopePolicy{{ Scene: RoleScopeSceneOrganizationExpansion, BaseScope: RoleScopeRegion, ExpandedScope: RoleScopeRegion, }}); err == nil { t.Fatal("partial role scope snapshot must be rejected") } if _, err := svc.UpdateRoleScopePolicies(context.Background(), []RoleScopePolicy{ {Scene: RoleScopeSceneOrganizationExpansion, BaseScope: RoleScopeRegion, ExpandedScope: RoleScopeRegion}, {Scene: RoleScopeSceneManagerOperations, BaseScope: RoleScopeGlobal, ExpandedScope: RoleScopeCountry, RegionExpansionConfigurable: true}, }); err == nil { t.Fatal("narrower expanded manager scope must be rejected") } }