Работник

This commit is contained in:
2025-03-09 20:36:28 +04:00
parent f3449dee3c
commit afe3a18866
11 changed files with 957 additions and 3 deletions

View File

@@ -0,0 +1,23 @@
using CatHasPawsContratcs.AdapterContracts.OperationResponses;
using CatHasPawsContratcs.BindingModels;
namespace CatHasPawsContratcs.AdapterContracts;
public interface IWorkerAdapter
{
WorkerOperationResponse GetList(bool includeDeleted);
WorkerOperationResponse GetPostList(string id, bool includeDeleted);
WorkerOperationResponse GetListByBirthDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
WorkerOperationResponse GetListByEmploymentDate(DateTime fromDate, DateTime toDate, bool includeDeleted);
WorkerOperationResponse GetElement(string data);
WorkerOperationResponse RegisterWorker(WorkerBindingModel workerModel);
WorkerOperationResponse ChangeWorkerInfo(WorkerBindingModel workerModel);
WorkerOperationResponse RemoveWorker(string id);
}

View File

@@ -0,0 +1,19 @@
using CatHasPawsContratcs.Infrastructure;
using CatHasPawsContratcs.ViewModels;
namespace CatHasPawsContratcs.AdapterContracts.OperationResponses;
public class WorkerOperationResponse : OperationResponse
{
public static WorkerOperationResponse OK(List<WorkerViewModel> data) => OK<WorkerOperationResponse, List<WorkerViewModel>>(data);
public static WorkerOperationResponse OK(WorkerViewModel data) => OK<WorkerOperationResponse, WorkerViewModel>(data);
public static WorkerOperationResponse NoContent() => NoContent<WorkerOperationResponse>();
public static WorkerOperationResponse NotFound(string message) => NotFound<WorkerOperationResponse>(message);
public static WorkerOperationResponse BadRequest(string message) => BadRequest<WorkerOperationResponse>(message);
public static WorkerOperationResponse InternalServerError(string message) => InternalServerError<WorkerOperationResponse>(message);
}

View File

@@ -0,0 +1,14 @@
namespace CatHasPawsContratcs.BindingModels;
public class WorkerBindingModel
{
public string? Id { get; set; }
public string? FIO { get; set; }
public string? PostId { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
}

View File

@@ -6,6 +6,8 @@ namespace CatHasPawsContratcs.DataModels;
public class WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted) : IValidation
{
private readonly PostDataModel? _post;
public string Id { get; private set; } = id;
public string FIO { get; private set; } = fio;
@@ -18,6 +20,15 @@ public class WorkerDataModel(string id, string fio, string postId, DateTime birt
public bool IsDeleted { get; private set; } = isDeleted;
public string PostName => _post?.PostName ?? string.Empty;
public WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate, bool isDeleted, PostDataModel post) : this(id, fio, postId, birthDate, employmentDate, isDeleted)
{
_post = post;
}
public WorkerDataModel(string id, string fio, string postId, DateTime birthDate, DateTime employmentDate) : this(id, fio, postId, birthDate, employmentDate, false) { }
public void Validate()
{
if (Id.IsEmpty())

View File

@@ -0,0 +1,18 @@
namespace CatHasPawsContratcs.ViewModels;
public class WorkerViewModel
{
public required string Id { get; set; }
public required string FIO { get; set; }
public required string PostId { get; set; }
public required string PostName { get; set; }
public bool IsDeleted { get; set; }
public DateTime BirthDate { get; set; }
public DateTime EmploymentDate { get; set; }
}

View File

@@ -16,6 +16,8 @@ internal class WorkerStorageContract : IWorkerStorageContract
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Post, PostDataModel>()
.ForMember(x => x.Id, x => x.MapFrom(src => src.PostId));
cfg.CreateMap<Worker, WorkerDataModel>();
cfg.CreateMap<WorkerDataModel, Worker>();
});
@@ -43,7 +45,7 @@ internal class WorkerStorageContract : IWorkerStorageContract
{
query = query.Where(x => x.EmploymentDate >= fromEmploymentDate && x.EmploymentDate <= toEmploymentDate);
}
return [.. query.Select(x => _mapper.Map<WorkerDataModel>(x))];
return [.. JoinPost(query).Select(x => _mapper.Map<WorkerDataModel>(x))];
}
catch (Exception ex)
{
@@ -69,7 +71,7 @@ internal class WorkerStorageContract : IWorkerStorageContract
{
try
{
return _mapper.Map<WorkerDataModel>(_dbContext.Workers.FirstOrDefault(x => x.FIO == fio));
return _mapper.Map<WorkerDataModel>(AddPost(_dbContext.Workers.FirstOrDefault(x => x.FIO == fio && !x.IsDeleted)));
}
catch (Exception ex)
{
@@ -137,5 +139,12 @@ internal class WorkerStorageContract : IWorkerStorageContract
}
}
private Worker? GetWorkerById(string id) => _dbContext.Workers.FirstOrDefault(x => x.Id == id && !x.IsDeleted);
private Worker? GetWorkerById(string id) => AddPost(_dbContext.Workers.FirstOrDefault(x => x.Id == id && !x.IsDeleted));
private IQueryable<Worker> JoinPost(IQueryable<Worker> query)
=> query.GroupJoin(_dbContext.Posts.Where(x => x.IsActual), x => x.PostId, y => y.PostId, (x, y) => new { Worker = x, Post = y })
.SelectMany(xy => xy.Post.DefaultIfEmpty(), (x, y) => x.Worker.AddPost(y));
private Worker? AddPost(Worker? worker)
=> worker?.AddPost(_dbContext.Posts.FirstOrDefault(x => x.PostId == worker.PostId && x.IsActual));
}

View File

@@ -16,9 +16,18 @@ internal class Worker
public bool IsDeleted { get; set; }
[NotMapped]
public Post? Post { get; set; }
[ForeignKey("WorkerId")]
public List<Salary>? Salaries { get; set; }
[ForeignKey("WorkerId")]
public List<Sale>? Sales { get; set; }
public Worker AddPost(Post? post)
{
Post = post;
return this;
}
}

View File

@@ -0,0 +1,508 @@
using CatHasPawsContratcs.BindingModels;
using CatHasPawsContratcs.ViewModels;
using CatHasPawsDatabase.Models;
using CatHasPawsTests.Infrastructure;
using System.Net;
namespace CatHasPawsTests.WebApiControllersTests;
[TestFixture]
internal class WorkerControllerTests : BaseWebApiControllerTest
{
private Post _post;
[SetUp]
public void SetUp()
{
_post = CatHasPawsDbContext.InsertPostToDatabaseAndReturn();
}
[TearDown]
public void TearDown()
{
CatHasPawsDbContext.RemovePostsFromDatabase();
CatHasPawsDbContext.RemoveWorkersFromDatabase();
}
[Test]
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var worker = CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", postId: _post.PostId)
.AddPost(_post);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", postId: _post.PostId);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 3", postId: _post.PostId);
//Act
var response = await HttpClient.GetAsync("/api/workers/getrecords");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(3));
});
AssertElement(data.First(x => x.Id == worker.Id), worker);
}
[Test]
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
{
//Act
var response = await HttpClient.GetAsync("/api/workers/getrecords");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
});
}
[Test]
public async Task GetList_OnlyActual_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", postId: _post.PostId, isDeleted: true);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", postId: _post.PostId, isDeleted: false);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 3", postId: _post.PostId, isDeleted: false);
//Act
var response = await HttpClient.GetAsync("/api/workers/getrecords?includeDeleted=false");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
Assert.That(data.All(x => !x.IsDeleted));
});
}
[Test]
public async Task GetList_IncludeNoActual_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", postId: _post.PostId, isDeleted: true);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", postId: _post.PostId, isDeleted: true);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 3", postId: _post.PostId, isDeleted: false);
//Act
var response = await HttpClient.GetAsync("/api/workers/getrecords?includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(3));
Assert.That(data.Any(x => x.IsDeleted));
Assert.That(data.Any(x => !x.IsDeleted));
});
}
[Test]
public async Task GetList_ByPostId_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", postId: _post.PostId);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", postId: _post.PostId);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 3", postId: _post.PostId, isDeleted: true);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 4");
//Act
var response = await HttpClient.GetAsync($"/api/workers/getpostrecords?id={_post.PostId}&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(3));
Assert.That(data.All(x => x.PostId == _post.PostId));
});
}
[Test]
public async Task GetList_ByPostId_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", postId: _post.PostId);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 4");
//Act
var response = await HttpClient.GetAsync($"/api/workers/getpostrecords?id={Guid.NewGuid()}&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
}
[Test]
public async Task GetList_ByPostId_WhenIdIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/workers/getpostrecords?id=id&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByBirthDate_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", birthDate: DateTime.UtcNow.AddYears(-25));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", birthDate: DateTime.UtcNow.AddYears(-21));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 3", birthDate: DateTime.UtcNow.AddYears(-20), isDeleted: true);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 4", birthDate: DateTime.UtcNow.AddYears(-19));
//Act
var response = await HttpClient.GetAsync($"/api/workers/getbirthdaterecords?fromDate={DateTime.UtcNow.AddYears(-21).AddMinutes(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddYears(-20).AddMinutes(1):MM/dd/yyyy HH:mm:ss}&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
});
}
[Test]
public async Task GetList_ByBirthDate_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/workers/getbirthdaterecords?fromDate={DateTime.UtcNow.AddMinutes(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddMinutes(-1):MM/dd/yyyy HH:mm:ss}&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByEmploymentDate_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 1", employmentDate: DateTime.UtcNow.AddDays(-2));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 2", employmentDate: DateTime.UtcNow.AddDays(-1));
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 3", employmentDate: DateTime.UtcNow.AddDays(1), isDeleted: true);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(fio: "fio 4", employmentDate: DateTime.UtcNow.AddDays(2));
//Act
var response = await HttpClient.GetAsync($"/api/workers/getemploymentrecords?fromDate={DateTime.UtcNow.AddDays(-1).AddMinutes(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1).AddMinutes(1):MM/dd/yyyy HH:mm:ss}&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<WorkerViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
});
}
[Test]
public async Task GetList_ByEmploymentDate_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/workers/getemploymentrecords?fromDate={DateTime.UtcNow.AddMinutes(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddMinutes(-1):MM/dd/yyyy HH:mm:ss}&includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var worker = CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(postId: _post.PostId).AddPost(_post);
//Act
var response = await HttpClient.GetAsync($"/api/workers/getrecord/{worker.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<WorkerViewModel>(response), worker);
}
[Test]
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/workers/getrecord/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ById_WhenRecordWasDeleted_ShouldNotFound_Test()
{
//Arrange
var worker = CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(postId: _post.PostId, isDeleted: true);
//Act
var response = await HttpClient.GetAsync($"/api/workers/getrecord/{worker.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ByFIO_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var worker = CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(postId: _post.PostId).AddPost(_post);
//Act
var response = await HttpClient.GetAsync($"/api/workers/getrecord/{worker.FIO}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<WorkerViewModel>(response), worker);
}
[Test]
public async Task GetElement_ByFIO_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/workers/getrecord/New%20Fio");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ByFIO_WhenRecordWasDeleted_ShouldNotFound_Test()
{
//Arrange
var worker = CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(postId: _post.PostId, isDeleted: true);
//Act
var response = await HttpClient.GetAsync($"/api/workers/getrecord/{worker.FIO}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task Post_ShouldSuccess_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn();
var workerModel = CreateModel(_post.Id);
//Act
var response = await HttpClient.PostAsync($"/api/workers/register", MakeContent(workerModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
AssertElement(CatHasPawsDbContext.GetWorkerFromDatabaseById(workerModel.Id!), workerModel);
}
[Test]
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
{
//Arrange
var workerModel = CreateModel(_post.Id);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(workerModel.Id);
//Act
var response = await HttpClient.PostAsync($"/api/workers/register", MakeContent(workerModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var workerModelWithIdIncorrect = new WorkerBindingModel { Id = "Id", FIO = "fio", BirthDate = DateTime.UtcNow.AddYears(-22), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = _post.Id };
var workerModelWithFioIncorrect = new WorkerBindingModel { Id = Guid.NewGuid().ToString(), FIO = string.Empty, BirthDate = DateTime.UtcNow.AddYears(-22), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = _post.Id };
var workerModelWithPostIdIncorrect = new WorkerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", BirthDate = DateTime.UtcNow.AddYears(-22), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = "Id" };
var workerModelWithBirthDateIncorrect = new WorkerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", BirthDate = DateTime.UtcNow.AddYears(-15), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = _post.Id };
//Act
var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/workers/register", MakeContent(workerModelWithIdIncorrect));
var responseWithFioIncorrect = await HttpClient.PostAsync($"/api/workers/register", MakeContent(workerModelWithFioIncorrect));
var responseWithPostIdIncorrect = await HttpClient.PostAsync($"/api/workers/register", MakeContent(workerModelWithPostIdIncorrect));
var responseWithBirthDateIncorrect = await HttpClient.PostAsync($"/api/workers/register", MakeContent(workerModelWithBirthDateIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithFioIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Fio is incorrect");
Assert.That(responseWithPostIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "PostId is incorrect");
Assert.That(responseWithBirthDateIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "BirthDate is incorrect");
});
}
[Test]
public async Task Post_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/workers/register", MakeContent(string.Empty));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Post_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/workers/register", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_ShouldSuccess_Test()
{
//Arrange
var workerModel = CreateModel(_post.Id);
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(workerModel.Id);
//Act
var response = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
CatHasPawsDbContext.ChangeTracker.Clear();
AssertElement(CatHasPawsDbContext.GetWorkerFromDatabaseById(workerModel.Id!), workerModel);
}
[Test]
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
var workerModel = CreateModel(_post.Id, fio: "new fio");
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn();
//Act
var response = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_WhenRecordWasDeleted_ShouldBadRequest_Test()
{
//Arrange
var workerModel = CreateModel(_post.Id, fio: "new fio");
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(workerModel.Id, isDeleted: true);
//Act
var response = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var workerModelWithIdIncorrect = new WorkerBindingModel { Id = "Id", FIO = "fio", BirthDate = DateTime.UtcNow.AddYears(-22), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = _post.Id };
var workerModelWithFioIncorrect = new WorkerBindingModel { Id = Guid.NewGuid().ToString(), FIO = string.Empty, BirthDate = DateTime.UtcNow.AddYears(-22), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = _post.Id };
var workerModelWithPostIdIncorrect = new WorkerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", BirthDate = DateTime.UtcNow.AddYears(-22), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = "Id" };
var workerModelWithBirthDateIncorrect = new WorkerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", BirthDate = DateTime.UtcNow.AddYears(-15), EmploymentDate = DateTime.UtcNow.AddDays(-5), PostId = _post.Id };
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModelWithIdIncorrect));
var responseWithFioIncorrect = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModelWithFioIncorrect));
var responseWithPostIdIncorrect = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModelWithPostIdIncorrect));
var responseWithBirthDateIncorrect = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(workerModelWithBirthDateIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithFioIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Fio is incorrect");
Assert.That(responseWithPostIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "PostId is incorrect");
Assert.That(responseWithBirthDateIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "BirthDate is incorrect");
});
}
[Test]
public async Task Put_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(string.Empty));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PutAsync($"/api/workers/changeinfo", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_ShouldSuccess_Test()
{
//Arrange
var workerId = Guid.NewGuid().ToString();
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(workerId);
//Act
var response = await HttpClient.DeleteAsync($"/api/workers/delete/{workerId}");
CatHasPawsDbContext.ChangeTracker.Clear();
//Assert
Assert.Multiple(() =>
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
Assert.That(CatHasPawsDbContext.GetWorkerFromDatabaseById(workerId)!.IsDeleted);
});
}
[Test]
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn();
//Act
var response = await HttpClient.DeleteAsync($"/api/workers/delete/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.DeleteAsync($"/api/workers/delete/id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenRecordWasDeleted_ShouldBadRequest_Test()
{
//Arrange
var workerId = CatHasPawsDbContext.InsertWorkerToDatabaseAndReturn(isDeleted: true).Id;
//Act
var response = await HttpClient.DeleteAsync($"/api/workers/delete/{workerId}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
private static void AssertElement(WorkerViewModel? actual, Worker expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.PostId, Is.EqualTo(expected.PostId));
Assert.That(actual.PostName, Is.EqualTo(expected.Post!.PostName));
Assert.That(actual.FIO, Is.EqualTo(expected.FIO));
Assert.That(actual.BirthDate.ToString(), Is.EqualTo(expected.BirthDate.ToString()));
Assert.That(actual.EmploymentDate.ToString(), Is.EqualTo(expected.EmploymentDate.ToString()));
Assert.That(actual.IsDeleted, Is.EqualTo(expected.IsDeleted));
});
}
private static WorkerBindingModel CreateModel(string postId, string? id = null, string fio = "fio", DateTime? birthDate = null, DateTime? employmentDate = null)
{
return new()
{
Id = id ?? Guid.NewGuid().ToString(),
FIO = fio,
BirthDate = birthDate ?? DateTime.UtcNow.AddYears(-22),
EmploymentDate = employmentDate ?? DateTime.UtcNow.AddDays(-5),
PostId = postId
};
}
private static void AssertElement(Worker? actual, WorkerBindingModel expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.PostId, Is.EqualTo(expected.PostId));
Assert.That(actual.FIO, Is.EqualTo(expected.FIO));
Assert.That(actual.BirthDate.ToString(), Is.EqualTo(expected.BirthDate.ToString()));
Assert.That(actual.EmploymentDate.ToString(), Is.EqualTo(expected.EmploymentDate.ToString()));
Assert.That(!actual.IsDeleted);
});
}
}

View File

@@ -0,0 +1,278 @@
using AutoMapper;
using CatHasPawsContratcs.AdapterContracts;
using CatHasPawsContratcs.AdapterContracts.OperationResponses;
using CatHasPawsContratcs.BindingModels;
using CatHasPawsContratcs.BusinessLogicsContracts;
using CatHasPawsContratcs.DataModels;
using CatHasPawsContratcs.Exceptions;
using CatHasPawsContratcs.ViewModels;
namespace CatHasPawsWebApi.Adapters;
public class WorkerAdapter : IWorkerAdapter
{
private readonly IWorkerBusinessLogicContract _buyerBusinessLogicContract;
private readonly ILogger _logger;
private readonly Mapper _mapper;
public WorkerAdapter(IWorkerBusinessLogicContract workerBusinessLogicContract, ILogger<WorkerAdapter> logger)
{
_buyerBusinessLogicContract = workerBusinessLogicContract;
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<WorkerBindingModel, WorkerDataModel>();
cfg.CreateMap<WorkerDataModel, WorkerViewModel>();
});
_mapper = new Mapper(config);
}
public WorkerOperationResponse GetList(bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.. _buyerBusinessLogicContract.GetAllWorkers(!includeDeleted).Select(x => _mapper.Map<WorkerViewModel>(x))]);
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetPostList(string id, bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.. _buyerBusinessLogicContract.GetAllWorkersByPost(id, !includeDeleted).Select(x => _mapper.Map<WorkerViewModel>(x))]);
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetListByBirthDate(DateTime fromDate, DateTime toDate, bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.. _buyerBusinessLogicContract.GetAllWorkersByBirthDate(fromDate, toDate, !includeDeleted).Select(x => _mapper.Map<WorkerViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return WorkerOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetListByEmploymentDate(DateTime fromDate, DateTime toDate, bool includeDeleted)
{
try
{
return WorkerOperationResponse.OK([.. _buyerBusinessLogicContract.GetAllWorkersByEmploymentDate(fromDate, toDate, !includeDeleted).Select(x => _mapper.Map<WorkerViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return WorkerOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return WorkerOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse GetElement(string data)
{
try
{
return WorkerOperationResponse.OK(_mapper.Map<WorkerViewModel>(_buyerBusinessLogicContract.GetWorkerByData(data)));
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return WorkerOperationResponse.NotFound($"Not found element by data {data}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse RegisterWorker(WorkerBindingModel workerModel)
{
try
{
_buyerBusinessLogicContract.InsertWorker(_mapper.Map<WorkerDataModel>(workerModel));
return WorkerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return WorkerOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse ChangeWorkerInfo(WorkerBindingModel workerModel)
{
try
{
_buyerBusinessLogicContract.UpdateWorker(_mapper.Map<WorkerDataModel>(workerModel));
return WorkerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Data is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return WorkerOperationResponse.BadRequest($"Not found element by Id {workerModel.Id}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
return WorkerOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
public WorkerOperationResponse RemoveWorker(string id)
{
try
{
_buyerBusinessLogicContract.DeleteWorker(id);
return WorkerOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
{
_logger.LogError(ex, "ArgumentNullException");
return WorkerOperationResponse.BadRequest("Id is empty");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return WorkerOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
return WorkerOperationResponse.BadRequest($"Not found element by id: {id}");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return WorkerOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
return WorkerOperationResponse.InternalServerError(ex.Message);
}
}
}

View File

@@ -0,0 +1,63 @@
using CatHasPawsContratcs.AdapterContracts;
using CatHasPawsContratcs.BindingModels;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace CatHasPawsWebApi.Controllers;
[Authorize]
[Route("api/[controller]/[action]")]
[ApiController]
[Produces("application/json")]
public class WorkersController(IWorkerAdapter adapter) : ControllerBase
{
private readonly IWorkerAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(bool includeDeleted = false)
{
return _adapter.GetList(includeDeleted).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetPostRecords(string id, bool includeDeleted = false)
{
return _adapter.GetPostList(id, includeDeleted).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetBirthDateRecords(DateTime fromDate, DateTime toDate, bool includeDeleted = false)
{
return _adapter.GetListByBirthDate(fromDate, toDate, includeDeleted).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetEmploymentRecords(DateTime fromDate, DateTime toDate, bool includeDeleted = false)
{
return _adapter.GetListByEmploymentDate(fromDate, toDate, includeDeleted).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] WorkerBindingModel model)
{
return _adapter.RegisterWorker(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] WorkerBindingModel model)
{
return _adapter.ChangeWorkerInfo(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemoveWorker(id).GetResponse(Request, Response);
}
}

View File

@@ -72,6 +72,8 @@ builder.Services.AddTransient<IManufacturerAdapter, ManufacturerAdapter>();
builder.Services.AddTransient<IPostAdapter, PostAdapter>();
builder.Services.AddTransient<IProductAdapter, ProductAdapter>();
builder.Services.AddTransient<ISaleAdapter, SaleAdapter>();
builder.Services.AddTransient<IWorkerAdapter, WorkerAdapter>();
// Learn more about configuring OpenAPI at https://aka.ms/aspnet/openapi
builder.Services.AddOpenApi();