using System; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Abp; using Abp.Authorization.Users; using Abp.Events.Bus; using Abp.Events.Bus.Entities; using Abp.MultiTenancy; using Abp.Runtime.Session; using Abp.TestBase; using YGNT.Exam.Authorization.Users; using YGNT.Exam.EntityFrameworkCore; using YGNT.Exam.EntityFrameworkCore.Seed.Host; using YGNT.Exam.EntityFrameworkCore.Seed.Tenants; using YGNT.Exam.MultiTenancy; namespace YGNT.Exam.Tests { public abstract class ExamTestBase : AbpIntegratedTestBase { protected ExamTestBase() { void NormalizeDbContext(ExamDbContext context) { context.EntityChangeEventHelper = NullEntityChangeEventHelper.Instance; context.EventBus = NullEventBus.Instance; context.SuppressAutoSetTenantId = true; } // Seed initial data for host AbpSession.TenantId = null; UsingDbContext(context => { NormalizeDbContext(context); new InitialHostDbBuilder(context).Create(); new DefaultTenantBuilder(context).Create(); }); // Seed initial data for default tenant AbpSession.TenantId = 1; UsingDbContext(context => { NormalizeDbContext(context); new TenantRoleAndUserBuilder(context, 1).Create(); }); LoginAsDefaultTenantAdmin(); } #region UsingDbContext protected IDisposable UsingTenantId(int? tenantId) { var previousTenantId = AbpSession.TenantId; AbpSession.TenantId = tenantId; return new DisposeAction(() => AbpSession.TenantId = previousTenantId); } protected void UsingDbContext(Action action) { UsingDbContext(AbpSession.TenantId, action); } protected Task UsingDbContextAsync(Func action) { return UsingDbContextAsync(AbpSession.TenantId, action); } protected T UsingDbContext(Func func) { return UsingDbContext(AbpSession.TenantId, func); } protected Task UsingDbContextAsync(Func> func) { return UsingDbContextAsync(AbpSession.TenantId, func); } protected void UsingDbContext(int? tenantId, Action action) { using (UsingTenantId(tenantId)) { using (var context = LocalIocManager.Resolve()) { action(context); context.SaveChanges(); } } } protected async Task UsingDbContextAsync(int? tenantId, Func action) { using (UsingTenantId(tenantId)) { using (var context = LocalIocManager.Resolve()) { await action(context); await context.SaveChangesAsync(); } } } protected T UsingDbContext(int? tenantId, Func func) { T result; using (UsingTenantId(tenantId)) { using (var context = LocalIocManager.Resolve()) { result = func(context); context.SaveChanges(); } } return result; } protected async Task UsingDbContextAsync(int? tenantId, Func> func) { T result; using (UsingTenantId(tenantId)) { using (var context = LocalIocManager.Resolve()) { result = await func(context); await context.SaveChangesAsync(); } } return result; } #endregion #region Login protected void LoginAsHostAdmin() { LoginAsHost(AbpUserBase.AdminUserName); } protected void LoginAsDefaultTenantAdmin() { LoginAsTenant(AbpTenantBase.DefaultTenantName, AbpUserBase.AdminUserName); } protected void LoginAsHost(string userName) { AbpSession.TenantId = null; var user = UsingDbContext( context => context.Users.FirstOrDefault(u => u.TenantId == AbpSession.TenantId && u.UserName == userName)); if (user == null) { throw new Exception("There is no user: " + userName + " for host."); } AbpSession.UserId = user.Id; } protected void LoginAsTenant(string tenancyName, string userName) { var tenant = UsingDbContext(context => context.Tenants.FirstOrDefault(t => t.TenancyName == tenancyName)); if (tenant == null) { throw new Exception("There is no tenant: " + tenancyName); } AbpSession.TenantId = tenant.Id; var user = UsingDbContext( context => context.Users.FirstOrDefault(u => u.TenantId == AbpSession.TenantId && u.UserName == userName)); if (user == null) { throw new Exception("There is no user: " + userName + " for tenant: " + tenancyName); } AbpSession.UserId = user.Id; } #endregion /// /// Gets current user if is not null. /// Throws exception if it's null. /// protected async Task GetCurrentUserAsync() { var userId = AbpSession.GetUserId(); return await UsingDbContext(context => context.Users.SingleAsync(u => u.Id == userId)); } /// /// Gets current tenant if is not null. /// Throws exception if there is no current tenant. /// protected async Task GetCurrentTenantAsync() { var tenantId = AbpSession.GetTenantId(); return await UsingDbContext(context => context.Tenants.SingleAsync(t => t.Id == tenantId)); } } }