From 52d1f775165e96ca3d5b97f0a5cc7ac739ef341e Mon Sep 17 00:00:00 2001 From: Halil ibrahim Kalkan Date: Wed, 22 May 2019 16:33:44 +0300 Subject: [PATCH] Added EF Core and base test projects --- templates/mvc/MyCompanyName.MyProjectName.sln | 16 +++++- .../Data/DataSeedHelper.cs | 23 ++++++++ ...ame.MyProjectName.Application.Tests.csproj | 11 +--- .../MyProjectNameApplicationTestBase.cs | 11 +--- .../MyProjectNameApplicationTestModule.cs | 53 +---------------- .../Samples/SampleAppServiceTests.cs | 34 +++++++++++ ...yProjectNameEntityFrameworkCoreTestBase.cs | 9 +++ ...rojectNameEntityFrameworkCoreTestModule.cs | 57 +++++++++++++++++++ .../Samples/SampleRepositoryTests.cs} | 25 +++----- ...ojectName.EntityFrameworkCore.Tests.csproj | 21 +++++++ ...yCompanyName.MyProjectName.TestBase.csproj | 26 +++++++++ .../MyProjectNameTestBase.cs | 14 +++++ .../MyProjectNameTestBaseModule.cs | 33 +++++++++++ .../MyProjectNameTestDataBuilder.cs | 3 +- 14 files changed, 247 insertions(+), 89 deletions(-) create mode 100644 templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/DataSeedHelper.cs create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleAppServiceTests.cs create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestBase.cs create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestModule.cs rename templates/mvc/test/{MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs => MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs} (65%) create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBase.cs create mode 100644 templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs rename templates/mvc/test/{MyCompanyName.MyProjectName.Application.Tests => MyCompanyName.MyProjectName.TestBase}/MyProjectNameTestDataBuilder.cs (85%) diff --git a/templates/mvc/MyCompanyName.MyProjectName.sln b/templates/mvc/MyCompanyName.MyProjectName.sln index e36757aa80..2c900dd961 100644 --- a/templates/mvc/MyCompanyName.MyProjectName.sln +++ b/templates/mvc/MyCompanyName.MyProjectName.sln @@ -35,7 +35,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName.IdentityServer", "src\MyCompanyName.MyProjectName.IdentityServer\MyCompanyName.MyProjectName.IdentityServer.csproj", "{073C361E-B8F4-49F5-93CC-72A3FF49C026}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompanyName.MyProjectName.HttpApi.Host", "src\MyCompanyName.MyProjectName.HttpApi.Host\MyCompanyName.MyProjectName.HttpApi.Host.csproj", "{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "MyCompanyName.MyProjectName.HttpApi.Host", "src\MyCompanyName.MyProjectName.HttpApi.Host\MyCompanyName.MyProjectName.HttpApi.Host.csproj", "{E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompanyName.MyProjectName.EntityFrameworkCore.Tests", "test\MyCompanyName.MyProjectName.EntityFrameworkCore.Tests\MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj", "{1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MyCompanyName.MyProjectName.TestBase", "test\MyCompanyName.MyProjectName.TestBase\MyCompanyName.MyProjectName.TestBase.csproj", "{91853F21-9CD9-4132-BC29-A7D5D84FFFE7}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution @@ -103,6 +107,14 @@ Global {E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Debug|Any CPU.Build.0 = Debug|Any CPU {E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Release|Any CPU.ActiveCfg = Release|Any CPU {E6D5BF0E-DE92-4D82-A352-EF04B37CB11C}.Release|Any CPU.Build.0 = Release|Any CPU + {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Debug|Any CPU.Build.0 = Debug|Any CPU + {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.ActiveCfg = Release|Any CPU + {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81}.Release|Any CPU.Build.0 = Release|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Debug|Any CPU.Build.0 = Debug|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.ActiveCfg = Release|Any CPU + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -123,6 +135,8 @@ Global {6FE54035-9C11-4702-A5E2-D16F23101468} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} {073C361E-B8F4-49F5-93CC-72A3FF49C026} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} {E6D5BF0E-DE92-4D82-A352-EF04B37CB11C} = {CA9AC87F-097E-4F15-8393-4BC07735A5B0} + {1FE30EB9-74A9-47F5-A9F6-7B1FAB672D81} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} + {91853F21-9CD9-4132-BC29-A7D5D84FFFE7} = {04DBDB01-70F4-4E06-B468-8F87850B22BE} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {28315BFD-90E7-4E14-A2EA-F3D23AF4126F} diff --git a/templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/DataSeedHelper.cs b/templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/DataSeedHelper.cs new file mode 100644 index 0000000000..8c31db364c --- /dev/null +++ b/templates/mvc/src/MyCompanyName.MyProjectName.Domain/Data/DataSeedHelper.cs @@ -0,0 +1,23 @@ +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.Data; +using Volo.Abp.Threading; + +namespace MyCompanyName.MyProjectName.Data +{ + public static class DataSeedHelper + { + public static void Seed(ApplicationInitializationContext context) + { + AsyncHelper.RunSync(async () => + { + using (var scope = context.ServiceProvider.CreateScope()) + { + await scope.ServiceProvider + .GetRequiredService() + .SeedAsync(); + } + }); + } + } +} \ No newline at end of file diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj index 11e5650be0..7c3b5f70bb 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyCompanyName.MyProjectName.Application.Tests.csproj @@ -9,20 +9,11 @@ - - - + - - - - - - - diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestBase.cs b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestBase.cs index d162535cd5..8b6ef3f422 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestBase.cs +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestBase.cs @@ -1,12 +1,7 @@ -using Volo.Abp; - -namespace MyCompanyName.MyProjectName +namespace MyCompanyName.MyProjectName { - public abstract class MyProjectNameApplicationTestBase : AbpIntegratedTest + public abstract class MyProjectNameApplicationTestBase : MyProjectNameTestBase { - protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) - { - options.UseAutofac(); - } + } } diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs index e8e31f4f65..fb9038b6c4 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameApplicationTestModule.cs @@ -1,63 +1,14 @@ -using Microsoft.Data.Sqlite; -using Microsoft.EntityFrameworkCore; -using Microsoft.EntityFrameworkCore.Infrastructure; -using Microsoft.EntityFrameworkCore.Storage; -using Microsoft.Extensions.DependencyInjection; -using MyCompanyName.MyProjectName.EntityFrameworkCore; -using Volo.Abp; -using Volo.Abp.Autofac; -using Volo.Abp.EntityFrameworkCore; +using MyCompanyName.MyProjectName.EntityFrameworkCore; using Volo.Abp.Modularity; namespace MyCompanyName.MyProjectName { [DependsOn( typeof(MyProjectNameApplicationModule), - typeof(MyProjectNameEntityFrameworkCoreModule), - typeof(AbpAutofacModule), - typeof(AbpTestBaseModule) + typeof(MyProjectNameEntityFrameworkCoreTestModule) )] public class MyProjectNameApplicationTestModule : AbpModule { - private SqliteConnection _sqliteConnection; - public override void ConfigureServices(ServiceConfigurationContext context) - { - context.Services.AddAlwaysAllowAuthorization(); - - ConfigureInMemorySqlite(context.Services); - } - - private void ConfigureInMemorySqlite(IServiceCollection services) - { - _sqliteConnection = CreateDatabaseAndGetConnection(); - - services.Configure(options => - { - options.Configure(context => { context.DbContextOptions.UseSqlite(_sqliteConnection); }); - }); - } - - public override void OnApplicationShutdown(ApplicationShutdownContext context) - { - _sqliteConnection.Dispose(); - } - - private static SqliteConnection CreateDatabaseAndGetConnection() - { - var connection = new SqliteConnection("Data Source=:memory:"); - connection.Open(); - - var options = new DbContextOptionsBuilder() - .UseSqlite(connection) - .Options; - - using (var context = new MyProjectNameMigrationsDbContext(options)) - { - context.GetService().CreateTables(); - } - - return connection; - } } } \ No newline at end of file diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleAppServiceTests.cs b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleAppServiceTests.cs new file mode 100644 index 0000000000..eb448aaccc --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleAppServiceTests.cs @@ -0,0 +1,34 @@ +using Microsoft.Extensions.DependencyInjection; +using Shouldly; +using System.Threading.Tasks; +using Volo.Abp.Identity; +using Xunit; + +namespace MyCompanyName.MyProjectName.Samples +{ + /* This is just an example test class. + * Normally, you don't test code of the modules you are using + * (like IIdentityUserAppService here). + * Only test your own application services. + */ + public class SampleAppServiceTests : MyProjectNameApplicationTestBase + { + private readonly IIdentityUserAppService _userAppService; + + public SampleAppServiceTests() + { + _userAppService = ServiceProvider.GetRequiredService(); + } + + [Fact] + public async Task Initial_Data_Should_Contain_Admin_User() + { + //Act + var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); + + //Assert + result.TotalCount.ShouldBeGreaterThan(0); + result.Items.ShouldContain(u => u.UserName == "admin"); + } + } +} diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestBase.cs b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestBase.cs new file mode 100644 index 0000000000..7e26566457 --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestBase.cs @@ -0,0 +1,9 @@ +using Volo.Abp; + +namespace MyCompanyName.MyProjectName.EntityFrameworkCore +{ + public abstract class MyProjectNameEntityFrameworkCoreTestBase : MyProjectNameTestBase + { + + } +} diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestModule.cs b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestModule.cs new file mode 100644 index 0000000000..86a7d55706 --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/MyProjectNameEntityFrameworkCoreTestModule.cs @@ -0,0 +1,57 @@ +using Microsoft.Data.Sqlite; +using Microsoft.EntityFrameworkCore; +using Microsoft.EntityFrameworkCore.Infrastructure; +using Microsoft.EntityFrameworkCore.Storage; +using Microsoft.Extensions.DependencyInjection; +using Volo.Abp; +using Volo.Abp.EntityFrameworkCore; +using Volo.Abp.Modularity; + +namespace MyCompanyName.MyProjectName.EntityFrameworkCore +{ + [DependsOn( + typeof(MyProjectNameEntityFrameworkCoreModule), + typeof(MyProjectNameTestBaseModule) + )] + public class MyProjectNameEntityFrameworkCoreTestModule : AbpModule + { + private SqliteConnection _sqliteConnection; + + public override void ConfigureServices(ServiceConfigurationContext context) + { + ConfigureInMemorySqlite(context.Services); + } + + private void ConfigureInMemorySqlite(IServiceCollection services) + { + _sqliteConnection = CreateDatabaseAndGetConnection(); + + services.Configure(options => + { + options.Configure(context => { context.DbContextOptions.UseSqlite(_sqliteConnection); }); + }); + } + + public override void OnApplicationShutdown(ApplicationShutdownContext context) + { + _sqliteConnection.Dispose(); + } + + private static SqliteConnection CreateDatabaseAndGetConnection() + { + var connection = new SqliteConnection("Data Source=:memory:"); + connection.Open(); + + var options = new DbContextOptionsBuilder() + .UseSqlite(connection) + .Options; + + using (var context = new MyProjectNameMigrationsDbContext(options)) + { + context.GetService().CreateTables(); + } + + return connection; + } + } +} diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs similarity index 65% rename from templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs rename to templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs index 3baff2826f..8e1b078e21 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/Samples/SampleTests.cs +++ b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/EntityFrameworkCore/Samples/SampleRepositoryTests.cs @@ -6,36 +6,27 @@ using Microsoft.Extensions.DependencyInjection; using MyCompanyName.MyProjectName.Users; using Shouldly; using Volo.Abp.Domain.Repositories; -using Volo.Abp.Identity; using Volo.Abp.Uow; using Xunit; -namespace MyCompanyName.MyProjectName.Samples +namespace MyCompanyName.MyProjectName.EntityFrameworkCore.Samples { - public class SampleTests : MyProjectNameApplicationTestBase + /* This is just an example test class. + * Normally, you don't test ABP framework code + * (like default AppUser repository IRepository here). + * Only test your custom repository methods. + */ + public class SampleRepositoryTests : MyProjectNameEntityFrameworkCoreTestBase { - private readonly IIdentityUserAppService _userAppService; private readonly IRepository _appUserRepository; private readonly IUnitOfWorkManager _unitOfWorkManager; - public SampleTests() + public SampleRepositoryTests() { - _userAppService = ServiceProvider.GetRequiredService(); _appUserRepository = ServiceProvider.GetRequiredService>(); _unitOfWorkManager = ServiceProvider.GetRequiredService(); } - [Fact] - public async Task Initial_Data_Should_Contain_Admin_User() - { - //Act - var result = await _userAppService.GetListAsync(new GetIdentityUsersInput()); - - //Assert - result.TotalCount.ShouldBeGreaterThan(0); - result.Items.ShouldContain(u => u.UserName == "admin"); - } - [Fact] public async Task Should_Query_AppUser() { diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj new file mode 100644 index 0000000000..46e07869da --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests/MyCompanyName.MyProjectName.EntityFrameworkCore.Tests.csproj @@ -0,0 +1,21 @@ + + + + + + netcoreapp2.2 + MyCompanyName.MyProjectName + + + + + + + + + + + + + + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj new file mode 100644 index 0000000000..37db2e4cbd --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyCompanyName.MyProjectName.TestBase.csproj @@ -0,0 +1,26 @@ + + + + + + netcoreapp2.2 + MyCompanyName.MyProjectName + + + + + + + + + + + + + + + + + + + diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBase.cs b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBase.cs new file mode 100644 index 0000000000..a7b4c4c57a --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBase.cs @@ -0,0 +1,14 @@ +using Volo.Abp; +using Volo.Abp.Modularity; + +namespace MyCompanyName.MyProjectName +{ + public abstract class MyProjectNameTestBase : AbpIntegratedTest + where TStartupModule : IAbpModule + { + protected override void SetAbpApplicationCreationOptions(AbpApplicationCreationOptions options) + { + options.UseAutofac(); + } + } +} diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs new file mode 100644 index 0000000000..bd74934e82 --- /dev/null +++ b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestBaseModule.cs @@ -0,0 +1,33 @@ +using Microsoft.Extensions.DependencyInjection; +using MyCompanyName.MyProjectName.Data; +using Volo.Abp; +using Volo.Abp.Authorization; +using Volo.Abp.Autofac; +using Volo.Abp.Modularity; + +namespace MyCompanyName.MyProjectName +{ + [DependsOn( + typeof(AbpAutofacModule), + typeof(AbpTestBaseModule), + typeof(AbpAuthorizationModule), + typeof(MyProjectNameDomainModule) + )] + public class MyProjectNameTestBaseModule : AbpModule + { + public override void ConfigureServices(ServiceConfigurationContext context) + { + context.Services.AddAlwaysAllowAuthorization(); + } + + public override void OnApplicationInitialization(ApplicationInitializationContext context) + { + SeedTestData(context); + } + + private static void SeedTestData(ApplicationInitializationContext context) + { + DataSeedHelper.Seed(context); + } + } +} diff --git a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameTestDataBuilder.cs b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestDataBuilder.cs similarity index 85% rename from templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameTestDataBuilder.cs rename to templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestDataBuilder.cs index 8f5ce86a66..64f90c71a8 100644 --- a/templates/mvc/test/MyCompanyName.MyProjectName.Application.Tests/MyProjectNameTestDataBuilder.cs +++ b/templates/mvc/test/MyCompanyName.MyProjectName.TestBase/MyProjectNameTestDataBuilder.cs @@ -8,8 +8,7 @@ namespace MyCompanyName.MyProjectName { public Task SeedAsync(DataSeedContext context) { - /* Seed additional test data... - */ + /* Seed additional test data... */ return Task.CompletedTask; }