using AsbCloudApp.Data; using AsbCloudApp.Data.ProcessMaps; using AsbCloudApp.Data.User; using AsbCloudApp.Requests; using AsbCloudDb.Model; using AsbCloudDb.Model.ProcessMapPlan; using AsbCloudWebApi.IntegrationTests.Clients; using AsbCloudWebApi.IntegrationTests.Data; using Mapster; using Microsoft.EntityFrameworkCore; using Refit; using System.Net; using System.Reflection; using Xunit; namespace AsbCloudWebApi.IntegrationTests.Controllers.ProcessMapPlan; public abstract class ProcessMapPlanBaseControllerTest : BaseIntegrationTest where TEntity : ProcessMapPlanBase where TDto : ProcessMapPlanBaseDto { private IProcessMapPlanClient client; private string controllerName; protected abstract TEntity? GetByWellId(); protected abstract TEntity GetByNote(DbSet dbSet, TDto dto); protected abstract TDto GetByNote(IEnumerable dtos, TDto dto); public ProcessMapPlanBaseControllerTest(WebAppFactoryFixture factory, string controllerName) : base(factory) { dbContext.CleanupDbSet(); client = factory.GetAuthorizedHttpClient>(string.Empty); this.controllerName = controllerName; } public async Task InsertRangeSuccess(TDto dto) { //arrange var expected = dto.Adapt(); //act var response = await client.InsertRange(dto.IdWell, controllerName, new TDto[] { expected }); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(1, response.Content); var entity = GetByWellId(); Assert.NotNull(entity); var actual = entity.Adapt>(); Assert.Equal(ProcessMapPlanBase.IdStateActual, actual.IdState); var excludeProps = new[] { nameof(ProcessMapPlanBaseDto.Id), nameof(ProcessMapPlanBaseDto.Section) }; MatchHelper.Match(expected, actual.Item, excludeProps); } public async Task InsertRangeFailed(TDto dto) { //act var response = await client.InsertRange(dto.IdWell, controllerName, new[] { dto }); //assert Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode); } public async Task ClearAndInsertRange(TEntity entity, TDto dto) { // arrange var dbset = dbContext.Set(); var entry = dbset.Add(entity); dbContext.SaveChanges(); entry.State = EntityState.Detached; var startTime = DateTimeOffset.UtcNow; // act var result = await client.ClearAndInsertRange(entity.IdWell, controllerName, new TDto[] { dto }); // assert var doneTime = DateTimeOffset.UtcNow; Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(2, result.Content); var count = dbset.Count(); Assert.Equal(2, count); var oldEntity = dbset.First(p => p.Id == entry.Entity.Id); Assert.Equal(ProcessMapPlanBase.IdCleared, oldEntity.IdState); Assert.Equal(1, oldEntity.IdEditor); Assert.NotNull(oldEntity.Obsolete); Assert.InRange(oldEntity.Obsolete.Value, startTime, doneTime); var newEntity = dbset.First(p => p.Id != entry.Entity.Id); Assert.Equal(ProcessMapPlanBase.IdStateActual, newEntity.IdState); Assert.Equal(1, newEntity.IdAuthor); Assert.Null(newEntity.IdEditor); Assert.Null(newEntity.Obsolete); Assert.Null(newEntity.IdPrevious); Assert.InRange(newEntity.Creation, startTime, doneTime); } public async Task UpdateOrInsertRange(TEntity entity, TDto dtoUpdate, TDto dtoInsert) { // arrange var startTime = DateTimeOffset.UtcNow; var dbset = dbContext.Set(); var user = dbContext.Set().First().Adapt(); user.Surname = "userSurname"; user.Email = "user@mail.domain"; var entry = dbset.Add(entity); dbContext.SaveChanges(); entry.State = EntityState.Detached; dtoUpdate.Id = entry.Entity.Id; // act var result = await client.UpdateOrInsertRange(entity.IdWell, controllerName, new TDto[] { dtoUpdate, dtoInsert }); // assert var doneTime = DateTimeOffset.UtcNow; Assert.Equal(HttpStatusCode.OK, result.StatusCode); Assert.Equal(3, result.Content); var count = dbset.Count(); Assert.Equal(3, count); var oldEntity = dbset.First(p => p.Id == entry.Entity.Id); Assert.Equal(ProcessMapPlanBase.IdStateReplaced, oldEntity.IdState); Assert.Equal(1, oldEntity.IdEditor); Assert.NotNull(oldEntity.Obsolete); Assert.InRange(oldEntity.Obsolete.Value, startTime, doneTime); var newEntity = GetByNote(dbset, dtoUpdate); Assert.Equal(ProcessMapPlanBase.IdStateActual, newEntity.IdState); Assert.Equal(1, newEntity.IdAuthor); Assert.Null(newEntity.IdEditor); Assert.Null(newEntity.Obsolete); Assert.Equal(oldEntity.Id, newEntity.IdPrevious); Assert.InRange(newEntity.Creation, startTime, doneTime); var expected = dtoUpdate.Adapt(); var excludeProps = new[] { nameof(ProcessMapPlanBase.Id), nameof(ProcessMapPlanBase.IdWell), nameof(ProcessMapPlanBase.Author), nameof(ProcessMapPlanBase.IdAuthor), nameof(ProcessMapPlanBase.Editor), nameof(ProcessMapPlanBase.Creation), }; MatchHelper.Match(expected, newEntity!, excludeProps); } public async Task DeleteRange(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); var entry = dbset.Add(entity); dbContext.SaveChanges(); entry.State = EntityState.Detached; var startTime = DateTimeOffset.UtcNow; //act var response = await client.DeleteRange(dto.IdWell, controllerName, new[] { entry.Entity.Id }); //assert var doneTime = DateTimeOffset.UtcNow; Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(1, response.Content); var actual = dbContext .Set() .FirstOrDefault(p => p.Id == entry.Entity.Id); Assert.NotNull(actual); Assert.Equal(ProcessMapPlanBase.IdStateDeleted, actual.IdState); Assert.Equal(1, actual.IdEditor); Assert.NotNull(actual.Obsolete); Assert.InRange(actual.Obsolete.Value, startTime, doneTime); } public async Task Clear(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); var entry = dbset.Add(entity); dbContext.SaveChanges(); entry.State = EntityState.Detached; var startTime = DateTimeOffset.UtcNow; //act var response = await client.Clear(dto.IdWell, controllerName); //assert var doneTime = DateTimeOffset.UtcNow; Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.Equal(1, response.Content); var actual = dbContext .Set() .FirstOrDefault(p => p.Id == entry.Entity.Id); Assert.NotNull(actual); Assert.Equal(ProcessMapPlanBase.IdCleared, actual.IdState); Assert.Equal(1, actual.IdEditor); Assert.NotNull(actual.Obsolete); Assert.InRange(actual.Obsolete.Value, startTime, doneTime); } public async Task GetDatesChange(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); var entity2 = entity.Adapt(); entity2.Creation = entity.Creation.AddDays(1); dbset.Add(entity); dbset.Add(entity2); dbContext.SaveChanges(); var timezoneHours = Defaults.Timezone.Hours; var offset = TimeSpan.FromHours(timezoneHours); var dates = new[] { entity.Creation, entity2.Creation } .Select(d => d.ToOffset(offset)) .Select(d => new DateOnly(d.Year, d.Month, d.Day)); //act var response = await client.GetDatesChange(dto.IdWell, controllerName); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.Equal(2, response.Content.Count()); Assert.All(response.Content, d => dates.Contains(d)); } public async Task Get(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); dbset.Add(entity); var entityDeleted = entity.Adapt(); entityDeleted.Creation = entity.Creation.AddDays(-1); entityDeleted.Obsolete = entity.Creation; entityDeleted.IdState = ProcessMapPlanBase.IdStateDeleted; entityDeleted.IdEditor = 1; dbset.Add(entityDeleted); dbContext.SaveChanges(); var response = await client.Get(dto.IdWell, controllerName); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.Single(response.Content); var actual = response.Content.First()!; Assert.NotNull(actual.Section); Assert.NotEmpty(actual.Section); var expected = entity.Adapt()!; var excludeProps = new[] { nameof(ProcessMapPlanBaseDto.Id), }; MatchHelper.Match(expected, actual, excludeProps); } public async Task GetAtMoment(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); var now = DateTimeOffset.UtcNow; var entityDeleted = entity.Adapt(); entityDeleted.Creation = now; entityDeleted.Obsolete = now.AddMinutes(1); entityDeleted.IdState = ProcessMapPlanBase.IdStateDeleted; entityDeleted.IdEditor = 1; dbset.Add(entityDeleted); var entityDeleted2 = entity.Adapt(); entityDeleted2.Creation = now.AddMinutes(1); entityDeleted2.Obsolete = now.AddMinutes(2); entityDeleted2.IdState = ProcessMapPlanBase.IdStateDeleted; entityDeleted2.IdEditor = 1; dbset.Add(entityDeleted2); dbContext.SaveChanges(); //act var response = await client.Get(dto.IdWell, controllerName, now.AddMinutes(0.5)); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.Single(response.Content); } public async Task GetByUpdated(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); dbset.Add(entity); var entity2 = entity.Adapt(); entity2.Obsolete = DateTimeOffset.UtcNow; dbset.Add(entity2); dbContext.SaveChanges(); //act var response = await client.Get(Defaults.RemoteUid, controllerName, DateTimeOffset.UtcNow.AddHours(-1)); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.Equal(2, response.Content.Count()); } public async Task GetUpdated(TEntity entity, TDto dto) { //arrange var dbset = dbContext.Set(); dbset.Add(entity); var entity2 = entity.Adapt(); entity2.Creation = entity.Creation.AddHours(1); dbset.Add(entity2); var entity3 = entity.Adapt(); entity3.Obsolete = entity.Creation.AddHours(1); dbset.Add(entity3); dbContext.SaveChanges(); var timezoneHours = Defaults.Timezone.Hours; var offset = TimeSpan.FromHours(timezoneHours); var updateFrom = entity.Creation.ToOffset(offset).AddHours(0.5); //act var request = new ProcessMapPlanBaseRequest { UpdateFrom = updateFrom, }; var response = await client.Get(dto.IdWell, controllerName); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); Assert.NotNull(response.Content); Assert.Equal(2, response.Content.Count()); var entity2Dto = entity2.Adapt(); var actual = GetByNote(response.Content, entity2Dto); var expected = entity2.Adapt(); var excludeProps = new[] { nameof(ProcessMapPlanBaseDto.Id), }; MatchHelper.Match(expected, actual, excludeProps); } public async Task Parse(int IdWell, string fileName, TDto dto) { //arrange var stream = Assembly.GetExecutingAssembly().GetFileCopyStream(fileName); var streamPart = new StreamPart(stream, fileName, "application/octet-stream"); //act var response = await client.Parse(IdWell, controllerName, streamPart); //assert Assert.Equal(HttpStatusCode.OK, response.StatusCode); var parserResult = response.Content; Assert.NotNull(parserResult); Assert.Single(parserResult.Item); Assert.True(parserResult.IsValid); var row = parserResult.Item.First(); var dtoActual = row.Item; Assert.True(row.IsValid); var excludeProps = new[] { nameof(ProcessMapPlanBaseDto.IdWell) }; MatchHelper.Match(dto, dtoActual, excludeProps); } public async Task ParseWithWarnings(int IdWell, string fileName) { //arrange var stream = Assembly.GetExecutingAssembly().GetFileCopyStream(fileName); var streamPart = new StreamPart(stream, fileName, "application/octet-stream"); //act var response = await client.Parse(IdWell, controllerName, streamPart); Assert.Equal(HttpStatusCode.OK, response.StatusCode); var parserResult = response.Content; Assert.NotNull(parserResult); Assert.False(parserResult.IsValid); Assert.Single(parserResult.Warnings); Assert.Single(parserResult.Item); var row = parserResult.Item.First(); Assert.False(row.IsValid); Assert.Equal(2, row.Warnings.Count()); } }