< Summary

Information
Class: Intentum.MultiTenancy.TenantAwareBehaviorSpaceRepository
Assembly: Intentum.MultiTenancy
File(s): /home/runner/work/Intentum/Intentum/src/Intentum.MultiTenancy/TenantAwareBehaviorSpaceRepository.cs
Line coverage
100%
Covered lines: 45
Uncovered lines: 0
Coverable lines: 45
Total lines: 87
Line coverage: 100%
Branch coverage
64%
Covered branches: 18
Total branches: 28
Branch coverage: 64.2%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Cyclomatic complexity NPath complexity Sequence coverage
.ctor(...)50%44100%
SaveAsync()100%22100%
GetByIdAsync()50%22100%
GetByMetadataAsync()100%22100%
GetByTimeWindowAsync()100%22100%
DeleteAsync()75%44100%
IsCurrentTenant(...)50%66100%

File(s)

/home/runner/work/Intentum/Intentum/src/Intentum.MultiTenancy/TenantAwareBehaviorSpaceRepository.cs

#LineLine coverage
 1using Intentum.Core.Behavior;
 2using Intentum.Persistence.Repositories;
 3
 4namespace Intentum.MultiTenancy;
 5
 6/// <summary>
 7/// Behavior space repository that scopes all operations to the current tenant.
 8/// Injects TenantId into metadata on save and filters by tenant on read.
 9/// </summary>
 10public sealed class TenantAwareBehaviorSpaceRepository : IBehaviorSpaceRepository
 11{
 12    private const string TenantIdKey = "TenantId";
 13
 14    private readonly IBehaviorSpaceRepository _inner;
 15    private readonly ITenantProvider _tenantProvider;
 16
 817    public TenantAwareBehaviorSpaceRepository(IBehaviorSpaceRepository inner, ITenantProvider tenantProvider)
 818    {
 819        _inner = inner ?? throw new ArgumentNullException(nameof(inner));
 820        _tenantProvider = tenantProvider ?? throw new ArgumentNullException(nameof(tenantProvider));
 821    }
 22
 23    /// <inheritdoc />
 24    public async Task<string> SaveAsync(BehaviorSpace behaviorSpace, CancellationToken cancellationToken = default)
 425    {
 426        var tenantId = _tenantProvider.GetCurrentTenantId();
 427        if (!string.IsNullOrEmpty(tenantId))
 428            behaviorSpace.SetMetadata(TenantIdKey, tenantId);
 429        return await _inner.SaveAsync(behaviorSpace, cancellationToken).ConfigureAwait(false);
 430    }
 31
 32    /// <inheritdoc />
 33    public async Task<BehaviorSpace?> GetByIdAsync(string id, CancellationToken cancellationToken = default)
 134    {
 135        var space = await _inner.GetByIdAsync(id, cancellationToken).ConfigureAwait(false);
 136        return IsCurrentTenant(space) ? space : null;
 137    }
 38
 39    /// <inheritdoc />
 40    public async Task<IReadOnlyList<BehaviorSpace>> GetByMetadataAsync(
 41        string key,
 42        object value,
 43        CancellationToken cancellationToken = default)
 244    {
 245        var tenantId = _tenantProvider.GetCurrentTenantId();
 246        if (string.IsNullOrEmpty(tenantId))
 147            return await _inner.GetByMetadataAsync(key, value, cancellationToken).ConfigureAwait(false);
 48
 149        var byTenant = await _inner.GetByMetadataAsync(TenantIdKey, tenantId, cancellationToken).ConfigureAwait(false);
 150        return byTenant
 151            .Where(s => s.Metadata.TryGetValue(key, out var v) && Equals(v, value))
 152            .ToList();
 253    }
 54
 55    /// <inheritdoc />
 56    public async Task<IReadOnlyList<BehaviorSpace>> GetByTimeWindowAsync(
 57        DateTimeOffset start,
 58        DateTimeOffset end,
 59        CancellationToken cancellationToken = default)
 260    {
 261        var tenantId = _tenantProvider.GetCurrentTenantId();
 262        if (string.IsNullOrEmpty(tenantId))
 163            return await _inner.GetByTimeWindowAsync(start, end, cancellationToken).ConfigureAwait(false);
 64
 165        var byTenant = await _inner.GetByMetadataAsync(TenantIdKey, tenantId, cancellationToken).ConfigureAwait(false);
 166        return byTenant
 367            .Where(s => s.Events.Count > 0 && s.Events.Min(e => e.OccurredAt) <= end && s.Events.Max(e => e.OccurredAt) 
 168            .ToList();
 269    }
 70
 71    /// <inheritdoc />
 72    public async Task<bool> DeleteAsync(string id, CancellationToken cancellationToken = default)
 273    {
 274        var space = await _inner.GetByIdAsync(id, cancellationToken).ConfigureAwait(false);
 275        if (space is null || !IsCurrentTenant(space))
 176            return false;
 177        return await _inner.DeleteAsync(id, cancellationToken).ConfigureAwait(false);
 278    }
 79
 80    private bool IsCurrentTenant(BehaviorSpace? space)
 381    {
 382        if (space is null) return false;
 383        var tenantId = _tenantProvider.GetCurrentTenantId();
 384        if (string.IsNullOrEmpty(tenantId)) return true;
 385        return space.Metadata.TryGetValue(TenantIdKey, out var v) && Equals(v, tenantId);
 386    }
 87}