18 Commits

Author SHA1 Message Date
43ae6247d5 Merge pull request 'Bank_Tests' (#6) from Bank_Tests into Task_4_Storage
Reviewed-on: #6
Первая версия тестов для контрактов бд, ещё не все мапперы настроены, будем фиксить в процессе работы
2025-05-01 15:26:49 +04:00
f270d36d22 feat: тесты, начало проверки многие ко многим 2025-05-01 15:24:28 +04:00
d636fb821e feat: тесты для всез классов, проверяющие получение списка, добавление и обновление, но не проверяющие многие ко многим 2025-04-30 12:35:29 +04:00
8d90b79a44 feat: новые тесты
Добавлены тесты для клерка, кредитной программы, валюты, вклада
2025-04-29 15:34:46 +04:00
46bfedef8d feat: создание проекта тестов
добавление двух с половиной классов тестов, пока не проверяет многие ко многим
2025-04-28 13:10:31 +04:00
78a053d6c0 feat: старт проекта тестов 2025-04-26 17:08:45 +04:00
514eb9ed19 fix: фикс гет по айди, который писал на https://git.is.ulstu.ru/slavaxom9k/PIBD-23_Coursework_Bank/pulls/5/files#issuecomment-56085 2025-04-26 13:17:34 +04:00
853d483ea5 feat: первая версия контрактов для хранения по кладовщику 2025-04-26 12:10:12 +04:00
3ae7c03f1c feat: сторадж контракты клерка 2025-04-26 11:21:39 +04:00
707f74dac9 feat: зависимости многие ко многим 2025-04-26 10:41:21 +04:00
a3e013f5ec fix: измение моделей 2025-04-26 09:59:20 +04:00
bcb1820207 fix: изменение проверок, убраны списки 2025-04-26 09:27:32 +04:00
d3797f12ab feat: подготовка моделей к для связи многие ко многи 2025-04-25 09:57:08 +04:00
9ed15b9d5e feat: реализация контракта хранилища кладовщика 2025-04-25 09:56:12 +04:00
0923f8dcf7 feat: добавил поля в моделях и модели многие ко многим 2025-04-25 09:54:23 +04:00
b582d03d45 fix: добавил списки в дата модель клерка 2025-04-25 01:13:35 +04:00
e909fa709f feat: создание проекта бд
добавление моделек для бд (кроме многие ко многим), реализация одного контракта хранилища
2025-04-25 01:12:51 +04:00
80d0ed46e6 Merge pull request 'Третий Task, реализация бизнес логики' (#4) from Task_3_BusinessLogic into main
Reviewed-on: #4
2025-04-24 18:45:52 +04:00
45 changed files with 3449 additions and 13 deletions

View File

@@ -6,6 +6,10 @@
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Logging.Abstractions" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BankContracts\BankContracts.csproj" />
</ItemGroup>

View File

@@ -5,6 +5,7 @@ using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.StorageContracts;
using Microsoft.Extensions.Logging;
using static System.Single;
namespace BankBusinessLogic.Implementations;
@@ -57,8 +58,10 @@ internal class DepositBusinessLogicContract(
return _depositStorageContract.GetElementById(data)
?? throw new ElementNotFoundException($"element not found: {data}");
}
return _depositStorageContract.GetElementByName(data)
?? throw new ElementNotFoundException($"element not found: {data}");
return TryParse(data, out var result) // пофиксить!!!
? _depositStorageContract.GetElementByInterestRate(result) ??
throw new ElementNotFoundException($"element not found: {data}")
: throw new ElementNotFoundException($"element not found: {data}");
}
public void InsertDeposit(DepositDataModel depositDataModel)

View File

@@ -1,7 +1,7 @@
using BankContracts.Exceptions;
using System.Text.RegularExpressions;
using BankContracts.Exceptions;
using BankContracts.Extensions;
using BankContracts.Infrastructure;
using System.Text.RegularExpressions;
namespace BankContracts.DataModels;
@@ -16,7 +16,16 @@ namespace BankContracts.DataModels;
/// <param name="password">пароль</param>
/// <param name="email">адрес электронной почты</param>
/// <param name="phoneNumber">номер телефона</param>
public class ClerkDataModel(string id, string name, string surname, string middleName, string login, string password, string email, string phoneNumber) : IValidation
public class ClerkDataModel(
string id,
string name,
string surname,
string middleName,
string login,
string password,
string email,
string phoneNumber
) : IValidation
{
public string Id { get; private set; } = id;
@@ -26,7 +35,7 @@ public class ClerkDataModel(string id, string name, string surname, string middl
public string MiddleName { get; private set; } = middleName;
public string Login { get; private set; } = login;
public string Login { get; private set; } = login;
public string Password { get; private set; } = password;

View File

@@ -12,7 +12,10 @@ namespace BankContracts.DataModels;
/// <param name="surname">фамилия клиента</param>
/// <param name="balance">баланс клиента</param>
/// <param name="clerkId">уникальный Guid индентификатор клерка</param>
public class ClientDataModel(string id, string name, string surname, decimal balance, string clerkId) : IValidation
/// <param name="depositClients">вклады клиента</param>
/// <param name="creditProgramClients">кредитные программы клиента</param>
public class ClientDataModel(string id, string name, string surname, decimal balance, string clerkId,
List<DepositClientDataModel> depositClients, List<ClientCreditProgramDataModel> creditProgramClients) : IValidation
{
public string Id { get; private set; } = id;
@@ -22,7 +25,11 @@ public class ClientDataModel(string id, string name, string surname, decimal bal
public decimal Balance { get; private set; } = balance;
public string Clerkid { get; private set; } = clerkId;
public string ClerkId { get; private set; } = clerkId;
public List<DepositClientDataModel> DepositClients { get; private set; } = depositClients;
public List<ClientCreditProgramDataModel> CreditProgramClients { get; private set; } = creditProgramClients;
public void Validate()
{
@@ -46,13 +53,21 @@ public class ClientDataModel(string id, string name, string surname, decimal bal
{
throw new ValidationException("Field Balance is less or equal to zero");
}
if (Clerkid.IsEmpty())
if (ClerkId.IsEmpty())
{
throw new ValidationException("Field Clerkid is null or empty");
}
if (!Clerkid.IsGuid())
if (!ClerkId.IsGuid())
{
throw new ValidationException("The value in the field Clerkid is not a unique identifier");
}
if (DepositClients is null)
{
throw new ValidationException("Field DepositClients is null");
}
if (CreditProgramClients is null)
{
throw new ValidationException("Field CreditProgramClients is null");
}
}
}

View File

@@ -13,7 +13,9 @@ namespace BankContracts.DataModels;
/// <param name="maxCost">максимальная сумма</param>
/// <param name="storekeeperId">уникальный Guid Индентификатор кладовщика</param>
/// <param name="periodId">уникальный Guid Индентификатор срока</param>
public class CreditProgramDataModel(string id, string name, decimal cost, decimal maxCost, string storekeeperId, string periodId) : IValidation
/// <param name="currencyCreditPrograms">валюты кредитной программы</param>
public class CreditProgramDataModel(string id, string name, decimal cost, decimal maxCost, string storekeeperId, string periodId,
List<CreditProgramCurrencyDataModel> currencyCreditPrograms) : IValidation
{
public string Id { get; private set; } = id;
@@ -27,6 +29,8 @@ public class CreditProgramDataModel(string id, string name, decimal cost, decima
public string PeriodId { get; private set; } = periodId;
public List<CreditProgramCurrencyDataModel> Currencies { get; private set; } = currencyCreditPrograms;
public void Validate()
{
if (Id.IsEmpty())
@@ -65,5 +69,9 @@ public class CreditProgramDataModel(string id, string name, decimal cost, decima
{
throw new ValidationException("The value in the field PeriodId is not a unique identifier");
}
if (Currencies is null)
{
throw new ValidationException("Field Currencies is null");
}
}
}

View File

@@ -12,7 +12,9 @@ namespace BankContracts.DataModels;
/// <param name="cost">стоимость</param>
/// <param name="period">срок</param>
/// <param name="clerkId">уникальный Guid индентификатор клерка</param>
public class DepositDataModel(string id, float interestRate, decimal cost, int period, string clerkId) : IValidation
/// <param name="depositCurrencies">валюты вклада</param>
public class DepositDataModel(string id, float interestRate, decimal cost, int period, string clerkId,
List<DepositCurrencyDataModel> depositCurrencies) : IValidation
{
public string Id { get; private set; } = id;
@@ -24,6 +26,8 @@ public class DepositDataModel(string id, float interestRate, decimal cost, int p
public string ClerkId { get; private set; } = clerkId;
public List<DepositCurrencyDataModel> Currencies { get; private set; } = depositCurrencies;
public void Validate()
{
if (Id.IsEmpty())
@@ -54,5 +58,9 @@ public class DepositDataModel(string id, float interestRate, decimal cost, int p
{
throw new ValidationException("The value in the field ClerkId is not a unique identifier");
}
if (Currencies is null)
{
throw new ValidationException("Field Currencies is null");
}
}
}

View File

@@ -0,0 +1,8 @@
namespace BankContracts.Exceptions;
/// <summary>
/// Исключение при работе с хранилищем
/// при добавлении существующего элемента
/// </summary>
/// <param name="message">сообщение</param>
public class ElementExistsException(string message) : Exception(message) { }

View File

@@ -0,0 +1,7 @@
namespace BankContracts.Exceptions;
/// <summary>
/// Исключение при работе с хранилищем
/// </summary>
/// <param name="message"></param>
public class StorageException(string message) : Exception(message) { }

View File

@@ -0,0 +1,10 @@
namespace BankContracts.Infrastructure;
/// <summary>
/// интерфейс для подключения к бд
/// хз зачем он нужен тут в контрактах а не в самой бд
/// </summary>
public interface IConfigurationDatabase
{
public string ConnectionString { get; }
}

View File

@@ -8,7 +8,7 @@ public interface IDepositStorageContract
DepositDataModel? GetElementById(string id);
DepositDataModel? GetElementByName(string name);
DepositDataModel? GetElementByInterestRate(float interestRate);
void AddElement(DepositDataModel depositDataModel);

View File

@@ -0,0 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="AutoMapper" Version="14.0.0" />
<PackageReference Include="Microsoft.EntityFrameworkCore" Version="9.0.4" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="9.0.4" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BankContracts\BankContracts.csproj" />
</ItemGroup>
<ItemGroup>
<InternalsVisibleTo Include="BankTests" />
<InternalsVisibleTo Include="DynamicProxyGenAssembly2" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,103 @@
using BankContracts.Infrastructure;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
namespace BankDatabase;
internal class BankDbContext(IConfigurationDatabase configurationDatabase) : DbContext
{
private readonly IConfigurationDatabase? _configurationDatabase = configurationDatabase;
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseNpgsql(_configurationDatabase?.ConnectionString, o => o.SetPostgresVersion(14, 2));
base.OnConfiguring(optionsBuilder);
}
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
base.OnModelCreating(modelBuilder);
modelBuilder.Entity<Clerk>()
.HasIndex(x => x.Login)
.IsUnique();
modelBuilder.Entity<Clerk>()
.HasIndex(x => x.Email)
.IsUnique();
modelBuilder.Entity<Clerk>()
.HasIndex(x => x.PhoneNumber)
.IsUnique();
modelBuilder.Entity<CreditProgram>()
.HasIndex(x => x.Name)
.IsUnique();
modelBuilder.Entity<Currency>()
.HasIndex(x => x.Abbreviation)
.IsUnique();
modelBuilder.Entity<Storekeeper>()
.HasIndex(x => x.PhoneNumber)
.IsUnique();
modelBuilder.Entity<Storekeeper>()
.HasIndex(x => x.Email)
.IsUnique();
modelBuilder.Entity<Storekeeper>()
.HasIndex(x => x.Login)
.IsUnique();
modelBuilder.Entity<Clerk>()
.HasMany(x => x.Deposits)
.WithOne(x => x.Clerk)
.HasForeignKey(x => x.ClerkId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Clerk>()
.HasMany(x => x.Clients)
.WithOne(x => x.Clerk)
.HasForeignKey(x => x.ClerkId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<Clerk>()
.HasMany(x => x.Replenishments)
.WithOne(x => x.Clerk)
.HasForeignKey(x => x.ClerkId)
.OnDelete(DeleteBehavior.Restrict);
modelBuilder.Entity<DepositCurrency>().HasKey(x => new { x.DepositId, x.CurrencyId });
modelBuilder.Entity<ClientCreditProgram>().HasKey(x => new { x.ClientId, x.CreditProgramId });
modelBuilder.Entity<DepositClient>().HasKey(x => new { x.DepositId, x.ClientId });
modelBuilder.Entity<CreditProgramCurrency>().HasKey(x => new { x.CreditProgramId, x.CurrencyId });
}
public DbSet<Clerk> Clerks { get; set; }
public DbSet<Client> Clients { get; set; }
public DbSet<CreditProgram> CreditPrograms { get; set; }
public DbSet<Currency> Currencies { get; set; }
public DbSet<Deposit> Deposits { get; set; }
public DbSet<Period> Periods { get; set; }
public DbSet<Replenishment> Replenishments { get; set; }
public DbSet<Storekeeper> Storekeepers { get; set; }
public DbSet<DepositCurrency> DepositCurrencies { get; set; }
public DbSet<ClientCreditProgram> CreditProgramClients { get; set; }
public DbSet<DepositClient> DepositClients { get; set; }
public DbSet<CreditProgramCurrency> CurrencyCreditPrograms { get; set; }
}

View File

@@ -0,0 +1,151 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
/// <summary>
/// реализация контракта для клерка
/// </summary>
internal class ClerkStorageContract : IClerkStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public ClerkStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Clerk, ClerkDataModel>();
cfg.CreateMap<ClerkDataModel, Clerk>();
});
_mapper = new Mapper(config);
}
public List<ClerkDataModel> GetList()
{
try
{
return [.. _dbContext.Clerks.Select(x => _mapper.Map<ClerkDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ClerkDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<ClerkDataModel>(GetClerkById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ClerkDataModel? GetElementByLogin(string login)
{
try
{
return _mapper.Map<ClerkDataModel>(_dbContext.Clerks.FirstOrDefault(x => x.Login == login));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ClerkDataModel? GetElementByPhoneNumber(string phoneNumber)
{
try
{
return _mapper.Map<ClerkDataModel>(_dbContext.Clerks.FirstOrDefault(x => x.PhoneNumber == phoneNumber));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(ClerkDataModel clerkDataModel)
{
try
{
_dbContext.Clerks.Add(_mapper.Map<Clerk>(clerkDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {clerkDataModel.Id}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clerks_Email" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Email {clerkDataModel.Email}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clerks_PhoneNumber" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"PhoneNumber {clerkDataModel.PhoneNumber}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clerks_Login" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Login {clerkDataModel.Login}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(ClerkDataModel clerkDataModel)
{
try
{
var element = GetClerkById(clerkDataModel.Id) ?? throw new ElementNotFoundException(clerkDataModel.Id);
_dbContext.Clerks.Update(_mapper.Map(clerkDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clerks_Email" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Email {clerkDataModel.Email}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clerks_PhoneNumber" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"PhoneNumber {clerkDataModel.PhoneNumber}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clerks_Login" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Login {clerkDataModel.Login}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Clerk? GetClerkById(string id) => _dbContext.Clerks.Where(x => x.Id == id).FirstOrDefault();
}

View File

@@ -0,0 +1,198 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
internal class ClientStorageContract : IClientStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public ClientStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Clerk, ClerkDataModel>();
cfg.CreateMap<Client, ClientDataModel>()
.ForMember(dest => dest.DepositClients, opt => opt.MapFrom(src => src.DepositClients))
.ForMember(dest => dest.CreditProgramClients, opt => opt.MapFrom(src => src.CreditProgramClients));
cfg.CreateMap<ClientDataModel, Client>()
.ForMember(dest => dest.DepositClients, opt => opt.MapFrom(src => src.DepositClients))
.ForMember(dest => dest.CreditProgramClients, opt => opt.MapFrom(src => src.CreditProgramClients));
cfg.CreateMap<DepositClient, DepositClientDataModel>()
.ForMember(dest => dest.DepositId, opt => opt.MapFrom(src => src.DepositId))
.ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId));
cfg.CreateMap<DepositClientDataModel, DepositClient>()
.ForMember(dest => dest.DepositId, opt => opt.MapFrom(src => src.DepositId))
.ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId));
cfg.CreateMap<Deposit, DepositClientDataModel>()
.ForMember(dest => dest.DepositId, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.ClientId, opt => opt.Ignore());
cfg.CreateMap<DepositClientDataModel, Deposit>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.DepositId));
cfg.CreateMap<ClientCreditProgram, ClientCreditProgramDataModel>()
.ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId))
.ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId));
cfg.CreateMap<ClientCreditProgramDataModel, ClientCreditProgram>()
.ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId))
.ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId));
cfg.CreateMap<CreditProgram, ClientCreditProgramDataModel>()
.ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.Id))
.ForMember(dest => dest.ClientId, opt => opt.Ignore());
cfg.CreateMap<ClientCreditProgramDataModel, CreditProgram>()
.ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.CreditProgramId));
cfg.CreateMap<Replenishment, ReplenishmentDataModel>();
});
_mapper = new Mapper(config);
}
public List<ClientDataModel> GetList(string? clerkId = null)
{
try
{
var query = _dbContext.Clients.Include(x => x.Clerk).AsQueryable();
if (clerkId is not null)
{
query = query.Where(x => x.ClerkId == clerkId);
}
return [.. query.Select(x => _mapper.Map<ClientDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ClientDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<ClientDataModel>(_dbContext.Clients.FirstOrDefault(x => x.Id == id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ClientDataModel? GetElementByName(string name)
{
try
{
return _mapper.Map<ClientDataModel>(_dbContext.Clients.Include(x => x.Clerk).FirstOrDefault(x => x.Name == name));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ClientDataModel? GetElementBySurname(string surname)
{
try
{
return _mapper.Map<ClientDataModel>(_dbContext.Clients.Include(x => x.Clerk).FirstOrDefault(x => x.Surname == surname));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(ClientDataModel clientDataModel)
{
try
{
_dbContext.Clients.Add(_mapper.Map<Client>(clientDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {clientDataModel.Id}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Name" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Name {clientDataModel.Name}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Surname" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Surname {clientDataModel.Surname}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(ClientDataModel clientDataModel)
{
try
{
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id);
//проверь пожалуйста(не уверен)
if (clientDataModel.DepositClients != null && clientDataModel.CreditProgramClients != null)
{
if (element.DepositClients != null || element.DepositClients?.Count >= 0)
{
_dbContext.DepositClients.RemoveRange(element.DepositClients);
}
if (element.CreditProgramClients != null || element.CreditProgramClients?.Count >= 0)
{
_dbContext.CreditProgramClients.RemoveRange(element.CreditProgramClients);
}
element.DepositClients = _mapper.Map<List<DepositClient>>(clientDataModel.DepositClients);
element.CreditProgramClients = _mapper.Map<List<ClientCreditProgram>>(clientDataModel.CreditProgramClients);
}
_mapper.Map(element, clientDataModel);
_dbContext.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Name" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Name {clientDataModel.Name}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Clients_Surname" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Surname {clientDataModel.Surname}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Client? GetClientById(string id) => _dbContext.Clients.Include(client => client.DepositClients).Include(client => client.CreditProgramClients).FirstOrDefault(x => x.Id == id);
}

View File

@@ -0,0 +1,126 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
/// <summary>
/// реализация контракта хранилища для кредитной программы
/// </summary>
internal class CreditProgramStorageContract : ICreditProgramStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public CreditProgramStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(x =>
{
x.CreateMap<CreditProgram, CreditProgramDataModel>()
.ForMember(dest => dest.Currencies, opt => opt.MapFrom(src => src.CurrencyCreditPrograms));
x.CreateMap<CreditProgramDataModel, CreditProgram>()
.ForMember(dest => dest.CurrencyCreditPrograms, opt => opt.MapFrom(src => src.Currencies));
x.CreateMap<CreditProgramCurrency, CreditProgramCurrencyDataModel>()
.ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId))
.ForMember(dest => dest.CurrencyId, opt => opt.MapFrom(src => src.CurrencyId));
x.CreateMap<CreditProgramCurrencyDataModel, CreditProgramCurrency>()
.ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId))
.ForMember(dest => dest.CurrencyId, opt => opt.MapFrom(src => src.CurrencyId))
.ForMember(dest => dest.CreditProgram, opt => opt.Ignore())
.ForMember(dest => dest.Currency, opt => opt.Ignore());
});
_mapper = new Mapper(config);
}
public List<CreditProgramDataModel> GetList(string? storekeeperId = null, string? periodId = null)
{
try
{
var query = _dbContext.CreditPrograms.AsQueryable();
if (storekeeperId is not null)
{
query = query.Where(x => x.StorekeeperId == storekeeperId);
}
if (periodId is not null)
{
query = query.Where(x => x.PeriodId == periodId);
}
return [.. query.Select(x => _mapper.Map<CreditProgramDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public CreditProgramDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<CreditProgramDataModel>(GetCreditProgramById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(CreditProgramDataModel creditProgramDataModel)
{
try
{
_dbContext.CreditPrograms.Add(_mapper.Map<CreditProgram>(creditProgramDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {creditProgramDataModel.Id}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_CreditPrograms_Name" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"PhoneNumber {creditProgramDataModel.Name}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(CreditProgramDataModel creditProgramDataModel)
{
try
{
var element = GetCreditProgramById(creditProgramDataModel.Id) ?? throw new ElementNotFoundException($"id: {creditProgramDataModel.Id}");
_dbContext.CreditPrograms.Update(_mapper.Map(creditProgramDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_CreditPrograms_Name" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"PhoneNumber {creditProgramDataModel.Name}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private CreditProgram? GetCreditProgramById(string id) => _dbContext.CreditPrograms.FirstOrDefault(x => x.Id == id);
}

View File

@@ -0,0 +1,123 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
/// <summary>
/// реализация контракта хранилища для валюты
/// </summary>
internal class CurrencyStorageContract : ICurrencyStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public CurrencyStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(x =>
{
x.CreateMap<CurrencyDataModel, Currency>();
x.CreateMap<Currency, CurrencyDataModel>();
});
_mapper = new Mapper(config);
}
public List<CurrencyDataModel> GetList(string? storekeeperId = null)
{
try
{
var query = _dbContext.Currencies.AsQueryable();
if (storekeeperId is not null)
{
query = query.Where(x => x.StorekeeperId == storekeeperId);
}
return [.. query.Select(x => _mapper.Map<CurrencyDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public CurrencyDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<CurrencyDataModel>(GetCurrencyById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public CurrencyDataModel? GetElementByAbbreviation(string abbreviation)
{
try
{
return _mapper.Map<CurrencyDataModel>(_dbContext.Currencies.FirstOrDefault(x => x.Abbreviation == abbreviation));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(CurrencyDataModel currencyDataModel)
{
try
{
_dbContext.Currencies.Add(_mapper.Map<Currency>(currencyDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {currencyDataModel.Id}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Currencies_Abbreviation" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Abbreviation {currencyDataModel.Abbreviation}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(CurrencyDataModel currencyDataModel)
{
try
{
var element = GetCurrencyById(currencyDataModel.Id) ?? throw new ElementNotFoundException($"id: {currencyDataModel.Id}");
_dbContext.Currencies.Update(_mapper.Map(currencyDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Currencies_Abbreviation" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Abbreviation {currencyDataModel.Name}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Currency? GetCurrencyById(string id) => _dbContext.Currencies.FirstOrDefault(x => x.Id == id);
}

View File

@@ -0,0 +1,142 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
internal class DepositStorageContract : IDepositStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public DepositStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Clerk, ClerkDataModel>();
cfg.CreateMap<Deposit, DepositDataModel>();
cfg.CreateMap<DepositDataModel, Deposit>();
cfg.CreateMap<Replenishment, ReplenishmentDataModel>();
});
_mapper = new Mapper(config);
}
public List<DepositDataModel> GetList(string? clerkId = null)
{
try
{
var query = _dbContext.Deposits.Include(x => x.Clerk).AsQueryable();
if (clerkId is not null)
{
query = query.Where(x => x.ClerkId == clerkId);
}
return [.. query.Select(x => _mapper.Map<DepositDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public DepositDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<DepositDataModel>(_dbContext.Deposits.FirstOrDefault(x => x.Id == id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public DepositDataModel? GetElementByInterestRate(float interestRate)
{
try
{
return _mapper.Map<DepositDataModel>(_dbContext.Deposits.Include(x => x.Clerk).FirstOrDefault(x => x.InterestRate == interestRate));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(DepositDataModel depositDataModel)
{
try
{
_dbContext.Deposits.Add(_mapper.Map<Deposit>(depositDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {depositDataModel.Id }");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Deposits_InterestRate" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"InterestRate {depositDataModel.InterestRate}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(DepositDataModel depositDataModel)
{
try
{
var transaction = _dbContext.Database.BeginTransaction();
try
{
var element = GetDepositById(depositDataModel.Id) ?? throw new ElementNotFoundException(depositDataModel.Id);
if (depositDataModel.Currencies != null)
{
if (element.DepositCurrencies != null || element.DepositCurrencies?.Count >= 0)
{
_dbContext.DepositCurrencies.RemoveRange(element.DepositCurrencies);
}
element.DepositCurrencies = _mapper.Map<List<DepositCurrency>>(depositDataModel.Currencies);
}
_mapper.Map(depositDataModel, element);
_dbContext.SaveChanges();
transaction.Commit();
}
catch
{
transaction.Rollback();
throw;
}
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Deposits_InterestRate" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"InterestRate {depositDataModel.InterestRate}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Deposit? GetDepositById(string id) => _dbContext.Deposits.FirstOrDefault(x => x.Id == id);
}

View File

@@ -0,0 +1,109 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
namespace BankDatabase.Implementations;
/// <summary>
/// реализация контракта хранилища для срока
/// </summary>
internal class PeriodStorageContract : IPeriodStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public PeriodStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Period, PeriodDataModel>()
.ConstructUsing(src => new PeriodDataModel(src.Id, src.StartTime, src.EndTime, src.StorekeeperId));
cfg.CreateMap<PeriodDataModel, Period>();
});
_mapper = new Mapper(config);
}
public List<PeriodDataModel> GetList(DateTime? startDate = null, DateTime? endDate = null, string? storekeeperId = null)
{
try
{
var query = _dbContext.Periods.AsQueryable();
if (startDate is not null)
{
query = query.Where(x => x.StartTime <= startDate);
}
if (endDate is not null)
{
query = query.Where(x => x.EndTime <= endDate);
}
if (storekeeperId is not null)
{
query = query.Where(x => x.StorekeeperId == storekeeperId);
}
var test0 = query.FirstOrDefault();
var test = _mapper.Map<PeriodDataModel>(test0);
return [..query.Select(x => _mapper.Map<PeriodDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public PeriodDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<PeriodDataModel>(GetPeriodById(id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(PeriodDataModel periodDataModel)
{
try
{
_dbContext.Periods.Add(_mapper.Map<Period>(periodDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {periodDataModel.Id}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(PeriodDataModel periodDataModel)
{
try
{
var element = GetPeriodById(periodDataModel.Id) ?? throw new ElementNotFoundException(periodDataModel.Id);
_dbContext.Periods.Update(_mapper.Map(periodDataModel, element));
_dbContext.SaveChanges();
} catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Period? GetPeriodById(string id) => _dbContext.Periods.FirstOrDefault(x => x.Id == id);
}

View File

@@ -0,0 +1,110 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
internal class ReplenishmentStorageContract : IReplenishmentStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public ReplenishmentStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Replenishment, ReplenishmentDataModel>();
cfg.CreateMap<ReplenishmentDataModel, Replenishment>();
});
_mapper = new Mapper(config);
}
public List<ReplenishmentDataModel> GetList(DateTime? fromDate = null, DateTime? toDate = null, string? clerkId = null, string? depositId = null)
{
try
{
var query = _dbContext.Replenishments.AsQueryable();
if (clerkId is not null)
{
query = query.Where(x => x.ClerkId == clerkId);
}
if (depositId is not null)
{
query = query.Where(x => x.DepositId == depositId);
}
if (fromDate is not null)
{
query = query.Where(x => x.Date >= fromDate);
}
if (toDate is not null)
{
query = query.Where(x => x.Date <= toDate);
}
return [.. query.Select(x => _mapper.Map<ReplenishmentDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public ReplenishmentDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<ReplenishmentDataModel>(_dbContext.Replenishments.FirstOrDefault(x => x.Id == id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(ReplenishmentDataModel replenishmentDataModel)
{
try
{
_dbContext.Replenishments.Add(_mapper.Map<Replenishment>(replenishmentDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {replenishmentDataModel.Id}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(ReplenishmentDataModel replenishmentDataModel)
{
try
{
var element = GetReplenishmentById(replenishmentDataModel.Id) ?? throw new ElementNotFoundException(replenishmentDataModel.Id);
_dbContext.Replenishments.Update(_mapper.Map(replenishmentDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Replenishment? GetReplenishmentById(string id) => _dbContext.Replenishments.FirstOrDefault(x => x.Id == id);
}

View File

@@ -0,0 +1,150 @@
using AutoMapper;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
using Npgsql;
namespace BankDatabase.Implementations;
/// <summary>
/// реализация контракта для кладовщика
/// </summary>
internal class StorekeeperStorageContract : IStorekeeperStorageContract
{
private readonly BankDbContext _dbContext;
private readonly Mapper _mapper;
public StorekeeperStorageContract(BankDbContext dbContext)
{
_dbContext = dbContext;
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Storekeeper, StorekeeperDataModel>();
cfg.CreateMap<StorekeeperDataModel, Storekeeper>();
});
_mapper = new Mapper(config);
}
public List<StorekeeperDataModel> GetList()
{
try
{
return [.. _dbContext.Storekeepers.Select(x => _mapper.Map<StorekeeperDataModel>(x))];
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public StorekeeperDataModel? GetElementById(string id)
{
try
{
return _mapper.Map<StorekeeperDataModel>(_dbContext.Storekeepers.FirstOrDefault(x => x.Id == id));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public StorekeeperDataModel? GetElementByLogin(string login)
{
try
{
return _mapper.Map<StorekeeperDataModel>(_dbContext.Storekeepers.FirstOrDefault(x => x.Login == login));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public StorekeeperDataModel? GetElementByPhoneNumber(string phoneNumber)
{
try
{
return _mapper.Map<StorekeeperDataModel>(_dbContext.Storekeepers.FirstOrDefault(x => x.PhoneNumber == phoneNumber));
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void AddElement(StorekeeperDataModel storekeeperDataModel)
{
try
{
_dbContext.Storekeepers.Add(_mapper.Map<Storekeeper>(storekeeperDataModel));
_dbContext.SaveChanges();
}
catch (InvalidOperationException ex) when (ex.TargetSite?.Name == "ThrowIdentityConflict")
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Id {storekeeperDataModel.Id}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Storekeepers_Email" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Email {storekeeperDataModel.Email}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Storekeepers_PhoneNumber" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"PhoneNumber {storekeeperDataModel.PhoneNumber}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Storekeepers_Login" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Login {storekeeperDataModel.Login}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
public void UpdElement(StorekeeperDataModel storekeeperDataModel)
{
try
{
var element = GetStorekeeperById(storekeeperDataModel.Id) ?? throw new ElementNotFoundException(storekeeperDataModel.Id);
_dbContext.Storekeepers.Update(_mapper.Map(storekeeperDataModel, element));
_dbContext.SaveChanges();
}
catch (ElementNotFoundException)
{
_dbContext.ChangeTracker.Clear();
throw;
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Storekeepers_Email" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Email {storekeeperDataModel.Email}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Storekeepers_PhoneNumber" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"PhoneNumber {storekeeperDataModel.PhoneNumber}");
}
catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Storekeepers_Login" })
{
_dbContext.ChangeTracker.Clear();
throw new ElementExistsException($"Login {storekeeperDataModel.Login}");
}
catch (Exception ex)
{
_dbContext.ChangeTracker.Clear();
throw new StorageException(ex.Message);
}
}
private Storekeeper? GetStorekeeperById(string id) => _dbContext.Storekeepers.Where(x => x.Id == id).FirstOrDefault();
}

View File

@@ -0,0 +1,32 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Clerk
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Surname { get; set; }
public required string MiddleName { get; set; }
public required string Login { get; set; }
// тут хэш пароля
public required string Password { get; set; }
public required string Email { get; set; }
public required string PhoneNumber { get; set; }
[ForeignKey("ClerkId")]
public List<Replenishment>? Replenishments { get; set; }
[ForeignKey("ClerkId")]
public List<Deposit>? Deposits { get; set; }
[ForeignKey("ClerkId")]
public List<Client>? Clients { get; set; }
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Client
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Surname { get; set; }
public decimal Balance { get; set; }
public required string ClerkId { get; set; }
public Clerk? Clerk { get; set; }
[ForeignKey("ClientId")]
public List<ClientCreditProgram>? CreditProgramClients { get; set; }
[ForeignKey("ClientId")]
public List<DepositClient>? DepositClients { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace BankDatabase.Models;
class ClientCreditProgram
{
public required string ClientId { get; set; }
public required string CreditProgramId { get; set; }
public Client? Client { get; set; }
public CreditProgram? CreditProgram { get; set; }
}

View File

@@ -0,0 +1,28 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class CreditProgram
{
public required string Id { get; set; }
public required string Name { get; set; }
public decimal Cost { get; set; }
public decimal MaxCost { get; set; }
public required string StorekeeperId { get; set; }
public required string PeriodId { get; set; }
public Storekeeper? Storekeeper { get; set; }
public Period? Period { get; set; }
[ForeignKey("CreditProgramId")]
public List<CreditProgramCurrency>? CurrencyCreditPrograms { get; set; }
[ForeignKey("CreditProgramId")]
public List<ClientCreditProgram>? CreditProgramClients { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace BankDatabase.Models;
class CreditProgramCurrency
{
public required string CreditProgramId { get; set; }
public required string CurrencyId { get; set; }
public CreditProgram? CreditProgram { get; set; }
public Currency? Currency { get; set; }
}

View File

@@ -0,0 +1,24 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Currency
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Abbreviation { get; set; }
public decimal Cost { get; set; }
public required string StorekeeperId { get; set; }
public Storekeeper? Storekeeper { get; set; }
[ForeignKey("CurrencyId")]
public List<CreditProgramCurrency>? CurrencyCreditPrograms { get; set; }
[ForeignKey("CurrencyId")]
public List<DepositCurrency>? DepositCurrencies { get; set; }
}

View File

@@ -0,0 +1,27 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Deposit
{
public required string Id { get; set; }
public float InterestRate { get; set; }
public decimal Cost { get; set; }
public int Period { get; set; }
public required string ClerkId { get; set; }
public Clerk? Clerk { get; set; }
[ForeignKey("DepositId")]
public List<DepositClient>? DepositClients { get; set; }
[ForeignKey("DepositId")]
public List<DepositCurrency>? DepositCurrencies { get; set; }
[ForeignKey("DepositId")]
public List<Replenishment>? Replenishments { get; set; }
}

View File

@@ -0,0 +1,12 @@
namespace BankDatabase.Models;
class DepositClient
{
public required string DepositId { get; set; }
public required string ClientId { get; set; }
public Deposit? Deposit { get; set; }
public Client? Client { get; set; }
}

View File

@@ -0,0 +1,18 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace BankDatabase.Models;
class DepositCurrency
{
public required string DepositId { get; set; }
public required string CurrencyId { get; set; }
public Deposit? Deposit { get; set; }
public Currency? Currency { get; set; }
}

View File

@@ -0,0 +1,19 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Period
{
public required string Id { get; set; }
public DateTime StartTime { get; set; }
public DateTime EndTime { get; set; }
public required string StorekeeperId { get; set; }
public Storekeeper? Storekeeper { get; set; }
[ForeignKey("PeriodId")]
public List<CreditProgram>? CreditPrograms { get; set; }
}

View File

@@ -0,0 +1,20 @@
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Replenishment
{
public required string Id { get; set; }
public decimal Amount { get; set; }
public DateTime Date { get; set; }
public required string DepositId { get; set; }
public required string ClerkId { get; set; }
public Clerk? Clerk { get; set; }
public Deposit? Deposit { get; set; }
}

View File

@@ -0,0 +1,32 @@
using BankContracts.DataModels;
using System.ComponentModel.DataAnnotations.Schema;
namespace BankDatabase.Models;
class Storekeeper
{
public required string Id { get; set; }
public required string Name { get; set; }
public required string Surname { get; set; }
public required string MiddleName { get; set; }
public required string Login { get; set; }
public required string Password { get; set; }
public required string Email { get; set; }
public required string PhoneNumber { get; set; }
[ForeignKey("StorekeeperId")]
public List<Currency>? Currencies { get; set; }
[ForeignKey("StorekeeperId")]
public List<Period>? Periods { get; set; }
[ForeignKey("StorekeeperId")]
public List<CreditProgram>? CreditPrograms { get; set; }
}

View File

@@ -0,0 +1,30 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net9.0</TargetFramework>
<LangVersion>latest</LangVersion>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<IsPackable>false</IsPackable>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="coverlet.collector" Version="6.0.2" />
<PackageReference Include="EntityFramework" Version="5.0.0" />
<PackageReference Include="EntityFramework.ru" Version="5.0.0" />
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.12.0" />
<PackageReference Include="NUnit" Version="4.2.2" />
<PackageReference Include="NUnit.Analyzers" Version="4.4.0" />
<PackageReference Include="NUnit3TestAdapter" Version="4.6.0" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\BankContracts\BankContracts.csproj" />
<ProjectReference Include="..\BankDatabase\BankDatabase.csproj" />
</ItemGroup>
<ItemGroup>
<Using Include="NUnit.Framework" />
</ItemGroup>
</Project>

View File

@@ -0,0 +1,298 @@
using System.Xml.Linq;
using BankDatabase;
using BankDatabase.Models;
using Microsoft.EntityFrameworkCore;
namespace BankTests.Infrastructure;
internal static class BankDbContextExtension
{
public static Clerk InsertClerkToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
string? name = "vasya",
string? surname = "petrov",
string? middlename = "petrovich",
string? login = "vasyapupkin",
string? passwd = "*******",
string? email = "email@email.com",
string? phone = "+7-777-777-77-77"
)
{
var clerck = new Clerk()
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Surname = surname,
MiddleName = middlename,
Login = login,
Password = passwd,
Email = email,
PhoneNumber = phone,
};
dbContext.Clerks.Add(clerck);
dbContext.SaveChanges();
return clerck;
}
public static Client InsertClientToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
string? name = "slava",
string? surname = "fomichev",
decimal balance = 1_000_000,
string? clerkId = null,
List<(string clientId, string creditProgramId)>? creditProgramClients = null, // Item1 = ClientId Item2 = CreditProgramId
List<(string depositId, string clientId)>? depositClients = null // Item1 = DepositId Item2 = ClientId
)
{
var client = new Client()
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Surname = surname,
Balance = balance,
ClerkId = clerkId ?? Guid.NewGuid().ToString(),
DepositClients = [],
CreditProgramClients = [],
};
if (creditProgramClients is not null)
{
foreach (var (clientId, creditProgramId) in creditProgramClients)
{
dbContext.CreditProgramClients.Add(
new ClientCreditProgram
{
ClientId = clientId,
CreditProgramId = creditProgramId,
}
);
}
}
if (depositClients is not null)
{
foreach (var (depositId, clientId) in depositClients)
{
dbContext.DepositClients.Add(
new DepositClient { ClientId = clientId, DepositId = depositId }
);
}
}
dbContext.Clients.Add(client);
dbContext.SaveChanges();
return client;
}
public static CreditProgram InsertCreditProgramToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
string? name = "bankrot",
decimal cost = 1_000_000,
decimal maxCost = 10_000_000,
string? storeleeperId = null,
string? periodId = null,
List<(string currencyId, string creditProgramId)>? creditProgramCurrency = null // Item1 = ClientId Item2 = CreditProgramId
)
{
var creditProgram = new CreditProgram()
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Cost = cost,
MaxCost = maxCost,
StorekeeperId = storeleeperId ?? Guid.NewGuid().ToString(),
PeriodId = periodId ?? Guid.NewGuid().ToString(),
};
dbContext.CreditPrograms.Add(creditProgram);
dbContext.SaveChanges();
if (creditProgramCurrency is not null)
{
foreach (var (currencyId, creditProgramId) in creditProgramCurrency)
{
dbContext.CurrencyCreditPrograms.Add(
new CreditProgramCurrency
{
CurrencyId = currencyId,
CreditProgramId = creditProgram.Id,
}
);
}
}
dbContext.SaveChanges();
return creditProgram;
}
public static Storekeeper InsertStorekeeperToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
string? name = "slava",
string? surname = "fomichev",
string? middlename = "sergeevich",
string? login = "xomyak",
string? password = "****",
string? email = "email@email.com",
string? phone = "+9-888-888-88-88"
)
{
var storekeeper = new Storekeeper()
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Surname = surname,
MiddleName = middlename,
Login = login,
Password = password,
Email = email,
PhoneNumber = phone,
};
dbContext.Storekeepers.Add(storekeeper);
dbContext.SaveChanges();
return storekeeper;
}
public static Period InsertPeriodToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
DateTime? start = null,
DateTime? end = null,
string? storekeeperId = null
)
{
var period = new Period()
{
Id = id ?? Guid.NewGuid().ToString(),
StartTime = start ?? DateTime.UtcNow,
EndTime = end ?? DateTime.UtcNow,
StorekeeperId = storekeeperId ?? Guid.NewGuid().ToString(),
};
dbContext.Periods.Add(period);
dbContext.SaveChanges();
return period;
}
public static Currency InsertCurrencyToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
string? name = "pop",
string? abbreviation = "rub",
decimal cost = 10,
string? storekeeperId = null
)
{
var currency = new Currency()
{
Id = id ?? Guid.NewGuid().ToString(),
Name = name,
Abbreviation = abbreviation,
Cost = cost,
StorekeeperId = storekeeperId ?? Guid.NewGuid().ToString(),
};
dbContext.Currencies.Add(currency);
dbContext.SaveChanges();
return currency;
}
public static Deposit InsertDepositToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
float interestRate = 1f,
decimal cost = 10,
int period = 1,
string? clerkId = null
)
{
var deposit = new Deposit()
{
Id = id ?? Guid.NewGuid().ToString(),
InterestRate = interestRate,
Cost = cost,
Period = period,
ClerkId = clerkId ?? Guid.NewGuid().ToString(),
};
dbContext.Deposits.Add(deposit);
dbContext.SaveChanges();
return deposit;
}
public static Replenishment InsertReplenishmentToDatabaseAndReturn(
this BankDbContext dbContext,
string? id = null,
decimal amount = 1,
DateTime? date = null,
string? depositId = null,
string? clerkId = null
)
{
var replenishment = new Replenishment()
{
Id = id ?? Guid.NewGuid().ToString(),
Amount = amount,
Date = date ?? DateTime.UtcNow,
DepositId = depositId ?? Guid.NewGuid().ToString(),
ClerkId = clerkId ?? Guid.NewGuid().ToString(),
};
dbContext.Replenishments.Add(replenishment);
dbContext.SaveChanges();
return replenishment;
}
public static void RemoveCurrenciesFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Currencies\" CASCADE");
public static void RemoveClientsFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Clients\" CASCADE");
public static void RemoveStorekeepersFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Storekeepers\" CASCADE");
public static void RemovePeriodsFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Periods\" CASCADE");
public static void RemoveClerksFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Clerks\" CASCADE");
public static void RemoveCreditProgramsFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"CreditPrograms\" CASCADE");
public static void RemoveDepositsFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Deposits\" CASCADE");
public static void RemoveReplenishmentsFromDatabase(this BankDbContext dbContext) =>
dbContext.ExecuteSqlRaw("TRUNCATE \"Replenishments\" CASCADE");
public static Client? GetClientFromDatabase(this BankDbContext dbContext, string id) =>
dbContext
.Clients.Include(x => x.DepositClients)
.Include(x => x.CreditProgramClients)
.FirstOrDefault(x => x.Id == id);
public static Clerk? GetClerkFromDatabase(this BankDbContext dbContext, string id) =>
dbContext.Clerks.FirstOrDefault(x => x.Id == id);
public static CreditProgram? GetCreditProgramFromDatabase(
this BankDbContext dbContext,
string id
) => dbContext.CreditPrograms.FirstOrDefault(x => x.Id == id);
public static Currency? GetCurrencyFromDatabase(this BankDbContext dbContext, string id) =>
dbContext.Currencies.FirstOrDefault(x => x.Id == id);
public static Deposit? GetDepositFromDatabase(this BankDbContext dbContext, string id) =>
dbContext.Deposits.FirstOrDefault(x => x.Id == id);
public static Period? GetPeriodFromDatabase(this BankDbContext dbContext, string id) =>
dbContext.Periods.FirstOrDefault(x => x.Id == id);
public static Replenishment? GetReplenishmentFromDatabase(
this BankDbContext dbContext,
string id
) => dbContext.Replenishments.FirstOrDefault(x => x.Id == id);
public static Storekeeper? GetStorekeeperFromDatabase(
this BankDbContext dbContext,
string id
) => dbContext.Storekeepers.FirstOrDefault(x => x.Id == id);
private static void ExecuteSqlRaw(this BankDbContext dbContext, string command) =>
dbContext.Database.ExecuteSqlRaw(command);
}

View File

@@ -0,0 +1,9 @@
using BankContracts.Infrastructure;
namespace BankTests.Infrastructure;
internal class ConfigurationDatabase : IConfigurationDatabase
{
public string ConnectionString =>
"Host=127.0.0.1;Port=5432;Database=TitanicTest;Username=postgres;Password=admin123;Include Error Detail=true";
}

View File

@@ -0,0 +1,25 @@
using BankDatabase;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
internal class BaseStorageContractTest
{
protected BankDbContext BankDbContext { get; private set; }
[OneTimeSetUp]
public void OneTimeSetUp()
{
BankDbContext = new BankDbContext(new ConfigurationDatabase());
BankDbContext.Database.EnsureDeleted();
BankDbContext.Database.EnsureCreated();
}
[OneTimeTearDown]
public void OneTimeTearDown()
{
BankDbContext.Database.EnsureDeleted();
BankDbContext.Dispose();
}
}

View File

@@ -0,0 +1,172 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class ClerkStorageContractTests : BaseStorageContractTest
{
private IClerkStorageContract _storageContract;
[SetUp]
public void SetUp()
{
_storageContract = new ClerkStorageContract(BankDbContext);
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveClerksFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSuccess_Test()
{
var clerk = BankDbContext.InsertClerkToDatabaseAndReturn();
BankDbContext.InsertClerkToDatabaseAndReturn(
login: "xomyak",
email: "email1@email.com",
phone: "+9-888-888-88-88"
);
BankDbContext.InsertClerkToDatabaseAndReturn(
login: "xomyak3",
email: "email3@email.com",
phone: "+9-888-888-88-78"
);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == clerk.Id), clerk);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var clerk = BankDbContext.InsertClerkToDatabaseAndReturn();
AssertElement(_storageContract.GetElementById(clerk.Id), clerk);
}
[Test]
public void Try_AddElement_Test()
{
var clerk = CreateModel();
_storageContract.AddElement(clerk);
AssertElement(BankDbContext.GetClerkFromDatabase(clerk.Id), clerk);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
{
var clerk = CreateModel();
BankDbContext.InsertClerkToDatabaseAndReturn(id: clerk.Id);
Assert.That(
() => _storageContract.AddElement(clerk),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameEmail_Test()
{
var clerk = CreateModel();
BankDbContext.InsertClerkToDatabaseAndReturn(email: clerk.Email);
Assert.That(
() => _storageContract.AddElement(clerk),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameLogin_Test()
{
var clerk = CreateModel(login: "cheburek");
BankDbContext.InsertClerkToDatabaseAndReturn(email: "email@email.ru", login: "cheburek");
Assert.That(
() => _storageContract.AddElement(clerk),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var clerk = CreateModel();
BankDbContext.InsertClerkToDatabaseAndReturn(clerk.Id, name: "Женя");
_storageContract.UpdElement(clerk);
AssertElement(BankDbContext.GetClerkFromDatabase(clerk.Id), clerk);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() => _storageContract.UpdElement(CreateModel()),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static ClerkDataModel CreateModel(
string? id = null,
string? name = "vasya",
string? surname = "petrov",
string? middlename = "petrovich",
string? login = "vasyapupkin",
string? passwd = "*******",
string? email = "email@email.com",
string? phone = "+7-777-777-77-77"
) =>
new(
id ?? Guid.NewGuid().ToString(),
name,
surname,
middlename,
login,
passwd,
email,
phone
);
private static void AssertElement(ClerkDataModel actual, Clerk? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.MiddleName, Is.EqualTo(expected.MiddleName));
Assert.That(actual.Login, Is.EqualTo(expected.Login));
Assert.That(actual.Password, Is.EqualTo(expected.Password));
Assert.That(actual.Email, Is.EqualTo(expected.Email));
Assert.That(actual.PhoneNumber, Is.EqualTo(expected.PhoneNumber));
});
}
private static void AssertElement(Clerk actual, ClerkDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.MiddleName, Is.EqualTo(expected.MiddleName));
Assert.That(actual.Login, Is.EqualTo(expected.Login));
Assert.That(actual.Password, Is.EqualTo(expected.Password));
Assert.That(actual.Email, Is.EqualTo(expected.Email));
Assert.That(actual.PhoneNumber, Is.EqualTo(expected.PhoneNumber));
});
}
}

View File

@@ -0,0 +1,301 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class ClientStorageContractTests : BaseStorageContractTest
{
private IClientStorageContract _clientStorageContract;
private string _clerkId;
private string _depositId;
private string _creditProgramId;
private string _storekeeperId;
private string _periodId;
[SetUp]
public void SetUp()
{
_clientStorageContract = new ClientStorageContract(BankDbContext);
_clerkId = BankDbContext.InsertClerkToDatabaseAndReturn().Id;
_storekeeperId = BankDbContext.InsertStorekeeperToDatabaseAndReturn().Id;
_depositId = BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId).Id;
_periodId = BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId).Id;
_creditProgramId = BankDbContext
.InsertCreditProgramToDatabaseAndReturn(
storeleeperId: _storekeeperId,
periodId: _periodId
)
.Id;
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveClientsFromDatabase();
BankDbContext.RemoveDepositsFromDatabase();
BankDbContext.RemovePeriodsFromDatabase();
BankDbContext.RemoveCreditProgramsFromDatabase();
BankDbContext.RemoveClerksFromDatabase();
BankDbContext.RemoveStorekeepersFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSucces_Test()
{
var clientId = Guid.NewGuid().ToString();
var client = BankDbContext.InsertClientToDatabaseAndReturn(
id: clientId,
clerkId: _clerkId,
depositClients: [(_depositId, clientId)]
);
BankDbContext.InsertClientToDatabaseAndReturn(
clerkId: _clerkId,
depositClients:
[
(BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId).Id, clientId),
]
);
BankDbContext.InsertClientToDatabaseAndReturn(
clerkId: _clerkId,
creditProgramClients: [(clientId, _creditProgramId)]
);
var list = _clientStorageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == clientId), client);
}
[Test]
public void TryGetList_WhenNoRecords_Test()
{
var list = _clientStorageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void TryGetList_ByClerk_WhenHaveRecords_Test()
{
var clerk = BankDbContext.InsertClerkToDatabaseAndReturn(
email: "slava@ilya.com",
login: "login",
phone: "+7-987-555-55-55"
);
BankDbContext.InsertClientToDatabaseAndReturn(clerkId: clerk.Id);
BankDbContext.InsertClientToDatabaseAndReturn(clerkId: clerk.Id);
BankDbContext.InsertClientToDatabaseAndReturn(clerkId: clerk.Id);
BankDbContext.InsertClientToDatabaseAndReturn(clerkId: clerk.Id);
var list = _clientStorageContract.GetList(clerkId: clerk.Id);
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(4));
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var client = BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId);
AssertElement(_clientStorageContract.GetElementById(client.Id), client);
}
[Test]
public void Try_AddElement_Test()
{
var clientId = Guid.NewGuid().ToString();
var client = CreateModel(
_clerkId,
clientId,
depositClients: [new DepositClientDataModel(_depositId, clientId)],
clientCredits: [new ClientCreditProgramDataModel(clientId, _creditProgramId)]
);
_clientStorageContract.AddElement(client);
AssertElement(BankDbContext.GetClientFromDatabase(client.Id), client);
}
[Test]
public void Try_UpdElement_Test()
{
var clientId = Guid.NewGuid().ToString();
var client = CreateModel(
_clerkId,
id: clientId,
depositClients: [new DepositClientDataModel(_depositId, clientId)]
);
BankDbContext.InsertClientToDatabaseAndReturn(
id: clientId,
clerkId: _clerkId,
creditProgramClients: [(clientId, _creditProgramId)]
);
_clientStorageContract.UpdElement(client);
BankDbContext.ChangeTracker.Clear();
AssertElement(BankDbContext.GetClientFromDatabase(clientId), client);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() => _clientStorageContract.UpdElement(CreateModel(_clerkId)),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static ClientDataModel CreateModel(
string clerkid,
string? id = null,
string? name = "null",
string? surname = "surname",
decimal balance = 1,
List<DepositClientDataModel>? depositClients = null,
List<ClientCreditProgramDataModel>? clientCredits = null
) =>
new(
id ?? Guid.NewGuid().ToString(),
name,
surname,
balance,
clerkid,
depositClients ?? [],
clientCredits ?? []
);
private static void AssertElement(ClientDataModel actual, Client? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.Surname, Is.EqualTo(expected.Surname));
Assert.That(actual.Balance, Is.EqualTo(expected.Balance));
Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId));
});
if (expected.DepositClients is not null)
{
Assert.That(actual.DepositClients, Is.Not.Null);
Assert.That(actual.DepositClients, Has.Count.EqualTo(expected.DepositClients.Count));
for (int i = 0; i < actual.DepositClients.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(
actual.DepositClients[i].ClientId,
Is.EqualTo(expected.DepositClients[i].ClientId)
);
Assert.That(
actual.DepositClients[i].DepositId,
Is.EqualTo(expected.DepositClients[i].DepositId)
);
});
}
}
else
{
Assert.That(actual.DepositClients, Is.Null);
}
if (expected.CreditProgramClients is not null)
{
Assert.That(actual.CreditProgramClients, Is.Not.Null);
Assert.That(
actual.CreditProgramClients,
Has.Count.EqualTo(expected.CreditProgramClients.Count)
);
for (int i = 0; i < actual.CreditProgramClients.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(
actual.CreditProgramClients[i].ClientId,
Is.EqualTo(expected.CreditProgramClients[i].ClientId)
);
Assert.That(
actual.CreditProgramClients[i].CreditProgramId,
Is.EqualTo(expected.CreditProgramClients[i].CreditProgramId)
);
});
}
}
else
{
Assert.That(actual.CreditProgramClients, Is.Null);
}
}
private static void AssertElement(Client actual, ClientDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.Surname, Is.EqualTo(expected.Surname));
Assert.That(actual.Balance, Is.EqualTo(expected.Balance));
Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId));
});
if (expected.DepositClients is not null)
{
Assert.That(actual.DepositClients, Is.Not.Null);
Assert.That(actual.DepositClients, Has.Count.EqualTo(expected.DepositClients.Count));
for (int i = 0; i < actual.DepositClients.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(
actual.DepositClients[i].ClientId,
Is.EqualTo(expected.DepositClients[i].ClientId)
);
Assert.That(
actual.DepositClients[i].DepositId,
Is.EqualTo(expected.DepositClients[i].DepositId)
);
});
}
}
else
{
Assert.That(actual.DepositClients, Is.Null);
}
if (expected.CreditProgramClients is not null)
{
Assert.That(actual.CreditProgramClients, Is.Not.Null);
Assert.That(
actual.CreditProgramClients,
Has.Count.EqualTo(expected.CreditProgramClients.Count)
);
for (int i = 0; i < actual.CreditProgramClients.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(
actual.CreditProgramClients[i].ClientId,
Is.EqualTo(expected.CreditProgramClients[i].ClientId)
);
Assert.That(
actual.CreditProgramClients[i].CreditProgramId,
Is.EqualTo(expected.CreditProgramClients[i].CreditProgramId)
);
});
}
}
else
{
Assert.That(actual.CreditProgramClients, Is.Null);
}
}
}

View File

@@ -0,0 +1,240 @@
using System.Xml.Linq;
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class CreditProgramStorageContractTests : BaseStorageContractTest
{
private ICreditProgramStorageContract _storageContract;
private string _storekeeperId;
private string _periodId;
private string _currenyId;
[SetUp]
public void SetUp()
{
_storageContract = new CreditProgramStorageContract(BankDbContext);
_storekeeperId = BankDbContext.InsertStorekeeperToDatabaseAndReturn().Id;
_periodId = BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId).Id;
_currenyId = BankDbContext.InsertCurrencyToDatabaseAndReturn(storekeeperId: _storekeeperId).Id;
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveCreditProgramsFromDatabase();
BankDbContext.RemovePeriodsFromDatabase();
BankDbContext.RemoveCurrenciesFromDatabase();
BankDbContext.RemoveStorekeepersFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSucces_Test()
{
var creditProgramId = Guid.NewGuid().ToString();
var creditProgram = BankDbContext.InsertCreditProgramToDatabaseAndReturn(
storeleeperId: _storekeeperId,
periodId: _periodId,
creditProgramCurrency: [( _currenyId, creditProgramId )]
);
BankDbContext.InsertCreditProgramToDatabaseAndReturn(
name: "bankrot2",
storeleeperId: _storekeeperId,
periodId: _periodId
);
BankDbContext.InsertCreditProgramToDatabaseAndReturn(
name: "bankrot3",
storeleeperId: _storekeeperId,
periodId: _periodId
);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == creditProgram.Id), creditProgram);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var creditProgram = BankDbContext.InsertCreditProgramToDatabaseAndReturn(
storeleeperId: _storekeeperId,
periodId: _periodId
);
AssertElement(_storageContract.GetElementById(creditProgram.Id), creditProgram);
}
[Test]
public void Try_AddElement_Test()
{
var credit = CreateModel(
name: "unique name",
periodId: _periodId,
storekeeperId: _storekeeperId
);
_storageContract.AddElement(credit);
AssertElement(BankDbContext.GetCreditProgramFromDatabase(credit.Id), credit);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameName_Test()
{
var credit = CreateModel(name: "1", storekeeperId: _storekeeperId, periodId: _periodId);
BankDbContext.InsertCreditProgramToDatabaseAndReturn(
name: "1",
periodId: _periodId,
storeleeperId: _storekeeperId,
creditProgramCurrency: [(_currenyId, credit.Id)]
);
Assert.That(
() => _storageContract.AddElement(credit),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var credit = CreateModel(
name: "unique name",
periodId: _periodId,
storekeeperId: _storekeeperId
);
BankDbContext.InsertCreditProgramToDatabaseAndReturn(
credit.Id,
periodId: _periodId,
storeleeperId: _storekeeperId,
creditProgramCurrency: [(_currenyId, credit.Id)]
);
_storageContract.UpdElement(credit);
AssertElement(BankDbContext.GetCreditProgramFromDatabase(credit.Id), credit);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() =>
_storageContract.UpdElement(
CreateModel(storekeeperId: _storekeeperId, periodId: _periodId)
),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static CreditProgramDataModel CreateModel(
string? id = null,
string? name = "name",
decimal cost = 1,
decimal maxCost = 2,
string? storekeeperId = null,
string? periodId = null,
List<CreditProgramCurrencyDataModel>? currency = null
) =>
new(
id ?? Guid.NewGuid().ToString(),
name,
cost,
maxCost,
storekeeperId ?? Guid.NewGuid().ToString(),
periodId ?? Guid.NewGuid().ToString(),
currency ?? []
);
private static void AssertElement(CreditProgramDataModel actual, CreditProgram? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
Assert.That(actual.MaxCost, Is.EqualTo(expected.MaxCost));
Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId));
Assert.That(actual.PeriodId, Is.EqualTo(expected.PeriodId));
});
if (actual.Currencies is not null)
{
Assert.That(expected.CurrencyCreditPrograms, Is.Not.Null);
Assert.That(
actual.Currencies,
Has.Count.EqualTo(expected.CurrencyCreditPrograms.Count)
);
for (int i = 0; i < actual.Currencies.Count; ++i)
{
Assert.Multiple(() =>
{
Assert.That(
actual.Currencies[i].CreditProgramId,
Is.EqualTo(expected.CurrencyCreditPrograms[i].CreditProgramId)
);
Assert.That(
actual.Currencies[i].CurrencyId,
Is.EqualTo(expected.CurrencyCreditPrograms[i].CurrencyId)
);
});
}
}
else
{
Assert.That(expected.CurrencyCreditPrograms, Is.Null);
}
}
private static void AssertElement(CreditProgram actual, CreditProgramDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
Assert.That(actual.MaxCost, Is.EqualTo(expected.MaxCost));
Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId));
Assert.That(actual.PeriodId, Is.EqualTo(expected.PeriodId));
});
if (actual.CurrencyCreditPrograms is not null)
{
Assert.That(expected.Currencies, Is.Not.Null);
Assert.That(
actual.CurrencyCreditPrograms,
Has.Count.EqualTo(expected.Currencies.Count)
);
for (int i = 0;i < actual.CurrencyCreditPrograms.Count;++i)
{
Assert.Multiple(() =>
{
Assert.That(
actual.CurrencyCreditPrograms[i].CreditProgramId,
Is.EqualTo(expected.Currencies[i].CreditProgramId)
);
Assert.That(
actual.CurrencyCreditPrograms[i].CurrencyId,
Is.EqualTo(expected.Currencies[i].CurrencyId)
);
});
}
}
else
{
Assert.That(expected.Currencies, Is.Null);
}
}
}

View File

@@ -0,0 +1,176 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class CurrencyStorageContractTests : BaseStorageContractTest
{
private ICurrencyStorageContract _storageContract;
private string _storekeeperId;
[SetUp]
public void SetUp()
{
_storageContract = new CurrencyStorageContract(BankDbContext);
_storekeeperId = BankDbContext.InsertStorekeeperToDatabaseAndReturn().Id;
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveCurrenciesFromDatabase();
BankDbContext.RemoveStorekeepersFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSuccess_Test()
{
var currency = BankDbContext.InsertCurrencyToDatabaseAndReturn(
storekeeperId: _storekeeperId
);
BankDbContext.InsertCurrencyToDatabaseAndReturn(
abbreviation: "$",
storekeeperId: _storekeeperId
);
BankDbContext.InsertCurrencyToDatabaseAndReturn(
abbreviation: "eur",
storekeeperId: _storekeeperId
);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(_storageContract.GetElementById(currency.Id), currency);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var currency = BankDbContext.InsertCurrencyToDatabaseAndReturn(
storekeeperId: _storekeeperId
);
AssertElement(_storageContract.GetElementById(currency.Id), currency);
}
[Test]
public void Try_GetElementByAbbreviation_WhenHaveRecord_Test()
{
var currency = BankDbContext.InsertCurrencyToDatabaseAndReturn(
abbreviation: "X",
storekeeperId: _storekeeperId
);
AssertElement(_storageContract.GetElementByAbbreviation(currency.Abbreviation), currency);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_AddElement_Test()
{
var currency = CreateModel(storekeeperId: _storekeeperId);
_storageContract.AddElement(currency);
AssertElement(BankDbContext.GetCurrencyFromDatabase(currency.Id), currency);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
{
var currency = CreateModel(storekeeperId: _storekeeperId);
BankDbContext.InsertCurrencyToDatabaseAndReturn(
id: currency.Id,
storekeeperId: _storekeeperId
);
Assert.That(
() => _storageContract.AddElement(currency),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameAbbreviation_Test()
{
var currency = CreateModel(storekeeperId: _storekeeperId, abbreviation: "хамстер коин");
BankDbContext.InsertCurrencyToDatabaseAndReturn(
storekeeperId: _storekeeperId,
abbreviation: currency.Abbreviation
);
Assert.That(
() => _storageContract.AddElement(currency),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var currency = CreateModel(storekeeperId: _storekeeperId, abbreviation: "хамстер коин");
BankDbContext.InsertCurrencyToDatabaseAndReturn(
id: currency.Id,
storekeeperId: _storekeeperId
);
_storageContract.UpdElement(currency);
AssertElement(BankDbContext.GetCurrencyFromDatabase(currency.Id), currency);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() => _storageContract.UpdElement(CreateModel()),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static CurrencyDataModel CreateModel(
string? id = null,
string? name = "pop",
string? abbreviation = "rub",
decimal cost = 10,
string? storekeeperId = null
) =>
new(
id ?? Guid.NewGuid().ToString(),
name,
abbreviation,
cost,
storekeeperId ?? Guid.NewGuid().ToString()
);
private static void AssertElement(CurrencyDataModel actual, Currency? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.Abbreviation, Is.EqualTo(expected.Abbreviation));
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId));
});
}
private static void AssertElement(Currency actual, CurrencyDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.Abbreviation, Is.EqualTo(expected.Abbreviation));
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId));
});
}
}

View File

@@ -0,0 +1,138 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class DepositStorageContractTests : BaseStorageContractTest
{
private IDepositStorageContract _storageContract;
private string _clerkId;
[SetUp]
public void SetUp()
{
_storageContract = new DepositStorageContract(BankDbContext);
_clerkId = BankDbContext.InsertClerkToDatabaseAndReturn().Id;
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveDepositsFromDatabase();
BankDbContext.RemoveClerksFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSuccess_Test()
{
var deposit = BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId);
BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId);
BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == deposit.Id), deposit);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var deposit = BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId);
AssertElement(_storageContract.GetElementById(deposit.Id), deposit);
}
[Test]
public void Try_AddElement_Test()
{
var deposit = CreateModel(clerkId: _clerkId);
_storageContract.AddElement(deposit);
AssertElement(BankDbContext.GetDepositFromDatabase(deposit.Id), deposit);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
{
var deposit = CreateModel(clerkId: _clerkId);
BankDbContext.InsertDepositToDatabaseAndReturn(id: deposit.Id, clerkId: _clerkId);
Assert.That(
() => _storageContract.AddElement(deposit),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var deposit = CreateModel(clerkId: _clerkId);
BankDbContext.InsertDepositToDatabaseAndReturn(id: deposit.Id, clerkId: _clerkId);
_storageContract.UpdElement(deposit);
AssertElement(BankDbContext.GetDepositFromDatabase(deposit.Id), deposit);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() => _storageContract.UpdElement(CreateModel(clerkId: _clerkId)),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static DepositDataModel CreateModel(
string? id = null,
float interestRate = 10,
decimal cost = 10,
int period = 10,
string? clerkId = null,
List<DepositCurrencyDataModel>? deposits = null
) =>
new(
id ?? Guid.NewGuid().ToString(),
interestRate,
cost,
period,
clerkId ?? Guid.NewGuid().ToString(),
deposits ?? []
);
private static void AssertElement(DepositDataModel actual, Deposit? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.InterestRate, Is.EqualTo(expected.InterestRate));
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
Assert.That(actual.Period, Is.EqualTo(expected.Period));
Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId));
});
}
private static void AssertElement(Deposit actual, DepositDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.InterestRate, Is.EqualTo(expected.InterestRate));
Assert.That(actual.Cost, Is.EqualTo(expected.Cost));
Assert.That(actual.Period, Is.EqualTo(expected.Period));
Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId));
});
}
}

View File

@@ -0,0 +1,132 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class PeriodStorageContractTests : BaseStorageContractTest
{
private IPeriodStorageContract _storageContract;
private string _storekeeperId;
[SetUp]
public void SetUp()
{
_storageContract = new PeriodStorageContract(BankDbContext);
_storekeeperId = BankDbContext.InsertStorekeeperToDatabaseAndReturn().Id;
}
[TearDown]
public void TearDown()
{
BankDbContext.RemovePeriodsFromDatabase();
BankDbContext.RemoveStorekeepersFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSuccess_Test()
{
var period = BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId);
BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId);
BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == period.Id), period);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var period = BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId);
AssertElement(_storageContract.GetElementById(period.Id), period);
}
[Test]
public void Try_AddElement_Test()
{
var period = CreateModel(storekeeperId: _storekeeperId);
_storageContract.AddElement(period);
AssertElement(BankDbContext.GetPeriodFromDatabase(period.Id), period);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
{
var period = CreateModel(storekeeperId: _storekeeperId);
BankDbContext.InsertPeriodToDatabaseAndReturn(id: period.Id, storekeeperId: _storekeeperId);
Assert.That(
() => _storageContract.AddElement(period),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var period = CreateModel(storekeeperId: _storekeeperId);
BankDbContext.InsertPeriodToDatabaseAndReturn(id: period.Id, storekeeperId: _storekeeperId);
_storageContract.UpdElement(period);
AssertElement(BankDbContext.GetPeriodFromDatabase(period.Id), period);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() => _storageContract.UpdElement(CreateModel(storekeeperId: _storekeeperId)),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static PeriodDataModel CreateModel(
string? id = null,
DateTime? startTime = null,
DateTime? endTime = null,
string? storekeeperId = null
) =>
new(
id ?? Guid.NewGuid().ToString(),
startTime ?? DateTime.UtcNow.AddDays(-1),
endTime ?? DateTime.UtcNow,
storekeeperId ?? Guid.NewGuid().ToString()
);
private static void AssertElement(PeriodDataModel actual, Period? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.StartTime, Is.EqualTo(expected.StartTime));
Assert.That(actual.EndTime, Is.EqualTo(expected.EndTime));
Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId));
});
}
private static void AssertElement(Period actual, PeriodDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.StartTime, Is.EqualTo(expected.StartTime));
Assert.That(actual.EndTime, Is.EqualTo(expected.EndTime));
Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId));
});
}
}

View File

@@ -0,0 +1,161 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class ReplenishmentStorageContractTests : BaseStorageContractTest
{
private IReplenishmentStorageContract _storageContract;
private string _depositId;
private string _clerkId;
[SetUp]
public void SetUp()
{
_storageContract = new ReplenishmentStorageContract(BankDbContext);
_clerkId = BankDbContext.InsertClerkToDatabaseAndReturn().Id;
_depositId = BankDbContext.InsertDepositToDatabaseAndReturn(clerkId: _clerkId).Id;
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveReplenishmentsFromDatabase();
BankDbContext.RemoveDepositsFromDatabase();
BankDbContext.RemoveClerksFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSuccess_Test()
{
var replenishment = BankDbContext.InsertReplenishmentToDatabaseAndReturn(
clerkId: _clerkId,
depositId: _depositId
);
BankDbContext.InsertReplenishmentToDatabaseAndReturn(
clerkId: _clerkId,
depositId: _depositId
);
BankDbContext.InsertReplenishmentToDatabaseAndReturn(
clerkId: _clerkId,
depositId: _depositId
);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == replenishment.Id), replenishment);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var replenishment = BankDbContext.InsertReplenishmentToDatabaseAndReturn(
clerkId: _clerkId,
depositId: _depositId
);
AssertElement(_storageContract.GetElementById(replenishment.Id), replenishment);
}
[Test]
public void Try_AddElement_Test()
{
var replenishment = CreateModel(clerkId: _clerkId, depositId: _depositId);
_storageContract.AddElement(replenishment);
AssertElement(BankDbContext.GetReplenishmentFromDatabase(replenishment.Id), replenishment);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
{
var replenishment = CreateModel(clerkId: _clerkId, depositId: _depositId);
BankDbContext.InsertReplenishmentToDatabaseAndReturn(
id: replenishment.Id,
clerkId: _clerkId,
depositId: _depositId
);
Assert.That(
() => _storageContract.AddElement(replenishment),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var replenishment = CreateModel(clerkId: _clerkId, depositId: _depositId);
BankDbContext.InsertReplenishmentToDatabaseAndReturn(
id: replenishment.Id,
clerkId: _clerkId,
depositId: _depositId
);
_storageContract.UpdElement(replenishment);
AssertElement(BankDbContext.GetReplenishmentFromDatabase(replenishment.Id), replenishment);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() =>
_storageContract.UpdElement(CreateModel(clerkId: _clerkId, depositId: _depositId)),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static ReplenishmentDataModel CreateModel(
string? id = null,
decimal amount = 1,
DateTime? date = null,
string? depositId = null,
string? clerkId = null
) =>
new(
id ?? Guid.NewGuid().ToString(),
amount,
date ?? DateTime.UtcNow,
depositId ?? Guid.NewGuid().ToString(),
clerkId ?? Guid.NewGuid().ToString()
);
private static void AssertElement(ReplenishmentDataModel actual, Replenishment? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Amount, Is.EqualTo(expected.Amount));
Assert.That(actual.Date, Is.EqualTo(expected.Date));
Assert.That(actual.DepositId, Is.EqualTo(expected.DepositId));
Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId));
});
}
private static void AssertElement(Replenishment actual, ReplenishmentDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Amount, Is.EqualTo(expected.Amount));
Assert.That(actual.Date, Is.EqualTo(expected.Date));
Assert.That(actual.DepositId, Is.EqualTo(expected.DepositId));
Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId));
});
}
}

View File

@@ -0,0 +1,175 @@
using BankContracts.DataModels;
using BankContracts.Exceptions;
using BankContracts.StorageContracts;
using BankDatabase.Implementations;
using BankDatabase.Models;
using BankTests.Infrastructure;
namespace BankTests.StorageContactsTests;
[TestFixture]
internal class StorekeeperStorageContractTests : BaseStorageContractTest
{
private IStorekeeperStorageContract _storageContract;
[SetUp]
public void SetUp()
{
_storageContract = new StorekeeperStorageContract(BankDbContext);
}
[TearDown]
public void TearDown()
{
BankDbContext.RemoveStorekeepersFromDatabase();
}
[Test]
public void TryGetListWhenHaveRecords_ShouldSuccess_Test()
{
var storekeeper = BankDbContext.InsertStorekeeperToDatabaseAndReturn();
BankDbContext.InsertStorekeeperToDatabaseAndReturn(
login: "xomyak2",
email: "email1@email.com",
phone: "+9-888-888-88-68"
);
BankDbContext.InsertStorekeeperToDatabaseAndReturn(
login: "xomyak3",
email: "email3@email.com",
phone: "+9-888-888-88-78"
);
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Has.Count.EqualTo(3));
AssertElement(list.First(x => x.Id == storekeeper.Id), storekeeper);
}
[Test]
public void Try_GetList_WhenNoRecords_Test()
{
var list = _storageContract.GetList();
Assert.That(list, Is.Not.Null);
Assert.That(list, Is.Empty);
}
[Test]
public void Try_GetElementById_WhenHaveRecord_Test()
{
var storekeeper = BankDbContext.InsertStorekeeperToDatabaseAndReturn();
AssertElement(_storageContract.GetElementById(storekeeper.Id), storekeeper);
}
[Test]
public void Try_AddElement_Test()
{
var storekeeper = CreateModel();
_storageContract.AddElement(storekeeper);
AssertElement(BankDbContext.GetStorekeeperFromDatabase(storekeeper.Id), storekeeper);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameId_Test()
{
var storekeeper = CreateModel();
BankDbContext.InsertStorekeeperToDatabaseAndReturn(id: storekeeper.Id);
Assert.That(
() => _storageContract.AddElement(storekeeper),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameEmail_Test()
{
var storekeeper = CreateModel();
BankDbContext.InsertStorekeeperToDatabaseAndReturn(email: storekeeper.Email);
Assert.That(
() => _storageContract.AddElement(storekeeper),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_AddElement_WhenHaveRecordWithSameLogin_Test()
{
var storekeeper = CreateModel(login: "cheburek");
BankDbContext.InsertStorekeeperToDatabaseAndReturn(
email: "email@email.ru",
login: "cheburek"
);
Assert.That(
() => _storageContract.AddElement(storekeeper),
Throws.TypeOf<ElementExistsException>()
);
}
[Test]
public void Try_UpdElement_Test()
{
var storekeeper = CreateModel();
BankDbContext.InsertStorekeeperToDatabaseAndReturn(storekeeper.Id, name: "Женя");
_storageContract.UpdElement(storekeeper);
AssertElement(BankDbContext.GetStorekeeperFromDatabase(storekeeper.Id), storekeeper);
}
[Test]
public void Try_UpdElement_WhenNoRecordWithThisId_Test()
{
Assert.That(
() => _storageContract.UpdElement(CreateModel()),
Throws.TypeOf<ElementNotFoundException>()
);
}
private static StorekeeperDataModel CreateModel(
string? id = null,
string? name = "vasya",
string? surname = "petrov",
string? middlename = "petrovich",
string? login = "vasyapupkin",
string? passwd = "*******",
string? email = "email@email.com",
string? phone = "+7-777-777-77-77"
) =>
new(
id ?? Guid.NewGuid().ToString(),
name,
surname,
middlename,
login,
passwd,
email,
phone
);
private static void AssertElement(StorekeeperDataModel actual, Storekeeper? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.MiddleName, Is.EqualTo(expected.MiddleName));
Assert.That(actual.Login, Is.EqualTo(expected.Login));
Assert.That(actual.Password, Is.EqualTo(expected.Password));
Assert.That(actual.Email, Is.EqualTo(expected.Email));
Assert.That(actual.PhoneNumber, Is.EqualTo(expected.PhoneNumber));
});
}
private static void AssertElement(Storekeeper actual, StorekeeperDataModel? expected)
{
Assert.That(expected, Is.Not.Null);
Assert.Multiple(() =>
{
Assert.That(actual.Id, Is.EqualTo(expected.Id));
Assert.That(actual.Name, Is.EqualTo(expected.Name));
Assert.That(actual.MiddleName, Is.EqualTo(expected.MiddleName));
Assert.That(actual.Login, Is.EqualTo(expected.Login));
Assert.That(actual.Password, Is.EqualTo(expected.Password));
Assert.That(actual.Email, Is.EqualTo(expected.Email));
Assert.That(actual.PhoneNumber, Is.EqualTo(expected.PhoneNumber));
});
}
}

View File

@@ -7,6 +7,10 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankContracts", "BankContra
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankBusinessLogic", "BankBusinessLogic\BankBusinessLogic.csproj", "{EAB70DA6-3C70-4069-B83C-D90330757C12}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankDatabase", "BankDatabase\BankDatabase.csproj", "{72F2568B-F5A8-4244-A777-BCABEF98F67A}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankTests", "BankTests\BankTests.csproj", "{7C898FC8-6BC2-41E8-9538-D42ACC263A97}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -21,6 +25,14 @@ Global
{EAB70DA6-3C70-4069-B83C-D90330757C12}.Debug|Any CPU.Build.0 = Debug|Any CPU
{EAB70DA6-3C70-4069-B83C-D90330757C12}.Release|Any CPU.ActiveCfg = Release|Any CPU
{EAB70DA6-3C70-4069-B83C-D90330757C12}.Release|Any CPU.Build.0 = Release|Any CPU
{72F2568B-F5A8-4244-A777-BCABEF98F67A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{72F2568B-F5A8-4244-A777-BCABEF98F67A}.Debug|Any CPU.Build.0 = Debug|Any CPU
{72F2568B-F5A8-4244-A777-BCABEF98F67A}.Release|Any CPU.ActiveCfg = Release|Any CPU
{72F2568B-F5A8-4244-A777-BCABEF98F67A}.Release|Any CPU.Build.0 = Release|Any CPU
{7C898FC8-6BC2-41E8-9538-D42ACC263A97}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7C898FC8-6BC2-41E8-9538-D42ACC263A97}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7C898FC8-6BC2-41E8-9538-D42ACC263A97}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7C898FC8-6BC2-41E8-9538-D42ACC263A97}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE