This commit is contained in:
2025-04-11 10:16:19 +04:00
parent 7beb84b967
commit 6449c0df73
22 changed files with 349 additions and 1011 deletions

View File

@@ -11,12 +11,14 @@ namespace CandyHouseBase.DataModels
public string Id { get; set; }
public PositionType Type { get; set; }
public string Title { get; set; }
public decimal Salary { get; set; }
public PositionDataModel(string id, PositionType type, string title)
public PositionDataModel(string id, PositionType type, string title, decimal salary)
{
Id = id;
Type = type;
Title = title;
Salary = salary;
}
public void Validate()

View File

@@ -6,31 +6,27 @@ namespace CandyHouseBase.DataModels
{
public class SalaryDataModel : IValidation
{
public string Id { get; private set; }
public string PekarId { get; private set; }
public DateTime Period { get; private set; }
public decimal BaseRate { get; private set; }
public decimal BonusRate { get; private set; }
public decimal TotalSalary { get; private set; }
public SalaryDataModel(string id, string pekarId, DateTime period, decimal baseRate, decimal bonusRate, decimal totalSalary)
public SalaryDataModel()
{
}
public SalaryDataModel(string pekarId, DateTime period, decimal salary)
{
Id = id;
PekarId = pekarId;
Period = period;
BaseRate = baseRate;
BonusRate = bonusRate;
TotalSalary = totalSalary;
TotalSalary = salary;
}
public void Validate()
{
if (Id.IsEmpty()) throw new ValidationException("Field Id is empty");
if (!Id.IsGuid()) throw new ValidationException("Id must be a GUID");
if (PekarId.IsEmpty()) throw new ValidationException("Field PekarId is empty");
if (!PekarId.IsGuid()) throw new ValidationException("PekarId must be a GUID");
if (BaseRate < 0) throw new ValidationException("BaseRate cannot be negative");
if (BonusRate < 0) throw new ValidationException("BonusRate cannot be negative");
if (TotalSalary < 0) throw new ValidationException("TotalSalary cannot be negative");
}
}

View File

@@ -12,73 +12,58 @@ namespace CandyHouseBase.Implementations
internal class SalaryBusinessLogicContract(
ISalaryStorageContact salaryStorageContact,
IPekarStorageContact pekarStorageContact,
IPositionStorageContact positionStorageContact,
ILogger logger)
: ISalaryBusinessLogicContact
{
private readonly ISalaryStorageContact _salaryStorageContact = salaryStorageContact;
private readonly IPekarStorageContact _pekarStorageContact = pekarStorageContact;
private readonly IPositionStorageContact _positionStorageContact = positionStorageContact;
private readonly ILogger _logger = logger;
public List<SalaryDataModel> GetAllSalaries()
public List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate)
{
_logger.LogInformation("GetAllSalaries");
var salaries = _salaryStorageContact.GetList() ?? throw new NullListException();
return salaries;
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}", fromDate, toDate);
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
return _salaryStorageContact.GetList(fromDate, toDate) ?? throw new NullListException();
}
public SalaryDataModel GetSalaryByData(string data)
public List<SalaryDataModel> GetAllSalariesByPeriodByWorker(DateTime fromDate, DateTime toDate, string workerId)
{
_logger.LogInformation("GetSalaryByData for data: {data}", data);
if (data == null)
throw new ArgumentNullException(nameof(data));
if (string.IsNullOrEmpty(data))
throw new ArgumentNullException(nameof(data));
if (!data.IsGuid())
throw new ValidationException("data must be a GUID");
if (fromDate.IsDateNotOlder(toDate))
{
throw new IncorrectDatesException(fromDate, toDate);
}
if (workerId.IsEmpty())
{
throw new ArgumentNullException(nameof(workerId));
}
if (!workerId.IsGuid())
{
throw new ValidationException("The value in the field workerId is not a unique identifier.");
}
_logger.LogInformation("GetAllSalaries params: {fromDate}, {toDate}, {workerId}", fromDate, toDate, workerId);
return _salaryStorageContact.GetList(fromDate, toDate, workerId) ?? throw new NullListException();
var salary = _salaryStorageContact.GetElementById(data) ?? throw new ElementNotFoundException(data);
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
throw new ElementNotFoundException(salary.PekarId);
return salary;
}
}
public void InsertSalary(SalaryDataModel salary)
public void CalculateSalaryByMonth(DateTime date)
{
_logger.LogInformation("InsertSalary: {json}", JsonSerializer.Serialize(salary));
if (salary == null)
throw new ArgumentNullException(nameof(salary));
salary.Validate();
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
throw new ElementNotFoundException(salary.PekarId);
_salaryStorageContact.AddElement(salary);
}
public void UpdateSalary(SalaryDataModel salary)
{
_logger.LogInformation("UpdateSalary: {json}", JsonSerializer.Serialize(salary));
if (salary == null)
throw new ArgumentNullException(nameof(salary));
salary.Validate();
if (_pekarStorageContact.GetElementById(salary.PekarId) == null)
throw new ElementNotFoundException(salary.PekarId);
_salaryStorageContact.UpdateElement(salary);
}
public void DeleteSalary(string id)
{
_logger.LogInformation("DeleteSalary for id: {id}", id);
if (id == null)
throw new ArgumentNullException(nameof(id));
if (string.IsNullOrEmpty(id))
throw new ArgumentNullException(nameof(id));
if (!id.IsGuid())
throw new ValidationException("id must be a GUID");
var salary = _salaryStorageContact.GetElementById(id);
if (salary == null)
throw new ElementNotFoundException(id);
_salaryStorageContact.DeleteElement(id);
_logger.LogInformation("CalculateSalaryByMouth: {date}", date);
var startDate = new DateTime(date.Year, date.Month, 1);
var finishDate = new DateTime(date.Year, date.Month, DateTime.DaysInMonth(date.Year, date.Month));
var workers = _pekarStorageContact.GetList() ?? throw new NullListException();
foreach (var worker in workers)
{
var post = _positionStorageContact.GetElementById(worker.Id) ??
throw new NullListException();
var salary = post.Salary;
_logger.LogDebug("The employee {workerId} was paid a salary of {salary}", worker.Id, salary);
_salaryStorageContact.AddElement(new SalaryDataModel(worker.Id, finishDate, salary));
}
}
}
}

View File

@@ -6,9 +6,12 @@ namespace CandyHouseBase.Interfaces.Adapters;
public interface ISalaryAdapter
{
SalaryOperationResponse GetList();
SalaryOperationResponse GetElement(string data);
SalaryOperationResponse Register(SalaryBindingModel model);
SalaryOperationResponse Update(SalaryBindingModel model);
SalaryOperationResponse Delete(string id);
SalaryOperationResponse GetList(DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetPekarList(string id, DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetManagerList(string id, DateTime fromDate, DateTime toDate);
SalaryOperationResponse GetSupervisorList(string id, DateTime fromDate, DateTime toDate);
SalaryOperationResponse CalculateSalary(SalaryBindingModel salaryModel);
}

View File

@@ -5,10 +5,10 @@ namespace CandyHouseBase.Interfaces.BusinessLogicsContracts
{
public interface ISalaryBusinessLogicContact
{
List<SalaryDataModel> GetAllSalaries();
SalaryDataModel GetSalaryByData(string data);
void InsertSalary(SalaryDataModel salary);
void UpdateSalary(SalaryDataModel salary);
void DeleteSalary(string id);
List<SalaryDataModel> GetAllSalariesByPeriod(DateTime fromDate, DateTime toDate);
List<SalaryDataModel> GetAllSalariesByPeriodByWorker(DateTime fromDate, DateTime toDate, string workerId);
void CalculateSalaryByMonth(DateTime date);
}
}

View File

@@ -5,10 +5,8 @@ namespace CandyHouseBase.Interfaces.StoragesContracts
{
public interface ISalaryStorageContact
{
List<SalaryDataModel> GetList();
SalaryDataModel GetElementById(string id);
void AddElement(SalaryDataModel element);
void UpdateElement(SalaryDataModel element);
void DeleteElement(string id);
List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? workerId = null);
void AddElement(SalaryDataModel salaryDataModel);
}
}

View File

@@ -22,7 +22,8 @@ public class CandyHouseDbContext : DbContext
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Salary>()
.HasKey(s => s.PekarId);
// Uniqueness for Ingredient
modelBuilder.Entity<Ingredient>()
.HasIndex(x => x.Name)

View File

@@ -24,27 +24,16 @@ internal class SalaryStorageContract : ISalaryStorageContact
_mapper = new Mapper(config);
}
public List<SalaryDataModel> GetList()
public List<SalaryDataModel> GetList(DateTime startDate, DateTime endDate, string? workerId = null)
{
try
{
return _dbContext.Salaries
.Select(x => _mapper.Map<SalaryDataModel>(x))
.ToList();
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public SalaryDataModel GetElementById(string id)
{
try
{
var entity = _dbContext.Salaries.FirstOrDefault(x => x.Id == id) ?? throw new ElementNotFoundException(id);
return _mapper.Map<SalaryDataModel>(entity);
var query = _dbContext.Salaries.Where(x => x.Period >= startDate && x.Period <= endDate);
if (workerId is not null)
{
query = query.Where(x => x.PekarId == workerId);
}
return [.. query.Select(x => _mapper.Map<SalaryDataModel>(x))];
}
catch (Exception ex)
{
@@ -73,53 +62,4 @@ internal class SalaryStorageContract : ISalaryStorageContact
throw new StorageException(ex);
}
}
public void UpdateElement(SalaryDataModel element)
{
try
{
element.Validate();
var entity = GetSalaryById(element.Id) ?? throw new ElementNotFoundException(element.Id);
_dbContext.Salaries.Update(_mapper.Map(element, entity));
_dbContext.SaveChanges();
}
catch (ValidationException ex)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
public void DeleteElement(string id)
{
try
{
var entity = GetSalaryById(id) ?? throw new ElementNotFoundException(id);
_dbContext.Salaries.Remove(entity);
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex);
}
}
private Salary? GetSalaryById(string id) =>
_dbContext.Salaries.FirstOrDefault(x => x.Id == id);
}

View File

@@ -13,6 +13,8 @@ public class Position
public string? PositionId { get; set; }
[Required] public string Title { get; set; }
[Required] public decimal Salary { get; set; }
public PositionType Type { get; set; }

View File

@@ -7,16 +7,11 @@ namespace CandyHouseDataBase.Models;
[AutoMap(typeof(SalaryDataModel), ReverseMap = true)]
public class Salary
{
[Key] public string Id { get; set; } = Guid.NewGuid().ToString();
[Required] public string PekarId { get; set; }
{
[Key] public string PekarId { get; set; }
[Required] public DateTime Period { get; set; }
[Required] public decimal BaseRate { get; set; }
[Required] public decimal BonusRate { get; set; }
[Required] public decimal TotalSalary { get; set; }

View File

@@ -92,9 +92,9 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
_pekarStorageContact.Setup(x => x.GetList()).Returns(pekars);
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekars[0].ProductsItems[0]);
_positionStorageContact.Setup(x => x.GetElementById(pekars[0].Position))
.Returns(new PositionDataModel(pekars[0].Position, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(pekars[0].Position, PositionType.Cool, "Baking position", 15000));
_positionStorageContact.Setup(x => x.GetElementById(pekars[1].Position))
.Returns(new PositionDataModel(pekars[1].Position, PositionType.Cool, "Pastry Chef position"));
.Returns(new PositionDataModel(pekars[1].Position, PositionType.Cool, "Pastry Chef position", 15000));
// Act
var list = _pekarBusinessLogicContract.GetAllPekars();
@@ -179,7 +179,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
};
_pekarStorageContact.Setup(x => x.GetPekarWithHistory(pekarId)).Returns(pekarsWithHistory);
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
// Act
var list = _pekarBusinessLogicContract.GetAllDataOfPekar(pekarId);
@@ -298,7 +298,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
_pekarStorageContact.Setup(x => x.GetElementById(id)).Returns(pekar);
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]);
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
// Act
var element = _pekarBusinessLogicContract.GetPekarByData(id);
@@ -387,7 +387,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
});
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]);
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
// Act
_pekarBusinessLogicContract.InsertPekar(pekar);
@@ -437,7 +437,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
_productStorageContact.Setup(x => x.GetElementById(productId))
.Returns(existingPekar.ProductsItems[0]); // Mock product existence
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
// Act & Assert
Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf<ElementExistsException>());
@@ -508,7 +508,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
_productStorageContact.Setup(x => x.GetElementById(productId))
.Returns(pekar.ProductsItems[0]); // Mock product existence
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
// Act & Assert
Assert.That(() => _pekarBusinessLogicContract.InsertPekar(pekar), Throws.TypeOf<StorageException>());
@@ -551,7 +551,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
});
_productStorageContact.Setup(x => x.GetElementById(productId)).Returns(pekar.ProductsItems[0]);
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
// Act
_pekarBusinessLogicContract.UpdatePekar(pekar);
@@ -592,7 +592,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
_productStorageContact.Setup(x => x.GetElementById(pekar.ProductsItems[0].Id))
.Returns(pekar.ProductsItems[0]);
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
_pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny<PekarDataModel>()))
.Throws(new ElementNotFoundException("Pekar not found"));
@@ -662,7 +662,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
_pekarStorageContact.Setup(x => x.UpdateElement(It.IsAny<PekarDataModel>()))
.Throws(new StorageException(new InvalidOperationException()));
_positionStorageContact.Setup(x => x.GetElementById(positionId))
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position"));
.Returns(new PositionDataModel(positionId, PositionType.Cool, "Baking position", 15000));
_productStorageContact.Setup(x => x.GetElementById(pekar.ProductsItems[0].Id))
.Returns(pekar.ProductsItems[0]);

View File

@@ -45,12 +45,12 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
),
new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Medium,
"Pastry Chef"
"Pastry Chef", 15000
)
};
_positionStorageContact.Setup(x => x.GetList()).Returns(positions);
@@ -113,7 +113,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
id,
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.GetElementById(id)).Returns(position);
@@ -175,7 +175,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.AddElement(It.IsAny<PositionDataModel>()))
.Callback((PositionDataModel x) =>
@@ -202,7 +202,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.AddElement(It.IsAny<PositionDataModel>()))
.Throws(new ElementExistsException("ID", position.Id));
@@ -229,7 +229,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
Assert.That(() => _positionBusinessLogicContract.InsertPosition(new PositionDataModel(
"",
(PositionType)999,
"123"
"123", 15000
)), Throws.TypeOf<ValidationException>());
_positionStorageContact.Verify(x => x.AddElement(It.IsAny<PositionDataModel>()), Times.Never);
}
@@ -241,7 +241,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.AddElement(It.IsAny<PositionDataModel>()))
.Throws(new StorageException(new InvalidOperationException()));
@@ -260,7 +260,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.UpdateElement(It.IsAny<PositionDataModel>()))
.Callback((PositionDataModel x) =>
@@ -287,7 +287,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.UpdateElement(It.IsAny<PositionDataModel>()))
.Throws(new ElementNotFoundException("Position not found"));
@@ -314,7 +314,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
Assert.That(() => _positionBusinessLogicContract.UpdatePosition(new PositionDataModel(
"", // Invalid ID
(PositionType)999,
"123"
"123", 15000
)), Throws.TypeOf<ValidationException>());
_positionStorageContact.Verify(x => x.UpdateElement(It.IsAny<PositionDataModel>()), Times.Never);
}
@@ -326,7 +326,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
Guid.NewGuid().ToString(),
PositionType.Cool,
"Baker"
"Baker", 15000
);
_positionStorageContact.Setup(x => x.UpdateElement(It.IsAny<PositionDataModel>()))
.Throws(new StorageException(new InvalidOperationException()));
@@ -345,7 +345,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
var position = new PositionDataModel(
id,
PositionType.Cool,
"Baker"
"Baker", 15000
);
var flag = false;
_positionStorageContact.Setup(x => x.GetElementById(id)).Returns(position);
@@ -405,7 +405,7 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
{
// Arrange
var id = Guid.NewGuid().ToString();
var position = new PositionDataModel(id, PositionType.Cool, "Baker");
var position = new PositionDataModel(id, PositionType.Cool, "Baker", 15000);
_positionStorageContact.Setup(x => x.GetElementById(id)).Returns(position);
_positionStorageContact.Setup(x => x.DeleteElement(id))
.Throws(new StorageException(new InvalidOperationException()));

View File

@@ -1,12 +1,9 @@
// Обновлённые тесты с учетом методов SalaryBusinessLogicContract
using Moq;
using NUnit.Framework;
using System;
using System.Collections.Generic;
using System.Linq;
using CandyHouseBase.DataModels;
using CandyHouseBase.Exceptions;
using CandyHouseBase.Implementations;
using CandyHouseBase.Interfaces.BusinessLogicsContracts;
using CandyHouseBase.Interfaces.StoragesContracts;
using Microsoft.Extensions.Logging;
@@ -15,520 +12,66 @@ namespace CandyHouseTests.BusinessLogicsContractsTests
[TestFixture]
internal class SalaryBusinessLogicContractTests
{
private SalaryBusinessLogicContract _salaryBusinessLogicContract;
private Mock<ISalaryStorageContact> _salaryStorageContact;
private Mock<IPekarStorageContact> _pekarStorageContact;
private SalaryBusinessLogicContract _logic;
private Mock<ISalaryStorageContact> _salaryStorage;
private Mock<IPekarStorageContact> _pekarStorage;
private Mock<IPositionStorageContact> _positionStorage;
[OneTimeSetUp]
public void OneTimeSetUp()
[SetUp]
public void Init()
{
_salaryStorageContact = new Mock<ISalaryStorageContact>();
_pekarStorageContact = new Mock<IPekarStorageContact>();
_salaryBusinessLogicContract = new SalaryBusinessLogicContract(
_salaryStorageContact.Object,
_pekarStorageContact.Object,
_salaryStorage = new Mock<ISalaryStorageContact>();
_pekarStorage = new Mock<IPekarStorageContact>();
_positionStorage = new Mock<IPositionStorageContact>();
_logic = new SalaryBusinessLogicContract(
_salaryStorage.Object,
_pekarStorage.Object,
_positionStorage.Object,
new Mock<ILogger>().Object
);
}
[SetUp]
public void SetUp()
[Test]
public void GetAllSalariesByPeriod_InvalidDate_Throws()
{
_salaryStorageContact.Reset();
_pekarStorageContact.Reset();
Assert.Throws<IncorrectDatesException>(() => _logic.GetAllSalariesByPeriod(DateTime.Now, DateTime.Now.AddDays(-1)));
}
[Test]
public void GetAllSalaries_ReturnsListOfRecords_Test()
public void GetAllSalariesByPeriodByWorker_Valid_ReturnsList()
{
// Arrange
var pekarId = Guid.NewGuid().ToString();
var salaries = new List<SalaryDataModel>
{
new SalaryDataModel(
Guid.NewGuid().ToString(),
pekarId,
DateTime.Now.AddMonths(-1),
1000.00m,
200.00m,
1200.00m
),
new SalaryDataModel(
Guid.NewGuid().ToString(),
pekarId,
DateTime.Now,
1500.00m,
300.00m,
1800.00m
)
new SalaryDataModel(pekarId, DateTime.Now.AddDays(-5), 2000)
};
_salaryStorageContact.Setup(x => x.GetList()).Returns(salaries);
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
_salaryStorage.Setup(s => s.GetList(It.IsAny<DateTime>(), It.IsAny<DateTime>(), pekarId)).Returns(salaries);
// Act
var list = _salaryBusinessLogicContract.GetAllSalaries();
var result = _logic.GetAllSalariesByPeriodByWorker(DateTime.Now.AddMonths(-1), DateTime.Now, pekarId);
// Assert
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.EquivalentTo(salaries));
Assert.That(list.All(s => Guid.TryParse(s.Id, out _) && Guid.TryParse(s.PekarId, out _) && s.BaseRate >= 0 && s.BonusRate >= 0 && s.TotalSalary >= 0), Is.True);
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
Assert.That(result, Is.EqualTo(salaries));
}
[Test]
public void GetAllSalaries_ReturnsEmptyList_Test()
public void GetAllSalariesByPeriodByWorker_InvalidGuid_Throws()
{
// Arrange
_salaryStorageContact.Setup(x => x.GetList()).Returns(new List<SalaryDataModel>());
// Act
var list = _salaryBusinessLogicContract.GetAllSalaries();
// Assert
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(0));
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
Assert.Throws<ValidationException>(() => _logic.GetAllSalariesByPeriodByWorker(DateTime.Now.AddMonths(-1), DateTime.Now, "not-a-guid"));
}
[Test]
public void GetAllSalaries_ReturnsNull_ThrowException_Test()
public void CalculateSalaryByMonth_MissingPosition_Throws()
{
// Arrange
_salaryStorageContact.Setup(x => x.GetList()).Returns((List<SalaryDataModel>)null);
var workerId = Guid.NewGuid().ToString();
var workers = new List<PekarDataModel>
{
new PekarDataModel(workerId, "Ivanov", Guid.NewGuid().ToString(), 1.2m, new())
};
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetAllSalaries(), Throws.TypeOf<NullListException>());
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
}
_pekarStorage.Setup(p => p.GetList()).Returns(workers);
_positionStorage.Setup(p => p.GetElementById(workerId)).Returns((PositionDataModel)null);
[Test]
public void GetAllSalaries_StorageThrowError_ThrowException_Test()
{
// Arrange
_salaryStorageContact.Setup(x => x.GetList()).Throws(new StorageException(new InvalidOperationException()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetAllSalaries(), Throws.TypeOf<StorageException>());
_salaryStorageContact.Verify(x => x.GetList(), Times.Once);
}
[Test]
public void GetSalaryByData_ReturnsSalaryById_Test()
{
// Arrange
var id = Guid.NewGuid().ToString();
var pekarId = Guid.NewGuid().ToString();
var salary = new SalaryDataModel(
id,
pekarId,
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns(salary);
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act
var element = _salaryBusinessLogicContract.GetSalaryByData(id);
// Assert
Assert.That(element, Is.Not.Null);
Assert.That(element.Id, Is.EqualTo(id));
Assert.That(Guid.TryParse(element.Id, out _), Is.True);
Assert.That(Guid.TryParse(element.PekarId, out _), Is.True);
Assert.That(element.BaseRate >= 0);
Assert.That(element.BonusRate >= 0);
Assert.That(element.TotalSalary >= 0);
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
}
[Test]
public void GetSalaryByData_EmptyId_ThrowException_Test()
{
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(null), Throws.TypeOf<ArgumentNullException>());
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(string.Empty), Throws.TypeOf<ArgumentNullException>());
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
}
[Test]
public void GetSalaryByData_InvalidId_ThrowException_Test()
{
// Arrange
var id = "invalid";
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(id), Throws.TypeOf<ValidationException>());
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Never);
}
[Test]
public void GetSalaryByData_NotFoundSalary_ThrowException_Test()
{
// Arrange
var id = Guid.NewGuid().ToString();
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(id), Throws.TypeOf<ElementNotFoundException>());
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
}
[Test]
public void GetSalaryByData_PekarNotFound_ThrowException_Test()
{
// Arrange
var id = Guid.NewGuid().ToString();
var pekarId = Guid.NewGuid().ToString();
var salary = new SalaryDataModel(id, pekarId, DateTime.Now, 1000.00m, 200.00m, 1200.00m);
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns(salary);
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns((PekarDataModel)null);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(id), Throws.TypeOf<ElementNotFoundException>());
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
}
[Test]
public void GetSalaryByData_StorageThrowError_ThrowException_Test()
{
// Arrange
_salaryStorageContact.Setup(x => x.GetElementById(It.IsAny<string>())).Throws(new StorageException(new InvalidOperationException()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.GetSalaryByData(Guid.NewGuid().ToString()), Throws.TypeOf<StorageException>());
_salaryStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Once);
}
[Test]
public void InsertSalary_CorrectRecord_Test()
{
// Arrange
var pekarId = Guid.NewGuid().ToString();
var flag = false;
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
pekarId,
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
flag = x.Id == salary.Id && x.PekarId == salary.PekarId && x.Period == salary.Period &&
x.BaseRate == salary.BaseRate && x.BonusRate == salary.BonusRate && x.TotalSalary == salary.TotalSalary;
});
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act
_salaryBusinessLogicContract.InsertSalary(salary);
// Assert
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Once);
Assert.That(flag);
Assert.That(Guid.TryParse(salary.Id, out _), Is.True);
Assert.That(Guid.TryParse(salary.PekarId, out _), Is.True);
Assert.That(salary.BaseRate >= 0);
Assert.That(salary.BonusRate >= 0);
Assert.That(salary.TotalSalary >= 0);
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
}
[Test]
public void InsertSalary_PekarNotFound_ThrowException_Test()
{
// Arrange
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns((PekarDataModel)null);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(salary), Throws.TypeOf<ElementNotFoundException>());
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Never);
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
}
[Test]
public void InsertSalary_RecordWithExistsData_ThrowException_Test()
{
// Arrange
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>())).Throws(new ElementExistsException("ID", salary.Id));
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(salary), Throws.TypeOf<ElementExistsException>());
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Once);
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
}
[Test]
public void InsertSalary_NullRecord_ThrowException_Test()
{
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(null), Throws.TypeOf<ArgumentNullException>());
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Never);
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
}
[Test]
public void InsertSalary_InvalidRecord_ThrowException_Test()
{
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(new SalaryDataModel(
"",
"",
DateTime.Now,
-1000.00m,
-200.00m,
-1200.00m
)), Throws.TypeOf<ValidationException>());
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Never);
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
}
[Test]
public void InsertSalary_StorageThrowError_ThrowException_Test()
{
// Arrange
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.AddElement(It.IsAny<SalaryDataModel>())).Throws(new StorageException(new InvalidOperationException()));
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.InsertSalary(salary), Throws.TypeOf<StorageException>());
_salaryStorageContact.Verify(x => x.AddElement(It.IsAny<SalaryDataModel>()), Times.Once);
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
}
[Test]
public void UpdateSalary_CorrectRecord_Test()
{
// Arrange
var pekarId = Guid.NewGuid().ToString();
var flag = false;
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
pekarId,
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny<SalaryDataModel>()))
.Callback((SalaryDataModel x) =>
{
flag = x.Id == salary.Id && x.PekarId == salary.PekarId && x.Period == salary.Period &&
x.BaseRate == salary.BaseRate && x.BonusRate == salary.BonusRate && x.TotalSalary == salary.TotalSalary;
});
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act
_salaryBusinessLogicContract.UpdateSalary(salary);
// Assert
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Once);
Assert.That(flag);
Assert.That(Guid.TryParse(salary.Id, out _), Is.True);
Assert.That(Guid.TryParse(salary.PekarId, out _), Is.True);
Assert.That(salary.BaseRate >= 0);
Assert.That(salary.BonusRate >= 0);
Assert.That(salary.TotalSalary >= 0);
_pekarStorageContact.Verify(x => x.GetElementById(pekarId), Times.Once);
}
[Test]
public void UpdateSalary_PekarNotFound_ThrowException_Test()
{
// Arrange
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns((PekarDataModel)null);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(salary), Throws.TypeOf<ElementNotFoundException>());
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Never);
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
}
[Test]
public void UpdateSalary_RecordNotFound_ThrowException_Test()
{
// Arrange
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny<SalaryDataModel>())).Throws(new ElementNotFoundException("Salary not found"));
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(salary), Throws.TypeOf<ElementNotFoundException>());
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Once);
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
}
[Test]
public void UpdateSalary_NullRecord_ThrowException_Test()
{
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(null), Throws.TypeOf<ArgumentNullException>());
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Never);
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
}
[Test]
public void UpdateSalary_InvalidRecord_ThrowException_Test()
{
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(new SalaryDataModel(
"",
"",
DateTime.Now,
-1000.00m,
-200.00m,
-1200.00m
)), Throws.TypeOf<ValidationException>());
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Never);
_pekarStorageContact.Verify(x => x.GetElementById(It.IsAny<string>()), Times.Never);
}
[Test]
public void UpdateSalary_StorageThrowError_ThrowException_Test()
{
// Arrange
var salary = new SalaryDataModel(
Guid.NewGuid().ToString(),
Guid.NewGuid().ToString(),
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
_salaryStorageContact.Setup(x => x.UpdateElement(It.IsAny<SalaryDataModel>())).Throws(new StorageException(new InvalidOperationException()));
_pekarStorageContact.Setup(x => x.GetElementById(salary.PekarId)).Returns(new PekarDataModel(salary.PekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.UpdateSalary(salary), Throws.TypeOf<StorageException>());
_salaryStorageContact.Verify(x => x.UpdateElement(It.IsAny<SalaryDataModel>()), Times.Once);
_pekarStorageContact.Verify(x => x.GetElementById(salary.PekarId), Times.Once);
}
[Test]
public void DeleteSalary_CorrectId_Test()
{
// Arrange
var id = Guid.NewGuid().ToString();
var pekarId = Guid.NewGuid().ToString();
var salary = new SalaryDataModel(
id,
pekarId,
DateTime.Now,
1000.00m,
200.00m,
1200.00m
);
var flag = false;
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns(salary);
_salaryStorageContact.Setup(x => x.DeleteElement(id)).Callback(() => { flag = true; });
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act
_salaryBusinessLogicContract.DeleteSalary(id);
// Assert
_salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
Assert.That(flag);
Assert.That(Guid.TryParse(salary.Id, out _), Is.True);
Assert.That(Guid.TryParse(salary.PekarId, out _), Is.True);
Assert.That(salary.BaseRate >= 0);
Assert.That(salary.BonusRate >= 0);
Assert.That(salary.TotalSalary >= 0);
}
[Test]
public void DeleteSalary_RecordNotFound_ThrowException_Test()
{
// Arrange
var id = Guid.NewGuid().ToString();
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns((SalaryDataModel)null);
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(id), Throws.TypeOf<ElementNotFoundException>());
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
}
[Test]
public void DeleteSalary_NullOrEmptyId_ThrowException_Test()
{
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(null), Throws.TypeOf<ArgumentNullException>());
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(string.Empty), Throws.TypeOf<ArgumentNullException>());
_salaryStorageContact.Verify(x => x.DeleteElement(It.IsAny<string>()), Times.Never);
}
[Test]
public void DeleteSalary_InvalidId_ThrowException_Test()
{
// Arrange
var id = "invalid";
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(id), Throws.TypeOf<ValidationException>());
_salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Never);
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Never);
}
[Test]
public void DeleteSalary_StorageThrowError_ThrowException_Test()
{
// Arrange
var id = Guid.NewGuid().ToString();
var pekarId = Guid.NewGuid().ToString();
var salary = new SalaryDataModel(id, pekarId, DateTime.Now, 1000.00m, 200.00m, 1200.00m);
_salaryStorageContact.Setup(x => x.GetElementById(id)).Returns(salary);
_salaryStorageContact.Setup(x => x.DeleteElement(id)).Throws(new StorageException(new InvalidOperationException()));
_pekarStorageContact.Setup(x => x.GetElementById(pekarId)).Returns(new PekarDataModel(pekarId, "Ivan Ivanov", "Baker", 1.5m, new List<ProductDataModel>()));
// Act & Assert
Assert.That(() => _salaryBusinessLogicContract.DeleteSalary(id), Throws.TypeOf<StorageException>());
_salaryStorageContact.Verify(x => x.GetElementById(id), Times.Once);
_salaryStorageContact.Verify(x => x.DeleteElement(id), Times.Once);
Assert.Throws<NullListException>(() => _logic.CalculateSalaryByMonth(new DateTime(2025, 1, 1)));
}
}
}

View File

@@ -15,12 +15,14 @@ namespace CandyHouseTests.DataModelsTests
var id = Guid.NewGuid().ToString();
var type = PositionType.Cool;
var title = "Manager";
var salary = 15000;
var position = new PositionDataModel(id, type, title);
var position = new PositionDataModel(id, type, title, salary);
Assert.That(id, Is.EqualTo(position.Id));
Assert.That(type, Is.EqualTo(position.Type));
Assert.That(title, Is.EqualTo(position.Title));
Assert.That(salary, Is.EqualTo(position.Salary));
}
[Test]
@@ -29,7 +31,8 @@ namespace CandyHouseTests.DataModelsTests
var invalidId = "";
var type = PositionType.Cool;
var title = "Manager";
var item = new PositionDataModel(invalidId, type, title);
var salary = 15000;
var item = new PositionDataModel(invalidId, type, title, salary);
Assert.Throws<ValidationException>(() => item.Validate());
}
@@ -40,7 +43,8 @@ namespace CandyHouseTests.DataModelsTests
var id = Guid.NewGuid().ToString();
var type = PositionType.Cool;
var invalidTitle = "";
var item = new PositionDataModel(id, type, invalidTitle);
var salary = 15000;
var item = new PositionDataModel(id, type, invalidTitle, salary);
Assert.Throws<ValidationException>(() => item.Validate());
}
@@ -51,7 +55,8 @@ namespace CandyHouseTests.DataModelsTests
var id = Guid.NewGuid().ToString();
var type = PositionType.Cool;
var invalidTitle = "Manager123";
var item = new PositionDataModel(id, type, invalidTitle);
var salary = 15000;
var item = new PositionDataModel(id, type, invalidTitle, salary);
Assert.Throws<ValidationException>(() => item.Validate());
}

View File

@@ -10,20 +10,14 @@ namespace CandyHouseTests.DataModelsTests
[Test]
public void CreateSalaryDataModel_ValidData_ShouldCreateSuccessfully()
{
var id = Guid.NewGuid().ToString();
var pekarId = Guid.NewGuid().ToString();
var period = new DateTime(2023, 10, 1);
var baseRate = 1000m;
var bonusRate = 200m;
var totalSalary = 1200m;
var salaryData = new SalaryDataModel(id, pekarId, period, baseRate, bonusRate, totalSalary);
var salaryData = new SalaryDataModel(pekarId, period, totalSalary);
Assert.That(id, Is.EqualTo(salaryData.Id));
Assert.That(pekarId, Is.EqualTo(salaryData.PekarId));
Assert.That(period, Is.EqualTo(salaryData.Period));
Assert.That(baseRate, Is.EqualTo(salaryData.BaseRate));
Assert.That(bonusRate, Is.EqualTo(salaryData.BonusRate));
Assert.That(totalSalary, Is.EqualTo(salaryData.TotalSalary));
}
@@ -31,25 +25,19 @@ namespace CandyHouseTests.DataModelsTests
public void CreateSalaryDataModel_InvalidId_ShouldThrowValidationException()
{
var invalidId = "";
var pekarId = Guid.NewGuid().ToString();
var period = new DateTime(2023, 10, 1);
var baseRate = 1000m;
var bonusRate = 200m;
var totalSalary = 1200m;
var salary = new SalaryDataModel(invalidId, pekarId, period, baseRate, bonusRate,
var salary = new SalaryDataModel(invalidId, period,
totalSalary);
Assert.Throws<ValidationException>(() => salary.Validate());}
[Test]
public void CreateSalaryDataModel_InvalidBaseRate_ShouldThrowValidationException()
{
var id = Guid.NewGuid().ToString();
var pekarId = Guid.NewGuid().ToString();
var period = new DateTime(2023, 10, 1);
var invalidBaseRate = -1000m;
var bonusRate = 200m;
var totalSalary = 1200m;
var salary = new SalaryDataModel(id, pekarId, period, invalidBaseRate, bonusRate,
var totalSalary = -1200m;
var salary = new SalaryDataModel(pekarId, period,
totalSalary);
Assert.Throws<ValidationException>(() => salary.Validate());
}

View File

@@ -7,21 +7,24 @@ namespace CandyHouseTests.Infrastructure;
internal static class CandyHouseDbContextExtensions
{
public static Ingredient InsertIngredientToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string name = "Flour", string unit = "kg", decimal cost = 1.0m)
public static Ingredient InsertIngredientToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null,
string name = "Flour", string unit = "kg", decimal cost = 1.0m)
{
var model = new Ingredient
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Unit = unit,
Cost = cost
var model = new Ingredient
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Unit = unit,
Cost = cost
};
db.Ingredients.Add(model);
db.SaveChanges();
return model;
}
public static Order InsertOrderToDatabaseAndReturn(this CandyHouseDbContext db, string productId, string pekarId, string? id = null, string? customerName = null, decimal totalAmount = 100m, decimal discountAmount = 10m, StatusType statusType = StatusType.Pending)
public static Order InsertOrderToDatabaseAndReturn(this CandyHouseDbContext db, string productId, string pekarId,
string? id = null, string? customerName = null, decimal totalAmount = 100m, decimal discountAmount = 10m,
StatusType statusType = StatusType.Pending)
{
var model = new Order
{
@@ -39,13 +42,14 @@ internal static class CandyHouseDbContextExtensions
return model;
}
public static Pekar InsertPekarToDatabaseAndReturn(this CandyHouseDbContext db, string positionId, string? id = null, string fio = "Pekar", decimal bonusCoefficient = 1.0m, bool isDeleted = false)
public static Pekar InsertPekarToDatabaseAndReturn(this CandyHouseDbContext db, string positionId,
string? id = null, string fio = "Pekar", decimal bonusCoefficient = 1.0m, bool isDeleted = false)
{
var model = new Pekar
{
Id = id ?? Guid.NewGuid().ToString(),
FIO = fio,
PositionId = positionId,
var model = new Pekar
{
Id = id ?? Guid.NewGuid().ToString(),
FIO = fio,
PositionId = positionId,
BonusCoefficient = bonusCoefficient,
IsDeleted = isDeleted
};
@@ -54,12 +58,13 @@ internal static class CandyHouseDbContextExtensions
return model;
}
public static Position InsertPositionToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string title = "Baker", PositionType type = PositionType.Cool, bool isActual = true, string? positionId = null)
public static Position InsertPositionToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null,
string title = "Baker", PositionType type = PositionType.Cool, bool isActual = true, string? positionId = null)
{
var model = new Position
{
Id = id ?? Guid.NewGuid().ToString(),
Title = title,
var model = new Position
{
Id = id ?? Guid.NewGuid().ToString(),
Title = title,
Type = type,
IsActual = isActual,
ChangeDate = DateTime.UtcNow,
@@ -70,14 +75,16 @@ internal static class CandyHouseDbContextExtensions
return model;
}
public static Product InsertProductToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null, string name = "Cake", string description = "Delicious cake", string oldName = "", string oldDescription = "", bool isDeleted = false)
public static Product InsertProductToDatabaseAndReturn(this CandyHouseDbContext db, string? id = null,
string name = "Cake", string description = "Delicious cake", string oldName = "", string oldDescription = "",
bool isDeleted = false)
{
var model = new Product
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Description = description,
OldName = oldName,
var model = new Product
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Description = description,
OldName = oldName,
OldDescription = oldDescription,
IsDeleted = isDeleted
};
@@ -86,23 +93,23 @@ internal static class CandyHouseDbContextExtensions
return model;
}
public static Salary InsertSalaryToDatabaseAndReturn(this CandyHouseDbContext db, string pekarId, string? id = null, DateTime? period = null, decimal baseRate = 1000m, decimal bonusRate = 200m, decimal? totalSalary = null)
public static Salary InsertSalaryToDatabaseAndReturn(this CandyHouseDbContext db, string pekarId,
DateTime? period = null, decimal totalSalary = 0)
{
var model = new Salary
{
Id = id ?? Guid.NewGuid().ToString(),
PekarId = pekarId,
Period = period ?? DateTime.UtcNow,
BaseRate = baseRate,
BonusRate = bonusRate,
TotalSalary = totalSalary ?? (baseRate + bonusRate)
TotalSalary = totalSalary
};
db.Salaries.Add(model);
db.SaveChanges();
return model;
}
public static PekarHistory InsertPekarHistoryToDatabaseAndReturn(this CandyHouseDbContext db, string pekarId, string positionId, string? id = null, string fio = "Pekar Hist", DateTime? date = null, decimal bonusCoefficient = 1.2m)
public static PekarHistory InsertPekarHistoryToDatabaseAndReturn(this CandyHouseDbContext db, string pekarId,
string positionId, string? id = null, string fio = "Pekar Hist", DateTime? date = null,
decimal bonusCoefficient = 1.2m)
{
var model = new PekarHistory
{
@@ -118,13 +125,14 @@ internal static class CandyHouseDbContextExtensions
return model;
}
public static Recipe InsertRecipeToDatabaseAndReturn(this CandyHouseDbContext db, string productId, string ingredientId, int quantity = 1)
public static Recipe InsertRecipeToDatabaseAndReturn(this CandyHouseDbContext db, string productId,
string ingredientId, int quantity = 1)
{
var model = new Recipe
{
ProductId = productId,
IngredientId = ingredientId,
Quantity = quantity
var model = new Recipe
{
ProductId = productId,
IngredientId = ingredientId,
Quantity = quantity
};
db.Recipes.Add(model);
db.SaveChanges();
@@ -132,12 +140,27 @@ internal static class CandyHouseDbContextExtensions
}
// Remove methods
public static void RemoveIngredientsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Ingredients\" CASCADE;");
public static void RemoveOrdersFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Orders\" CASCADE;");
public static void RemovePekarsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
public static void RemovePositionsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
public static void RemoveProductsFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Products\" CASCADE;");
public static void RemoveSalariesFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Salaries\" CASCADE;");
public static void RemovePekarHistoriesFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"PekarHistories\" CASCADE;");
public static void RemoveRecipesFromDatabase(this CandyHouseDbContext db) => db.Database.ExecuteSqlRaw("TRUNCATE \"Recipes\" CASCADE;");
public static void RemoveIngredientsFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Ingredients\" CASCADE;");
public static void RemoveOrdersFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Orders\" CASCADE;");
public static void RemovePekarsFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
public static void RemovePositionsFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
public static void RemoveProductsFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Products\" CASCADE;");
public static void RemoveSalariesFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Salaries\" CASCADE;");
public static void RemovePekarHistoriesFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"PekarHistories\" CASCADE;");
public static void RemoveRecipesFromDatabase(this CandyHouseDbContext db) =>
db.Database.ExecuteSqlRaw("TRUNCATE \"Recipes\" CASCADE;");
}

View File

@@ -31,10 +31,10 @@ namespace CandyHouseTests.StoragesContracts
[Test]
public void Try_GetList_WhenHaveRecords_Test()
{
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager");
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Medium, "Clerk");
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Cool, "Supervisor",
false); // Not actual
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager",15000);
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Medium ,"Clerk", 15000);
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Cool, "Supervisor"
, 15000, false); // Not actual
var list = _positionStorageContract.GetList();
@@ -55,7 +55,7 @@ namespace CandyHouseTests.StoragesContracts
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager");
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager", 15000);
Console.WriteLine($"Inserted PositionId: {position.PositionId}");
Console.WriteLine($"Querying with id: {position.Id}");
var result = _positionStorageContract.GetElementById(position.PositionId);
@@ -77,7 +77,7 @@ namespace CandyHouseTests.StoragesContracts
[Test]
public void Try_AddElement_Test()
{
var position = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager");
var position = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager", 15000);
_positionStorageContract.AddElement(position);
AssertElement(GetPositionFromDatabase(position.Id), position);
@@ -87,8 +87,8 @@ namespace CandyHouseTests.StoragesContracts
public void Try_AddElement_WhenHaveRecordWithSameTitle_Test()
{
var positionId = Guid.NewGuid().ToString();
InsertPositionToDatabaseAndReturn(positionId, PositionType.Small, "Manager");
var duplicatePosition = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager");
InsertPositionToDatabaseAndReturn(positionId, PositionType.Small, "Manager", 15000);
var duplicatePosition = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager", 15000);
Assert.That(() => _positionStorageContract.AddElement(duplicatePosition),
Throws.TypeOf<ElementExistsException>());
@@ -97,7 +97,7 @@ namespace CandyHouseTests.StoragesContracts
[Test]
public void Try_UpdateElement_WhenNoRecord_Test()
{
var position = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager");
var position = CreateModel(Guid.NewGuid().ToString(), PositionType.Medium, "Manager", 15000);
Assert.That(() => _positionStorageContract.UpdateElement(position),
Throws.TypeOf<ElementNotFoundException>());
@@ -108,9 +108,9 @@ namespace CandyHouseTests.StoragesContracts
{
var positionId1 = Guid.NewGuid().ToString();
var positionId2 = Guid.NewGuid().ToString();
InsertPositionToDatabaseAndReturn(positionId1, PositionType.Small, "Manager");
InsertPositionToDatabaseAndReturn(positionId2, PositionType.Medium, "Senior Manager");
var updatedPosition = CreateModel(positionId1, PositionType.Cool, "Senior Manager");
InsertPositionToDatabaseAndReturn(positionId1, PositionType.Small, "Manager", 15000);
InsertPositionToDatabaseAndReturn(positionId2, PositionType.Medium, "Senior Manager", 15000);
var updatedPosition = CreateModel(positionId1, PositionType.Cool, "Senior Manager", 15000);
Assert.That(() => _positionStorageContract.UpdateElement(updatedPosition),
Throws.TypeOf<ElementExistsException>());
@@ -119,7 +119,7 @@ namespace CandyHouseTests.StoragesContracts
[Test]
public void Try_DeleteElement_Test()
{
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager");
var position = InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager", 15000);
_positionStorageContract.DeleteElement(position.PositionId);
var deletedPosition = GetPositionFromDatabaseByPositionId(position.PositionId, true);
@@ -140,13 +140,13 @@ namespace CandyHouseTests.StoragesContracts
public void Try_DeleteElement_WhenAlreadyNotActual_Test()
{
var position =
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager", false);
InsertPositionToDatabaseAndReturn(Guid.NewGuid().ToString(), PositionType.Small, "Manager", 15000, false);
Assert.That(() => _positionStorageContract.DeleteElement(position.PositionId),
Throws.TypeOf<ElementDeletedException>());
}
private Position InsertPositionToDatabaseAndReturn(string positionId, PositionType type, string title,
private Position InsertPositionToDatabaseAndReturn(string positionId, PositionType type, string title, decimal salary,
bool isActual = true)
{
var position = new Position
@@ -155,6 +155,7 @@ namespace CandyHouseTests.StoragesContracts
Id = Guid.NewGuid().ToString(),
Type = type,
Title = title,
Salary = salary,
IsActual = isActual,
ChangeDate = DateTime.UtcNow
};
@@ -191,9 +192,9 @@ namespace CandyHouseTests.StoragesContracts
});
}
private static PositionDataModel CreateModel(string id, PositionType type, string title)
private static PositionDataModel CreateModel(string id, PositionType type, string title, decimal salary)
{
return new PositionDataModel(id, type, title);
return new PositionDataModel(id, type, title, salary);
}
private Position GetPositionFromDatabase(string id)

View File

@@ -32,54 +32,56 @@ namespace CandyHouseTests.StoragesContracts
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Pekars\" CASCADE;");
CandyHouseDbContext.Database.ExecuteSqlRaw("TRUNCATE \"Positions\" CASCADE;");
}
[Test]
public void Try_GetList_ByPeriod_Test()
{
var now = DateTime.UtcNow;
var s1 = InsertSalaryToDatabaseAndReturn(now.AddDays(-3), 1000, 200, 1200);
var list = _salaryStorageContract.GetList(now.AddDays(-5), now);
Assert.That(list, Has.Count.EqualTo(1));
Assert.That(list.Any(x => x.PekarId == s1.PekarId));
}
[Test]
public void Try_GetList_ByPeriodAndWorker_Test()
{
var now = DateTime.UtcNow;
var s1 = InsertSalaryToDatabaseAndReturn(now.AddDays(-3), 1000, 200, 1200);
var anotherPekar = InsertPekarToDatabaseAndReturn(_position.Id);
var s2 = new Salary
{
PekarId = anotherPekar.Id,
Period = now.AddDays(-2),
TotalSalary = 950
};
CandyHouseDbContext.Salaries.Add(s2);
CandyHouseDbContext.SaveChanges();
var list = _salaryStorageContract.GetList(now.AddDays(-5), now, _pekarId);
Assert.That(list, Has.Count.EqualTo(1));
Assert.That(list.First().PekarId, Is.EqualTo(s1.PekarId));
}
[Test]
public void Try_GetList_WhenHaveRecords_Test()
{
var salary1 = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
var salary2 = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow.AddMonths(-1), 1100m, 300m, 1400m);
var salaries = _salaryStorageContract.GetList();
var salaries = _salaryStorageContract.GetList(DateTime.UtcNow.AddMonths(-2), DateTime.UtcNow);
Assert.That(salaries, Is.Not.Null);
Assert.That(salaries, Has.Count.EqualTo(2));
AssertSalary(salaries.First(s => s.Id == salary1.Id), salary1);
Assert.That(salaries, Has.Count.EqualTo(1));
AssertSalary(salaries.First(s => s.PekarId == salary1.PekarId), salary1);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var salaries = _salaryStorageContract.GetList();
Assert.That(salaries, Is.Not.Null);
Assert.That(salaries, Is.Empty);
}
[Test]
public void Try_GetElementById_ValidSalary_Test()
{
var salary = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
var result = _salaryStorageContract.GetElementById(salary.Id);
Assert.That(result, Is.Not.Null);
AssertSalary(result, salary);
}
[Test]
public void Try_GetElementById_NonExistentSalary_Test()
{
Assert.That(() => _salaryStorageContract.GetElementById(Guid.NewGuid().ToString()),
Throws.TypeOf<StorageException>());
}
[Test]
public void Try_AddElement_ValidSalary_Test()
{
var salary = CreateSalaryModel(Guid.NewGuid().ToString(), DateTime.UtcNow, 1000m, 200m, 1200m);
var salary = CreateSalaryModel(DateTime.UtcNow, 1000m);
_salaryStorageContract.AddElement(salary);
var dbSalary = GetSalaryFromDatabaseById(salary.Id);
var dbSalary = GetSalaryFromDatabaseById(salary.PekarId);
Assert.That(dbSalary, Is.Not.Null);
AssertSalary(dbSalary, salary);
@@ -88,63 +90,20 @@ namespace CandyHouseTests.StoragesContracts
[Test]
public void Try_AddElement_InvalidSalary_Test()
{
var salary = CreateSalaryModel("", DateTime.UtcNow, -1000m, 200m, 1200m); // Invalid Id and BaseRate
var salary = CreateSalaryModel(DateTime.UtcNow, -1000m); // Invalid Id and BaseRate
Assert.That(() => _salaryStorageContract.AddElement(salary),
Throws.TypeOf<ValidationException>());
}
[Test]
public void Try_UpdateElement_ValidSalary_Test()
{
var originalSalary = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
var updatedSalary = CreateSalaryModel(originalSalary.Id, DateTime.UtcNow.AddMonths(1), 1500m, 300m, 1800m);
_salaryStorageContract.UpdateElement(updatedSalary);
var dbSalary = GetSalaryFromDatabaseById(updatedSalary.Id);
Assert.That(dbSalary, Is.Not.Null);
AssertSalary(dbSalary, updatedSalary);
}
[Test]
public void Try_UpdateElement_NonExistentSalary_Test()
{
var salary = CreateSalaryModel(Guid.NewGuid().ToString(), DateTime.UtcNow, 1000m, 200m, 1200m);
Assert.That(() => _salaryStorageContract.UpdateElement(salary),
Throws.TypeOf<ElementNotFoundException>());
}
[Test]
public void Try_DeleteElement_ValidSalary_Test()
{
var salary = InsertSalaryToDatabaseAndReturn(DateTime.UtcNow, 1000m, 200m, 1200m);
_salaryStorageContract.DeleteElement(salary.Id);
var dbSalary = GetSalaryFromDatabaseById(salary.Id);
Assert.That(dbSalary, Is.Null);
}
[Test]
public void Try_DeleteElement_NonExistentSalary_Test()
{
Assert.That(() => _salaryStorageContract.DeleteElement(Guid.NewGuid().ToString()),
Throws.TypeOf<ElementNotFoundException>());
}
// Helper Methods
private Salary InsertSalaryToDatabaseAndReturn(DateTime period, decimal baseRate, decimal bonusRate,
decimal totalSalary)
{
var salary = new Salary
{
Id = Guid.NewGuid().ToString(),
PekarId = _pekarId,
Period = period,
BaseRate = baseRate,
BonusRate = bonusRate,
TotalSalary = totalSalary
};
CandyHouseDbContext.Salaries.Add(salary);
@@ -184,13 +143,12 @@ namespace CandyHouseTests.StoragesContracts
private Salary GetSalaryFromDatabaseById(string id)
{
return CandyHouseDbContext.Salaries.FirstOrDefault(x => x.Id == id);
return CandyHouseDbContext.Salaries.FirstOrDefault(x => x.PekarId == id);
}
private SalaryDataModel CreateSalaryModel(string id, DateTime period, decimal baseRate, decimal bonusRate,
decimal totalSalary)
private SalaryDataModel CreateSalaryModel(DateTime period, decimal totalSalary)
{
return new SalaryDataModel(id, _pekarId, period, baseRate, bonusRate, totalSalary);
return new SalaryDataModel(_pekarId, period, totalSalary);
}
private static void AssertSalary(SalaryDataModel actual, Salary expected)
@@ -198,11 +156,8 @@ namespace CandyHouseTests.StoragesContracts
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.PekarId, Is.EqualTo(expected.PekarId));
Assert.That(actual.Period, Is.EqualTo(expected.Period));
Assert.That(actual.BaseRate, Is.EqualTo(expected.BaseRate));
Assert.That(actual.BonusRate, Is.EqualTo(expected.BonusRate));
Assert.That(actual.TotalSalary, Is.EqualTo(expected.TotalSalary));
});
}
@@ -212,11 +167,8 @@ namespace CandyHouseTests.StoragesContracts
Assert.That(actual, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.PekarId, Is.EqualTo(expected.PekarId));
Assert.That(actual.Period, Is.EqualTo(expected.Period));
Assert.That(actual.BaseRate, Is.EqualTo(expected.BaseRate));
Assert.That(actual.BonusRate, Is.EqualTo(expected.BonusRate));
Assert.That(actual.TotalSalary, Is.EqualTo(expected.TotalSalary));
});
}

View File

@@ -78,26 +78,6 @@ internal class PositionControllerTests : BaseWebApiControllerTest
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.InternalServerError));
}
[Test]
public async Task Post_ShouldReturnBadRequest_Test()
{
// Arrange
var model = new PositionBindingModel
{
Id = Guid.NewGuid().ToString(),
Title = "Junior Baker",
Type = PositionType.Small,
IsActual = true,
ChangeDate = DateTime.UtcNow
};
// Act
var response = await HttpClient.PostAsync("/api/positions", MakeContent(model));
// Assert - adjusted to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NoContent));
}
[Test]
public async Task Put_ShouldReturnBadRequest_Test()
{

View File

@@ -32,57 +32,7 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
CandyHouseDbContext.RemovePekarsFromDatabase();
CandyHouseDbContext.RemovePositionsFromDatabase();
}
[Test]
public async Task GetList_WhenHaveRecords_ShouldReturnInternalServerError_Test()
{
// Arrange
var salary1 = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, id: null, period: DateTime.UtcNow.AddMonths(-1));
var salary2 = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, id: null, period: DateTime.UtcNow);
// Act
var response = await HttpClient.GetAsync("/api/salaries");
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetList_ByDateRange_ShouldReturnInternalServerError_Test()
{
// Arrange
var from = DateTime.UtcNow.AddMonths(-2);
var to = DateTime.UtcNow.AddMonths(-1);
var outOfRangeBefore = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, id: null, period: from.AddDays(-10));
var outOfRangeAfter = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, id: null, period: to.AddDays(10));
var inRange1 = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, id: null, period: from.AddDays(5));
var inRange2 = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId, id: null, period: to.AddDays(-5));
// Act
var response = await HttpClient.GetAsync($"/api/salaries?fromDate={from:yyyy-MM-dd}&toDate={to:yyyy-MM-dd}");
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetList_ByPekarId_ShouldReturnInternalServerError_Test()
{
// Arrange
var anotherPekar = CandyHouseDbContext.InsertPekarToDatabaseAndReturn(_positionId);
var targetPekarSalary1 = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
var targetPekarSalary2 = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
var otherPekarSalary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(anotherPekar.Id);
// Act
var response = await HttpClient.GetAsync($"/api/salaries?pekarId={_pekarId}");
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task GetElement_ById_WhenHaveRecord_ShouldReturnInternalServerError_Test()
@@ -91,7 +41,7 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
// Act
var response = await HttpClient.GetAsync($"/api/salaries/{salary.Id}");
var response = await HttpClient.GetAsync($"/api/salaries/{salary.PekarId}");
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
@@ -107,49 +57,6 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task Post_ShouldReturnBadRequest_Test()
{
// Arrange
var model = new SalaryBindingModel
{
Id = Guid.NewGuid().ToString(),
PekarId = _pekarId,
Period = DateTime.UtcNow,
BaseRate = 1500m,
BonusRate = 300m,
TotalSalary = 1800m
};
// Act
var response = await HttpClient.PostAsync("/api/salaries", MakeContent(model));
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task Put_ShouldReturnBadRequest_Test()
{
// Arrange
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
var model = new SalaryBindingModel
{
Id = salary.Id,
PekarId = _pekarId,
Period = DateTime.UtcNow,
BaseRate = 2000m,
BonusRate = 400m,
TotalSalary = 2400m
};
// Act
var response = await HttpClient.PutAsync("/api/salaries", MakeContent(model));
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
}
[Test]
public async Task Delete_ShouldReturnBadRequest_Test()
{
@@ -157,7 +64,7 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
var salary = CandyHouseDbContext.InsertSalaryToDatabaseAndReturn(_pekarId);
// Act
var response = await HttpClient.DeleteAsync($"/api/salaries/{salary.Id}");
var response = await HttpClient.DeleteAsync($"/api/salaries/{salary.PekarId}");
// Assert - updated to match actual behavior
Assert.That(response.StatusCode, Is.EqualTo(HttpStatusCode.NotFound));
@@ -199,10 +106,7 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
{
Assert.Multiple(() =>
{
Assert.That(viewModel.Id, Is.EqualTo(model.Id));
Assert.That(viewModel.PekarId, Is.EqualTo(model.PekarId));
Assert.That(viewModel.BaseRate, Is.EqualTo(model.BaseRate));
Assert.That(viewModel.BonusRate, Is.EqualTo(model.BonusRate));
Assert.That(viewModel.TotalSalary, Is.EqualTo(model.TotalSalary));
// Compare DateTimes with tolerance
@@ -215,10 +119,7 @@ internal class SalaryControllerTests : BaseWebApiControllerTest
{
Assert.Multiple(() =>
{
Assert.That(model.Id, Is.EqualTo(bindingModel.Id));
Assert.That(model.PekarId, Is.EqualTo(bindingModel.PekarId));
Assert.That(model.BaseRate, Is.EqualTo(bindingModel.BaseRate));
Assert.That(model.BonusRate, Is.EqualTo(bindingModel.BonusRate));
Assert.That(model.TotalSalary, Is.EqualTo(bindingModel.TotalSalary));
// Compare DateTimes with tolerance

View File

@@ -32,11 +32,11 @@ public class SalaryAdapter : ISalaryAdapter
_mapper = new Mapper(config);
}
public SalaryOperationResponse GetList()
public SalaryOperationResponse GetList(DateTime fromDate, DateTime toDate)
{
try
{
return SalaryOperationResponse.OK(_logic.GetAllSalaries().Select(x => _mapper.Map<SalaryViewModel>(x)).ToList());
return SalaryOperationResponse.OK(_logic.GetAllSalariesByPeriod(fromDate, toDate).Select(x => _mapper.Map<SalaryViewModel>(x)).ToList());
}
catch (Exception ex)
{
@@ -45,63 +45,79 @@ public class SalaryAdapter : ISalaryAdapter
}
}
public SalaryOperationResponse GetElement(string data)
public SalaryOperationResponse GetPekarList(string id, DateTime fromDate, DateTime toDate)
{
try
{
return SalaryOperationResponse.OK(_mapper.Map<SalaryViewModel>(_logic.GetSalaryByData(data)));
return SalaryOperationResponse.OK([.. _logic.GetAllSalariesByPeriodByWorker(fromDate, toDate, id).Select(x => _mapper.Map<SalaryViewModel>(x))]);
}
catch (ElementNotFoundException ex)
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "Not found");
return SalaryOperationResponse.NotFound(ex.Message);
_logger.LogError(ex, "IncorrectDatesException");
return SalaryOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SalaryOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Error");
_logger.LogError(ex, "Exception");
return SalaryOperationResponse.InternalServerError(ex.Message);
}
}
public SalaryOperationResponse Register(SalaryBindingModel model)
public SalaryOperationResponse GetManagerList(string id, DateTime fromDate, DateTime toDate)
{
try
{
_logic.InsertSalary(_mapper.Map<SalaryDataModel>(model));
return SalaryOperationResponse.NoContent();
return SalaryOperationResponse.OK([.. _logic.GetAllSalariesByPeriodByWorker(fromDate, toDate, id).Select(x => _mapper.Map<SalaryViewModel>(x))]);
}
catch (IncorrectDatesException ex)
{
_logger.LogError(ex, "IncorrectDatesException");
return SalaryOperationResponse.BadRequest($"Incorrect dates: {ex.Message}");
}
catch (ValidationException ex)
{
_logger.LogError(ex, "ValidationException");
return SalaryOperationResponse.BadRequest($"Incorrect data transmitted: {ex.Message}");
}
catch (NullListException)
{
_logger.LogError("NullListException");
return SalaryOperationResponse.NotFound("The list is not initialized");
}
catch (StorageException ex)
{
_logger.LogError(ex, "StorageException");
return SalaryOperationResponse.InternalServerError($"Error while working with data storage: {ex.InnerException!.Message}");
}
catch (Exception ex)
{
_logger.LogError(ex, "Register error");
return SalaryOperationResponse.BadRequest(ex.Message);
_logger.LogError(ex, "Exception");
return SalaryOperationResponse.InternalServerError(ex.Message);
}
}
public SalaryOperationResponse Update(SalaryBindingModel model)
public SalaryOperationResponse GetSupervisorList(string id, DateTime fromDate, DateTime toDate)
{
try
{
_logic.UpdateSalary(_mapper.Map<SalaryDataModel>(model));
return SalaryOperationResponse.NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, "Update error");
return SalaryOperationResponse.BadRequest(ex.Message);
}
throw new NotImplementedException();
}
public SalaryOperationResponse Delete(string id)
public SalaryOperationResponse CalculateSalary(SalaryBindingModel salaryModel)
{
try
{
_logic.DeleteSalary(id);
return SalaryOperationResponse.NoContent();
}
catch (Exception ex)
{
_logger.LogError(ex, "Delete error");
return SalaryOperationResponse.BadRequest(ex.Message);
}
throw new NotImplementedException();
}
}

View File

@@ -7,7 +7,7 @@ using Microsoft.AspNetCore.Mvc;
namespace CandyHouseWebApi.Controllers;
[Authorize]
[Route("api/[controller]")]
[Route("api/[controller]/[action]")]
[ApiController]
[Produces("application/json")]
public class SalarysController(ISalaryAdapter adapter) : ControllerBase
@@ -15,20 +15,27 @@ public class SalarysController(ISalaryAdapter adapter) : ControllerBase
private readonly ISalaryAdapter _adapter = adapter;
[HttpGet]
public IActionResult Get() => _adapter.GetList().GetResponse(Request, Response);
public IActionResult GetRecords(DateTime fromDate, DateTime toDate)
{
return _adapter.GetList(fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet("{data}")]
public IActionResult Get(string data) => _adapter.GetElement(data).GetResponse(Request, Response);
[HttpGet]
public IActionResult GetPekarRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetPekarList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpGet]
public IActionResult GetManagerRecords(string id, DateTime fromDate, DateTime toDate)
{
return _adapter.GetManagerList(id, fromDate, toDate).GetResponse(Request, Response);
}
[HttpPost]
public IActionResult Post([FromBody] SalaryBindingModel model) =>
_adapter.Register(model).GetResponse(Request, Response);
[HttpPut]
public IActionResult Put([FromBody] SalaryBindingModel model) =>
_adapter.Update(model).GetResponse(Request, Response);
[HttpDelete("{id}")]
public IActionResult Delete(string id) =>
_adapter.Delete(id).GetResponse(Request, Response);
public IActionResult Calculate([FromBody] SalaryBindingModel model)
{
return _adapter.CalculateSalary(model).GetResponse(Request, Response);
}
}