// Tests for service import shadowing detection. // Go reference: accounts.go serviceImportShadowed (~line 2015). using NATS.Server.Auth; using NATS.Server.Imports; using NATS.Server.Subscriptions; namespace NATS.Server.Tests.Auth; public class ImportShadowingTests { private static Account CreateAccount(string name) => new(name); private static Subscription MakeSub(string subject) => new() { Subject = subject, Sid = subject }; /// /// Adds a service import entry directly to the account's import map (bypassing /// export/cycle checks) so that shadowing tests can exercise the import map iteration. /// private static void RegisterServiceImport(Account account, string fromSubject) { var dest = CreateAccount("Dest"); var si = new ServiceImport { DestinationAccount = dest, From = fromSubject, To = fromSubject, }; account.Imports.AddServiceImport(si); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void ServiceImportShadowed_NoLocalSubs_ReturnsFalse() { var account = CreateAccount("A"); var result = account.ServiceImportShadowed("orders.create"); result.ShouldBeFalse(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void ServiceImportShadowed_ExactMatch_ReturnsTrue() { var account = CreateAccount("A"); account.SubList.Insert(MakeSub("orders.create")); var result = account.ServiceImportShadowed("orders.create"); result.ShouldBeTrue(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void ServiceImportShadowed_WildcardMatch_ReturnsTrue() { // Local subscription "orders.*" shadows import on "orders.create" var account = CreateAccount("A"); account.SubList.Insert(MakeSub("orders.*")); var result = account.ServiceImportShadowed("orders.create"); result.ShouldBeTrue(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void ServiceImportShadowed_GtWildcard_ReturnsTrue() { // Local subscription "orders.>" shadows import on "orders.create.new" var account = CreateAccount("A"); account.SubList.Insert(MakeSub("orders.>")); var result = account.ServiceImportShadowed("orders.create.new"); result.ShouldBeTrue(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void ServiceImportShadowed_NoMatch_ReturnsFalse() { // Local subscription "users.*" does NOT shadow import on "orders.create" var account = CreateAccount("A"); account.SubList.Insert(MakeSub("users.*")); var result = account.ServiceImportShadowed("orders.create"); result.ShouldBeFalse(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void GetShadowedServiceImports_ReturnsOnlyShadowed() { var account = CreateAccount("A"); // Register two service imports RegisterServiceImport(account, "orders.create"); RegisterServiceImport(account, "users.profile"); // Only add a local sub that shadows "orders.create" account.SubList.Insert(MakeSub("orders.create")); var shadowed = account.GetShadowedServiceImports(); shadowed.Count.ShouldBe(1); shadowed.ShouldContain("orders.create"); shadowed.ShouldNotContain("users.profile"); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void HasShadowedImports_True_WhenShadowed() { var account = CreateAccount("A"); RegisterServiceImport(account, "orders.create"); account.SubList.Insert(MakeSub("orders.create")); account.HasShadowedImports.ShouldBeTrue(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void HasShadowedImports_False_WhenNone() { var account = CreateAccount("A"); RegisterServiceImport(account, "orders.create"); // No local subs — nothing shadows the import account.HasShadowedImports.ShouldBeFalse(); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void CheckServiceImportShadowing_ReturnsShadowingSubscriptions() { var account = CreateAccount("A"); account.SubList.Insert(MakeSub("orders.*")); account.SubList.Insert(MakeSub("orders.>")); var result = account.CheckServiceImportShadowing("orders.create"); result.IsShadowed.ShouldBeTrue(); result.ImportSubject.ShouldBe("orders.create"); result.ShadowingSubscriptions.Count.ShouldBeGreaterThan(0); // Both wildcard subs match "orders.create" result.ShadowingSubscriptions.ShouldContain("orders.*"); result.ShadowingSubscriptions.ShouldContain("orders.>"); } // Go reference: accounts.go serviceImportShadowed (~line 2015). [Fact] public void CheckServiceImportShadowing_NotShadowed() { var account = CreateAccount("A"); account.SubList.Insert(MakeSub("users.*")); var result = account.CheckServiceImportShadowing("orders.create"); result.IsShadowed.ShouldBeFalse(); result.ImportSubject.ShouldBe("orders.create"); result.ShadowingSubscriptions.Count.ShouldBe(0); } }