Gaps fill up, fixes, ui restructuring
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
using StellaOps.Telemetry.Federation.Consent;
|
||||
|
||||
namespace StellaOps.Telemetry.Federation.Tests;
|
||||
|
||||
public sealed class ConsentManagerTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Default_consent_state_is_not_granted()
|
||||
{
|
||||
var manager = new ConsentManager();
|
||||
|
||||
var state = await manager.GetConsentStateAsync("tenant-1");
|
||||
|
||||
Assert.False(state.Granted);
|
||||
Assert.Null(state.GrantedBy);
|
||||
Assert.Null(state.GrantedAt);
|
||||
Assert.Null(state.ExpiresAt);
|
||||
Assert.Null(state.DsseDigest);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Grant_consent_sets_granted_state()
|
||||
{
|
||||
var manager = new ConsentManager();
|
||||
|
||||
var proof = await manager.GrantConsentAsync("tenant-1", "admin@example.com");
|
||||
|
||||
Assert.Equal("tenant-1", proof.TenantId);
|
||||
Assert.Equal("admin@example.com", proof.GrantedBy);
|
||||
Assert.NotNull(proof.DsseDigest);
|
||||
Assert.StartsWith("sha256:", proof.DsseDigest);
|
||||
Assert.NotEmpty(proof.Envelope);
|
||||
|
||||
var state = await manager.GetConsentStateAsync("tenant-1");
|
||||
Assert.True(state.Granted);
|
||||
Assert.Equal("admin@example.com", state.GrantedBy);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Revoke_consent_clears_state()
|
||||
{
|
||||
var manager = new ConsentManager();
|
||||
|
||||
await manager.GrantConsentAsync("tenant-1", "admin@example.com");
|
||||
await manager.RevokeConsentAsync("tenant-1", "admin@example.com");
|
||||
|
||||
var state = await manager.GetConsentStateAsync("tenant-1");
|
||||
Assert.False(state.Granted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task TTL_expiry_revokes_consent()
|
||||
{
|
||||
var fakeTime = new FakeTimeProvider(DateTimeOffset.UtcNow);
|
||||
var manager = new ConsentManager(fakeTime);
|
||||
|
||||
await manager.GrantConsentAsync("tenant-1", "admin@example.com", ttl: TimeSpan.FromHours(1));
|
||||
|
||||
var stateBefore = await manager.GetConsentStateAsync("tenant-1");
|
||||
Assert.True(stateBefore.Granted);
|
||||
|
||||
// Advance time past TTL
|
||||
fakeTime.Advance(TimeSpan.FromHours(2));
|
||||
|
||||
var stateAfter = await manager.GetConsentStateAsync("tenant-1");
|
||||
Assert.False(stateAfter.Granted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Grant_without_TTL_has_no_expiry()
|
||||
{
|
||||
var manager = new ConsentManager();
|
||||
|
||||
var proof = await manager.GrantConsentAsync("tenant-1", "admin@example.com");
|
||||
|
||||
Assert.Null(proof.ExpiresAt);
|
||||
|
||||
var state = await manager.GetConsentStateAsync("tenant-1");
|
||||
Assert.True(state.Granted);
|
||||
Assert.Null(state.ExpiresAt);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Multiple_tenants_independent()
|
||||
{
|
||||
var manager = new ConsentManager();
|
||||
|
||||
await manager.GrantConsentAsync("tenant-1", "admin1@example.com");
|
||||
await manager.GrantConsentAsync("tenant-2", "admin2@example.com");
|
||||
|
||||
await manager.RevokeConsentAsync("tenant-1", "admin1@example.com");
|
||||
|
||||
var state1 = await manager.GetConsentStateAsync("tenant-1");
|
||||
var state2 = await manager.GetConsentStateAsync("tenant-2");
|
||||
|
||||
Assert.False(state1.Granted);
|
||||
Assert.True(state2.Granted);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Grant_overwrites_previous_consent()
|
||||
{
|
||||
var manager = new ConsentManager();
|
||||
|
||||
var proof1 = await manager.GrantConsentAsync("tenant-1", "admin@example.com");
|
||||
var proof2 = await manager.GrantConsentAsync("tenant-1", "newadmin@example.com");
|
||||
|
||||
Assert.NotEqual(proof1.DsseDigest, proof2.DsseDigest);
|
||||
|
||||
var state = await manager.GetConsentStateAsync("tenant-1");
|
||||
Assert.Equal("newadmin@example.com", state.GrantedBy);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Simple fake TimeProvider for testing time-dependent behavior.
|
||||
/// </summary>
|
||||
internal sealed class FakeTimeProvider : TimeProvider
|
||||
{
|
||||
private DateTimeOffset _utcNow;
|
||||
|
||||
public FakeTimeProvider(DateTimeOffset start)
|
||||
{
|
||||
_utcNow = start;
|
||||
}
|
||||
|
||||
public override DateTimeOffset GetUtcNow() => _utcNow;
|
||||
|
||||
public void Advance(TimeSpan duration) => _utcNow += duration;
|
||||
|
||||
public void SetUtcNow(DateTimeOffset value) => _utcNow = value;
|
||||
}
|
||||
Reference in New Issue
Block a user