4 теста контроллера

This commit is contained in:
2025-09-12 00:34:40 +04:00
parent d8c0ff638b
commit d9288a2165
20 changed files with 1745 additions and 98 deletions

View File

@@ -14,5 +14,7 @@ public class BuyerBindingModel
public string? Email { get; set; }
public float TotalSpend { get; set; }
public double DiscountSize { get; set; }
}

View File

@@ -14,6 +14,7 @@ public class ProductHistoryDataModel(string productId, double oldPrice) : IValid
public string ProductId { get; private set; } = productId;
public double OldPrice { get; private set; } = oldPrice;
public DateTime ChangeDate { get; private set; } = DateTime.UtcNow;
public ProductDataModel? Product { get; set; }
public void Validate()
{
if (ProductId.IsEmpty())

View File

@@ -26,7 +26,8 @@ namespace RomashkiDatabase.Implementations
cfg.CreateMap<Product, ProductDataModel>();
cfg.CreateMap<ProductDataModel, Product>()
.ForMember(x => x.IsDeleted, x => x.MapFrom(src => false));
cfg.CreateMap<ProductHistory, ProductHistoryDataModel>();
cfg.CreateMap<ProductHistory, ProductHistoryDataModel>()
.ForMember(dest => dest.Product, opt => opt.MapFrom(src => src.Product));
});
_mapper = new Mapper(config);
}
@@ -53,7 +54,11 @@ namespace RomashkiDatabase.Implementations
{
try
{
return [.. _dbContext.ProductHistories.Where(x => x.ProductId == productId).OrderByDescending(x => x.ChangeDate).Select(x => _mapper.Map<ProductHistoryDataModel>(x))];
return [.. _dbContext.ProductHistories
.Include(x => x.Product)
.Where(x => x.ProductId == productId)
.OrderByDescending(x => x.ChangeDate)
.Select(x => _mapper.Map<ProductHistoryDataModel>(x))];
}
catch (Exception ex)
{

View File

@@ -116,6 +116,5 @@ internal class SaleStorageContract : ISaleStorageContract
throw new StorageException(ex);
}
}
private Sale? GetSaleById(string id) => _dbContext.Sales.FirstOrDefault(x
=> x.Id == id);
private Sale? GetSaleById(string id) => _dbContext.Sales.Include(x => x.SaleProducts).FirstOrDefault(x => x.Id == id);
}

View File

@@ -45,7 +45,7 @@ internal static class RomashkiDbContextExtensions
return productHistory;
}
public static Discount InsertSalaryToDatabaseAndReturn(this RomashkiDbContext dbContext, string buyerId,DateTime? discountDate = null, double discountSize = 10)
public static Discount InsertDiscountToDatabaseAndReturn(this RomashkiDbContext dbContext, string buyerId,DateTime? discountDate = null, double discountSize = 10)
{
var discount = new Discount() { BuyerId = buyerId, DiscountDate = discountDate ?? DateTime.UtcNow, DiscountSize = discountSize };
dbContext.Discounts.Add(discount);

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.EntityFrameworkCore;
using RomashkiContract.DataModels;
using RomashkiContract.Exceptions;
using RomashkiContracts.DataModels;
using RomashkiContracts.Enums;
@@ -37,9 +38,9 @@ internal class DiscountStorageContractTests : BaseStorageContractTest
[Test]
public void Try_GetList_WhenHaveRecords_Test()
{
var discount = RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountSize: 10);
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id);
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id);
var discount = RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountSize: 10);
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id);
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id);
var list = _discountStorageContract.GetList(DateTime.UtcNow.AddDays(-10), DateTime.UtcNow.AddDays(10));
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
@@ -57,12 +58,12 @@ internal class DiscountStorageContractTests : BaseStorageContractTest
[Test]
public void Try_GetList_OnlyInDatePeriod_Test()
{
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
var list = _discountStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1));
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
@@ -74,10 +75,10 @@ internal class DiscountStorageContractTests : BaseStorageContractTest
[Test]
public void Try_GetList_ByBuyer_Test()
{
var buyer = RomashkiDbContext.InsertBuyerToDatabaseAndReturn(fio: "name 2");
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id);
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id);
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(buyer.Id);
var buyer = RomashkiDbContext.InsertBuyerToDatabaseAndReturn(fio: "name 2", email: "test2@asd.as");
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id);
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id);
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(buyer.Id);
var list = _discountStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), _buyer.Id);
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>
@@ -90,13 +91,13 @@ internal class DiscountStorageContractTests : BaseStorageContractTest
[Test]
public void Try_GetList_ByBuyerOnlyInDatePeriod_Test()
{
var buyer = RomashkiDbContext.InsertBuyerToDatabaseAndReturn(fio: "name 2");
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
RomashkiDbContext.InsertSalaryToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
var buyer = RomashkiDbContext.InsertBuyerToDatabaseAndReturn(fio: "name 2", email: "test3@asd.as");
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(buyer.Id, discountDate: DateTime.UtcNow.AddDays(-1).AddMinutes(5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(buyer.Id, discountDate: DateTime.UtcNow.AddDays(1).AddMinutes(-5));
RomashkiDbContext.InsertDiscountToDatabaseAndReturn(_buyer.Id, discountDate: DateTime.UtcNow.AddDays(-2));
var list = _discountStorageContract.GetList(DateTime.UtcNow.AddDays(-1), DateTime.UtcNow.AddDays(1), _buyer.Id);
Assert.That(list, Is.Not.Null);
Assert.Multiple(() =>

View File

@@ -206,7 +206,7 @@ internal class PostStorageContractTests : BaseStorageContractTest
{
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn(Guid.NewGuid().ToString(), isActual: true);
_postStorageContract.DelElement(post.PostId);
var element = RomashkiDbContext.GetPostFromDatabaseByPostId(post.PostId);
var element = RomashkiDbContext.GetPostsFromDatabaseByPostId(post.PostId).FirstOrDefault();
Assert.Multiple(() =>
{
Assert.That(element, Is.Not.Null);
@@ -232,7 +232,7 @@ internal class PostStorageContractTests : BaseStorageContractTest
{
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn(Guid.NewGuid().ToString(), isActual: false);
_postStorageContract.ResElement(post.PostId);
var element = RomashkiDbContext.GetPostFromDatabaseByPostId(post.PostId);
var element = RomashkiDbContext.GetPostsFromDatabaseByPostId(post.PostId).FirstOrDefault();
Assert.Multiple(() =>
{
Assert.That(element, Is.Not.Null);

View File

@@ -163,9 +163,9 @@ internal class BuyerControllerTests : BaseWebApiControllerTest
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var buyerModelWithIdIncorrect = new BuyerBindingModel { Id = "Id", FIO = "fio", Email = "test@5.com", DiscountSize = 10 };
var buyerModelWithFioIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = string.Empty, Email = "test@5.com", DiscountSize = 10 };
var buyerModelWithEmailIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", Email = "71", DiscountSize = 10 };
var buyerModelWithIdIncorrect = new BuyerBindingModel { Id = "Id", FIO = "fio", Email = "test@5.com", TotalSpend = 0, DiscountSize = 10 };
var buyerModelWithFioIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = string.Empty, Email = "test@5.com", TotalSpend = 0, DiscountSize = 10 };
var buyerModelWithEmailIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", Email = "71", TotalSpend = 0, DiscountSize = 10 };
//Act
var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/buyers", MakeContent(buyerModelWithIdIncorrect));
var responseWithFioIncorrect = await HttpClient.PostAsync($"/api/buyers", MakeContent(buyerModelWithFioIncorrect));
@@ -240,9 +240,9 @@ internal class BuyerControllerTests : BaseWebApiControllerTest
public async Task Put_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var buyerModelWithIdIncorrect = new BuyerBindingModel { Id = "Id", FIO = "fio", Email = "test@5.com", DiscountSize = 10 };
var buyerModelWithFioIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = string.Empty, Email = "test@5.com", DiscountSize = 10 };
var buyerModelWithEmailIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", Email = "71", DiscountSize = 10 };
var buyerModelWithIdIncorrect = new BuyerBindingModel { Id = "Id", FIO = "fio", Email = "test@5.com", TotalSpend = 0, DiscountSize = 10 };
var buyerModelWithFioIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = string.Empty, Email = "test@5.com", TotalSpend = 0, DiscountSize = 10 };
var buyerModelWithEmailIncorrect = new BuyerBindingModel { Id = Guid.NewGuid().ToString(), FIO = "fio", Email = "71", TotalSpend = 0, DiscountSize = 10 };
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/buyers", MakeContent(buyerModelWithIdIncorrect));
var responseWithFioIncorrect = await HttpClient.PutAsync($"/api/buyers", MakeContent(buyerModelWithFioIncorrect));
@@ -348,12 +348,13 @@ internal class BuyerControllerTests : BaseWebApiControllerTest
});
}
private static BuyerBindingModel CreateBindingModel(string? id = null, string fio = "fio", string email = "test@6.com", double discountSize = 10) =>
private static BuyerBindingModel CreateBindingModel(string? id = null, string fio = "fio", string email = "test@6.com", float totalSpend = 0, double discountSize = 10) =>
new()
{
Id = id ?? Guid.NewGuid().ToString(),
FIO = fio,
Email = email,
TotalSpend = totalSpend,
DiscountSize = discountSize
};
@@ -365,6 +366,7 @@ internal class BuyerControllerTests : BaseWebApiControllerTest
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.FIO, Is.EqualTo(expected.FIO));
Assert.That(actual.Email, Is.EqualTo(expected.Email));
Assert.That(actual.TotalSpend, Is.EqualTo(expected.TotalSpend));
Assert.That(actual.DiscountSize, Is.EqualTo(expected.DiscountSize));
});
}

View File

@@ -0,0 +1,413 @@
using RomashkiDatabase;
using RomashkiDatabase.Models;
using RomashkiTests.Infrastructure;
using RomashkiContract.BindingModels;
using RomashkiContract.ViewModels;
using RomashkiContracts.Enums;
using System.Net;
namespace RomashkiTests.WebApiControllersTests;
[TestFixture]
internal class PostControllerTests : BaseWebApiControllerTest
{
[TearDown]
public void TearDown()
{
RomashkiDbContext.RemoveWorkersFromDatabase();
RomashkiDbContext.RemovePostsFromDatabase();
}
[Test]
public async Task GetAllRecords_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn(postName: "name 1");
RomashkiDbContext.InsertPostToDatabaseAndReturn(postName: "name 2");
RomashkiDbContext.InsertPostToDatabaseAndReturn(postName: "name 3");
//Act
var response = await HttpClient.GetAsync("/api/posts");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<PostViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(3));
});
AssertElement(data.First(x => x.Id == post.PostId), post);
}
[Test]
public async Task GetAllRecords_WhenNoRecords_ShouldSuccess_Test()
{
//Act
var response = await HttpClient.GetAsync("/api/posts");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<PostViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
});
}
[Test]
public async Task GetRecord_ById_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/posts/{post.PostId}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<PostViewModel>(response), post);
}
[Test]
public async Task GetRecord_ById_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/posts/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetRecord_ById_WhenRecordWasDeleted_ShouldNotFound_Test()
{
//Arrange
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn(isActual: false);
//Act
var response = await HttpClient.GetAsync($"/api/posts/{post.PostId}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetRecord_ByName_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/posts/{post.PostName}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<PostViewModel>(response), post);
}
[Test]
public async Task GetRecord_ByName_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/posts/New%20Name");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetRecord_ByName_WhenRecordWasDeleted_ShouldNotFound_Test()
{
//Arrange
var post = RomashkiDbContext.InsertPostToDatabaseAndReturn(isActual: false);
//Act
var response = await HttpClient.GetAsync($"/api/posts/{post.PostName}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task Register_ShouldSuccess_Test()
{
//Arrange
RomashkiDbContext.InsertPostToDatabaseAndReturn();
var postModel = CreateModel();
//Act
var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
AssertElement(RomashkiDbContext.GetPostFromDatabaseByPostId(postModel.Id!), postModel);
}
[Test]
public async Task Register_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
{
//Arrange
var postModel = CreateModel();
RomashkiDbContext.InsertPostToDatabaseAndReturn(postModel.Id);
//Act
var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Register_WhenHaveRecordWithSameName_ShouldBadRequest_Test()
{
//Arrange
var postModel = CreateModel(postName: "unique name");
RomashkiDbContext.InsertPostToDatabaseAndReturn(postName: postModel.PostName!);
//Act
var response = await HttpClient.PostAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Register_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var postModelWithIdIncorrect = new PostBindingModel { Id = "Id", PostName = "name", PostType = PostType.Assistant.ToString() };
var postModelWithNameIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = PostType.Assistant.ToString() };
var postModelWithPostTypeIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = "name", PostType = string.Empty };
//Act
var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithIdIncorrect));
var responseWithNameIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithNameIncorrect));
var responseWithPostTypeIncorrect = await HttpClient.PostAsync($"/api/posts", MakeContent(postModelWithPostTypeIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect");
Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Type is incorrect");
});
}
[Test]
public async Task Register_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/posts", MakeContent(string.Empty));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Register_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/posts", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task ChangeInfo_ShouldSuccess_Test()
{
//Arrange
var postModel = CreateModel();
RomashkiDbContext.InsertPostToDatabaseAndReturn(postModel.Id);
//Act
var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
RomashkiDbContext.ChangeTracker.Clear();
AssertElement(RomashkiDbContext.GetPostFromDatabaseByPostId(postModel.Id!), postModel);
}
[Test]
public async Task ChangeInfo_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
var postModel = CreateModel();
RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task ChangeInfo_WhenRecordWasDeleted_ShouldBadRequest_Test()
{
//Arrange
var postModel = CreateModel();
RomashkiDbContext.InsertPostToDatabaseAndReturn(postModel.Id, isActual: false);
//Act
var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task ChangeInfo_WhenHaveRecordWithSameName_ShouldBadRequest_Test()
{
//Arrange
var postModel = CreateModel(postName: "unique name");
RomashkiDbContext.InsertPostToDatabaseAndReturn(postModel.Id);
RomashkiDbContext.InsertPostToDatabaseAndReturn(postName: postModel.PostName!);
//Act
var response = await HttpClient.PutAsync($"/api/posts", MakeContent(postModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task ChangeInfo_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var postModelWithIdIncorrect = new PostBindingModel { Id = "Id", PostName = "name", PostType = PostType.Assistant.ToString() };
var postModelWithNameIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = string.Empty, PostType = PostType.Assistant.ToString() };
var postModelWithPostTypeIncorrect = new PostBindingModel { Id = Guid.NewGuid().ToString(), PostName = "name", PostType = string.Empty };
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithIdIncorrect));
var responseWithNameIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithNameIncorrect));
var responseWithPostTypeIncorrect = await HttpClient.PutAsync($"/api/posts", MakeContent(postModelWithPostTypeIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect");
Assert.That(responseWithPostTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Type is incorrect");
});
}
[Test]
public async Task ChangeInfo_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PutAsync($"/api/posts", MakeContent(string.Empty));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task ChangeInfo_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PutAsync($"/api/posts", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_ShouldSuccess_Test()
{
//Arrange
var postId = RomashkiDbContext.InsertPostToDatabaseAndReturn().PostId;
//Act
var response = await HttpClient.DeleteAsync($"/api/posts/{postId}");
//Assert
Assert.Multiple(() =>
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
Assert.That(RomashkiDbContext.GetPostFromDatabaseByPostId(postId), Is.Null);
});
}
[Test]
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.DeleteAsync($"/api/posts/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenRecordWasDeleted_ShouldBadRequest_Test()
{
//Arrange
var postId = RomashkiDbContext.InsertPostToDatabaseAndReturn(isActual: false).PostId;
//Act
var response = await HttpClient.DeleteAsync($"/api/posts/{postId}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.DeleteAsync($"/api/posts/id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Restore_ShouldSuccess_Test()
{
//Arrange
var postId = RomashkiDbContext.InsertPostToDatabaseAndReturn(isActual: false).PostId;
//Act
var response = await HttpClient.PatchAsync($"/api/posts/{postId}", null);
//Assert
Assert.Multiple(() =>
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
Assert.That(RomashkiDbContext.GetPostFromDatabaseByPostId(postId), Is.Not.Null);
});
}
[Test]
public async Task Restore_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
RomashkiDbContext.InsertPostToDatabaseAndReturn();
//Act
var response = await HttpClient.PatchAsync($"/api/posts/{Guid.NewGuid()}", null);
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Restore_WhenRecordNotWasDeleted_ShouldSuccess_Test()
{
//Arrange
var postId = RomashkiDbContext.InsertPostToDatabaseAndReturn().PostId;
//Act
var response = await HttpClient.PatchAsync($"/api/posts/{postId}", null);
//Assert
Assert.Multiple(() =>
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
Assert.That(RomashkiDbContext.GetPostFromDatabaseByPostId(postId), Is.Not.Null);
});
}
[Test]
public async Task Restore_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PatchAsync($"/api/posts/id", null);
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
private static void AssertElement(PostViewModel? actual, Post expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.PostId));
Assert.That(actual.PostName, Is.EqualTo(expected.PostName));
Assert.That(actual.PostType, Is.EqualTo(expected.PostType.ToString()));
});
}
private static PostBindingModel CreateModel(string? postId = null, string postName = "name", PostType postType = PostType.Assistant)
=> new()
{
Id = postId ?? Guid.NewGuid().ToString(),
PostName = postName,
PostType = postType.ToString()
};
private static void AssertElement(Post? actual, PostBindingModel expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.PostId, Is.EqualTo(expected.Id));
Assert.That(actual.PostName, Is.EqualTo(expected.PostName));
Assert.That(actual.PostType.ToString(), Is.EqualTo(expected.PostType));
});
}
}

View File

@@ -0,0 +1,472 @@
using RomashkiDatabase;
using RomashkiDatabase.Models;
using RomashkiTests.Infrastructure;
using RomashkiContract.BindingModels;
using RomashkiContract.ViewModels;
using RomashkiContracts.Enums;
using System.Net;
namespace RomashkiTests.WebApiControllersTests;
[TestFixture]
internal class ProductControllerTests : BaseWebApiControllerTest
{
[TearDown]
public void TearDown()
{
RomashkiDbContext.RemoveProductsFromDatabase();
}
[Test]
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 1");
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 2");
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 3");
//Act
var response = await HttpClient.GetAsync("/api/products?includeDeleted=false");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<ProductViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(3));
});
AssertElement(data.First(x => x.Id == product.Id), product);
}
[Test]
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
{
//Act
var response = await HttpClient.GetAsync("/api/products?includeDeleted=false");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<ProductViewModel>>(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
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 1", isDeleted: true);
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 2", isDeleted: false);
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 3", isDeleted: false);
//Act
var response = await HttpClient.GetAsync("/api/products?includeDeleted=false");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<ProductViewModel>>(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
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 1", isDeleted: true);
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 2", isDeleted: true);
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "name 3", isDeleted: false);
//Act
var response = await HttpClient.GetAsync("/api/products?includeDeleted=true");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<ProductViewModel>>(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 GetHistoryByProductId_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn();
RomashkiDbContext.InsertProductHistoryToDatabaseAndReturn(product.Id, 20, DateTime.UtcNow.AddDays(-1));
RomashkiDbContext.InsertProductHistoryToDatabaseAndReturn(product.Id, 30, DateTime.UtcNow.AddMinutes(-10));
var history = RomashkiDbContext.InsertProductHistoryToDatabaseAndReturn(product.Id, 40, DateTime.UtcNow.AddDays(1));
//Act
var response = await HttpClient.GetAsync($"/api/products/history/{product.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<ProductHistoryViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(3));
AssertElement(data[0], history);
}
[Test]
public async Task GetHistoryByProductId_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn();
RomashkiDbContext.InsertProductHistoryToDatabaseAndReturn(product.Id, 20, DateTime.UtcNow.AddDays(-1));
RomashkiDbContext.InsertProductHistoryToDatabaseAndReturn(product.Id, 30, DateTime.UtcNow.AddMinutes(-10));
RomashkiDbContext.InsertProductHistoryToDatabaseAndReturn(product.Id, 40, DateTime.UtcNow.AddDays(1));
//Act
var response = await HttpClient.GetAsync($"/api/products/history/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<ProductHistoryViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
}
[Test]
public async Task GetHistoryByProductId_WhenProductIdIsNotGuid_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/products/history/id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/products/{product.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<ProductViewModel>(response), product);
}
[Test]
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
RomashkiDbContext.InsertProductToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/products/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ById_WhenRecordWasDeleted_ShouldNotFound_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn(isDeleted: true);
//Act
var response = await HttpClient.GetAsync($"/api/products/{product.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ByName_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/products/{product.ProductName}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<ProductViewModel>(response), product);
}
[Test]
public async Task GetElement_ByName_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
RomashkiDbContext.InsertProductToDatabaseAndReturn();
//Act
var response = await HttpClient.GetAsync($"/api/products/New%20Name");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ByName_WhenRecordWasDeleted_ShouldNotFound_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn(isDeleted: true);
//Act
var response = await HttpClient.GetAsync($"/api/products/{product.ProductName}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task Post_ShouldSuccess_Test()
{
//Arrange
RomashkiDbContext.InsertProductToDatabaseAndReturn();
var productModel = CreateModel();
//Act
var response = await HttpClient.PostAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
AssertElement(RomashkiDbContext.GetProductFromDatabaseById(productModel.Id!), productModel);
}
[Test]
public async Task Post_WhenHaveRecordWithSameId_ShouldBadRequest_Test()
{
//Arrange
var productModel = CreateModel();
RomashkiDbContext.InsertProductToDatabaseAndReturn(productModel.Id);
//Act
var response = await HttpClient.PostAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Post_WhenHaveRecordWithSameName_ShouldBadRequest_Test()
{
//Arrange
var productModel = CreateModel(productName: "unique name");
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: productModel.ProductName!);
//Act
var response = await HttpClient.PostAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var productModelWithIdIncorrect = new ProductBindingModel { Id = "Id", ProductName = "name", Price = 100, ProductType = ProductType.Flower.ToString() };
var productModelWithNameIncorrect = new ProductBindingModel { Id = Guid.NewGuid().ToString(), ProductName = string.Empty, Price = 100, ProductType = ProductType.Flower.ToString() };
var productModelWithProductTypeIncorrect = new ProductBindingModel { Id = Guid.NewGuid().ToString(), ProductName = "name", Price = 100, ProductType = string.Empty };
var productModelWithPriceIncorrect = new ProductBindingModel { Id = Guid.NewGuid().ToString(), ProductName = "name", Price = 0, ProductType = ProductType.Flower.ToString() };
//Act
var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/products", MakeContent(productModelWithIdIncorrect));
var responseWithNameIncorrect = await HttpClient.PostAsync($"/api/products", MakeContent(productModelWithNameIncorrect));
var responseWithProductTypeIncorrect = await HttpClient.PostAsync($"/api/products", MakeContent(productModelWithProductTypeIncorrect));
var responseWithPriceIncorrect = await HttpClient.PostAsync($"/api/products", MakeContent(productModelWithPriceIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect");
Assert.That(responseWithProductTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "ProductType is incorrect");
Assert.That(responseWithPriceIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Price is incorrect");
});
}
[Test]
public async Task Post_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/products", 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/products", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_ShouldSuccess_Test()
{
//Arrange
var productModel = CreateModel();
RomashkiDbContext.InsertProductToDatabaseAndReturn(productModel.Id);
//Act
var response = await HttpClient.PutAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
RomashkiDbContext.ChangeTracker.Clear();
AssertElement(RomashkiDbContext.GetProductFromDatabaseById(productModel.Id!), productModel);
}
[Test]
public async Task Put_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
var productModel = CreateModel();
RomashkiDbContext.InsertProductToDatabaseAndReturn();
//Act
var response = await HttpClient.PutAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_WhenHaveRecordWithSameName_ShouldBadRequest_Test()
{
//Arrange
var productModel = CreateModel(productName: "unique name");
RomashkiDbContext.InsertProductToDatabaseAndReturn(productModel.Id);
RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: productModel.ProductName!);
//Act
var response = await HttpClient.PutAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_WhenRecordWasDeleted_ShouldBadRequest_Test()
{
//Arrange
var productModel = CreateModel();
RomashkiDbContext.InsertProductToDatabaseAndReturn(productModel.Id, isDeleted: true);
//Act
var response = await HttpClient.PutAsync($"/api/products", MakeContent(productModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Put_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var productModelWithIdIncorrect = new ProductBindingModel { Id = "Id", ProductName = "name", Price = 100, ProductType = ProductType.Flower.ToString() };
var productModelWithNameIncorrect = new ProductBindingModel { Id = Guid.NewGuid().ToString(), ProductName = string.Empty, Price = 100, ProductType = ProductType.Flower.ToString() };
var productModelWithProductTypeIncorrect = new ProductBindingModel { Id = Guid.NewGuid().ToString(), ProductName = "name", Price = 100, ProductType = string.Empty };
var productModelWithPriceIncorrect = new ProductBindingModel { Id = Guid.NewGuid().ToString(), ProductName = "name", Price = 0, ProductType = ProductType.Flower.ToString() };
//Act
var responseWithIdIncorrect = await HttpClient.PutAsync($"/api/products", MakeContent(productModelWithIdIncorrect));
var responseWithNameIncorrect = await HttpClient.PutAsync($"/api/products", MakeContent(productModelWithNameIncorrect));
var responseWithProductTypeIncorrect = await HttpClient.PutAsync($"/api/products", MakeContent(productModelWithProductTypeIncorrect));
var responseWithPriceIncorrect = await HttpClient.PutAsync($"/api/products", MakeContent(productModelWithPriceIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithNameIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Name is incorrect");
Assert.That(responseWithProductTypeIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "ProductType is incorrect");
Assert.That(responseWithPriceIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Price is incorrect");
});
}
[Test]
public async Task Put_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PutAsync($"/api/products", 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/products", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_ShouldSuccess_Test()
{
//Arrange
var productId = Guid.NewGuid().ToString();
RomashkiDbContext.InsertProductToDatabaseAndReturn(productId);
//Act
var response = await HttpClient.DeleteAsync($"/api/products/{productId}");
RomashkiDbContext.ChangeTracker.Clear();
//Assert
Assert.Multiple(() =>
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
Assert.That(RomashkiDbContext.GetProductFromDatabaseById(productId)!.IsDeleted);
});
}
[Test]
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
RomashkiDbContext.InsertProductToDatabaseAndReturn();
//Act
var response = await HttpClient.DeleteAsync($"/api/products/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenRecordWasDeleted_ShouldBadRequest_Test()
{
//Arrange
var productId = RomashkiDbContext.InsertProductToDatabaseAndReturn(isDeleted: true).Id;
//Act
var response = await HttpClient.DeleteAsync($"/api/products/{productId}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.DeleteAsync($"/api/products/id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
private static void AssertElement(ProductViewModel? actual, Product expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.ProductName, Is.EqualTo(expected.ProductName));
Assert.That(actual.ProductType, Is.EqualTo(expected.ProductType.ToString()));
Assert.That(actual.Price, Is.EqualTo(expected.Price));
Assert.That(actual.IsDeleted, Is.EqualTo(expected.IsDeleted));
});
}
private static void AssertElement(ProductHistoryViewModel? actual, ProductHistory expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.ProductName, Is.EqualTo(expected.Product!.ProductName));
Assert.That(actual.OldPrice, Is.EqualTo(expected.OldPrice));
Assert.That(actual.ChangeDate.ToString(), Is.EqualTo(expected.ChangeDate.ToString()));
});
}
private static ProductBindingModel CreateModel(string? id = null, string productName = "name", ProductType productType = ProductType.Flower, double price = 1)
=> new()
{
Id = id ?? Guid.NewGuid().ToString(),
ProductName = productName,
ProductType = productType.ToString(),
Price = price
};
private static void AssertElement(Product? actual, ProductBindingModel expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.ProductName, Is.EqualTo(expected.ProductName));
Assert.That(actual.ProductType.ToString(), Is.EqualTo(expected.ProductType));
Assert.That(actual.Price, Is.EqualTo(expected.Price));
Assert.That(!actual.IsDeleted);
});
}
}

View File

@@ -0,0 +1,505 @@
using RomashkiContract.BindingModels;
using RomashkiContract.ViewModels;
using RomashkiContracts.Enums;
using RomashkiDatabase.Models;
using RomashkiTests.Infrastructure;
using System.Net;
namespace RomashkiTests.WebApiControllersTests;
[TestFixture]
internal class SalesControllerTests : BaseWebApiControllerTest
{
private string _buyerId;
private string _workerId;
private string _productId;
[SetUp]
public void SetUp()
{
_buyerId = RomashkiDbContext.InsertBuyerToDatabaseAndReturn().Id;
_workerId = RomashkiDbContext.InsertWorkerToDatabaseAndReturn().Id;
_productId = RomashkiDbContext.InsertProductToDatabaseAndReturn().Id;
}
[TearDown]
public void TearDown()
{
RomashkiDbContext.RemoveSalesFromDatabase();
RomashkiDbContext.RemoveWorkersFromDatabase();
RomashkiDbContext.RemoveBuyersFromDatabase();
RomashkiDbContext.RemoveProductsFromDatabase();
}
[Test]
public async Task GetList_WhenHaveRecords_ShouldSuccess_Test()
{
//Arrange
var sale = RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, buyerId: _buyerId, sum: 10, products: [(_productId, 10, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, products: [(_productId, 10, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, products: [(_productId, 10, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(3));
});
AssertElement(data.First(x => x.Sum == sale.Sum), sale);
}
[Test]
public async Task GetList_WhenNoRecords_ShouldSuccess_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
});
}
[Test]
public async Task GetList_ByPeriod_ShouldSuccess_Test()
{
//Arrange
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, saleDate: DateTime.UtcNow.AddDays(-1).AddMinutes(-3), products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, saleDate: DateTime.UtcNow.AddDays(-1).AddMinutes(3), products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, null, saleDate: DateTime.UtcNow.AddDays(1).AddMinutes(-3), products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, null, saleDate: DateTime.UtcNow.AddDays(1).AddMinutes(3), products: [(_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.Multiple(() =>
{
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(2));
});
}
[Test]
public async Task GetList_ByPeriod_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByWorkerId_ShouldSuccess_Test()
{
//Arrange
var worker = RomashkiDbContext.InsertWorkerToDatabaseAndReturn(fio: "Other worker");
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(worker.Id, null, products: [(_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/worker/{_workerId}?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
Assert.That(data.All(x => x.WorkerId == _workerId));
});
}
[Test]
public async Task GetList_ByWorkerId_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
var worker = RomashkiDbContext.InsertWorkerToDatabaseAndReturn(fio: "Other worker");
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/worker/{worker.Id}?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
}
[Test]
public async Task GetList_ByWorkerId_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/worker/{_workerId}?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByWorkerId_WhenIdIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/worker/Id?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByBuyerId_ShouldSuccess_Test()
{
//Arrange
var buyer = RomashkiDbContext.InsertBuyerToDatabaseAndReturn(fio: "Other fio", email: "other@test.com");
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, buyer.Id, products: [(_productId, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, null, products: [(_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/buyer/{_buyerId}?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(2));
Assert.That(data.All(x => x.BuyerId == _buyerId));
});
}
[Test]
public async Task GetList_ByBuyerId_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
var buyer = RomashkiDbContext.InsertBuyerToDatabaseAndReturn(fio: "Other buyer", email: "other@test.com");
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/buyer/{buyer.Id}?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
}
[Test]
public async Task GetList_ByBuyerId_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/buyer/{_buyerId}?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByBuyerId_WhenIdIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/buyer/Id?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByProductId_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "Other name");
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1), (product.Id, 4, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, null, products: [(product.Id, 1, 1.1)]);
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, null, products: [(product.Id, 1, 1.1), (_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/product/{_productId}?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(data, Has.Count.EqualTo(3));
Assert.That(data.All(x => x.Products.Any(y => y.ProductId == _productId)));
});
}
[Test]
public async Task GetList_ByProductId_WhenNoRecords_ShouldSuccess_Test()
{
//Arrange
var product = RomashkiDbContext.InsertProductToDatabaseAndReturn(productName: "Other product");
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/product/{product.Id}?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
var data = await GetModelFromResponseAsync<List<SaleViewModel>>(response);
Assert.That(data, Is.Not.Null);
Assert.That(data, Has.Count.EqualTo(0));
}
[Test]
public async Task GetList_ByProductId_WhenDateIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/product/{_productId}?fromDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetList_ByProductId_WhenIdIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/product/Id?fromDate={DateTime.UtcNow.AddDays(-1):MM/dd/yyyy HH:mm:ss}&toDate={DateTime.UtcNow.AddDays(1):MM/dd/yyyy HH:mm:ss}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task GetElement_ById_WhenHaveRecord_ShouldSuccess_Test()
{
//Arrange
var sale = RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/{sale.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
AssertElement(await GetModelFromResponseAsync<SaleViewModel>(response), sale);
}
[Test]
public async Task GetElement_ById_WhenNoRecord_ShouldNotFound_Test()
{
//Arrange
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)]);
//Act
var response = await HttpClient.GetAsync($"/api/sales/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ById_WhenRecordHasCanceled_ShouldSuccess_Test()
{
//Arrange
var sale = RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 1, 1.2)], isCancel: true);
//Act
var response = await HttpClient.GetAsync($"/api/sales/{sale.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.OK));
}
[Test]
public async Task GetElement_ById_WhenIdIsIncorrect_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.GetAsync($"/api/sales/Id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Post_ShouldSuccess_Test()
{
//Arrange
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, null, products: [(_productId, 5, 1.1)]);
var saleModel = CreateModel(_workerId, _buyerId, _productId);
//Act
var response = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
AssertElement(RomashkiDbContext.GetSalesByBuyerId(_buyerId)[0], saleModel);
}
[Test]
public async Task Post_WhenNoBuyer_ShouldSuccess_Test()
{
//Arrange
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)]);
var saleModel = CreateModel(_workerId, null, _productId);
//Act
var response = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModel));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
AssertElement(RomashkiDbContext.GetSalesByBuyerId(null)[0], saleModel);
}
[Test]
public async Task Post_WhenDataIsIncorrect_ShouldBadRequest_Test()
{
//Arrange
var saleId = Guid.NewGuid().ToString();
var saleModelWithIdIncorrect = new SaleBindingModel { Id = "Id", WorkerId = _workerId, BuyerId = _buyerId, DiscountType = 1, Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = _productId, Count = 10, Price = 1.1 }] };
var saleModelWithWorkerIdIncorrect = new SaleBindingModel { Id = saleId, WorkerId = "Id", BuyerId = _buyerId, DiscountType = 1, Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = _productId, Count = 10, Price = 1.1 }] };
var saleModelWithBuyerIdIncorrect = new SaleBindingModel { Id = saleId, WorkerId = _workerId, BuyerId = "Id", DiscountType = 1, Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = _productId, Count = 10, Price = 1.1 }] };
var saleModelWithProductsIncorrect = new SaleBindingModel { Id = saleId, WorkerId = _workerId, BuyerId = _buyerId, DiscountType = 1, Products = null };
var saleModelWithProductIdIncorrect = new SaleBindingModel { Id = saleId, WorkerId = _workerId, BuyerId = _buyerId, DiscountType = 1, Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = "Id", Count = 10, Price = 1.1 }] };
var saleModelWithCountIncorrect = new SaleBindingModel { Id = saleId, WorkerId = _workerId, BuyerId = _buyerId, DiscountType = 1, Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = _productId, Count = -10, Price = 1.1 }] };
var saleModelWithPriceIncorrect = new SaleBindingModel { Id = saleId, WorkerId = _workerId, BuyerId = _buyerId, DiscountType = 1, Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = _productId, Count = 10, Price = -1.1 }] };
//Act
var responseWithIdIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithIdIncorrect));
var responseWithWorkerIdIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithWorkerIdIncorrect));
var responseWithBuyerIdIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithBuyerIdIncorrect));
var responseWithProductsIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithProductsIncorrect));
var responseWithProductIdIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithProductIdIncorrect));
var responseWithCountIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithCountIncorrect));
var responseWithPriceIncorrect = await HttpClient.PostAsync($"/api/sales", MakeContent(saleModelWithPriceIncorrect));
//Assert
Assert.Multiple(() =>
{
Assert.That(responseWithIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Id is incorrect");
Assert.That(responseWithWorkerIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "WorkerId is incorrect");
Assert.That(responseWithBuyerIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "BuyerId is incorrect");
Assert.That(responseWithProductsIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Products is incorrect");
Assert.That(responseWithProductIdIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "ProductId is incorrect");
Assert.That(responseWithCountIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Count is incorrect");
Assert.That(responseWithPriceIncorrect.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest), "Price is incorrect");
});
}
[Test]
public async Task Post_WhenSendEmptyData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.PostAsync($"/api/sales", 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/sales", MakeContent(new { Data = "test", Position = 10 }));
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_ShouldSuccess_Test()
{
//Arrange
var sale = RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)]);
//Act
var response = await HttpClient.DeleteAsync($"/api/sales/{sale.Id}");
RomashkiDbContext.ChangeTracker.Clear();
//Assert
Assert.Multiple(() =>
{
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
Assert.That(RomashkiDbContext.GetSaleFromDatabaseById(sale.Id)!.IsCancel);
});
}
[Test]
public async Task Delete_WhenNoFoundRecord_ShouldBadRequest_Test()
{
//Arrange
RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)]);
//Act
var response = await HttpClient.DeleteAsync($"/api/sales/{Guid.NewGuid()}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenIsCanceled_ShouldBadRequest_Test()
{
//Arrange
var sale = RomashkiDbContext.InsertSaleToDatabaseAndReturn(_workerId, _buyerId, products: [(_productId, 5, 1.1)], isCancel: true);
//Act
var response = await HttpClient.DeleteAsync($"/api/sales/{sale.Id}");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
[Test]
public async Task Delete_WhenSendWrongFormatData_ShouldBadRequest_Test()
{
//Act
var response = await HttpClient.DeleteAsync($"/api/sales/id");
//Assert
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.BadRequest));
}
private static void AssertElement(SaleViewModel? actual, Sale expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.WorkerId, Is.EqualTo(expected.WorkerId));
Assert.That(actual.BuyerId, Is.EqualTo(expected.BuyerId));
Assert.That(actual.DiscountType, Is.EqualTo(expected.DiscountType.ToString()));
Assert.That(actual.Discount, Is.EqualTo(expected.Discount));
Assert.That(actual.IsCancel, Is.EqualTo(expected.IsCancel));
});
if (expected.SaleProducts is not null)
{
Assert.That(actual.Products, Is.Not.Null);
Assert.That(actual.Products, Has.Count.EqualTo(expected.SaleProducts.Count));
for (int i = 0; i < actual.Products.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(actual.Products[i].ProductId, Is.EqualTo(expected.SaleProducts[i].ProductId));
Assert.That(actual.Products[i].Count, Is.EqualTo(expected.SaleProducts[i].Count));
Assert.That(actual.Products[i].Price, Is.EqualTo(expected.SaleProducts[i].Price));
});
}
}
else
{
Assert.That(actual.Products, Is.Null);
}
}
private static SaleBindingModel CreateModel(string workerId, string? buyerId, string productId, string? id = null, DiscountType discountType = DiscountType.OnSale, int count = 1, double price = 1.1)
{
var saleId = id ?? Guid.NewGuid().ToString();
return new()
{
Id = saleId,
WorkerId = workerId,
BuyerId = buyerId,
DiscountType = (int)discountType,
Products = [new SaleProductBindingModel { SaleId = saleId, ProductId = productId, Count = count, Price = price }]
};
}
private static void AssertElement(Sale? actual, SaleBindingModel expected)
{
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.WorkerId, Is.EqualTo(expected.WorkerId));
Assert.That(actual.BuyerId, Is.EqualTo(expected.BuyerId));
Assert.That((int)actual.DiscountType, Is.EqualTo(expected.DiscountType));
Assert.That(!actual.IsCancel);
});
if (expected.Products is not null)
{
Assert.That(actual.SaleProducts, Is.Not.Null);
Assert.That(actual.SaleProducts, Has.Count.EqualTo(expected.Products.Count));
for (int i = 0; i < actual.SaleProducts.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(actual.SaleProducts[i].ProductId, Is.EqualTo(expected.Products[i].ProductId));
Assert.That(actual.SaleProducts[i].Count, Is.EqualTo(expected.Products[i].Count));
Assert.That(actual.SaleProducts[i].Price, Is.EqualTo(expected.Products[i].Price));
});
}
}
else
{
Assert.That(actual.SaleProducts, Is.Null);
}
}
}

View File

@@ -5,6 +5,7 @@ using RomashkiContract.BindingModels;
using RomashkiContract.BusinessLogicContracts;
using RomashkiContract.Exceptions;
using RomashkiContract.ViewModels;
using RomashkiContract.DataModels;
using RomashkiContracts.DataModels;
using RomashkiContracts.Exceptions;

View File

@@ -7,6 +7,7 @@ using RomashkiContract.Exceptions;
using RomashkiContract.ViewModels;
using RomashkiContracts.DataModels;
using RomashkiContracts.Exceptions;
using RomashkiContracts.Enums;
namespace RomashkiWebApi.Adapters;
@@ -24,9 +25,9 @@ public class ProductAdapter : IProductAdapter
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<ProductBindingModel, ProductDataModel>();
cfg.CreateMap<ProductDataModel, ProductViewModel>();
cfg.CreateMap<ProductHistoryDataModel, ProductHistoryViewModel>();
cfg.CreateMap<ProductHistoryDataModel, ProductHistoryViewModel>()
.ForMember(dest => dest.ProductName, opt => opt.MapFrom(src => src.Product!.ProductName));
});
_mapper = new Mapper(config);
}
@@ -120,7 +121,32 @@ public class ProductAdapter : IProductAdapter
{
try
{
_productBusinessLogicContract.InsertProduct(_mapper.Map<ProductDataModel>(productModel));
_logger.LogInformation("RegisterProduct called with ProductType: {ProductType}", productModel.ProductType);
// Проверяем, что ProductType не пустой
if (string.IsNullOrEmpty(productModel.ProductType))
{
_logger.LogError("ProductType is null or empty");
return ProductOperationResponse.BadRequest("ProductType is required");
}
// Проверяем, что ProductType является валидным enum значением
if (!Enum.TryParse<ProductType>(productModel.ProductType, true, out var productType))
{
_logger.LogError("Invalid ProductType: {ProductType}", productModel.ProductType);
return ProductOperationResponse.BadRequest($"Invalid ProductType: {productModel.ProductType}");
}
// Создаем ProductDataModel вручную
var productDataModel = new ProductDataModel(
productModel.Id ?? Guid.NewGuid().ToString(),
productModel.ProductName ?? string.Empty,
productType,
productModel.Price,
false
);
_productBusinessLogicContract.InsertProduct(productDataModel);
return ProductOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
@@ -130,22 +156,22 @@ public class ProductAdapter : IProductAdapter
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
_logger.LogError(ex, "ValidationException: {Message}", ex.Message);
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
_logger.LogError(ex, "ElementExistsException: {Message}", ex.Message);
return ProductOperationResponse.BadRequest(ex.Message);
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
_logger.LogError(ex, "StorageException: {Message}", ex.InnerException?.Message ?? ex.Message);
return ProductOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
_logger.LogError(ex, "Exception: {Message}", ex.Message);
return ProductOperationResponse.InternalServerError(ex.Message);
}
}
@@ -154,7 +180,32 @@ public class ProductAdapter : IProductAdapter
{
try
{
_productBusinessLogicContract.UpdateProduct(_mapper.Map<ProductDataModel>(productModel));
_logger.LogInformation("ChangeProductInfo called with ProductType: {ProductType}", productModel.ProductType);
// Проверяем, что ProductType не пустой
if (string.IsNullOrEmpty(productModel.ProductType))
{
_logger.LogError("ProductType is null or empty");
return ProductOperationResponse.BadRequest("ProductType is required");
}
// Проверяем, что ProductType является валидным enum значением
if (!Enum.TryParse<ProductType>(productModel.ProductType, true, out var productType))
{
_logger.LogError("Invalid ProductType: {ProductType}", productModel.ProductType);
return ProductOperationResponse.BadRequest($"Invalid ProductType: {productModel.ProductType}");
}
// Создаем ProductDataModel вручную
var productDataModel = new ProductDataModel(
productModel.Id ?? Guid.NewGuid().ToString(),
productModel.ProductName ?? string.Empty,
productType,
productModel.Price,
false
);
_productBusinessLogicContract.UpdateProduct(productDataModel);
return ProductOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
@@ -164,32 +215,32 @@ public class ProductAdapter : IProductAdapter
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
_logger.LogError(ex, "ValidationException: {Message}", ex.Message);
return ProductOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (ElementNotFoundException ex)
{
_logger.LogError(ex, "ElementNotFoundException");
_logger.LogError(ex, "ElementNotFoundException: {Message}", ex.Message);
return ProductOperationResponse.BadRequest($"Not found element by Id {productModel.Id}");
}
catch (ElementExistsException ex)
{
_logger.LogError(ex, "ElementExistsException");
_logger.LogError(ex, "ElementExistsException: {Message}", ex.Message);
return ProductOperationResponse.BadRequest(ex.Message);
}
catch (ElementDeletedException ex)
{
_logger.LogError(ex, "ElementDeletedException");
_logger.LogError(ex, "ElementDeletedException: {Message}", ex.Message);
return ProductOperationResponse.BadRequest($"Element by id: {productModel.Id} was deleted");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
_logger.LogError(ex, "StorageException: {Message}", ex.InnerException?.Message ?? ex.Message);
return ProductOperationResponse.BadRequest($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Exception");
_logger.LogError(ex, "Exception: {Message}", ex.Message);
return ProductOperationResponse.InternalServerError(ex.Message);
}
}

View File

@@ -7,6 +7,7 @@ using RomashkiContract.ViewModels;
using RomashkiContracts.DataModels;
using RomashkiContracts.Exceptions;
using RomashkiContract.AdapterContracts;
using RomashkiContracts.Enums;
namespace RomashkiWebApi.Adapters;
public class SaleAdapter : ISaleAdapter
@@ -23,10 +24,15 @@ public class SaleAdapter : ISaleAdapter
_logger = logger;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<SaleBindingModel, SaleDataModel>();
cfg.CreateMap<SaleDataModel, SaleViewModel>();
cfg.CreateMap<SaleProductBindingModel, SaleProductDataModel>();
cfg.CreateMap<SaleProductDataModel, SaleProductViewModel>();
cfg.CreateMap<SaleBindingModel, SaleDataModel>()
.ConvertUsing<SaleBindingModelToSaleDataModelConverter>();
cfg.CreateMap<SaleDataModel, SaleViewModel>()
.ForMember(dest => dest.WorkerFIO, opt => opt.MapFrom(src => ""))
.ForMember(dest => dest.BuyerFIO, opt => opt.MapFrom(src => ""));
cfg.CreateMap<SaleProductBindingModel, SaleProductDataModel>()
.ConvertUsing<SaleProductBindingModelToSaleProductDataModelConverter>();
cfg.CreateMap<SaleProductDataModel, SaleProductViewModel>()
.ForMember(dest => dest.ProductName, opt => opt.MapFrom(src => ""));
});
_mapper = new Mapper(config);
}
@@ -196,7 +202,7 @@ public class SaleAdapter : ISaleAdapter
try
{
var data = _mapper.Map<SaleDataModel>(saleModel);
_saleBusinessLogicContract.InsertSale(_mapper.Map<SaleDataModel>(saleModel));
_saleBusinessLogicContract.InsertSale(data);
return SaleOperationResponse.NoContent();
}
catch (ArgumentNullException ex)
@@ -260,3 +266,46 @@ public class SaleAdapter : ISaleAdapter
}
}
}
public class SaleBindingModelToSaleDataModelConverter : ITypeConverter<SaleBindingModel, SaleDataModel>
{
public SaleDataModel Convert(SaleBindingModel source, SaleDataModel destination, ResolutionContext context)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
var saleId = source.Id ?? Guid.NewGuid().ToString();
var workerId = source.WorkerId ?? throw new ArgumentNullException(nameof(source.WorkerId));
var products = source.Products?.Select(p => new SaleProductDataModel(
saleId,
p.ProductId ?? throw new ArgumentNullException(nameof(p.ProductId)),
p.Count,
p.Price
)).ToList() ?? new List<SaleProductDataModel>();
return new SaleDataModel(
saleId,
workerId,
source.BuyerId,
(DiscountType)source.DiscountType,
false,
products
);
}
}
public class SaleProductBindingModelToSaleProductDataModelConverter : ITypeConverter<SaleProductBindingModel, SaleProductDataModel>
{
public SaleProductDataModel Convert(SaleProductBindingModel source, SaleProductDataModel destination, ResolutionContext context)
{
if (source == null)
throw new ArgumentNullException(nameof(source));
return new SaleProductDataModel(
source.SaleId ?? throw new ArgumentNullException(nameof(source.SaleId)),
source.ProductId ?? throw new ArgumentNullException(nameof(source.ProductId)),
source.Count,
source.Price
);
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RomashkiContract.AdapterContracts;
using RomashkiContract.BindingModels;
namespace RomashkiWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class PostsController(IPostAdapter adapter) : ControllerBase
{
private readonly IPostAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetAllRecords()
{
return _adapter.GetList().GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] PostBindingModel model)
{
return _adapter.RegisterPost(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] PostBindingModel model)
{
return _adapter.ChangePostInfo(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemovePost(id).GetResponse(Request, Response);
}
[HttpPatch("{id}")]
public IActionResult Restore(string id)
{
return _adapter.RestorePost(id).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,52 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RomashkiContract.AdapterContracts;
using RomashkiContract.BindingModels;
namespace RomashkiWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class ProductsController(IProductAdapter adapter) : ControllerBase
{
private readonly IProductAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(bool includeDeleted)
{
return _adapter.GetList(includeDeleted).GetResponse(Request, Response);
}
[HttpGet("history/{id}")]
public IActionResult GetHistory(string id)
{
return _adapter.GetHistory(id).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Register([FromBody] ProductBindingModel model)
{
return _adapter.RegisterProduct(model).GetResponse(Request, Response);
}
[HttpPut]
public IActionResult ChangeInfo([FromBody] ProductBindingModel model)
{
return _adapter.ChangeProductInfo(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Delete(string id)
{
return _adapter.RemoveProduct(id).GetResponse(Request, Response);
}
}

View File

@@ -0,0 +1,57 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using RomashkiContract.AdapterContracts;
using RomashkiContract.BindingModels;
namespace RomashkiWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[ApiController]
[Produces("application/json")]
public class SalesController(ISaleAdapter adapter) : ControllerBase
{
private readonly ISaleAdapter _adapter = adapter;
[HttpGet]
public IActionResult GetRecords(DateTime fromDate, DateTime toDate)
{
return _adapter.GetList(fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet("worker/{id}")]
public IActionResult GetWorkerRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetWorkerList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet("buyer/{id}")]
public IActionResult GetBuyerRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetBuyerList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet("product/{id}")]
public IActionResult GetProductRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetProductList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult GetRecord(string data)
{
return _adapter.GetElement(data).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Sale([FromBody] SaleBindingModel model)
{
return _adapter.MakeSale(model).GetResponse(Request, Response);
}
[HttpDelete("{id}")]
public IActionResult Cancel(string id)
{
return _adapter.CancelSale(id).GetResponse(Request, Response);
}
}

View File

@@ -1,11 +0,0 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
namespace RomashkiWebApi.Controllers
{
[Route("api/[controller]")]
[ApiController]
public class ValuesController : ControllerBase
{
}
}

View File

@@ -1,34 +0,0 @@
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
namespace RomashkiWebApi.Controllers;
[Authorize]
[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
private static readonly string[] Summaries = new[]
{
"Freezing", "Bracing", "Chilly", "Cool", "Mild", "Warm", "Balmy", "Hot", "Sweltering", "Scorching"
};
private readonly ILogger<WeatherForecastController> _logger;
public WeatherForecastController(ILogger<WeatherForecastController> logger)
{
_logger = logger;
}
[HttpGet(Name = "GetWeatherForecast")]
public IEnumerable<WeatherForecast> Get()
{
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateOnly.FromDateTime(DateTime.Now.AddDays(index)),
TemperatureC = Random.Shared.Next(-20, 55),
Summary = Summaries[Random.Shared.Next(Summaries.Length)]
})
.ToArray();
}
}

30
Romashki/TestMapping.cs Normal file
View File

@@ -0,0 +1,30 @@
using RomashkiContract.BindingModels;
using RomashkiContracts.Enums;
namespace Romashki;
public class TestMapping
{
public static void TestProductTypeMapping()
{
var productModel = new ProductBindingModel
{
Id = Guid.NewGuid().ToString(),
ProductName = "Test Product",
ProductType = "Flower",
Price = 10.0
};
Console.WriteLine($"ProductType string: {productModel.ProductType}");
if (Enum.TryParse<ProductType>(productModel.ProductType, true, out var productType))
{
Console.WriteLine($"Parsed ProductType: {productType}");
}
else
{
Console.WriteLine("Failed to parse ProductType");
}
}
}