From 84d91c50f8ef54955f3a1a85fe1622a353c10b27 Mon Sep 17 00:00:00 2001 From: Ali Yousefi Date: Wed, 6 Mar 2024 20:58:02 +0330 Subject: [PATCH] Multi language getall not working correctly #172 --- .../BasicTests.cs | 338 +++++++++++------- .../UserMultilingualSimpleController.cs | 13 + .../Fixtures/BaseFixture.cs | 12 +- .../Program.cs | 5 +- .../Security/UniqueIdentityTests.cs | 214 +++++------ .../Startup.cs | 10 + .../appsettings.json | 51 +++ .../Authorizations/AspCoreAuthorization.cs | 2 +- .../EasyMicroservices.Cores.AspCoreApi.csproj | 2 +- ...tilingualReadableQueryServiceController.cs | 7 +- ...ultilingualSimpleQueryServiceController.cs | 2 +- ...ces.Cores.AspEntityFrameworkCoreApi.csproj | 2 +- .../InternalContentResolver.cs | 10 +- .../EasyMicroservices.Cores.Clients.csproj | 2 +- .../EasyMicroservices.Cores.Contracts.csproj | 2 +- .../Database/Helpers/DatabaseExtensions.cs | 19 +- .../Database/Interfaces/IDatabaseWidget.cs | 21 ++ .../Interfaces/IDatabaseWidgetManager.cs | 10 + .../Logics/DatabaseLogicInfrastructure.cs | 17 +- .../Managers/DatabaseWidgetManager.cs | 20 ++ ...t.cs => SimpleReportingAddEntityWidget.cs} | 16 +- .../SimpleReportingBaseEntityWidget.cs | 25 ++ .../SimpleReportingUpdateEntityWidget.cs | 71 ++++ .../EasyMicroservices.Cores.Database.csproj | 2 +- .../Interfaces/IContentResolver.cs | 6 + ...oservices.Cores.EntityFrameworkCore.csproj | 2 +- ...yMicroservices.Cores.Infrastructure.csproj | 2 +- ...ores.Relational.EntityFrameworkCore.csproj | 2 +- .../Common/MultiLanguageUserContract.cs | 16 + .../Contracts/Common/UserContract.cs | 12 + .../Database/Entities/UserEntity.cs | 1 + 31 files changed, 635 insertions(+), 279 deletions(-) create mode 100644 src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserMultilingualSimpleController.cs create mode 100644 src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json rename src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/{SimpleReportingEntityWidget.cs => SimpleReportingAddEntityWidget.cs} (88%) create mode 100644 src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingBaseEntityWidget.cs create mode 100644 src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingUpdateEntityWidget.cs create mode 100644 src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/MultiLanguageUserContract.cs create mode 100644 src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/UserContract.cs diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs index 204c686..28fab31 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/BasicTests.cs @@ -1,146 +1,206 @@ -using EasyMicroservices.Cores.Database.Managers; +using EasyMicroservices.Cores.Contracts.Requests; +using EasyMicroservices.Cores.Database.Managers; using EasyMicroservices.Cores.Tests.Contracts.Common; -using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; using EasyMicroservices.ServiceContracts; using Newtonsoft.Json; namespace EasyMicroservices.Cores.AspCore.Tests { - public abstract class BasicTests - { - protected static HttpClient HttpClient { get; set; } = new HttpClient(); - public abstract int AppPort { get; } - string RouteAddress - { - get - { - return $"http://localhost:{AppPort}"; - } - } - - protected string GetBaseUrl() - { - return RouteAddress; - } - - [Fact] - public async Task Get_EndpointsReturnSuccessAndCorrectContentType() - { - var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/getall"); - var result = JsonConvert.DeserializeObject(data); - AssertTrue(result); - return data; - } - - [Fact] - public async Task> Filter() - { - var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/filter", new object()); - var result = JsonConvert.DeserializeObject>(await data.Content.ReadAsStringAsync()); - AssertTrue(result); - return result; - } - - [Fact] - public async Task AuthorizeTest() - { - var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/AuthorizeError"); - var result = JsonConvert.DeserializeObject(data); - AuthorizeAssert(result); - } - - [Fact] - public async Task AsCheckedResult() - { - var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/AsCheckedResult"); - var result = JsonConvert.DeserializeObject>(data); - if (result.Error.FailedReasonType == FailedReasonType.SessionAccessDenied) - return; - Assert.True(result.Error.FailedReasonType == FailedReasonType.Incorrect); - Assert.True(result.Error.StackTrace.Any(x => x.Contains("AsCheckedResult"))); - } - - [Fact] - public async Task PostAuthorizeTest() - { - var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/PostAuthorizeError", ""); - var result = JsonConvert.DeserializeObject(await data.Content.ReadAsStringAsync()); - AuthorizeAssert(result); - } - - [Fact] - public async Task InternalErrorTest() - { - var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/InternalError"); - var result = JsonConvert.DeserializeObject(data); - AssertFalse(result); - if (result.Error.FailedReasonType != FailedReasonType.SessionAccessDenied && result.Error.FailedReasonType != FailedReasonType.AccessDenied) - AssertContains(result.Error.StackTrace, x => x.Contains("UserController.cs")); - } - - [Fact] - public async Task AddUser() - { - var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/Add", new UpdateUserContract() - { - UserName = "Ali", - UniqueIdentity = "1-2" - }); - var jsondata = await data.Content.ReadAsStringAsync(); - var result = JsonConvert.DeserializeObject(jsondata); - AssertTrue(result); - var getAllRespone = await Get_EndpointsReturnSuccessAndCorrectContentType(); - var users = JsonConvert.DeserializeObject>(getAllRespone); - AssertTrue(users); - if (users.IsSuccess) - Assert.True(users.Result.All(x => DefaultUniqueIdentityManager.DecodeUniqueIdentity(x.UniqueIdentity).Length > 2), - JsonConvert.SerializeObject(users.Result)); - } - - [Fact] - public async Task AddUserEmptyUniqueIdentity() - { - var userName = "EmptyUID"; - var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/Add", new UpdateUserContract() - { - UserName = userName - }); - var jsondata = await data.Content.ReadAsStringAsync(); - var result = JsonConvert.DeserializeObject(jsondata); - AssertTrue(result); - var getAllRespone = await Get_EndpointsReturnSuccessAndCorrectContentType(); - var users = JsonConvert.DeserializeObject>(getAllRespone); - AssertTrue(users); - if (users.IsSuccess) - Assert.True(users.Result.Any(x => x.UserName == userName), - JsonConvert.SerializeObject(users.Result)); - users = await Filter(); - AssertTrue(users); - if (users.IsSuccess) - Assert.True(users.Result.Any(x => x.UserName == userName), - JsonConvert.SerializeObject(users.Result)); - } - - protected virtual void AuthorizeAssert(MessageContract messageContract) - { - Assert.True(messageContract.Error.FailedReasonType == FailedReasonType.SessionAccessDenied); - } - - protected virtual void AssertTrue(MessageContract messageContract) - { - Assert.True(messageContract, messageContract.Error?.ToString()); - } - - protected virtual void AssertFalse(MessageContract messageContract) - { - Assert.False(messageContract); - } - - protected virtual void AssertContains( - IEnumerable collection, - Predicate filter) - { - Assert.Contains(collection, filter); - } - } + public abstract class BasicTests + { + protected static HttpClient HttpClient { get; set; } = new HttpClient(); + public abstract int AppPort { get; } + string RouteAddress + { + get + { + return $"http://localhost:{AppPort}"; + } + } + + protected string GetBaseUrl() + { + return RouteAddress; + } + + [Fact] + public async Task Get_EndpointsReturnSuccessAndCorrectContentType() + { + var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/getall"); + var result = JsonConvert.DeserializeObject(data); + AssertTrue(result); + return data; + } + + [Fact] + public async Task GetAllWithAllLanguage_EndpointsReturnSuccessAndCorrectContentType() + { + var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/usermultilingualsimple/getallwithalllanguage"); + var result = JsonConvert.DeserializeObject(data); + AssertTrue(result); + return data; + } + + [Fact] + public async Task> Filter() + { + var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/filter", new object()); + var result = JsonConvert.DeserializeObject>(await data.Content.ReadAsStringAsync()); + AssertTrue(result); + return result; + } + + [Fact] + public async Task AuthorizeTest() + { + var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/AuthorizeError"); + var result = JsonConvert.DeserializeObject(data); + AuthorizeAssert(result); + } + + [Fact] + public async Task AsCheckedResult() + { + var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/AsCheckedResult"); + var result = JsonConvert.DeserializeObject>(data); + if (result.Error.FailedReasonType == FailedReasonType.SessionAccessDenied) + return; + Assert.True(result.Error.FailedReasonType == FailedReasonType.Incorrect); + Assert.True(result.Error.StackTrace.Any(x => x.Contains("AsCheckedResult"))); + } + + [Fact] + public async Task PostAuthorizeTest() + { + var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/PostAuthorizeError", ""); + var result = JsonConvert.DeserializeObject(await data.Content.ReadAsStringAsync()); + AuthorizeAssert(result); + } + + [Fact] + public async Task InternalErrorTest() + { + var data = await HttpClient.GetStringAsync($"{GetBaseUrl()}/api/user/InternalError"); + var result = JsonConvert.DeserializeObject(data); + AssertFalse(result); + if (result.Error.FailedReasonType != FailedReasonType.SessionAccessDenied && result.Error.FailedReasonType != FailedReasonType.AccessDenied) + AssertContains(result.Error.StackTrace, x => x.Contains("UserController.cs")); + } + + [Fact] + public async Task AddUser() + { + var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/Add", new UpdateUserContract() + { + UserName = "Ali", + UniqueIdentity = "8-10" + }); + var jsondata = await data.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(jsondata); + AssertTrue(result); + var getAllRespone = await Get_EndpointsReturnSuccessAndCorrectContentType(); + var users = JsonConvert.DeserializeObject>(getAllRespone); + AssertTrue(users); + if (users.IsSuccess) + { + var myResult = users.Result.Where(x => x.UniqueIdentity.StartsWith("8-10-")); + Assert.True(myResult.All(x => DefaultUniqueIdentityManager.DecodeUniqueIdentity(x.UniqueIdentity).Length > 2), + JsonConvert.SerializeObject(myResult)); + } + } + + [Fact] + public async Task AddBulkUser() + { + string persianName = "نام فارسی"; + string englishName = "english name"; + var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/usermultilingualsimple/AddBulk", new CreateBulkRequestContract() + { + Items = new List() + { + new MultiLanguageUserContract() + { + UserName = "Ali", + UniqueIdentity = "8-10", + Names = new List() + { + new Contents.GeneratedServices.LanguageDataContract() + { + Data = persianName, + Language = "fa-IR" + }, + new Contents.GeneratedServices.LanguageDataContract() + { + Data = englishName, + Language = "en-US" + } + } + } + } + }); + var jsondata = await data.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(jsondata); + AssertTrue(result); + var getAllRespone = await GetAllWithAllLanguage_EndpointsReturnSuccessAndCorrectContentType(); + var users = JsonConvert.DeserializeObject>(getAllRespone); + AssertTrue(users); + + if (users.IsSuccess) + { + var myResult = users.Result.Where(x => x.UniqueIdentity.StartsWith("8-10-")); + Assert.True(myResult.All(x => DefaultUniqueIdentityManager.DecodeUniqueIdentity(x.UniqueIdentity).Length > 2), + JsonConvert.SerializeObject(myResult)); + Assert.True(myResult.Any(x => x.Names.Any(y => y.Data == persianName)), + JsonConvert.SerializeObject(myResult)); + Assert.True(myResult.Any(x => x.Names.Any(y => y.Data == englishName)), + JsonConvert.SerializeObject(myResult)); + } + } + + [Fact] + public async Task AddUserEmptyUniqueIdentity() + { + var userName = "EmptyUID"; + var data = await HttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/user/Add", new UpdateUserContract() + { + UserName = userName + }); + var jsondata = await data.Content.ReadAsStringAsync(); + var result = JsonConvert.DeserializeObject(jsondata); + AssertTrue(result); + var getAllRespone = await Get_EndpointsReturnSuccessAndCorrectContentType(); + var users = JsonConvert.DeserializeObject>(getAllRespone); + AssertTrue(users); + if (users.IsSuccess) + Assert.True(users.Result.Any(x => x.UserName == userName), + JsonConvert.SerializeObject(users.Result)); + users = await Filter(); + AssertTrue(users); + if (users.IsSuccess) + Assert.True(users.Result.Any(x => x.UserName == userName), + JsonConvert.SerializeObject(users.Result)); + } + + protected virtual void AuthorizeAssert(MessageContract messageContract) + { + Assert.True(messageContract.Error.FailedReasonType == FailedReasonType.SessionAccessDenied); + } + + protected virtual void AssertTrue(MessageContract messageContract) + { + Assert.True(messageContract, messageContract.Error?.ToString()); + } + + protected virtual void AssertFalse(MessageContract messageContract) + { + Assert.False(messageContract); + } + + protected virtual void AssertContains( + IEnumerable collection, + Predicate filter) + { + Assert.Contains(collection, filter); + } + } } diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserMultilingualSimpleController.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserMultilingualSimpleController.cs new file mode 100644 index 0000000..65add3e --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Controllers/UserMultilingualSimpleController.cs @@ -0,0 +1,13 @@ +using EasyMicroservices.Cores.AspCoreApi; +using EasyMicroservices.Cores.AspEntityFrameworkCoreApi.Interfaces; +using EasyMicroservices.Cores.Tests.Contracts.Common; +using EasyMicroservices.Cores.Tests.DatabaseLogics.Database.Entities; + +namespace EasyMicroservices.Cores.AspCore.Tests.Controllers; + +public class UserMultilingualSimpleController : MultilingualSimpleQueryServiceController +{ + public UserMultilingualSimpleController(IUnitOfWork unitOfWork) : base(unitOfWork) + { + } +} \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/BaseFixture.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/BaseFixture.cs index bf5228c..cedee0d 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/BaseFixture.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Fixtures/BaseFixture.cs @@ -34,11 +34,21 @@ public static async Task Init(int port, int? whiteLabelPort, A await BaseWhiteLabelFixture.Run(whiteLabelPort.Value); whiteLabelPort ??= 1041; UnitOfWork.ManualServiceAddresses = new List() - { + { new ServiceAddressInfo() { Name = "WhiteLabel", Address = $"http://localhost:{whiteLabelPort}" + }, + new ServiceAddressInfo() + { + Name = "Authentication", + Address = "http://localhost:1044", + }, + new ServiceAddressInfo() + { + Name = "Content", + Address = $"http://localhost:2003" } }; app.Services.AddControllers().AddApplicationPart(typeof(UserController).Assembly); diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs index e726124..97a643f 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Program.cs @@ -16,7 +16,8 @@ public static async Task Main(string[] args) { string microserviceName = "TestExample"; var app = StartUpExtensions.Create(args); - app.Services.Builder(microserviceName); + app.Services.Builder(microserviceName) + .UseDefaultSwaggerOptions(); app.Services.AddScoped((serviceProvider) => new UnitOfWork(serviceProvider).GetLongContractLogic()); app.Services.AddTransient(serviceProvider => new MyTestContext(serviceProvider.GetService())); app.Services.AddScoped(); @@ -26,7 +27,7 @@ public static async Task Main(string[] args) return new DefaultUniqueIdentityManager(provider.GetService().CurrentWhiteLabel); }); //StartUpExtensions.AddWhiteLabel(microserviceName, "RootAddresses:WhiteLabel"); - var build = await app.Build(); + var build = await app.BuildWithUseCors(null, true); build.MapControllers(); build.Run(); } diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs index f0a4fec..9b44ee3 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Security/UniqueIdentityTests.cs @@ -10,116 +10,124 @@ namespace EasyMicroservices.Cores.AspCore.Tests.Security; public class UniqueIdentityTests : IClassFixture { - public int AppPort => 4567; - public UniqueIdentityTests() - { } + public int AppPort => 4567; + public UniqueIdentityTests() + { } - string GetBaseUrl() - { - return $"http://localhost:{AppPort}"; - } + string GetBaseUrl() + { + return $"http://localhost:{AppPort}"; + } - async Task Login(HttpClient currentHttpClient, string roleName, string fromUniqueIdentity) - { - var loginResult = await currentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/login2?role={roleName}&uniqueIdentity={fromUniqueIdentity}"); - Assert.True(loginResult); - currentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); - } + async Task Login(HttpClient currentHttpClient, string roleName, string fromUniqueIdentity) + { + var loginResult = await currentHttpClient.GetFromJsonAsync>($"{GetBaseUrl()}/api/user/login2?role={roleName}&uniqueIdentity={fromUniqueIdentity}"); + Assert.True(loginResult); + currentHttpClient.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", loginResult.Result); + } - [Theory] - [InlineData("Owner", "User", "Add", "1-2", "{}", true)] - [InlineData("Owner", "User", "Add", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", true)] - [InlineData("Owner", "User", "Add", "1-2", @"{""UniqueIdentity"":""3-4""}", true)] - [InlineData("Moderator", "User", "Add", "1-2", @"{""UniqueIdentity"":""3-4-3-4""}", false)] - [InlineData("Moderator", "User", "Add", "1-2", @"{""UniqueIdentity"":""3-4""}", false)] - [InlineData("Moderator", "User", "Add", "1-2", @"{""UniqueIdentity"":""1-2""}", true)] - public async Task AddAsync(string roleName, string controller, string method, string fromUniqueIdentity, string data, bool canHaveAccess) - { - HttpClient currentHttpClient = new HttpClient(); - await Login(currentHttpClient, roleName, fromUniqueIdentity); - var content = new StringContent(data, Encoding.UTF8, "application/json"); - var apiResult = await currentHttpClient.PostAsync($"{GetBaseUrl()}/api/{controller}/{method}", content); - var response = await apiResult.Content.ReadAsStringAsync(); - var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); - if (canHaveAccess) - Assert.True(result, result.Error?.ToString()); - else - { - Assert.False(result, "User has access, expect: no access!"); - Assert.True(!result && !result.Error.Message.Contains("There is no claim role founded"), result.Error.ToString()); - Assert.True(result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); - } + [Theory] + [InlineData("Owner", "User", "Add", "1-2", @"{""UniqueIdentity"":""""}", true)] + [InlineData("Owner", "User", "Add", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", true)] + [InlineData("Owner", "User", "Add", "1-2", @"{""UniqueIdentity"":""3-4""}", true)] + [InlineData("Moderator", "User", "Add", "1-2", @"{""UniqueIdentity"":""3-4-3-4""}", false)] + [InlineData("Moderator", "User", "Add", "1-2", @"{""UniqueIdentity"":""3-4""}", false)] + [InlineData("Moderator", "User", "Add", "1-2", @"{""UniqueIdentity"":""1-2""}", true)] + public async Task AddAsync(string roleName, string controller, string method, string fromUniqueIdentity, string data, bool canHaveAccess) + { + HttpClient currentHttpClient = new HttpClient(); + await Login(currentHttpClient, roleName, fromUniqueIdentity); + var content = new StringContent(data, Encoding.UTF8, "application/json"); + var apiResult = await currentHttpClient.PostAsync($"{GetBaseUrl()}/api/{controller}/{method}", content); + var response = await apiResult.Content.ReadAsStringAsync(); + var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); + if (canHaveAccess) + { + Assert.True(result, result.Error?.ToString()); + content = new StringContent($"{{\"Id\":{result.Result}}}", Encoding.UTF8, "application/json"); + var apiResult2 = await currentHttpClient.PostAsync($"{GetBaseUrl()}/api/{controller}/getbyid", content); + var response2 = await apiResult2.Content.ReadAsStringAsync(); + var result2 = Newtonsoft.Json.JsonConvert.DeserializeObject>(response2); + var dataUid = Newtonsoft.Json.JsonConvert.DeserializeObject(data); - return result.Result; - } + Assert.True(result2.Result.UniqueIdentity.Length > dataUid.UniqueIdentity.Length); + } + else + { + Assert.False(result, "User has access, expect: no access!"); + Assert.True(!result && !result.Error.Message.Contains("There is no claim role founded"), result.Error.ToString()); + Assert.True(result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); + } + return result.Result; + } - [Theory] - [InlineData("Owner", "User", "Update", "1-2", "1-2", "{}", "{}", true)] - [InlineData("Owner", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", @"{""UniqueIdentity"":""1-2-3-4""}", true)] - [InlineData("Owner", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""3-4""}", @"{""UniqueIdentity"":""3-4""}", true)] - [InlineData("Moderator", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", @"{""UniqueIdentity"":""1-2""}", true)] - //[InlineData("Moderator", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", @"{""UniqueIdentity"":""3-4""}", false)] - public async Task UpdateAsync(string roleName, string controller, string method, string fromUniqueIdentity, string toUniqueIdentity, string addData, string data, bool canHaveAccess) - { - var model = JsonSerializer.Deserialize(data); - model.Id = await AddAsync(roleName, controller, "Add", fromUniqueIdentity, addData, true); - model.UserName = Guid.NewGuid().ToString(); - HttpClient currentHttpClient = new HttpClient(); - await Login(currentHttpClient, roleName, fromUniqueIdentity); - var apiResult = await currentHttpClient.PutAsJsonAsync($"{GetBaseUrl()}/api/{controller}/{method}", model); - var response = await apiResult.Content.ReadAsStringAsync(); - var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); - if (canHaveAccess) - { - Assert.True(result, result.Error?.ToString()); - Assert.Equal(result.Result.UserName, model.UserName); - } - else - { - Assert.False(result, "User has access, expect: no access!"); - Assert.True(!result && !result.Error.Message.Contains("There is no claim role founded"), result.Error.ToString()); - Assert.True(result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); - } + [Theory] + [InlineData("Owner", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""""}", @"{""UniqueIdentity"":""""}", true)] + [InlineData("Owner", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", @"{""UniqueIdentity"":""1-2-3-4""}", true)] + [InlineData("Owner", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""3-4""}", @"{""UniqueIdentity"":""3-4""}", true)] + [InlineData("Moderator", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", @"{""UniqueIdentity"":""1-2""}", true)] + //[InlineData("Moderator", "User", "Update", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", @"{""UniqueIdentity"":""3-4""}", false)] + public async Task UpdateAsync(string roleName, string controller, string method, string fromUniqueIdentity, string toUniqueIdentity, string addData, string data, bool canHaveAccess) + { + var model = JsonSerializer.Deserialize(data); + model.Id = await AddAsync(roleName, controller, "Add", fromUniqueIdentity, addData, true); + model.UserName = Guid.NewGuid().ToString(); + HttpClient currentHttpClient = new HttpClient(); + await Login(currentHttpClient, roleName, fromUniqueIdentity); + var apiResult = await currentHttpClient.PutAsJsonAsync($"{GetBaseUrl()}/api/{controller}/{method}", model); + var response = await apiResult.Content.ReadAsStringAsync(); + var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); + if (canHaveAccess) + { + Assert.True(result, result.Error?.ToString()); + Assert.Equal(result.Result.UserName, model.UserName); + } + else + { + Assert.False(result, "User has access, expect: no access!"); + Assert.True(!result && !result.Error.Message.Contains("There is no claim role founded"), result.Error.ToString()); + Assert.True(result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); + } - } + } - [Theory] - [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", "{}", true)] - [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", true)] - [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "3-4", "1-2", @"{""UniqueIdentity"":""3-4""}", true)] - [InlineData("Moderator", "User", "GetByUniqueIdentity", "1-2", "3-4", "1-2", @"{""UniqueIdentity"":""3-4""}", false)] - [InlineData("Moderator", "User", "GetByUniqueIdentity", "3-4", "3-4", "3-4", @"{""UniqueIdentity"":""3-4""}", true)] - [InlineData("Moderator", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", true)] - public async Task GetByUniqueIdentityAsync(string roleName, string controller, string method,string userUniqueIdentity, string fromUniqueIdentity, string toUniqueIdentity, string data, bool canHaveAccess) - { - var model = JsonSerializer.Deserialize(data); - model.Id = await AddAsync(roleName, controller, "Add", fromUniqueIdentity, data, true); - HttpClient currentHttpClient = new HttpClient(); - await Login(currentHttpClient, roleName, userUniqueIdentity); - var apiResult = await currentHttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/{controller}/{method}", new GetByUniqueIdentityRequestContract() - { - UniqueIdentity = fromUniqueIdentity, - Type = DataTypes.GetUniqueIdentityType.All - }); - var response = await apiResult.Content.ReadAsStringAsync(); - var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); - if (canHaveAccess) - { - Assert.True(result, result.Error?.ToString()); - Assert.True(result.Result.UniqueIdentity.StartsWith(fromUniqueIdentity)); - } - else - { - Assert.False(result, "User has access, expect: no access!"); - Assert.True(result.Error.FailedReasonType == FailedReasonType.NotFound || result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); - } - } + [Theory] + [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""""}", true)] + [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""1-2-3-4""}", true)] + [InlineData("Owner", "User", "GetByUniqueIdentity", "1-2", "3-4", "1-2", @"{""UniqueIdentity"":""3-4""}", true)] + [InlineData("Moderator", "User", "GetByUniqueIdentity", "1-2", "3-4", "1-2", @"{""UniqueIdentity"":""3-4""}", false)] + [InlineData("Moderator", "User", "GetByUniqueIdentity", "3-4", "3-4", "3-4", @"{""UniqueIdentity"":""3-4""}", true)] + [InlineData("Moderator", "User", "GetByUniqueIdentity", "1-2", "1-2", "1-2", @"{""UniqueIdentity"":""1-2""}", true)] + public async Task GetByUniqueIdentityAsync(string roleName, string controller, string method, string userUniqueIdentity, string fromUniqueIdentity, string toUniqueIdentity, string data, bool canHaveAccess) + { + var model = JsonSerializer.Deserialize(data); + model.Id = await AddAsync(roleName, controller, "Add", fromUniqueIdentity, data, true); + HttpClient currentHttpClient = new HttpClient(); + await Login(currentHttpClient, roleName, userUniqueIdentity); + var apiResult = await currentHttpClient.PostAsJsonAsync($"{GetBaseUrl()}/api/{controller}/{method}", new GetByUniqueIdentityRequestContract() + { + UniqueIdentity = fromUniqueIdentity, + Type = DataTypes.GetUniqueIdentityType.All + }); + var response = await apiResult.Content.ReadAsStringAsync(); + var result = Newtonsoft.Json.JsonConvert.DeserializeObject>(response); + if (canHaveAccess) + { + Assert.True(result, result.Error?.ToString()); + Assert.True(result.Result.UniqueIdentity.StartsWith(fromUniqueIdentity)); + } + else + { + Assert.False(result, "User has access, expect: no access!"); + Assert.True(result.Error.FailedReasonType == FailedReasonType.NotFound || result.Error.FailedReasonType == FailedReasonType.AccessDenied, result.Error.ToString()); + } + } - class DataModel - { - public long Id { get; set; } - public string UniqueIdentity { get; set; } - public string UserName { get; set; } - } + class DataModel + { + public long Id { get; set; } + public string UniqueIdentity { get; set; } + public string UserName { get; set; } + } } diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs index e579027..bf99e01 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/Startup.cs @@ -33,6 +33,16 @@ static WebApplicationBuilder CreateBuilder(long port) { Name = "WhiteLabel", Address = $"http://localhost:6041" + }, + new ServiceAddressInfo() + { + Name = "Authentication", + Address = "http://localhost:1044", + }, + new ServiceAddressInfo() + { + Name = "Content", + Address = $"http://localhost:2003" } }; app.Services.AddControllers().AddApplicationPart(typeof(UserController).Assembly); diff --git a/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json new file mode 100644 index 0000000..b91516a --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.AspCore.Tests/appsettings.json @@ -0,0 +1,51 @@ +{ + "Logging": { + "LogLevel": { + "Default": "Information", + "Microsoft.AspNetCore": "Warning" + } + }, + "AllowedHosts": "*", + "Databases": [ + { + "Name": "Entity", + "ProviderName": "InMemory", + "ConnectionString": "Server=.;Database=TestsCore;Integrated Security=True;Trusted_Connection=True;TrustServerCertificate=True" + } + ], + "ServiceAddresses": [ + { + "Name": "Authentication", + "Address": "http://localhost:1044", + "Databases": null + }, + { + "Name": "WhiteLabel", + "Address": "http://localhost:1041", + "Databases": null + }, + { + "Name": "Content", + "Address": "http://localhost:2003", + "Databases": null + } + ], + "Authorization": { + "IsUse": false, + "JWT": { + "Key": "VGhpc0lzGHGHGHlY3JldEtleUZvckp3dEF1dGhlbnRpY2F0aW9u=", + "Issuer": "https://github.com/easymicroservices", + "Audience": "easymicroservices", + + "TokenExpireTimeInSeconds": 86400 + }, + "FullAccessPAT": "ownerpat" + }, + "Swagger": { + "IsUse": true, + "SwaggerUI": { + "Endpoints": [] + } + }, + "Urls": "http://*:4564" +} \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/Authorizations/AspCoreAuthorization.cs b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/Authorizations/AspCoreAuthorization.cs index 1c6d5ed..49718dd 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/Authorizations/AspCoreAuthorization.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/Authorizations/AspCoreAuthorization.cs @@ -110,7 +110,7 @@ MessageContract IsAnonymousMethodCalling(HttpContext httpContext) return true; var controllerActionDescriptor = endpoints.Metadata.GetMetadata(); if (controllerActionDescriptor == null) - return (FailedReasonType.Nothing, "controllerActionDescriptor is null or empty, did you sent correct route to me?"); + return (FailedReasonType.Nothing, $"controllerActionDescriptor is null or empty, did you sent correct route to me? check: {endpoints}"); if (controllerActionDescriptor.ControllerTypeInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute)).Any() || controllerActionDescriptor.MethodInfo.GetCustomAttributes(typeof(AllowAnonymousAttribute)).Any()) return true; diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj index 7bf3ce5..44a02ad 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/EasyMicroservices.Cores.AspCoreApi.csproj @@ -4,7 +4,7 @@ netstandard2.1;net6.0;net7.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 asp core servces. EasyMicroservices@gmail.com core,cores,base,database,services,asp,aspnet diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs index 7cad9f4..6cebd4d 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualReadableQueryServiceController.cs @@ -105,7 +105,10 @@ async Task> ResolveContentAllLang var contentResolver = UnitOfWork.GetContentResolver(); var mapper = UnitOfWork.GetMapper(); var mapped = mapper.MapToList(result.Result); - await contentResolver.ResolveContentAllLanguage(mapped); + foreach (var item in mapped) + { + await contentResolver.ResolveContentAllLanguage(item); + } return mapped; } @@ -217,7 +220,7 @@ public async Task> GetAllByLanguage(GetBy /// /// /// - [HttpPost] + [HttpGet] public async Task> GetAllWithAllLanguage(CancellationToken cancellationToken = default) { var result = await ContractLogic.GetAll(OnGetAllQuery(), cancellationToken); diff --git a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualSimpleQueryServiceController.cs b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualSimpleQueryServiceController.cs index 64ad7e6..c836594 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualSimpleQueryServiceController.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspCoreApi/MultilingualSimpleQueryServiceController.cs @@ -153,7 +153,7 @@ public virtual async Task> Add(TCreateRequestContract reque public virtual async Task AddBulk(CreateBulkRequestContract request, CancellationToken cancellationToken = default) { var result = await WritableContractLogic.AddBulk(request, cancellationToken); - return await AddToContentLanguage(result, request); + return await AddToContentLanguage(result, request.Items.Cast().ToArray()); } /// diff --git a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj index cdfa11d..bb19f46 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj +++ b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/EasyMicroservices.Cores.AspEntityFrameworkCoreApi.csproj @@ -4,7 +4,7 @@ net6.0;net7.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 asp core servces. EasyMicroservices@gmail.com core,cores,base,database,services,asp,aspnet,aspcore,efcore diff --git a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/InternalContentResolver.cs b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/InternalContentResolver.cs index e6da5b4..fe91168 100644 --- a/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/InternalContentResolver.cs +++ b/src/CSharp/EasyMicroservices.Cores.AspEntityFrameworkCoreApi/InternalContentResolver.cs @@ -1,7 +1,6 @@ using EasyMicroservices.ContentsMicroservice.Clients.Helpers; using EasyMicroservices.Cores.Interfaces; -using EasyMicroservices.ServiceContracts; -using System.Linq; +using System.Collections; using System.Threading.Tasks; namespace EasyMicroservices.Cores.AspEntityFrameworkCoreApi; @@ -16,7 +15,7 @@ public InternalContentResolver(ContentLanguageHelper contentLanguageHelper) public async Task AddToContentLanguage(params object[] items) { await Task.WhenAll(_contentLanguageHelper.AddToContentLanguage(items)); - //.Select(x => x.AsCheckedResult())); ; ; + //.Select(x => x.AsCheckedResult())); ; ; } public Task ResolveContentAllLanguage(object contract) @@ -24,6 +23,11 @@ public Task ResolveContentAllLanguage(object contract) return _contentLanguageHelper.ResolveContentAllLanguage(contract); } + public Task ResolveContentAllLanguage(IEnumerable items) + { + return _contentLanguageHelper.ResolveContentAllLanguage(items); + } + public Task ResolveContentLanguage(object contract, string language) { return _contentLanguageHelper.ResolveContentLanguage(contract, language); diff --git a/src/CSharp/EasyMicroservices.Cores.Clients/EasyMicroservices.Cores.Clients.csproj b/src/CSharp/EasyMicroservices.Cores.Clients/EasyMicroservices.Cores.Clients.csproj index 2987556..441c90e 100644 --- a/src/CSharp/EasyMicroservices.Cores.Clients/EasyMicroservices.Cores.Clients.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Clients/EasyMicroservices.Cores.Clients.csproj @@ -4,7 +4,7 @@ netstandard2.0;netstandard2.1;net6.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 core of database. EasyMicroservices@gmail.com core,cores,base,client,clients diff --git a/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj b/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj index e4ce0b6..41d922a 100644 --- a/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Contracts/EasyMicroservices.Cores.Contracts.csproj @@ -4,7 +4,7 @@ netstandard2.0;netstandard2.1;net45;net6.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 core contracts. EasyMicroservices@gmail.com core,cores,base,contract,contracts,dto,dtos diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs index a353bf8..a927b56 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Helpers/DatabaseExtensions.cs @@ -11,16 +11,33 @@ namespace EasyMicroservices.Cores.Database.Helpers; /// internal static class DatabaseExtensions { - public static void SetIdToRecordId(IContext context, TEntity entity, TRecordEntity recordEntity) + public static object GetRecordId(TRecordEntity entity) { var idProperty = typeof(TRecordEntity) .GetProperty(nameof(IRecordIdSchema.RecordId), BindingFlags.Public | BindingFlags.Instance); + if (idProperty == null) throw new Exception($"I cannot find RecordId in your {typeof(TRecordEntity).Name}, Did you inherit from IRecordIdSchema?"); + return idProperty.GetValue(entity); + } + + public static object[] GetId(IContext context, TEntity entity) + { var ids = context.GetPrimaryKeyValues(entity); if (!ids.HasAny()) throw new Exception($"I cannot find any primary key in your {typeof(TEntity).Name}!"); + return ids; + } + + public static void SetIdToRecordId(IContext context, TEntity entity, TRecordEntity recordEntity) + { + var idProperty = typeof(TRecordEntity) + .GetProperty(nameof(IRecordIdSchema.RecordId), BindingFlags.Public | BindingFlags.Instance); + if (idProperty == null) + throw new Exception($"I cannot find RecordId in your {typeof(TRecordEntity).Name}, Did you inherit from IRecordIdSchema?"); + + var ids = GetId(context, entity); idProperty.SetValue(recordEntity, ids.First()); } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs index 3df8f56..f91327a 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidget.cs @@ -34,3 +34,24 @@ public interface IDatabaseWidget : IWidget /// Task AddBulkProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, Dictionary items, CancellationToken cancellationToken = default); } + +/// +/// +/// +public interface IDatabaseWidget : IWidget + where TEntity : class +{ + /// + /// + /// + bool CanProcess(IBaseUnitOfWork baseUnitOfWork); + /// + /// + /// + /// + /// + /// + /// + /// + Task UpdateBulkProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, List items, CancellationToken cancellationToken = default); +} \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs index ef7a503..37773e9 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Interfaces/IDatabaseWidgetManager.cs @@ -32,4 +32,14 @@ Task Add(IBaseUnitOfWork baseUnitOfWork, TEntity entity, T contract, /// Task AddBulk(IBaseUnitOfWork baseUnitOfWork, Dictionary items, CancellationToken cancellationToken = default) where TEntity : class; + /// + /// + /// + /// + /// + /// + /// + /// + Task UpdateBulk(IBaseUnitOfWork baseUnitOfWork, List items, CancellationToken cancellationToken = default) + where TEntity : class; } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs index 5fcdfc7..9ed0461 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Logics/DatabaseLogicInfrastructure.cs @@ -642,6 +642,12 @@ await ActivityChangeLogLogic.ChangeLogAsync(respone.Select(x => ( cancellationToken); } } + + if (!doSkipUpdate || !doSkipDelete) + { + var widgetManager = _baseUnitOfWork.GetDatabaseWidgetManager(); + await widgetManager.UpdateBulk(_baseUnitOfWork, respone, cancellationToken); + } return respone; } @@ -914,6 +920,7 @@ await ActivityChangeLogLogic.ChangeLogAsync(getResult.Result.Selec else return (FailedReasonType.OperationFailed, $"Your entity type {item.GetType().FullName} is not inheritance from ISoftDeleteSchema"); } + return await InternalUpdateBulk(easyWritableQueryable, getResult.Result, false, true, false, false, cancellationToken); } @@ -979,7 +986,7 @@ await InternalUpdate(easyWritableQueryable, result.Entity, false, true, true, tr } } var widgetManager = _baseUnitOfWork.GetDatabaseWidgetManager(); - await widgetManager.Add(_baseUnitOfWork, result.Entity, contract); + await widgetManager.Add(_baseUnitOfWork, result.Entity, contract, cancellationToken); await ActivityChangeLogLogic.AddAsync(result.Entity, _baseUnitOfWork); return result.Entity; } @@ -993,7 +1000,7 @@ await InternalUpdate(easyWritableQueryable, result.Entity, false, true, true, tr /// /// /// - internal async Task> AddBulk(IEasyWritableQueryableAsync easyWritableQueryable, Dictionary items, CancellationToken cancellationToken = default) + internal async Task> AddBulk(IEasyWritableQueryableAsync easyWritableQueryable, Dictionary items, CancellationToken cancellationToken = default) where TEntity : class { var result = await easyWritableQueryable.AddBulkAsync(items.Values, cancellationToken); @@ -1032,7 +1039,7 @@ await InternalUpdateBulk(easyWritableQueryable, result.Select(x => x.Entity).ToL } var response = result.Select(x => x.Entity).ToList(); var widgetManager = _baseUnitOfWork.GetDatabaseWidgetManager(); - await widgetManager.AddBulk(_baseUnitOfWork, items); + await widgetManager.AddBulk(_baseUnitOfWork, items, cancellationToken); await ActivityChangeLogLogic.AddBulkAsync(response, _baseUnitOfWork); return response; } @@ -1082,7 +1089,7 @@ public async Task> AddBulk(IEas /// /// /// - protected async Task> MapToListAsync(IEnumerable items) + protected async Task> MapToListAsync(IEnumerable items) { if (typeof(TFrom) == typeof(TTo)) return items.Cast().ToList(); @@ -1098,7 +1105,7 @@ protected async Task> MapToListAsync(IEnumerable ite /// /// /// - protected async Task> MapToDictionaryAsync(IEnumerable items) + protected async Task> MapToDictionaryAsync(IEnumerable items) { if (typeof(TFrom) == typeof(TTo)) return items.Cast().ToDictionary(x => (TFrom)x, x => (TTo)x); diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs index 9a3b439..0a10499 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Managers/DatabaseWidgetManager.cs @@ -63,4 +63,24 @@ public async Task AddBulk(IBaseUnitOfWork baseUnitOfWork, Dictionary } } } + + /// + /// + /// + /// + /// + /// + /// + /// + public async Task UpdateBulk(IBaseUnitOfWork baseUnitOfWork, List items, CancellationToken cancellationToken = default) where TEntity : class + { + var widgets = GetWidgetsByType(typeof(TEntity)); + foreach (var widget in widgets) + { + if (widget is IDatabaseWidget databaseWidget && databaseWidget.CanProcess(baseUnitOfWork)) + { + await databaseWidget.UpdateBulkProcess(this, baseUnitOfWork, items); + } + } + } } \ No newline at end of file diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingAddEntityWidget.cs similarity index 88% rename from src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs rename to src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingAddEntityWidget.cs index 4d7c42c..baeb314 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingEntityWidget.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingAddEntityWidget.cs @@ -8,7 +8,7 @@ using System.Threading; using System.Threading.Tasks; -namespace EasyMicroservices.Cores.Widgets; +namespace EasyMicroservices.Cores.Database.Widgets; /// /// @@ -16,26 +16,16 @@ namespace EasyMicroservices.Cores.Widgets; /// /// /// -public class SimpleReportingEntityWidget : IDatabaseWidget +public class SimpleReportingAddEntityWidget : SimpleReportingBaseEntityWidget, IDatabaseWidget where TReportEntity : class where TEntity : class where TObjectContract : class { - /// - /// - /// - public bool CanProcess(IBaseUnitOfWork baseUnitOfWork) - { - if (baseUnitOfWork.LogicOptions.HasValue) - return !baseUnitOfWork.LogicOptions.Value.DoStopReporting; - return true; - } - /// /// /// /// - public Type GetObjectType() + public override Type GetObjectType() { return typeof(TObjectContract); } diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingBaseEntityWidget.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingBaseEntityWidget.cs new file mode 100644 index 0000000..7293d19 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingBaseEntityWidget.cs @@ -0,0 +1,25 @@ +using EasyMicroservices.Cores.Interfaces; +using System; + +namespace EasyMicroservices.Cores.Database.Widgets; +/// +/// +/// +public abstract class SimpleReportingBaseEntityWidget +{ + /// + /// + /// + public bool CanProcess(IBaseUnitOfWork baseUnitOfWork) + { + if (baseUnitOfWork.LogicOptions.HasValue) + return !baseUnitOfWork.LogicOptions.Value.DoStopReporting; + return true; + } + + /// + /// + /// + /// + public abstract Type GetObjectType(); +} diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingUpdateEntityWidget.cs b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingUpdateEntityWidget.cs new file mode 100644 index 0000000..7b5c968 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.Database/Database/Widgets/SimpleReportingUpdateEntityWidget.cs @@ -0,0 +1,71 @@ +using EasyMicroservices.Cores.Database.Helpers; +using EasyMicroservices.Cores.Database.Interfaces; +using EasyMicroservices.Cores.Interfaces; +using EasyMicroservices.ServiceContracts; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Threading; +using System.Threading.Tasks; + +namespace EasyMicroservices.Cores.Database.Widgets; + +/// +/// +/// +/// +/// +public class SimpleReportingUpdateEntityWidget : SimpleReportingBaseEntityWidget, IDatabaseWidget + where TReportEntity : class + where TEntity : class +{ + /// + /// + /// + /// + /// + public override Type GetObjectType() + { + return typeof(TEntity); + } + + /// + /// + /// + /// + /// + public Task Initialize(params TEntity[] parameters) + { + return TaskHelper.GetCompletedTask(); + } + + /// + /// + /// + /// + /// + /// + /// + /// + /// + public async Task UpdateBulkProcess(IDatabaseWidgetManager databaseWidgetManager, IBaseUnitOfWork baseUnitOfWork, List items, CancellationToken cancellationToken = default) + { + var logic = baseUnitOfWork.GetLogic(new Models.LogicOptions() + { + DoStopReporting = true + }); + var context = logic.GetReadableContext(); + var getRecordIds = items.Select(x => DatabaseExtensions.GetId(context, x).First()).ToArray(); + var reportEntities = await baseUnitOfWork + .GetMapper() + .MapToDictionaryAsync(items); + + var allItems = await logic + .GetAll(q => q.Where(x => getRecordIds.Contains(((IRecordIdSchema)x).RecordId)), cancellationToken) + .AsCheckedResult(); + + await logic + .UpdateBulk(reportEntities.Values.ToList(), cancellationToken) + .AsCheckedResult(); + } +} diff --git a/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj b/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj index 1d52d1f..12e5e17 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Database/EasyMicroservices.Cores.Database.csproj @@ -4,7 +4,7 @@ netstandard2.0;netstandard2.1;net45;net6.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 core of database. EasyMicroservices@gmail.com core,cores,base,database diff --git a/src/CSharp/EasyMicroservices.Cores.Database/Interfaces/IContentResolver.cs b/src/CSharp/EasyMicroservices.Cores.Database/Interfaces/IContentResolver.cs index 1351726..7f87c51 100644 --- a/src/CSharp/EasyMicroservices.Cores.Database/Interfaces/IContentResolver.cs +++ b/src/CSharp/EasyMicroservices.Cores.Database/Interfaces/IContentResolver.cs @@ -33,4 +33,10 @@ public interface IContentResolver /// /// Task ResolveContentAllLanguage(object contract); + /// + /// + /// + /// + /// + Task ResolveContentAllLanguage(IEnumerable items); } diff --git a/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj b/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj index 68bbcbd..17f9f38 100644 --- a/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj +++ b/src/CSharp/EasyMicroservices.Cores.EntityFrameworkCore/EasyMicroservices.Cores.EntityFrameworkCore.csproj @@ -4,7 +4,7 @@ netstandard2.1;net6.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 ef core of database. EasyMicroservices@gmail.com core,cores,base,database,ef,efcore diff --git a/src/CSharp/EasyMicroservices.Cores.Infrastructure/EasyMicroservices.Cores.Infrastructure.csproj b/src/CSharp/EasyMicroservices.Cores.Infrastructure/EasyMicroservices.Cores.Infrastructure.csproj index 894e54f..dc95cf1 100644 --- a/src/CSharp/EasyMicroservices.Cores.Infrastructure/EasyMicroservices.Cores.Infrastructure.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Infrastructure/EasyMicroservices.Cores.Infrastructure.csproj @@ -4,7 +4,7 @@ netstandard2.0;netstandard2.1;net45;net6.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 core of infrastructure. EasyMicroservices@gmail.com core,cores,base,infrastructure diff --git a/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj index 0354524..c304d2c 100644 --- a/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj +++ b/src/CSharp/EasyMicroservices.Cores.Relational.EntityFrameworkCore/EasyMicroservices.Cores.Relational.EntityFrameworkCore.csproj @@ -4,7 +4,7 @@ netstandard2.1;net6.0;net7.0;net8.0 AnyCPU;x64;x86 EasyMicroservices - 0.0.1.59 + 0.0.1.60 ef core of Relational database. EasyMicroservices@gmail.com core,cores,base,database,ef,efcore,Relational diff --git a/src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/MultiLanguageUserContract.cs b/src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/MultiLanguageUserContract.cs new file mode 100644 index 0000000..b7087c2 --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/MultiLanguageUserContract.cs @@ -0,0 +1,16 @@ +using Contents.GeneratedServices; +using EasyMicroservices.ContentsMicroservice.Clients.Attributes; + +namespace EasyMicroservices.Cores.Tests.Contracts.Common; +public class MultiLanguageUserContract +{ + public long Id { get; set; } + public string UserName { get; set; } + public string UniqueIdentity { get; set; } + [ContentLanguage(nameof(Names))] + public List Names { get; set; } + public bool IsDeleted { get; set; } + public DateTime? DeletedDateTime { get; set; } + public DateTime CreationDateTime { get; set; } + public DateTime? ModificationDateTime { get; set; } +} diff --git a/src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/UserContract.cs b/src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/UserContract.cs new file mode 100644 index 0000000..a3ebfbe --- /dev/null +++ b/src/CSharp/EasyMicroservices.Cores.Tests/Contracts/Common/UserContract.cs @@ -0,0 +1,12 @@ +namespace EasyMicroservices.Cores.Tests.Contracts.Common; +public class UserContract +{ + public long Id { get; set; } + public string UserName { get; set; } + public string UniqueIdentity { get; set; } + public string Name { get; set; } + public bool IsDeleted { get; set; } + public DateTime? DeletedDateTime { get; set; } + public DateTime CreationDateTime { get; set; } + public DateTime? ModificationDateTime { get; set; } +} diff --git a/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Entities/UserEntity.cs b/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Entities/UserEntity.cs index ad566e5..8e4d0ff 100644 --- a/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Entities/UserEntity.cs +++ b/src/CSharp/EasyMicroservices.Cores.Tests/DatabaseLogics/Database/Entities/UserEntity.cs @@ -6,6 +6,7 @@ public class UserEntity : IIdSchema, IUniqueIdentitySchema, IDateTimeSchem { public long Id { get; set; } public string UserName { get; set; } + public string Name { get; set; } public string UniqueIdentity { get; set; } public bool IsDeleted { get; set; } public DateTime? DeletedDateTime { get; set; }