refactor: extract NATS.Server.Auth.Tests project
Move 50 auth/accounts/permissions/JWT/NKey test files from NATS.Server.Tests into a dedicated NATS.Server.Auth.Tests project. Update namespaces, replace private GetFreePort/ReadUntilAsync helpers with TestUtilities calls, replace Task.Delay with TaskCompletionSource in test doubles, and add InternalsVisibleTo. 690 tests pass.
This commit is contained in:
200
tests/NATS.Server.Auth.Tests/Auth/ActivationExpirationTests.cs
Normal file
200
tests/NATS.Server.Auth.Tests/Auth/ActivationExpirationTests.cs
Normal file
@@ -0,0 +1,200 @@
|
||||
// Tests for Account JWT activation claim expiration: RegisterActivation,
|
||||
// CheckActivationExpiry, IsActivationExpired, GetExpiredActivations,
|
||||
// RemoveExpiredActivations, and ActiveActivationCount.
|
||||
// Go reference: server/accounts.go — checkActivation (~line 2943),
|
||||
// activationExpired (~line 2920).
|
||||
|
||||
using NATS.Server.Auth;
|
||||
|
||||
namespace NATS.Server.Auth.Tests.Auth;
|
||||
|
||||
public class ActivationExpirationTests
|
||||
{
|
||||
// Helpers for well-past / well-future dates to avoid timing flakiness.
|
||||
private static DateTime WellFuture => DateTime.UtcNow.AddDays(30);
|
||||
private static DateTime WellPast => DateTime.UtcNow.AddDays(-30);
|
||||
|
||||
private static ActivationClaim ValidClaim(string subject) => new()
|
||||
{
|
||||
Subject = subject,
|
||||
IssuedAt = DateTime.UtcNow.AddDays(-1),
|
||||
ExpiresAt = WellFuture,
|
||||
Issuer = "AABC123",
|
||||
};
|
||||
|
||||
private static ActivationClaim ExpiredClaim(string subject) => new()
|
||||
{
|
||||
Subject = subject,
|
||||
IssuedAt = DateTime.UtcNow.AddDays(-60),
|
||||
ExpiresAt = WellPast,
|
||||
Issuer = "AABC123",
|
||||
};
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// RegisterActivation
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void RegisterActivation_StoresActivation()
|
||||
{
|
||||
// Go ref: accounts.go — checkActivation stores the decoded activation claim.
|
||||
var account = new Account("test");
|
||||
var claim = ValidClaim("svc.foo");
|
||||
|
||||
account.RegisterActivation("svc.foo", claim);
|
||||
|
||||
var result = account.CheckActivationExpiry("svc.foo");
|
||||
result.Found.ShouldBeTrue();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// CheckActivationExpiry
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void CheckActivationExpiry_Valid_NotExpired()
|
||||
{
|
||||
// Go ref: accounts.go — act.Expires > tn ⇒ checkActivation returns true (not expired).
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.valid", ValidClaim("svc.valid"));
|
||||
|
||||
var result = account.CheckActivationExpiry("svc.valid");
|
||||
|
||||
result.Found.ShouldBeTrue();
|
||||
result.IsExpired.ShouldBeFalse();
|
||||
result.ExpiresAt.ShouldNotBeNull();
|
||||
result.TimeToExpiry.ShouldNotBeNull();
|
||||
result.TimeToExpiry!.Value.ShouldBeGreaterThan(TimeSpan.Zero);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckActivationExpiry_Expired_ReturnsExpired()
|
||||
{
|
||||
// Go ref: accounts.go — act.Expires <= tn ⇒ checkActivation returns false (expired).
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.expired", ExpiredClaim("svc.expired"));
|
||||
|
||||
var result = account.CheckActivationExpiry("svc.expired");
|
||||
|
||||
result.Found.ShouldBeTrue();
|
||||
result.IsExpired.ShouldBeTrue();
|
||||
result.ExpiresAt.ShouldNotBeNull();
|
||||
result.TimeToExpiry.ShouldBe(TimeSpan.Zero);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CheckActivationExpiry_NotFound()
|
||||
{
|
||||
// Go ref: accounts.go — checkActivation returns false when claim is nil/empty token.
|
||||
var account = new Account("test");
|
||||
|
||||
var result = account.CheckActivationExpiry("svc.unknown");
|
||||
|
||||
result.Found.ShouldBeFalse();
|
||||
result.IsExpired.ShouldBeFalse();
|
||||
result.ExpiresAt.ShouldBeNull();
|
||||
result.TimeToExpiry.ShouldBeNull();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// IsActivationExpired
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void IsActivationExpired_Valid_ReturnsFalse()
|
||||
{
|
||||
// Go ref: accounts.go — act.Expires > tn ⇒ not expired.
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.ok", ValidClaim("svc.ok"));
|
||||
|
||||
account.IsActivationExpired("svc.ok").ShouldBeFalse();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void IsActivationExpired_Expired_ReturnsTrue()
|
||||
{
|
||||
// Go ref: accounts.go — act.Expires <= tn ⇒ expired, activationExpired fires.
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.past", ExpiredClaim("svc.past"));
|
||||
|
||||
account.IsActivationExpired("svc.past").ShouldBeTrue();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// GetExpiredActivations
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void GetExpiredActivations_ReturnsOnlyExpired()
|
||||
{
|
||||
// Go ref: accounts.go — activationExpired is called only for expired claims.
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.a", ValidClaim("svc.a"));
|
||||
account.RegisterActivation("svc.b", ExpiredClaim("svc.b"));
|
||||
account.RegisterActivation("svc.c", ValidClaim("svc.c"));
|
||||
account.RegisterActivation("svc.d", ExpiredClaim("svc.d"));
|
||||
|
||||
var expired = account.GetExpiredActivations();
|
||||
|
||||
expired.Count.ShouldBe(2);
|
||||
expired.ShouldContain("svc.b");
|
||||
expired.ShouldContain("svc.d");
|
||||
expired.ShouldNotContain("svc.a");
|
||||
expired.ShouldNotContain("svc.c");
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// RemoveExpiredActivations
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void RemoveExpiredActivations_RemovesAndReturnsCount()
|
||||
{
|
||||
// Go ref: accounts.go — activationExpired removes the import when activation expires.
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.live", ValidClaim("svc.live"));
|
||||
account.RegisterActivation("svc.gone1", ExpiredClaim("svc.gone1"));
|
||||
account.RegisterActivation("svc.gone2", ExpiredClaim("svc.gone2"));
|
||||
|
||||
var removed = account.RemoveExpiredActivations();
|
||||
|
||||
removed.ShouldBe(2);
|
||||
|
||||
// The expired ones should no longer be found.
|
||||
account.CheckActivationExpiry("svc.gone1").Found.ShouldBeFalse();
|
||||
account.CheckActivationExpiry("svc.gone2").Found.ShouldBeFalse();
|
||||
|
||||
// The live one should still be registered.
|
||||
account.CheckActivationExpiry("svc.live").Found.ShouldBeTrue();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ActiveActivationCount
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void ActiveActivationCount_ExcludesExpired()
|
||||
{
|
||||
// Go ref: accounts.go — only non-expired activations are considered active.
|
||||
var account = new Account("test");
|
||||
account.RegisterActivation("svc.1", ValidClaim("svc.1"));
|
||||
account.RegisterActivation("svc.2", ValidClaim("svc.2"));
|
||||
account.RegisterActivation("svc.3", ExpiredClaim("svc.3"));
|
||||
|
||||
account.ActiveActivationCount.ShouldBe(2);
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// ActivationClaim.TimeToExpiry
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
[Fact]
|
||||
public void ActivationClaim_TimeToExpiry_Zero_WhenExpired()
|
||||
{
|
||||
// Go ref: accounts.go — expired activation has no remaining time.
|
||||
var claim = ExpiredClaim("svc.expired");
|
||||
|
||||
claim.IsExpired.ShouldBeTrue();
|
||||
claim.TimeToExpiry.ShouldBe(TimeSpan.Zero);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user