diff --git a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs index d17a2b6f87..d06eb60566 100644 --- a/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Components.MauiBlazor/Volo/Abp/AspNetCore/Components/MauiBlazor/MauiBlazorRemoteTenantStore.cs @@ -23,13 +23,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency Cache = cache; } - public async Task FindAsync(string name) + public async Task FindAsync(string normalizedName) { - var cacheKey = CreateCacheKey(name); + var cacheKey = CreateCacheKey(normalizedName); var tenantConfiguration = await Cache.GetOrAddAsync( cacheKey, - async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name))!, + async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(normalizedName))!, () => new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = @@ -57,13 +57,13 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency return tenantConfiguration; } - public TenantConfiguration? Find(string name) + public TenantConfiguration? Find(string normalizedName) { - var cacheKey = CreateCacheKey(name); + var cacheKey = CreateCacheKey(normalizedName); var tenantConfiguration = Cache.GetOrAdd( cacheKey, - () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(name)))!, + () => AsyncHelper.RunSync(async () => CreateTenantConfiguration(await TenantAppService.FindTenantByNameAsync(normalizedName)))!, () => new DistributedCacheEntryOptions { AbsoluteExpirationRelativeToNow = @@ -110,4 +110,4 @@ public class MauiBlazorRemoteTenantStore : ITenantStore, ITransientDependency { return $"RemoteTenantStore_Id_{tenantId:N}"; } -} \ No newline at end of file +} diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs index e0c450b8b4..1bc7856ca6 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Client/Volo/Abp/AspNetCore/Mvc/Client/MvcRemoteTenantStore.cs @@ -29,9 +29,9 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency Options = options.Value; } - public async Task FindAsync(string name) + public async Task FindAsync(string normalizedName) { - var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) @@ -42,7 +42,7 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency var tenantConfiguration = await Cache.GetAsync(cacheKey); if (tenantConfiguration == null) { - await TenantAppService.FindTenantByNameAsync(name); + await TenantAppService.FindTenantByNameAsync(normalizedName); tenantConfiguration = await Cache.GetAsync(cacheKey); } @@ -79,9 +79,9 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency return tenantConfiguration?.Value; } - public TenantConfiguration? Find(string name) + public TenantConfiguration? Find(string normalizedName) { - var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(name); + var cacheKey = TenantConfigurationCacheItem.CalculateCacheKey(normalizedName); var httpContext = HttpContextAccessor?.HttpContext; if (httpContext != null && httpContext.Items[cacheKey] is TenantConfigurationCacheItem tenantConfigurationInHttpContext) @@ -92,7 +92,7 @@ public class MvcRemoteTenantStore : ITenantStore, ITransientDependency var tenantConfiguration = Cache.Get(cacheKey); if (tenantConfiguration == null) { - AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(name)); + AsyncHelper.RunSync(async () => await TenantAppService.FindTenantByNameAsync(normalizedName)); tenantConfiguration = Cache.Get(cacheKey); } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs index 599b0b8a67..1de5f942dc 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.Contracts/Volo/Abp/AspNetCore/Mvc/MultiTenancy/FindTenantResultDto.cs @@ -11,5 +11,7 @@ public class FindTenantResultDto public string? Name { get; set; } + public string? NormalizedName { get; set; } + public bool IsActive { get; set; } } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs index 279bcee8ad..75649c1f6b 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/AbpTenantAppService.cs @@ -9,15 +9,17 @@ namespace Pages.Abp.MultiTenancy; public class AbpTenantAppService : ApplicationService, IAbpTenantAppService { protected ITenantStore TenantStore { get; } + protected ITenantNormalizer TenantNormalizer { get; } - public AbpTenantAppService(ITenantStore tenantStore) + public AbpTenantAppService(ITenantStore tenantStore, ITenantNormalizer tenantNormalizer) { TenantStore = tenantStore; + TenantNormalizer = tenantNormalizer; } public virtual async Task FindTenantByNameAsync(string name) { - var tenant = await TenantStore.FindAsync(name); + var tenant = await TenantStore.FindAsync(TenantNormalizer.NormalizeName(name)!); if (tenant == null) { @@ -29,6 +31,7 @@ public class AbpTenantAppService : ApplicationService, IAbpTenantAppService Success = true, TenantId = tenant.Id, Name = tenant.Name, + NormalizedName = tenant.NormalizedName, IsActive = tenant.IsActive }; } @@ -47,6 +50,7 @@ public class AbpTenantAppService : ApplicationService, IAbpTenantAppService Success = true, TenantId = tenant.Id, Name = tenant.Name, + NormalizedName = tenant.NormalizedName, IsActive = tenant.IsActive }; } diff --git a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs index f6711be826..94a6760df3 100644 --- a/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs +++ b/framework/src/Volo.Abp.AspNetCore.Mvc.UI.MultiTenancy/Pages/Abp/MultiTenancy/TenantSwitchModal.cshtml.cs @@ -18,13 +18,16 @@ public class TenantSwitchModalModel : AbpPageModel public TenantInfoModel Input { get; set; } = default!; protected ITenantStore TenantStore { get; } + protected ITenantNormalizer TenantNormalizer { get; } protected AbpAspNetCoreMultiTenancyOptions Options { get; } public TenantSwitchModalModel( ITenantStore tenantStore, + ITenantNormalizer tenantNormalizer, IOptions options) { TenantStore = tenantStore; + TenantNormalizer = tenantNormalizer; Options = options.Value; LocalizationResourceType = typeof(AbpUiMultiTenancyResource); } @@ -45,7 +48,7 @@ public class TenantSwitchModalModel : AbpPageModel Guid? tenantId = null; if (!Input.Name.IsNullOrEmpty()) { - var tenant = await TenantStore.FindAsync(Input.Name!); + var tenant = await TenantStore.FindAsync(TenantNormalizer.NormalizeName(Input.Name!)!); if (tenant == null) { throw new UserFriendlyException(L["GivenTenantIsNotExist", Input.Name!]); diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs new file mode 100644 index 0000000000..1c5f0859f5 --- /dev/null +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantNormalizer.cs @@ -0,0 +1,6 @@ +namespace Volo.Abp.MultiTenancy; + +public interface ITenantNormalizer +{ + string? NormalizeName(string? name); +} diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs index 93dd609cc4..d97d438b01 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/ITenantStore.cs @@ -5,12 +5,12 @@ namespace Volo.Abp.MultiTenancy; public interface ITenantStore { - Task FindAsync(string name); + Task FindAsync(string normalizedName); Task FindAsync(Guid id); [Obsolete("Use FindAsync method.")] - TenantConfiguration? Find(string name); + TenantConfiguration? Find(string normalizedName); [Obsolete("Use FindAsync method.")] TenantConfiguration? Find(Guid id); diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs index 0e5faf9386..29b0971708 100644 --- a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/TenantConfiguration.cs @@ -11,6 +11,8 @@ public class TenantConfiguration public string Name { get; set; } = default!; + public string NormalizedName { get; set; } = default!; + public ConnectionStrings? ConnectionStrings { get; set; } public bool IsActive { get; set; } @@ -30,4 +32,12 @@ public class TenantConfiguration ConnectionStrings = new ConnectionStrings(); } + + public TenantConfiguration(Guid id, [NotNull] string name, [NotNull] string normalizedName) + : this(id, name) + { + Check.NotNull(normalizedName, nameof(normalizedName)); + + NormalizedName = normalizedName; + } } diff --git a/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs new file mode 100644 index 0000000000..cba6b32349 --- /dev/null +++ b/framework/src/Volo.Abp.MultiTenancy.Abstractions/Volo/Abp/MultiTenancy/UpperInvariantTenantNormalizer.cs @@ -0,0 +1,11 @@ +using Volo.Abp.DependencyInjection; + +namespace Volo.Abp.MultiTenancy; + +public class UpperInvariantTenantNormalizer : ITenantNormalizer, ITransientDependency +{ + public virtual string? NormalizeName(string? name) + { + return name?.Normalize().ToUpperInvariant(); + } +} diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs index d86d810d11..e91e749fe3 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/ConfigurationStore/DefaultTenantStore.cs @@ -16,9 +16,9 @@ public class DefaultTenantStore : ITenantStore, ITransientDependency _options = options.CurrentValue; } - public Task FindAsync(string name) + public Task FindAsync(string normalizedName) { - return Task.FromResult(Find(name)); + return Task.FromResult(Find(normalizedName)); } public Task FindAsync(Guid id) @@ -26,9 +26,9 @@ public class DefaultTenantStore : ITenantStore, ITransientDependency return Task.FromResult(Find(id)); } - public TenantConfiguration? Find(string name) + public TenantConfiguration? Find(string normalizedName) { - return _options.Tenants?.FirstOrDefault(t => t.Name == name); + return _options.Tenants?.FirstOrDefault(t => t.NormalizedName == normalizedName); } public TenantConfiguration? Find(Guid id) diff --git a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs index 7e93cf888a..79f07deb4a 100644 --- a/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs +++ b/framework/src/Volo.Abp.MultiTenancy/Volo/Abp/MultiTenancy/TenantConfigurationProvider.cs @@ -10,6 +10,7 @@ public class TenantConfigurationProvider : ITenantConfigurationProvider, ITransi { protected virtual ITenantResolver TenantResolver { get; } protected virtual ITenantStore TenantStore { get; } + protected virtual ITenantNormalizer TenantNormalizer { get; } protected virtual ITenantResolveResultAccessor TenantResolveResultAccessor { get; } protected virtual IStringLocalizer StringLocalizer { get; } @@ -17,10 +18,12 @@ public class TenantConfigurationProvider : ITenantConfigurationProvider, ITransi ITenantResolver tenantResolver, ITenantStore tenantStore, ITenantResolveResultAccessor tenantResolveResultAccessor, - IStringLocalizer stringLocalizer) + IStringLocalizer stringLocalizer, + ITenantNormalizer tenantNormalizer) { TenantResolver = tenantResolver; TenantStore = tenantStore; + TenantNormalizer = tenantNormalizer; TenantResolveResultAccessor = tenantResolveResultAccessor; StringLocalizer = stringLocalizer; } @@ -69,7 +72,7 @@ public class TenantConfigurationProvider : ITenantConfigurationProvider, ITransi } else { - return await TenantStore.FindAsync(tenantIdOrName); + return await TenantStore.FindAsync(TenantNormalizer.NormalizeName(tenantIdOrName)!); } } } diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs index e80b47b2a5..02d0288b4b 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_WithDomainResolver_Tests.cs @@ -16,6 +16,7 @@ public class AspNetCoreMultiTenancy_WithDomainResolver_Tests : AspNetCoreMultiTe { private readonly Guid _testTenantId = Guid.NewGuid(); private readonly string _testTenantName = "acme"; + private readonly string _testTenantNormalizedName = "ACME"; private readonly AbpAspNetCoreMultiTenancyOptions _options; @@ -30,7 +31,7 @@ public class AspNetCoreMultiTenancy_WithDomainResolver_Tests : AspNetCoreMultiTe { options.Tenants = new[] { - new TenantConfiguration(_testTenantId, _testTenantName) + new TenantConfiguration(_testTenantId, _testTenantName, _testTenantNormalizedName) }; }); diff --git a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs index 56da287ef8..71ee5f11df 100644 --- a/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.MultiTenancy.Tests/Volo/Abp/AspNetCore/MultiTenancy/AspNetCoreMultiTenancy_Without_DomainResolver_Tests.cs @@ -17,6 +17,7 @@ public class AspNetCoreMultiTenancy_Without_DomainResolver_Tests : AspNetCoreMul { private readonly Guid _testTenantId = Guid.NewGuid(); private readonly string _testTenantName = "acme"; + private readonly string _testTenantNormalizedName = "ACME"; private readonly AbpAspNetCoreMultiTenancyOptions _options; @@ -31,7 +32,7 @@ public class AspNetCoreMultiTenancy_Without_DomainResolver_Tests : AspNetCoreMul { options.Tenants = new[] { - new TenantConfiguration(_testTenantId, _testTenantName) + new TenantConfiguration(_testTenantId, _testTenantName, _testTenantNormalizedName) }; }); diff --git a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs index 4782a5e768..1fb1402b26 100644 --- a/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs +++ b/framework/test/Volo.Abp.AspNetCore.Serilog.Tests/Volo/Abp/AspNetCore/Serilog/Serilog_Enrichers_Tests.cs @@ -20,6 +20,7 @@ public class Serilog_Enrichers_Tests : AbpSerilogTestBase private readonly Guid _testTenantId = Guid.NewGuid(); private readonly string _testTenantName = "acme"; + private readonly string _testTenantNormalizedName = "ACME"; private readonly AbpAspNetCoreMultiTenancyOptions _tenancyOptions; private readonly AbpAspNetCoreSerilogOptions _serilogOptions; @@ -39,7 +40,7 @@ public class Serilog_Enrichers_Tests : AbpSerilogTestBase { options.Tenants = new[] { - new TenantConfiguration(_testTenantId, _testTenantName) + new TenantConfiguration(_testTenantId, _testTenantName, _testTenantNormalizedName) }; }); base.ConfigureServices(services); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs index 6412993d14..41ea978524 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/ITenantRepository.cs @@ -9,13 +9,13 @@ namespace Volo.Abp.TenantManagement; public interface ITenantRepository : IBasicRepository { Task FindByNameAsync( - string name, + string normalizedName, bool includeDetails = true, CancellationToken cancellationToken = default); [Obsolete("Use FindByNameAsync method.")] Tenant FindByName( - string name, + string normalizedName, bool includeDetails = true ); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs index 5275e39ab3..6567cf8efd 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/Tenant.cs @@ -10,7 +10,9 @@ namespace Volo.Abp.TenantManagement; public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion { public virtual string Name { get; protected set; } - + + public virtual string NormalizedName { get; protected set; } + public virtual int EntityVersion { get; protected set; } public virtual List ConnectionStrings { get; protected set; } @@ -20,10 +22,11 @@ public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion } - protected internal Tenant(Guid id, [NotNull] string name) + protected internal Tenant(Guid id, [NotNull] string name, [CanBeNull] string normalizedTenantName) : base(id) { SetName(name); + SetNormalizedTenantName(normalizedTenantName); ConnectionStrings = new List(); } @@ -78,4 +81,9 @@ public class Tenant : FullAuditedAggregateRoot, IHasEntityVersion { Name = Check.NotNullOrWhiteSpace(name, nameof(name), TenantConsts.MaxNameLength); } + + protected internal virtual void SetNormalizedTenantName([CanBeNull] string normalizedTenantName) + { + NormalizedName = normalizedTenantName; + } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs index e629186e20..09c1a9368f 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantConfigurationCacheItemInvalidator.cs @@ -22,21 +22,21 @@ public class TenantConfigurationCacheItemInvalidator : public virtual async Task HandleEventAsync(EntityChangedEventData eventData) { - await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.Name); + await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.NormalizedName); } public virtual async Task HandleEventAsync(EntityDeletedEventData eventData) { - await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.Name); + await ClearCacheAsync(eventData.Entity.Id, eventData.Entity.NormalizedName); } - protected virtual async Task ClearCacheAsync(Guid? id, string name) + protected virtual async Task ClearCacheAsync(Guid? id, string normalizedName) { await Cache.RemoveManyAsync( new[] { TenantConfigurationCacheItem.CalculateCacheKey(id, null), - TenantConfigurationCacheItem.CalculateCacheKey(null, name), + TenantConfigurationCacheItem.CalculateCacheKey(null, normalizedName), }); } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs index 1ad7324c35..43594dfde7 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantManager.cs @@ -11,19 +11,22 @@ public class TenantManager : DomainService, ITenantManager protected ITenantRepository TenantRepository { get; } protected IDistributedCache Cache { get; } - public TenantManager(ITenantRepository tenantRepository, - IDistributedCache cache) + protected ITenantNormalizer TenantNormalizer { get; } + + public TenantManager(ITenantRepository tenantRepository, IDistributedCache cache, ITenantNormalizer tenantNormalizer) { TenantRepository = tenantRepository; Cache = cache; + TenantNormalizer = tenantNormalizer; } public virtual async Task CreateAsync(string name) { Check.NotNull(name, nameof(name)); - await ValidateNameAsync(name); - return new Tenant(GuidGenerator.Create(), name); + var normalizedTenantName = TenantNormalizer.NormalizeName(name); + await ValidateNameAsync(normalizedTenantName); + return new Tenant(GuidGenerator.Create(), name, normalizedTenantName); } public virtual async Task ChangeNameAsync(Tenant tenant, string name) @@ -31,17 +34,20 @@ public class TenantManager : DomainService, ITenantManager Check.NotNull(tenant, nameof(tenant)); Check.NotNull(name, nameof(name)); - await ValidateNameAsync(name, tenant.Id); - await Cache.RemoveAsync(TenantConfigurationCacheItem.CalculateCacheKey(tenant.Name)); + var normalizedTenantName = TenantNormalizer.NormalizeName(name); + + await ValidateNameAsync(normalizedTenantName, tenant.Id); + await Cache.RemoveAsync(TenantConfigurationCacheItem.CalculateCacheKey(tenant.NormalizedName)); tenant.SetName(name); + tenant.SetNormalizedTenantName(normalizedTenantName); } - protected virtual async Task ValidateNameAsync(string name, Guid? expectedId = null) + protected virtual async Task ValidateNameAsync(string normalizeName, Guid? expectedId = null) { - var tenant = await TenantRepository.FindByNameAsync(name); + var tenant = await TenantRepository.FindByNameAsync(normalizeName); if (tenant != null && tenant.Id != expectedId) { - throw new BusinessException("Volo.Abp.TenantManagement:DuplicateTenantName").WithData("Name", name); + throw new BusinessException("Volo.Abp.TenantManagement:DuplicateTenantName").WithData("Name", normalizeName); } } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs index 5fd23add6b..f2ef1ed066 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.Domain/Volo/Abp/TenantManagement/TenantStore.cs @@ -27,9 +27,9 @@ public class TenantStore : ITenantStore, ITransientDependency Cache = cache; } - public virtual async Task FindAsync(string name) + public virtual async Task FindAsync(string normalizedName) { - return (await GetCacheItemAsync(null, name)).Value; + return (await GetCacheItemAsync(null, normalizedName)).Value; } public virtual async Task FindAsync(Guid id) @@ -38,9 +38,9 @@ public class TenantStore : ITenantStore, ITransientDependency } [Obsolete("Use FindAsync method.")] - public virtual TenantConfiguration Find(string name) + public virtual TenantConfiguration Find(string normalizedName) { - return (GetCacheItem(null, name)).Value; + return (GetCacheItem(null, normalizedName)).Value; } [Obsolete("Use FindAsync method.")] @@ -49,9 +49,9 @@ public class TenantStore : ITenantStore, ITransientDependency return (GetCacheItem(id, null)).Value; } - protected virtual async Task GetCacheItemAsync(Guid? id, string name) + protected virtual async Task GetCacheItemAsync(Guid? id, string normalizedName) { - var cacheKey = CalculateCacheKey(id, name); + var cacheKey = CalculateCacheKey(id, normalizedName); var cacheItem = await Cache.GetAsync(cacheKey, considerUow: true); if (cacheItem != null) @@ -68,11 +68,11 @@ public class TenantStore : ITenantStore, ITransientDependency } } - if (!name.IsNullOrWhiteSpace()) + if (!normalizedName.IsNullOrWhiteSpace()) { using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities! { - var tenant = await TenantRepository.FindByNameAsync(name); + var tenant = await TenantRepository.FindByNameAsync(normalizedName); return await SetCacheAsync(cacheKey, tenant); } } @@ -89,9 +89,9 @@ public class TenantStore : ITenantStore, ITransientDependency } [Obsolete("Use GetCacheItemAsync method.")] - protected virtual TenantConfigurationCacheItem GetCacheItem(Guid? id, string name) + protected virtual TenantConfigurationCacheItem GetCacheItem(Guid? id, string normalizedName) { - var cacheKey = CalculateCacheKey(id, name); + var cacheKey = CalculateCacheKey(id, normalizedName); var cacheItem = Cache.Get(cacheKey, considerUow: true); if (cacheItem != null) @@ -108,11 +108,11 @@ public class TenantStore : ITenantStore, ITransientDependency } } - if (!name.IsNullOrWhiteSpace()) + if (!normalizedName.IsNullOrWhiteSpace()) { using (CurrentTenant.Change(null)) //TODO: No need this if we can implement to define host side (or tenant-independent) entities! { - var tenant = TenantRepository.FindByName(name); + var tenant = TenantRepository.FindByName(normalizedName); return SetCache(cacheKey, tenant); } } @@ -129,8 +129,8 @@ public class TenantStore : ITenantStore, ITransientDependency return cacheItem; } - protected virtual string CalculateCacheKey(Guid? id, string name) + protected virtual string CalculateCacheKey(Guid? id, string normalizedName) { - return TenantConfigurationCacheItem.CalculateCacheKey(id, name); + return TenantConfigurationCacheItem.CalculateCacheKey(id, normalizedName); } } diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs index 6b1d7f7e8e..bb189e72a1 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/AbpTenantManagementDbContextModelCreatingExtensions.cs @@ -23,6 +23,7 @@ public static class AbpTenantManagementDbContextModelCreatingExtensions b.ConfigureByConvention(); b.Property(t => t.Name).IsRequired().HasMaxLength(TenantConsts.MaxNameLength); + b.Property(t => t.NormalizedName).IsRequired().HasMaxLength(TenantConsts.MaxNameLength); b.HasMany(u => u.ConnectionStrings).WithOne().HasForeignKey(uc => uc.TenantId).IsRequired(); diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs index 34d350d242..e58512dc13 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.EntityFrameworkCore/Volo/Abp/TenantManagement/EntityFrameworkCore/EfCoreTenantRepository.cs @@ -19,23 +19,23 @@ public class EfCoreTenantRepository : EfCoreRepository FindByNameAsync( - string name, + string normalizedName, bool includeDetails = true, CancellationToken cancellationToken = default) { return await (await GetDbSetAsync()) .IncludeDetails(includeDetails) .OrderBy(t => t.Id) - .FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken)); + .FirstOrDefaultAsync(t => t.NormalizedName == normalizedName, GetCancellationToken(cancellationToken)); } [Obsolete("Use FindByNameAsync method.")] - public virtual Tenant FindByName(string name, bool includeDetails = true) + public virtual Tenant FindByName(string normalizedName, bool includeDetails = true) { return DbSet .IncludeDetails(includeDetails) .OrderBy(t => t.Id) - .FirstOrDefault(t => t.Name == name); + .FirstOrDefault(t => t.NormalizedName == normalizedName); } [Obsolete("Use FindAsync method.")] diff --git a/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs b/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs index 321dcf365f..049dc5e57c 100644 --- a/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs +++ b/modules/tenant-management/src/Volo.Abp.TenantManagement.MongoDB/Volo/Abp/TenantManagement/MongoDb/MongoTenantRepository.cs @@ -20,19 +20,19 @@ public class MongoTenantRepository : MongoDbRepository FindByNameAsync( - string name, + string normalizedName, bool includeDetails = true, CancellationToken cancellationToken = default) { return await (await GetMongoQueryableAsync(cancellationToken)) - .FirstOrDefaultAsync(t => t.Name == name, GetCancellationToken(cancellationToken)); + .FirstOrDefaultAsync(t => t.NormalizedName == normalizedName, GetCancellationToken(cancellationToken)); } [Obsolete("Use FindByNameAsync method.")] - public virtual Tenant FindByName(string name, bool includeDetails = true) + public virtual Tenant FindByName(string normalizedName, bool includeDetails = true) { return GetMongoQueryable() - .FirstOrDefault(t => t.Name == name); + .FirstOrDefault(t => t.NormalizedName == normalizedName); } [Obsolete("Use FindAsync method.")] diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs index 9671402560..2dc844d71e 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantCacheItemInvalidator_Tests.cs @@ -12,6 +12,7 @@ public class TenantConfigurationCacheItemInvalidator_Tests : AbpTenantManagement private readonly ITenantStore _tenantStore; private readonly ITenantRepository _tenantRepository; private readonly ITenantManager _tenantManager; + private readonly ITenantNormalizer _tenantNormalizer; public TenantConfigurationCacheItemInvalidator_Tests() { @@ -19,86 +20,87 @@ public class TenantConfigurationCacheItemInvalidator_Tests : AbpTenantManagement _tenantStore = GetRequiredService(); _tenantRepository = GetRequiredService(); _tenantManager = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } [Fact] public async Task Get_Tenant_Should_Cached() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldBeNull(); await _tenantStore.FindAsync(acme.Id); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); - await _tenantStore.FindAsync(acme.Name); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); + await _tenantStore.FindAsync(acme.NormalizedName); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldNotBeNull(); - var volosoft = _tenantRepository.FindByName("volosoft"); + var volosoft = _tenantRepository.FindByName(_tenantNormalizer.NormalizeName("volosoft")); volosoft.ShouldNotBeNull(); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldBeNull(); _tenantStore.Find(volosoft.Id); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); - _tenantStore.Find(volosoft.Name); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); + _tenantStore.Find(volosoft.NormalizedName); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldNotBeNull(); } [Fact] public async Task Cache_Should_Invalidator_When_Tenant_Changed() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); // FindAsync will cache tenant. await _tenantStore.FindAsync(acme.Id); - await _tenantStore.FindAsync(acme.Name); + await _tenantStore.FindAsync(acme.NormalizedName); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldNotBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldNotBeNull(); await _tenantRepository.DeleteAsync(acme); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(acme.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.Name))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, acme.NormalizedName))).ShouldBeNull(); - var volosoft = await _tenantRepository.FindByNameAsync("volosoft"); + var volosoft = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("volosoft")); volosoft.ShouldNotBeNull(); // Find will cache tenant. _tenantStore.Find(volosoft.Id); - _tenantStore.Find(volosoft.Name); + _tenantStore.Find(volosoft.NormalizedName); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldNotBeNull(); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldNotBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldNotBeNull(); await _tenantRepository.DeleteAsync(volosoft); (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(volosoft.Id, null))).ShouldBeNull(); - (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.Name))).ShouldBeNull(); + (_cache.Get(TenantConfigurationCacheItem.CalculateCacheKey(null, volosoft.NormalizedName))).ShouldBeNull(); - var abp = await _tenantRepository.FindByNameAsync("abp"); + var abp = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("abp")); abp.ShouldNotBeNull(); // Find will cache tenant. await _tenantStore.FindAsync(abp.Id); - await _tenantStore.FindAsync(abp.Name); + await _tenantStore.FindAsync(abp.NormalizedName); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(abp.Id, null))).ShouldNotBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, abp.Name))).ShouldNotBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, abp.NormalizedName))).ShouldNotBeNull(); await _tenantManager.ChangeNameAsync(abp, "abp2"); await _tenantRepository.UpdateAsync(abp); (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(abp.Id, null))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, "abp"))).ShouldBeNull(); - (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, "abp2"))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, _tenantNormalizer.NormalizeName("abp")))).ShouldBeNull(); + (await _cache.GetAsync(TenantConfigurationCacheItem.CalculateCacheKey(null, _tenantNormalizer.NormalizeName("abp2")))).ShouldBeNull(); } } diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs index 161882e412..f46bcf8573 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantManager_Tests.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Shouldly; +using Volo.Abp.MultiTenancy; using Xunit; namespace Volo.Abp.TenantManagement; @@ -8,19 +9,21 @@ public class TenantManager_Tests : AbpTenantManagementDomainTestBase { private readonly ITenantManager _tenantManager; private readonly ITenantRepository _tenantRepository; + private readonly ITenantNormalizer _tenantNormalizer; public TenantManager_Tests() { _tenantManager = GetRequiredService(); _tenantRepository = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } - [Fact] public async Task CreateAsync() { var tenant = await _tenantManager.CreateAsync("Test"); tenant.Name.ShouldBe("Test"); + tenant.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("Test")); } [Fact] @@ -32,18 +35,20 @@ public class TenantManager_Tests : AbpTenantManagementDomainTestBase [Fact] public async Task ChangeNameAsync() { - var tenant = await _tenantRepository.FindByNameAsync("volosoft"); + var tenant = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("volosoft")); tenant.ShouldNotBeNull(); + tenant.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("volosoft")); await _tenantManager.ChangeNameAsync(tenant, "newVolosoft"); tenant.Name.ShouldBe("newVolosoft"); + tenant.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("newVolosoft")); } [Fact] public async Task ChangeName_Tenant_Name_Can_Not_Duplicate() { - var tenant = await _tenantRepository.FindByNameAsync("acme"); + var tenant = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); tenant.ShouldNotBeNull(); await Assert.ThrowsAsync(async () => await _tenantManager.ChangeNameAsync(tenant, "volosoft")); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs index 1af4ebd1ea..10f203eb43 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/TenantStore_Tests.cs @@ -9,25 +9,28 @@ public class TenantStore_Tests : AbpTenantManagementDomainTestBase { private readonly ITenantStore _tenantStore; private readonly ITenantRepository _tenantRepository; + private readonly ITenantNormalizer _tenantNormalizer; public TenantStore_Tests() { _tenantStore = GetRequiredService(); _tenantRepository = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } [Fact] public async Task FindAsyncByName() { - var acme = await _tenantStore.FindAsync("acme"); + var acme = await _tenantStore.FindAsync(_tenantNormalizer.NormalizeName("acme")!); acme.ShouldNotBeNull(); acme.Name.ShouldBe("acme"); + acme.NormalizedName.ShouldBe(_tenantNormalizer.NormalizeName("acme")!); } [Fact] public async Task FindAsyncById() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); (await _tenantStore.FindAsync(acme.Id)).ShouldNotBeNull(); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs index dbe631d431..bcefc527e6 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.Domain.Tests/Volo/Abp/TenantManagement/Tenant_Tests.cs @@ -1,5 +1,6 @@ using System.Threading.Tasks; using Shouldly; +using Volo.Abp.MultiTenancy; using Xunit; namespace Volo.Abp.TenantManagement; @@ -7,16 +8,18 @@ namespace Volo.Abp.TenantManagement; public class Tenant_Tests : AbpTenantManagementDomainTestBase { private readonly ITenantRepository _tenantRepository; + private readonly ITenantNormalizer _tenantNormalizer; public Tenant_Tests() { _tenantRepository = GetRequiredService(); + _tenantNormalizer = GetRequiredService(); } [Fact] public async Task FindDefaultConnectionString() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); acme.FindDefaultConnectionString().ShouldBe("DefaultConnString-Value"); @@ -25,7 +28,7 @@ public class Tenant_Tests : AbpTenantManagementDomainTestBase [Fact] public async Task FindConnectionString() { - var acme = await _tenantRepository.FindByNameAsync("acme"); + var acme = await _tenantRepository.FindByNameAsync(_tenantNormalizer.NormalizeName("acme")); acme.ShouldNotBeNull(); acme.FindConnectionString(Data.ConnectionStrings.DefaultConnectionStringName).ShouldBe("DefaultConnString-Value"); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs index 049d93cf65..9fe123d73b 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/LazyLoad_Tests.cs @@ -2,6 +2,7 @@ using System.Threading.Tasks; using Shouldly; using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; using Volo.Abp.Uow; using Xunit; @@ -11,10 +12,12 @@ public abstract class LazyLoad_Tests : TenantManagementTestBase< where TStartupModule : IAbpModule { public ITenantRepository TenantRepository { get; } + public ITenantNormalizer TenantNormalizer { get; } protected LazyLoad_Tests() { TenantRepository = GetRequiredService(); + TenantNormalizer = GetRequiredService(); } [Fact] @@ -22,7 +25,7 @@ public abstract class LazyLoad_Tests : TenantManagementTestBase< { using (var uow = GetRequiredService().Begin()) { - var role = await TenantRepository.FindByNameAsync("acme", includeDetails: false); + var role = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme"), includeDetails: false); role.ConnectionStrings.ShouldNotBeNull(); role.ConnectionStrings.Any().ShouldBeTrue(); diff --git a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs index c8ff94d069..6e4c3c8db5 100644 --- a/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs +++ b/modules/tenant-management/test/Volo.Abp.TenantManagement.TestBase/Volo/Abp/TenantManagement/TenantRepository_Tests.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Threading.Tasks; using Shouldly; using Volo.Abp.Modularity; +using Volo.Abp.MultiTenancy; using Xunit; namespace Volo.Abp.TenantManagement; @@ -11,22 +12,24 @@ public abstract class TenantRepository_Tests : TenantManagementT where TStartupModule : IAbpModule { public ITenantRepository TenantRepository { get; } + public ITenantNormalizer TenantNormalizer { get; } protected TenantRepository_Tests() { TenantRepository = GetRequiredService(); + TenantNormalizer = GetRequiredService(); } [Fact] public async Task FindByNameAsync() { - var tenant = await TenantRepository.FindByNameAsync("acme"); + var tenant = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme")); tenant.ShouldNotBeNull(); - tenant = await TenantRepository.FindByNameAsync("undefined-tenant"); + tenant = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("undefined-tenant")); tenant.ShouldBeNull(); - tenant = await TenantRepository.FindByNameAsync("acme", includeDetails: true); + tenant = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme"), includeDetails: true); tenant.ShouldNotBeNull(); tenant.ConnectionStrings.Count.ShouldBeGreaterThanOrEqualTo(2); } @@ -34,7 +37,7 @@ public abstract class TenantRepository_Tests : TenantManagementT [Fact] public async Task FindAsync() { - var tenantId = (await TenantRepository.FindByNameAsync("acme")).Id; + var tenantId = (await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme"))).Id; var tenant = await TenantRepository.FindAsync(tenantId); tenant.ShouldNotBeNull(); @@ -51,14 +54,14 @@ public abstract class TenantRepository_Tests : TenantManagementT public async Task GetListAsync() { var tenants = await TenantRepository.GetListAsync(); - tenants.ShouldContain(t => t.Name == "acme"); - tenants.ShouldContain(t => t.Name == "volosoft"); + tenants.ShouldContain(t => t.Name == "acme" && t.NormalizedName == TenantNormalizer.NormalizeName("acme")); + tenants.ShouldContain(t => t.Name == "volosoft" && t.NormalizedName == TenantNormalizer.NormalizeName("volosoft")); } [Fact] public async Task Should_Eager_Load_Tenant_Collections() { - var role = await TenantRepository.FindByNameAsync("acme"); + var role = await TenantRepository.FindByNameAsync(TenantNormalizer.NormalizeName("acme")); role.ConnectionStrings.ShouldNotBeNull(); role.ConnectionStrings.Any().ShouldBeTrue(); }