diff --git a/src/Volo.Abp/Volo/Abp/AbpServiceBase.cs b/src/Volo.Abp/Volo/Abp/AbpServiceBase.cs index 38df473ebb..097e60aea4 100644 --- a/src/Volo.Abp/Volo/Abp/AbpServiceBase.cs +++ b/src/Volo.Abp/Volo/Abp/AbpServiceBase.cs @@ -1,6 +1,7 @@ using System; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Abstractions; +using Volo.Abp.Guids; using Volo.Abp.ObjectMapping; using Volo.Abp.Uow; @@ -12,6 +13,8 @@ namespace Volo.Abp public IObjectMapper ObjectMapper { get; set; } + public IGuidGenerator GuidGenerator { get; set; } + protected IUnitOfWork CurrentUnitOfWork => UnitOfWorkManager?.Current; public ILoggerFactory LoggerFactory { get; set; } @@ -23,5 +26,10 @@ namespace Volo.Abp - Setting manager - Localization manager and helper methods */ + + protected AbpServiceBase() + { + GuidGenerator = SimpleGuidGenerator.Instance; + } } } diff --git a/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs b/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs index a8c0671a69..e36c6a9628 100644 --- a/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs +++ b/src/Volo.Abp/Volo/Abp/Application/Services/CrudAppServiceBase.cs @@ -18,7 +18,7 @@ namespace Volo.Abp.Application.Services where TUpdateInput : IEntityDto { protected IQueryableRepository Repository { get; } - + protected virtual string GetPermissionName { get; set; } protected virtual string GetAllPermissionName { get; set; } @@ -115,7 +115,16 @@ namespace Volo.Abp.Application.Services /// protected virtual TEntity MapToEntity(TCreateInput createInput) { - return ObjectMapper.Map(createInput); + var entity = ObjectMapper.Map(createInput); + + //Set ID for GUIDs + var entityWithGuidId = entity as IEntity; + if (entityWithGuidId != null && entityWithGuidId.Id == Guid.Empty) + { + entityWithGuidId.Id = GuidGenerator.Create(); + } + + return entity; } /// diff --git a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/AppModule.cs b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/AppModule.cs index e712b05b18..297a5ed134 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/AppModule.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/App/AppModule.cs @@ -26,6 +26,8 @@ namespace Volo.Abp.AspNetCore.App { options.CreateControllersForAppServices(typeof(TestAppModule).Assembly); }); + + services.AddAssemblyOf(); } public override void OnApplicationInitialization(ApplicationInitializationContext context) diff --git a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs index 0d7d91999f..a27e28a503 100644 --- a/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs +++ b/test/Volo.Abp.AspNetCore.Mvc.Tests/Volo/Abp/AspNetCore/Mvc/PersonAppService_Tests.cs @@ -1,18 +1,127 @@ -using Shouldly; +using System; +using Shouldly; using System.Threading.Tasks; +using Microsoft.Extensions.DependencyInjection; using Volo.Abp.Application.Dtos; using Volo.Abp.TestApp.Application; +using Volo.Abp.TestApp.Domain; using Xunit; +using Volo.Abp.Domain.Repositories; +using System.Linq; +using System.Net; +using System.Net.Http; +using System.Text; +using Volo.Abp.ObjectMapping; +using Volo.Abp.Json; namespace Volo.Abp.AspNetCore.Mvc { + //TODO: Refactor to make tests easier. + public class PersonAppService_Tests : AspNetCoreMvcTestBase { + private readonly IQueryableRepository _personRepository; + private readonly IJsonSerializer _jsonSerializer; + private readonly IObjectMapper _objectMapper; + + public PersonAppService_Tests() + { + _personRepository = ServiceProvider.GetRequiredService>(); + _jsonSerializer = ServiceProvider.GetRequiredService(); + _objectMapper = ServiceProvider.GetRequiredService(); + } + [Fact] public async Task GetAll_Test() { + //Ideally should be [GET] /api/app/person var result = await GetResponseAsObjectAsync>("/api/services/app/person/GetAll"); result.Items.Count.ShouldBeGreaterThan(0); } + + [Fact] + public async Task Get_Test() + { + var firstPerson = _personRepository.GetList().First(); + + //Ideally should be [GET] /api/app/person/{id} + var result = await GetResponseAsObjectAsync("/api/services/app/person/Get?id=" + firstPerson.Id); + result.Name.ShouldBe(firstPerson.Name); + } + + [Fact] + public async Task Delete_Test() + { + var firstPerson = _personRepository.GetList().First(); + + //Ideally should be [DELETE] /api/app/person/{id} + await Client.DeleteAsync("/api/services/app/person/Delete?id=" + firstPerson.Id); + + (await _personRepository.FindAsync(firstPerson.Id)).ShouldBeNull(); + } + + [Fact] + public async Task Create_Test() + { + //Act + + var postData = _jsonSerializer.Serialize(new PersonDto {Name = "John", Age = 33}); + + //Ideally should be [POST] /api/app/person + var response = await Client.PostAsync( + "/api/services/app/person/Create", + new StringContent(postData, Encoding.UTF8, "application/json") + ); + + response.IsSuccessStatusCode.ShouldBeTrue(); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + var resultAsString = await response.Content.ReadAsStringAsync(); + PersonDto resultDto = _jsonSerializer.Deserialize(resultAsString); + + //Assert + + resultDto.Id.ShouldNotBe(default(Guid)); + resultDto.Name.ShouldBe("John"); + resultDto.Age.ShouldBe(33); + + (await _personRepository.FindAsync(resultDto.Id)).ShouldNotBeNull(); + } + + + [Fact] + public async Task Update_Test() + { + //Arrange + + var firstPerson = _personRepository.GetList().First(); + var firstPersonAge = firstPerson.Age; //Persist to a variable since we are using in-memory database which shares same entity. + var updateDto = _objectMapper.Map(firstPerson); + updateDto.Age = updateDto.Age + 1; + var putData = _jsonSerializer.Serialize(updateDto); + + //Act + + //Ideally should be [PUT] /api/app/person + var response = await Client.PutAsync( + "/api/services/app/person/Update", + new StringContent(putData, Encoding.UTF8, "application/json") + ); + + response.IsSuccessStatusCode.ShouldBeTrue(); + response.StatusCode.ShouldBe(HttpStatusCode.OK); + var resultAsString = await response.Content.ReadAsStringAsync(); + PersonDto resultDto = _jsonSerializer.Deserialize(resultAsString); + + //Assert + + resultDto.Id.ShouldBe(firstPerson.Id); + resultDto.Name.ShouldBe(firstPerson.Name); + resultDto.Age.ShouldBe(firstPersonAge + 1); + + var personInDb = (await _personRepository.FindAsync(resultDto.Id)); + personInDb.ShouldNotBeNull(); + personInDb.Name.ShouldBe(firstPerson.Name); + personInDb.Age.ShouldBe(firstPersonAge + 1); + } } } diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs index 0f60b722a3..74ebf2c821 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/Domain/Person.cs @@ -9,6 +9,11 @@ namespace Volo.Abp.TestApp.Domain public int Age { get; set; } + private Person() + { + + } + public Person(Guid id, string name, int age) { Id = id; diff --git a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs index 0c7f3ed811..6660f5c873 100644 --- a/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs +++ b/test/Volo.Abp.TestApp/Volo/Abp/TestApp/TestAppModule.cs @@ -11,14 +11,7 @@ namespace Volo.Abp.TestApp { public override void ConfigureServices(IServiceCollection services) { - services.Configure(options => - { - options.Configurators.Add((IAbpAutoMapperConfigurationContext ctx) => - { - ctx.MapperConfiguration.CreateMap(); - }); - }); - + ConfigureAutoMapper(services); services.AddAssemblyOf(); } @@ -27,6 +20,17 @@ namespace Volo.Abp.TestApp SeedTestData(context); } + private static void ConfigureAutoMapper(IServiceCollection services) + { + services.Configure(options => + { + options.Configurators.Add((IAbpAutoMapperConfigurationContext ctx) => + { + ctx.MapperConfiguration.CreateMap().ReverseMap(); + }); + }); + } + private static void SeedTestData(ApplicationInitializationContext context) { using (IServiceScope scope = context.ServiceProvider.CreateScope())