< Summary

Information
Class: Elsa.Common.Multitenancy.TenantVisibility
Assembly: Elsa.Common
File(s): /home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Common/Multitenancy/TenantVisibility.cs
Line coverage
100%
Covered lines: 14
Uncovered lines: 0
Coverable lines: 14
Total lines: 57
Line coverage: 100%
Branch coverage
100%
Covered branches: 16
Total branches: 16
Branch coverage: 100%
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
IsVisible(...)100%66100%
CanReplace(...)100%44100%
CanReplaceOwnedRow(...)100%44100%
WhereVisibleToTenant(...)100%22100%

File(s)

/home/runner/work/elsa-core/elsa-core/src/modules/Elsa.Common/Multitenancy/TenantVisibility.cs

#LineLine coverage
 1using Elsa.Common.Entities;
 2
 3namespace Elsa.Common.Multitenancy;
 4
 5/// <summary>
 6/// Memory-store counterpart of EF Core <c>SetTenantIdFilter</c>.
 7/// A row is visible when its <see cref="Entity.TenantId"/> matches the ambient tenant,
 8/// is <see cref="Tenant.AgnosticTenantId"/>, or is null while the ambient tenant is the default.
 9/// </summary>
 10public static class TenantVisibility
 11{
 12    /// <summary>
 13    /// Returns whether <paramref name="entityTenantId"/> is visible under <paramref name="ambientTenantId"/>.
 14    /// </summary>
 15    public static bool IsVisible(string? entityTenantId, string ambientTenantId) =>
 816        entityTenantId == ambientTenantId
 817        || entityTenantId == Tenant.AgnosticTenantId
 818        || entityTenantId is null && ambientTenantId == Tenant.DefaultTenantId;
 19
 20    /// <summary>
 21    /// Write counterpart of <see cref="IsVisible"/>. <c>*</c> is visible to every tenant, but only an
 22    /// agnostic writer may replace it. Named tenants may replace their own rows (and the default tenant
 23    /// may replace a null <see cref="Entity.TenantId"/>).
 24    /// </summary>
 25    public static bool CanReplace(string? existingTenantId, string writerTenantId) =>
 1426        existingTenantId == writerTenantId
 1427        || existingTenantId is null && writerTenantId == Tenant.DefaultTenantId;
 28
 29    /// <summary>
 30    /// CAS match for an upsert. Named rows are owned by the <paramref name="ambientTenantId"/>
 31    /// (Memory <see cref="CanReplace"/>), not by a forged source <c>TenantId</c>. A <c>*</c> row
 32    /// is replaceable only when both the incoming entity and the ambient writer are <c>*</c>.
 33    /// </summary>
 34    public static bool CanReplaceOwnedRow(string? existingTenantId, string? sourceTenantId, string ambientTenantId)
 35    {
 1036        if (existingTenantId == Tenant.AgnosticTenantId)
 437            return sourceTenantId == Tenant.AgnosticTenantId && ambientTenantId == Tenant.AgnosticTenantId;
 38
 639        return CanReplace(existingTenantId, ambientTenantId);
 40    }
 41
 42    /// <summary>
 43    /// Restricts <paramref name="queryable"/> to rows visible to <paramref name="ambientTenantId"/>,
 44    /// unless <paramref name="tenantAgnostic"/> is set (EF <c>IgnoreQueryFilters</c>).
 45    /// </summary>
 46    public static IQueryable<T> WhereVisibleToTenant<T>(this IQueryable<T> queryable, string ambientTenantId, bool tenan
 47        where T : Entity
 48    {
 349        if (tenantAgnostic)
 150            return queryable;
 51
 252        return queryable.Where(entity =>
 253            entity.TenantId == ambientTenantId
 254            || entity.TenantId == Tenant.AgnosticTenantId
 255            || entity.TenantId == null && ambientTenantId == Tenant.DefaultTenantId);
 56    }
 57}