forked from ddrilling/AsbCloudServer
ProcessMapPlanDrilling.http - fix encoding.
Handle foreignKeys exceptions as validation exceptions. Add integr.tests for bad request cases.
This commit is contained in:
parent
8a38777db3
commit
54ef71411a
@ -5,8 +5,10 @@ using AsbCloudApp.Requests;
|
||||
using AsbCloudApp.Services;
|
||||
using AsbCloudDb.Model;
|
||||
using AsbCloudDb.Model.ProcessMapPlan;
|
||||
using AsbCloudDb.Model.WellSections;
|
||||
using Mapster;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
@ -47,8 +49,8 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRe
|
||||
entity.Obsolete = null;
|
||||
dbSet.Add(entity);
|
||||
}
|
||||
|
||||
result += await context.SaveChangesAsync(token);
|
||||
|
||||
result += await SaveChangesWithExceptionHandling(token);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -60,28 +62,21 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRe
|
||||
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
var result = 0;
|
||||
try
|
||||
|
||||
var dbSet = context.Set<TEntity>();
|
||||
var entitiesToMarkDeleted = dbSet
|
||||
.Where(e => e.IdWell == idWell)
|
||||
.Where(e => e.Obsolete == null);
|
||||
var obsolete = DateTimeOffset.UtcNow;
|
||||
foreach (var entity in entitiesToMarkDeleted)
|
||||
{
|
||||
var dbSet = context.Set<TEntity>();
|
||||
var entitiesToMarkDeleted = dbSet
|
||||
.Where(e => e.IdWell == idWell)
|
||||
.Where(e => e.Obsolete == null);
|
||||
var obsolete = DateTimeOffset.UtcNow;
|
||||
foreach (var entity in entitiesToMarkDeleted)
|
||||
{
|
||||
entity.IdState = ChangeLogAbstract.IdClearedOnImport;
|
||||
entity.Obsolete = obsolete;
|
||||
entity.IdEditor = idUser;
|
||||
}
|
||||
result += await context.SaveChangesAsync(token);
|
||||
result += await InsertRange(idUser, dtos, token);
|
||||
await transaction.CommitAsync(token);
|
||||
}
|
||||
catch
|
||||
{
|
||||
await transaction.RollbackAsync(CancellationToken.None);
|
||||
throw;
|
||||
entity.IdState = ChangeLogAbstract.IdClearedOnImport;
|
||||
entity.Obsolete = obsolete;
|
||||
entity.IdEditor = idUser;
|
||||
}
|
||||
result += await SaveChangesWithExceptionHandling(token);
|
||||
result += await InsertRange(idUser, dtos, token);
|
||||
await transaction.CommitAsync(token);
|
||||
|
||||
return result;
|
||||
}
|
||||
@ -99,7 +94,7 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRe
|
||||
entity.Obsolete = obsolete;
|
||||
entity.IdEditor = idUser;
|
||||
}
|
||||
var result = await context.SaveChangesAsync(token);
|
||||
var result = await SaveChangesWithExceptionHandling(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -201,48 +196,39 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRe
|
||||
|
||||
using var transaction = context.Database.BeginTransaction();
|
||||
var result = 0;
|
||||
try
|
||||
|
||||
var ids = dtos.Select(d => d.Id);
|
||||
var dbSet = context.Set<TEntity>();
|
||||
|
||||
var entitiesToDelete = dbSet
|
||||
.Where(e => ids.Contains(e.Id));
|
||||
|
||||
var updateTime = DateTimeOffset.UtcNow;
|
||||
foreach (var entity in entitiesToDelete)
|
||||
{
|
||||
var ids = dtos.Select(d => d.Id);
|
||||
var dbSet = context.Set<TEntity>();
|
||||
|
||||
var entitiesToDelete = dbSet
|
||||
.Where(e => ids.Contains(e.Id));
|
||||
|
||||
var updateTime = DateTimeOffset.UtcNow;
|
||||
foreach (var entity in entitiesToDelete)
|
||||
{
|
||||
if(entity.Obsolete is not null)
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Недопустимо редактировать устаревшие записи");
|
||||
entity.IdState = ChangeLogAbstract.IdStateReplaced;
|
||||
entity.Obsolete = updateTime;
|
||||
entity.IdEditor = idUser;
|
||||
}
|
||||
result += await context.SaveChangesAsync(token);
|
||||
|
||||
var entitiesNew = dtos.Select(Convert);
|
||||
foreach (var entity in entitiesNew)
|
||||
{
|
||||
entity.IdPrevious = entity.Id;
|
||||
entity.Id = default;
|
||||
entity.Creation = updateTime;
|
||||
entity.IdAuthor = idUser;
|
||||
entity.Obsolete = null;
|
||||
entity.IdEditor = null;
|
||||
entity.IdState = ChangeLogAbstract.IdStateActual;
|
||||
dbSet.Add(entity);
|
||||
}
|
||||
|
||||
result += await context.SaveChangesAsync(token);
|
||||
|
||||
await transaction.CommitAsync(token);
|
||||
if(entity.Obsolete is not null)
|
||||
throw new ArgumentInvalidException(nameof(dtos), "Недопустимо редактировать устаревшие записи");
|
||||
entity.IdState = ChangeLogAbstract.IdStateReplaced;
|
||||
entity.Obsolete = updateTime;
|
||||
entity.IdEditor = idUser;
|
||||
}
|
||||
catch
|
||||
result += await context.SaveChangesAsync(token);
|
||||
|
||||
var entitiesNew = dtos.Select(Convert);
|
||||
foreach (var entity in entitiesNew)
|
||||
{
|
||||
await transaction.RollbackAsync(CancellationToken.None);
|
||||
throw;
|
||||
entity.IdPrevious = entity.Id;
|
||||
entity.Id = default;
|
||||
entity.Creation = updateTime;
|
||||
entity.IdAuthor = idUser;
|
||||
entity.Obsolete = null;
|
||||
entity.IdEditor = null;
|
||||
entity.IdState = ChangeLogAbstract.IdStateActual;
|
||||
dbSet.Add(entity);
|
||||
}
|
||||
|
||||
|
||||
result += await SaveChangesWithExceptionHandling(token);
|
||||
await transaction.CommitAsync(token);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -267,4 +253,25 @@ public class ProcessMapPlanBaseRepository<TDto, TEntity> : IProcessMapPlanBaseRe
|
||||
|
||||
return dto;
|
||||
}
|
||||
|
||||
private async Task<int> SaveChangesWithExceptionHandling(CancellationToken token)
|
||||
{
|
||||
try
|
||||
{
|
||||
var result = await context.SaveChangesAsync(token);
|
||||
return result;
|
||||
}
|
||||
catch (DbUpdateException ex)
|
||||
{
|
||||
if (ex.InnerException is PostgresException pgException)
|
||||
TryConvertPostgresExceptionToValidateException(pgException);
|
||||
throw;
|
||||
}
|
||||
}
|
||||
|
||||
private static void TryConvertPostgresExceptionToValidateException(PostgresException pgException)
|
||||
{
|
||||
if (pgException.SqlState == PostgresErrorCodes.ForeignKeyViolation)
|
||||
throw new ArgumentInvalidException("dtos", pgException.Message + "\r\n" + pgException.Detail);
|
||||
}
|
||||
}
|
||||
|
@ -117,6 +117,57 @@ public class ProcessMapPlanDrillingControllerTest: BaseIntegrationTest
|
||||
MatchHelper.Match(expected, actual, excludeProps);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_BadRequest_for_IdWellSectionType()
|
||||
{
|
||||
//arrange
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.RemoveRange(dbset);
|
||||
dbContext.SaveChanges();
|
||||
var badDto = dto.Adapt<ProcessMapPlanDrillingDto>();
|
||||
badDto.IdWellSectionType = int.MaxValue;
|
||||
|
||||
//act
|
||||
var response = await client.InsertRange(dto.IdWell, new[] { badDto });
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_BadRequest_for_IdMode()
|
||||
{
|
||||
//arrange
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.RemoveRange(dbset);
|
||||
dbContext.SaveChanges();
|
||||
var badDto = dto.Adapt<ProcessMapPlanDrillingDto>();
|
||||
badDto.IdMode = int.MaxValue;
|
||||
|
||||
//act
|
||||
var response = await client.InsertRange(dto.IdWell, new[] { badDto });
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InsertRange_returns_BadRequest_for_IdWell()
|
||||
{
|
||||
//arrange
|
||||
var dbset = dbContext.Set<ProcessMapPlanDrilling>();
|
||||
dbset.RemoveRange(dbset);
|
||||
dbContext.SaveChanges();
|
||||
var badDto = dto.Adapt<ProcessMapPlanDrillingDto>();
|
||||
badDto.IdWell = int.MaxValue;
|
||||
|
||||
//act
|
||||
var response = await client.InsertRange(dto.IdWell, new[] { badDto });
|
||||
|
||||
//assert
|
||||
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task ClearAndInsertRange_returns_success()
|
||||
{
|
||||
|
@ -7,7 +7,7 @@
|
||||
@id = 1
|
||||
@idWell = 1
|
||||
|
||||
### получение данных drill test с панели и сохранение их в ЕЦП
|
||||
### получение данных drill test с панели и сохранение их в ЕЦП
|
||||
POST {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
@ -54,12 +54,12 @@ Authorization: {{auth}}
|
||||
}
|
||||
]
|
||||
|
||||
### Получение всех
|
||||
### Получение всех
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### замена старых записей новыми
|
||||
### замена старых записей новыми
|
||||
POST {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling/replace
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
||||
@ -75,7 +75,7 @@ Authorization: {{auth}}
|
||||
"idState": 0,
|
||||
"idPrevious": 0,
|
||||
"idWell": 1,
|
||||
"idWellSectionType": 1,
|
||||
"idWellSectionType": 1500,
|
||||
"depthStart": 0,
|
||||
"depthEnd": 10,
|
||||
"idMode": 2,
|
||||
@ -106,22 +106,22 @@ Authorization: {{auth}}
|
||||
}
|
||||
]
|
||||
|
||||
### Получение только актуальных
|
||||
### Получение только актуальных
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling?Moment=3000-01-01
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### Получение
|
||||
### Получение
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling/dates
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### Получение изменений за дату
|
||||
### Получение изменений за дату
|
||||
GET {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling/changeLog?date=2024-01-19
|
||||
accept: */*
|
||||
Authorization: {{auth}}
|
||||
|
||||
### удаление
|
||||
### удаление
|
||||
DELETE {{baseUrl}}/api/well/{{idWell}}/ProcessMapPlanDrilling
|
||||
Content-Type: {{contentType}}
|
||||
accept: */*
|
Loading…
Reference in New Issue
Block a user