Files
natsdotnet/tests/NATS.Server.Tests/Auth/ReverseResponseMapTests.cs

175 lines
6.2 KiB
C#

// Tests for Account.AddReverseRespMapEntry / CheckForReverseEntries and related helpers.
// Go reference: server/accounts.go — addRespMapEntry (~line 2800), checkForReverseEntries (~line 2810).
using NATS.Server.Auth;
namespace NATS.Server.Tests.Auth;
public class ReverseResponseMapTests
{
// ---------------------------------------------------------------------------
// AddReverseRespMapEntry / CheckForReverseEntries
// ---------------------------------------------------------------------------
[Fact]
public void AddReverseRespMapEntry_StoresEntry()
{
// Go ref: accounts.go addRespMapEntry — stores respMapEntry keyed by rewritten reply
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.abc", "B", "reply.1");
account.ReverseResponseMapCount.ShouldBe(1);
}
[Fact]
public void CheckForReverseEntries_Found_ReturnsEntry()
{
// Go ref: accounts.go checkForReverseEntries — returns entry when key exists
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.xyz", "origin-account", "original.reply.subject");
var entry = account.CheckForReverseEntries("_R_.xyz");
entry.ShouldNotBeNull();
entry.ReplySubject.ShouldBe("_R_.xyz");
entry.OriginAccount.ShouldBe("origin-account");
entry.OriginalReply.ShouldBe("original.reply.subject");
}
[Fact]
public void CheckForReverseEntries_NotFound_ReturnsNull()
{
// Go ref: accounts.go checkForReverseEntries — returns nil when key absent
var account = new Account("A");
var entry = account.CheckForReverseEntries("_R_.nonexistent");
entry.ShouldBeNull();
}
// ---------------------------------------------------------------------------
// RemoveReverseRespMapEntry
// ---------------------------------------------------------------------------
[Fact]
public void RemoveReverseRespMapEntry_Found_ReturnsTrue()
{
// Go ref: accounts.go — reverse map cleanup after response is routed
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.del", "B", "orig.reply");
var removed = account.RemoveReverseRespMapEntry("_R_.del");
removed.ShouldBeTrue();
account.ReverseResponseMapCount.ShouldBe(0);
}
[Fact]
public void RemoveReverseRespMapEntry_NotFound_ReturnsFalse()
{
// Go ref: accounts.go — removing an absent entry is a no-op
var account = new Account("A");
var removed = account.RemoveReverseRespMapEntry("_R_.missing");
removed.ShouldBeFalse();
}
// ---------------------------------------------------------------------------
// ReverseResponseMapCount
// ---------------------------------------------------------------------------
[Fact]
public void ReverseResponseMapCount_MatchesEntries()
{
// Go ref: accounts.go — map length reflects outstanding response mappings
var account = new Account("A");
account.ReverseResponseMapCount.ShouldBe(0);
account.AddReverseRespMapEntry("_R_.1", "B", "r1");
account.AddReverseRespMapEntry("_R_.2", "C", "r2");
account.AddReverseRespMapEntry("_R_.3", "D", "r3");
account.ReverseResponseMapCount.ShouldBe(3);
account.RemoveReverseRespMapEntry("_R_.2");
account.ReverseResponseMapCount.ShouldBe(2);
}
// ---------------------------------------------------------------------------
// ClearReverseResponseMap
// ---------------------------------------------------------------------------
[Fact]
public void ClearReverseResponseMap_EmptiesAll()
{
// Go ref: accounts.go — clearing map after bulk expiry / account teardown
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.a", "B", "ra");
account.AddReverseRespMapEntry("_R_.b", "C", "rb");
account.ClearReverseResponseMap();
account.ReverseResponseMapCount.ShouldBe(0);
account.CheckForReverseEntries("_R_.a").ShouldBeNull();
account.CheckForReverseEntries("_R_.b").ShouldBeNull();
}
// ---------------------------------------------------------------------------
// GetReverseResponseMapKeys
// ---------------------------------------------------------------------------
[Fact]
public void GetReverseResponseMapKeys_ReturnsAllKeys()
{
// Go ref: accounts.go — iterating active respMapEntry keys for diagnostics
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.k1", "B", "r1");
account.AddReverseRespMapEntry("_R_.k2", "C", "r2");
var keys = account.GetReverseResponseMapKeys();
keys.Count.ShouldBe(2);
keys.ShouldContain("_R_.k1");
keys.ShouldContain("_R_.k2");
}
// ---------------------------------------------------------------------------
// Overwrite and CreatedAt preservation
// ---------------------------------------------------------------------------
[Fact]
public void AddReverseRespMapEntry_OverwritesPrevious()
{
// Go ref: accounts.go addRespMapEntry — map assignment overwrites existing key
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.ov", "B", "first.reply");
account.AddReverseRespMapEntry("_R_.ov", "C", "second.reply");
var entry = account.CheckForReverseEntries("_R_.ov");
entry.ShouldNotBeNull();
entry.OriginAccount.ShouldBe("C");
entry.OriginalReply.ShouldBe("second.reply");
account.ReverseResponseMapCount.ShouldBe(1);
}
[Fact]
public void ReverseRespMapEntry_PreservesCreatedAt()
{
// Go ref: accounts.go respMapEntry — timestamp recorded at map insertion time
var before = DateTime.UtcNow;
var account = new Account("A");
account.AddReverseRespMapEntry("_R_.ts", "B", "ts.reply");
var after = DateTime.UtcNow;
var entry = account.CheckForReverseEntries("_R_.ts");
entry.ShouldNotBeNull();
entry.CreatedAt.ShouldBeGreaterThanOrEqualTo(before);
entry.CreatedAt.ShouldBeLessThanOrEqualTo(after);
}
}