From e909fa709f383000c1cd71f1c910a1c100afe674 Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Fri, 25 Apr 2025 01:12:51 +0400 Subject: [PATCH 01/16] =?UTF-8?q?feat:=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= =?UTF-8?q?=20=D0=B1=D0=B4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit добавление моделек для бд (кроме многие ко многим), реализация одного контракта хранилища --- .../Exceptions/ElementExistsException.cs | 8 + .../Exceptions/StorageException.cs | 7 + .../Infrastructure/IConfigurationDatabase.cs | 10 ++ TheBank/BankDatabase/BankDatabase.csproj | 19 +++ TheBank/BankDatabase/BankDbContext.cs | 87 +++++++++++ .../Implementations/ClerkStorageContract.cs | 141 ++++++++++++++++++ TheBank/BankDatabase/Models/Clerk.cs | 32 ++++ TheBank/BankDatabase/Models/Client.cs | 19 +++ TheBank/BankDatabase/Models/CreditProgram.cs | 16 ++ TheBank/BankDatabase/Models/Currency.cs | 14 ++ TheBank/BankDatabase/Models/Deposit.cs | 19 +++ TheBank/BankDatabase/Models/Period.cs | 12 ++ TheBank/BankDatabase/Models/Replenishment.cs | 19 +++ TheBank/BankDatabase/Models/Storekeeper.cs | 20 +++ TheBank/TheBank.sln | 6 + 15 files changed, 429 insertions(+) create mode 100644 TheBank/BankContracts/Exceptions/ElementExistsException.cs create mode 100644 TheBank/BankContracts/Exceptions/StorageException.cs create mode 100644 TheBank/BankContracts/Infrastructure/IConfigurationDatabase.cs create mode 100644 TheBank/BankDatabase/BankDatabase.csproj create mode 100644 TheBank/BankDatabase/BankDbContext.cs create mode 100644 TheBank/BankDatabase/Implementations/ClerkStorageContract.cs create mode 100644 TheBank/BankDatabase/Models/Clerk.cs create mode 100644 TheBank/BankDatabase/Models/Client.cs create mode 100644 TheBank/BankDatabase/Models/CreditProgram.cs create mode 100644 TheBank/BankDatabase/Models/Currency.cs create mode 100644 TheBank/BankDatabase/Models/Deposit.cs create mode 100644 TheBank/BankDatabase/Models/Period.cs create mode 100644 TheBank/BankDatabase/Models/Replenishment.cs create mode 100644 TheBank/BankDatabase/Models/Storekeeper.cs diff --git a/TheBank/BankContracts/Exceptions/ElementExistsException.cs b/TheBank/BankContracts/Exceptions/ElementExistsException.cs new file mode 100644 index 0000000..cecbe29 --- /dev/null +++ b/TheBank/BankContracts/Exceptions/ElementExistsException.cs @@ -0,0 +1,8 @@ +namespace BankContracts.Exceptions; + +/// +/// Исключение при работе с хранилищем +/// при добавлении существующего элемента +/// +/// сообщение +public class ElementExistsException(string message) : Exception(message) { } diff --git a/TheBank/BankContracts/Exceptions/StorageException.cs b/TheBank/BankContracts/Exceptions/StorageException.cs new file mode 100644 index 0000000..d2782aa --- /dev/null +++ b/TheBank/BankContracts/Exceptions/StorageException.cs @@ -0,0 +1,7 @@ +namespace BankContracts.Exceptions; + +/// +/// Исключение при работе с хранилищем +/// +/// +public class StorageException(string message) : Exception(message) { } diff --git a/TheBank/BankContracts/Infrastructure/IConfigurationDatabase.cs b/TheBank/BankContracts/Infrastructure/IConfigurationDatabase.cs new file mode 100644 index 0000000..efc6252 --- /dev/null +++ b/TheBank/BankContracts/Infrastructure/IConfigurationDatabase.cs @@ -0,0 +1,10 @@ +namespace BankContracts.Infrastructure; + +/// +/// интерфейс для подключения к бд +/// хз зачем он нужен тут в контрактах а не в самой бд +/// +public interface IConfigurationDatabase +{ + public string ConnectionString { get; } +} diff --git a/TheBank/BankDatabase/BankDatabase.csproj b/TheBank/BankDatabase/BankDatabase.csproj new file mode 100644 index 0000000..ba7e73b --- /dev/null +++ b/TheBank/BankDatabase/BankDatabase.csproj @@ -0,0 +1,19 @@ + + + + net9.0 + enable + enable + + + + + + + + + + + + + diff --git a/TheBank/BankDatabase/BankDbContext.cs b/TheBank/BankDatabase/BankDbContext.cs new file mode 100644 index 0000000..0ab2064 --- /dev/null +++ b/TheBank/BankDatabase/BankDbContext.cs @@ -0,0 +1,87 @@ +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() + .HasIndex(x => x.Login) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.Email) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.PhoneNumber) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.Name) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.Abbreviation) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.PhoneNumber) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.Email) + .IsUnique(); + + modelBuilder.Entity() + .HasIndex(x => x.Login) + .IsUnique(); + + modelBuilder.Entity() + .HasMany(x => x.Deposits) + .WithOne(x => x.Clerk) + .HasForeignKey(x => x.ClerkId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasMany(x => x.Clients) + .WithOne(x => x.Clerk) + .HasForeignKey(x => x.ClerkId) + .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity() + .HasMany(x => x.Replenishments) + .WithOne(x => x.Clerk) + .HasForeignKey(x => x.ClerkId) + .OnDelete(DeleteBehavior.Restrict); + } + + public DbSet Clerks { get; set; } + + public DbSet Clients { get; set; } + + public DbSet CreditPrograms { get; set; } + + public DbSet Currencies { get; set; } + + public DbSet Deposits { get; set; } + + public DbSet Periods { get; set; } + + public DbSet Replenishments { get; set; } + + public DbSet Storekeepers { get; set; } +} diff --git a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs new file mode 100644 index 0000000..c4a210f --- /dev/null +++ b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs @@ -0,0 +1,141 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; + +namespace BankDatabase.Implementations; + +/// +/// реализация контракта для клерка +/// +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(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List GetList() + { + try + { + return [.. _dbContext.Clerks.Select(x => _mapper.Map(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + public ClerkDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_dbContext.Clerks.FirstOrDefault(x => x.Id == id)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ClerkDataModel? GetElementByLogin(string login) + { + try + { + return _mapper.Map(_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(_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(clerkDataModel)); + _dbContext.SaveChanges(); + } + 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 (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(); +} diff --git a/TheBank/BankDatabase/Models/Clerk.cs b/TheBank/BankDatabase/Models/Clerk.cs new file mode 100644 index 0000000..70c98be --- /dev/null +++ b/TheBank/BankDatabase/Models/Clerk.cs @@ -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("ReplenishmentId")] + public List? Replenishments { get; set; } + + [ForeignKey("DepositId")] + public List? Deposits { get; set; } + + [ForeignKey("ClientId")] + public List? Clients { get; set; } +} diff --git a/TheBank/BankDatabase/Models/Client.cs b/TheBank/BankDatabase/Models/Client.cs new file mode 100644 index 0000000..7cdd58d --- /dev/null +++ b/TheBank/BankDatabase/Models/Client.cs @@ -0,0 +1,19 @@ +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; } + + [ForeignKey("ClerkId")] + public Clerk? Clerk { get; set; } +} diff --git a/TheBank/BankDatabase/Models/CreditProgram.cs b/TheBank/BankDatabase/Models/CreditProgram.cs new file mode 100644 index 0000000..b86e5b4 --- /dev/null +++ b/TheBank/BankDatabase/Models/CreditProgram.cs @@ -0,0 +1,16 @@ +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; } +} diff --git a/TheBank/BankDatabase/Models/Currency.cs b/TheBank/BankDatabase/Models/Currency.cs new file mode 100644 index 0000000..604ccae --- /dev/null +++ b/TheBank/BankDatabase/Models/Currency.cs @@ -0,0 +1,14 @@ +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; } +} diff --git a/TheBank/BankDatabase/Models/Deposit.cs b/TheBank/BankDatabase/Models/Deposit.cs new file mode 100644 index 0000000..800b60e --- /dev/null +++ b/TheBank/BankDatabase/Models/Deposit.cs @@ -0,0 +1,19 @@ +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; } + + [ForeignKey("ClerkId")] + public Clerk? Clerk { get; set; } +} diff --git a/TheBank/BankDatabase/Models/Period.cs b/TheBank/BankDatabase/Models/Period.cs new file mode 100644 index 0000000..e09aa66 --- /dev/null +++ b/TheBank/BankDatabase/Models/Period.cs @@ -0,0 +1,12 @@ +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; } +} diff --git a/TheBank/BankDatabase/Models/Replenishment.cs b/TheBank/BankDatabase/Models/Replenishment.cs new file mode 100644 index 0000000..13408e2 --- /dev/null +++ b/TheBank/BankDatabase/Models/Replenishment.cs @@ -0,0 +1,19 @@ +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; } + + [ForeignKey("ClerkId")] + public Clerk? Clerk { get; set; } +} diff --git a/TheBank/BankDatabase/Models/Storekeeper.cs b/TheBank/BankDatabase/Models/Storekeeper.cs new file mode 100644 index 0000000..eacea22 --- /dev/null +++ b/TheBank/BankDatabase/Models/Storekeeper.cs @@ -0,0 +1,20 @@ +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; } +} diff --git a/TheBank/TheBank.sln b/TheBank/TheBank.sln index 9bda558..7515a62 100644 --- a/TheBank/TheBank.sln +++ b/TheBank/TheBank.sln @@ -7,6 +7,8 @@ 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 Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -21,6 +23,10 @@ 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 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE From b582d03d45b8bdd9084bb10a5f359558f9bbe3b3 Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Fri, 25 Apr 2025 01:13:35 +0400 Subject: [PATCH 02/16] =?UTF-8?q?fix:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D1=81=D0=BF=D0=B8=D1=81=D0=BA=D0=B8=20=D0=B2=20?= =?UTF-8?q?=D0=B4=D0=B0=D1=82=D0=B0=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D1=8C?= =?UTF-8?q?=20=D0=BA=D0=BB=D0=B5=D1=80=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataModels/ClerkDataModel.cs | 41 +++++++++++++++++-- .../DataModels/ClientDataModel.cs | 6 +-- 2 files changed, 40 insertions(+), 7 deletions(-) diff --git a/TheBank/BankContracts/DataModels/ClerkDataModel.cs b/TheBank/BankContracts/DataModels/ClerkDataModel.cs index 81dac6b..fa43b41 100644 --- a/TheBank/BankContracts/DataModels/ClerkDataModel.cs +++ b/TheBank/BankContracts/DataModels/ClerkDataModel.cs @@ -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,22 @@ namespace BankContracts.DataModels; /// пароль /// адрес электронной почты /// номер телефона -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, + List deposits, + List clients, + List replenishments +) : IValidation { public string Id { get; private set; } = id; @@ -26,7 +41,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; @@ -34,6 +49,12 @@ public class ClerkDataModel(string id, string name, string surname, string middl public string PhoneNumber { get; private set; } = phoneNumber; + public List Deposits { get; private set; } = deposits; + + public List Clients { get; private set; } = clients; + + public List Replenishments { get; private set; } = replenishments; + public void Validate() { if (Id.IsEmpty()) @@ -80,5 +101,17 @@ public class ClerkDataModel(string id, string name, string surname, string middl { throw new ValidationException("Field PhoneNumber is not a phone number"); } + if (Deposits is null) + { + throw new ValidationException("Field Deposits is null"); + } + if (Clients is null) + { + throw new ValidationException("Field Clients is null"); + } + if (Replenishments is null) + { + throw new ValidationException("Field Replenishments is null"); + } } } diff --git a/TheBank/BankContracts/DataModels/ClientDataModel.cs b/TheBank/BankContracts/DataModels/ClientDataModel.cs index bcff9c5..1665709 100644 --- a/TheBank/BankContracts/DataModels/ClientDataModel.cs +++ b/TheBank/BankContracts/DataModels/ClientDataModel.cs @@ -22,7 +22,7 @@ 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 void Validate() { @@ -46,11 +46,11 @@ 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"); } From 0923f8dcf7e604b67ec0c44b6ffa40f759cb89fc Mon Sep 17 00:00:00 2001 From: xom9k Date: Fri, 25 Apr 2025 09:54:23 +0400 Subject: [PATCH 03/16] =?UTF-8?q?feat:=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2?= =?UTF-8?q?=D0=B8=D0=BB=20=D0=BF=D0=BE=D0=BB=D1=8F=20=D0=B2=20=D0=BC=D0=BE?= =?UTF-8?q?=D0=B4=D0=B5=D0=BB=D1=8F=D1=85=20=D0=B8=20=D0=BC=D0=BE=D0=B4?= =?UTF-8?q?=D0=B5=D0=BB=D0=B8=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8=D0=B5=20?= =?UTF-8?q?=D0=BA=D0=BE=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TheBank/BankDatabase/Models/Client.cs | 6 ++++++ .../BankDatabase/Models/ClientCreditProgram.cs | 18 ++++++++++++++++++ TheBank/BankDatabase/Models/CreditProgram.cs | 13 ++++++++++++- .../Models/CreditProgramCurrency.cs | 18 ++++++++++++++++++ TheBank/BankDatabase/Models/Currency.cs | 7 ++++++- TheBank/BankDatabase/Models/Deposit.cs | 3 +++ TheBank/BankDatabase/Models/DepositClient.cs | 18 ++++++++++++++++++ TheBank/BankDatabase/Models/DepositCurrency.cs | 18 ++++++++++++++++++ TheBank/BankDatabase/Models/Period.cs | 7 ++++++- TheBank/BankDatabase/Models/Replenishment.cs | 3 +++ TheBank/BankDatabase/Models/Storekeeper.cs | 14 +++++++++++++- 11 files changed, 121 insertions(+), 4 deletions(-) create mode 100644 TheBank/BankDatabase/Models/ClientCreditProgram.cs create mode 100644 TheBank/BankDatabase/Models/CreditProgramCurrency.cs create mode 100644 TheBank/BankDatabase/Models/DepositClient.cs create mode 100644 TheBank/BankDatabase/Models/DepositCurrency.cs diff --git a/TheBank/BankDatabase/Models/Client.cs b/TheBank/BankDatabase/Models/Client.cs index 7cdd58d..dfdc263 100644 --- a/TheBank/BankDatabase/Models/Client.cs +++ b/TheBank/BankDatabase/Models/Client.cs @@ -16,4 +16,10 @@ class Client [ForeignKey("ClerkId")] public Clerk? Clerk { get; set; } + + [ForeignKey("DepositId")] + public List? Deposits { get; set; } + + [ForeignKey("CreditProgramId")] + public List? CreditPrograms { get; set; } } diff --git a/TheBank/BankDatabase/Models/ClientCreditProgram.cs b/TheBank/BankDatabase/Models/ClientCreditProgram.cs new file mode 100644 index 0000000..87cb933 --- /dev/null +++ b/TheBank/BankDatabase/Models/ClientCreditProgram.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +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; } +} diff --git a/TheBank/BankDatabase/Models/CreditProgram.cs b/TheBank/BankDatabase/Models/CreditProgram.cs index b86e5b4..4f9b92d 100644 --- a/TheBank/BankDatabase/Models/CreditProgram.cs +++ b/TheBank/BankDatabase/Models/CreditProgram.cs @@ -1,4 +1,6 @@ -namespace BankDatabase.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace BankDatabase.Models; class CreditProgram { @@ -13,4 +15,13 @@ class CreditProgram public required string StorekeeperId { get; set; } public required string PeriodId { get; set; } + //надо??? + [ForeignKey("StorekeeperId")] + public Storekeeper? Storekeeper { get; set; } + //и это надо?? + [ForeignKey("PeriodId")] + public Period? Period { get; set; } + + [ForeignKey("CurrencyId")] + public List? Currencies { get; set; } } diff --git a/TheBank/BankDatabase/Models/CreditProgramCurrency.cs b/TheBank/BankDatabase/Models/CreditProgramCurrency.cs new file mode 100644 index 0000000..09e19dc --- /dev/null +++ b/TheBank/BankDatabase/Models/CreditProgramCurrency.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +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; } +} diff --git a/TheBank/BankDatabase/Models/Currency.cs b/TheBank/BankDatabase/Models/Currency.cs index 604ccae..0738957 100644 --- a/TheBank/BankDatabase/Models/Currency.cs +++ b/TheBank/BankDatabase/Models/Currency.cs @@ -1,4 +1,6 @@ -namespace BankDatabase.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace BankDatabase.Models; class Currency { @@ -11,4 +13,7 @@ class Currency public decimal Cost { get; set; } public required string StorekeeperId { get; set; } + + [ForeignKey("StorekeeperId")] + public Storekeeper? Storekeeper { get; set; } } diff --git a/TheBank/BankDatabase/Models/Deposit.cs b/TheBank/BankDatabase/Models/Deposit.cs index 800b60e..a436bf5 100644 --- a/TheBank/BankDatabase/Models/Deposit.cs +++ b/TheBank/BankDatabase/Models/Deposit.cs @@ -16,4 +16,7 @@ class Deposit [ForeignKey("ClerkId")] public Clerk? Clerk { get; set; } + + [ForeignKey("CurrencyId")] + public List? Currencies { get; set; } } diff --git a/TheBank/BankDatabase/Models/DepositClient.cs b/TheBank/BankDatabase/Models/DepositClient.cs new file mode 100644 index 0000000..ff3c1a9 --- /dev/null +++ b/TheBank/BankDatabase/Models/DepositClient.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +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; } +} diff --git a/TheBank/BankDatabase/Models/DepositCurrency.cs b/TheBank/BankDatabase/Models/DepositCurrency.cs new file mode 100644 index 0000000..b086970 --- /dev/null +++ b/TheBank/BankDatabase/Models/DepositCurrency.cs @@ -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; } +} diff --git a/TheBank/BankDatabase/Models/Period.cs b/TheBank/BankDatabase/Models/Period.cs index e09aa66..b17d6ad 100644 --- a/TheBank/BankDatabase/Models/Period.cs +++ b/TheBank/BankDatabase/Models/Period.cs @@ -1,4 +1,6 @@ -namespace BankDatabase.Models; +using System.ComponentModel.DataAnnotations.Schema; + +namespace BankDatabase.Models; class Period { @@ -9,4 +11,7 @@ class Period public DateTime EndTime { get; set; } public required string StorekeeperId { get; set; } + + [ForeignKey("StorekeeperId")] + public Storekeeper? Storekeeper { get; set; } } diff --git a/TheBank/BankDatabase/Models/Replenishment.cs b/TheBank/BankDatabase/Models/Replenishment.cs index 13408e2..91b672c 100644 --- a/TheBank/BankDatabase/Models/Replenishment.cs +++ b/TheBank/BankDatabase/Models/Replenishment.cs @@ -16,4 +16,7 @@ class Replenishment [ForeignKey("ClerkId")] public Clerk? Clerk { get; set; } + + [ForeignKey("DepositId")] + public Deposit? Deposit { get; set; } } diff --git a/TheBank/BankDatabase/Models/Storekeeper.cs b/TheBank/BankDatabase/Models/Storekeeper.cs index eacea22..88c3bef 100644 --- a/TheBank/BankDatabase/Models/Storekeeper.cs +++ b/TheBank/BankDatabase/Models/Storekeeper.cs @@ -1,4 +1,7 @@ -namespace BankDatabase.Models; +using BankContracts.DataModels; +using System.ComponentModel.DataAnnotations.Schema; + +namespace BankDatabase.Models; class Storekeeper { @@ -17,4 +20,13 @@ class Storekeeper public required string Email { get; set; } public required string PhoneNumber { get; set; } + + [ForeignKey("CurrencyId")] + public List? Currencies { get; set; } + + [ForeignKey("PeriodId")] + public List? Periods { get; set; } + + [ForeignKey("CreditProgramId")] + public List? CreditPrograms { get; set; } } From 9ed15b9d5e4ec59f04a0799496ceba0f5ca92957 Mon Sep 17 00:00:00 2001 From: xom9k Date: Fri, 25 Apr 2025 09:56:12 +0400 Subject: [PATCH 04/16] =?UTF-8?q?feat:=20=D1=80=D0=B5=D0=B0=D0=BB=D0=B8?= =?UTF-8?q?=D0=B7=D0=B0=D1=86=D0=B8=D1=8F=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80?= =?UTF-8?q?=D0=B0=D0=BA=D1=82=D0=B0=20=D1=85=D1=80=D0=B0=D0=BD=D0=B8=D0=BB?= =?UTF-8?q?=D0=B8=D1=89=D0=B0=20=D0=BA=D0=BB=D0=B0=D0=B4=D0=BE=D0=B2=D1=89?= =?UTF-8?q?=D0=B8=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../StorekeeperStorageContract.cs | 140 ++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100644 TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs diff --git a/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs b/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs new file mode 100644 index 0000000..d758b5d --- /dev/null +++ b/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs @@ -0,0 +1,140 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; + +namespace BankDatabase.Implementations; + +/// +/// реализация контракта для кладовщика +/// +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(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + public List GetList() + { + try + { + return [.. _dbContext.Storekeepers.Select(x => _mapper.Map(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public StorekeeperDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_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(_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(_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(storekeeperDataModel)); + _dbContext.SaveChanges(); + } + 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 (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(); +} From d3797f12abf02f0c1a360b80002b30f2e3511395 Mon Sep 17 00:00:00 2001 From: xom9k Date: Fri, 25 Apr 2025 09:57:08 +0400 Subject: [PATCH 05/16] =?UTF-8?q?feat:=20=D0=BF=D0=BE=D0=B4=D0=B3=D0=BE?= =?UTF-8?q?=D1=82=D0=BE=D0=B2=D0=BA=D0=B0=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB?= =?UTF-8?q?=D0=B5=D0=B9=20=D0=BA=20=D0=B4=D0=BB=D1=8F=20=D1=81=D0=B2=D1=8F?= =?UTF-8?q?=D0=B7=D0=B8=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8=D0=B5=20=D0=BA?= =?UTF-8?q?=D0=BE=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataModels/ClientDataModel.cs | 17 ++++++++++++- .../DataModels/CreditProgramDataModel.cs | 10 +++++++- .../DataModels/DepositDataModel.cs | 10 +++++++- .../DataModels/StorekeeperDataModel.cs | 24 ++++++++++++++++++- 4 files changed, 57 insertions(+), 4 deletions(-) diff --git a/TheBank/BankContracts/DataModels/ClientDataModel.cs b/TheBank/BankContracts/DataModels/ClientDataModel.cs index 1665709..d1c5763 100644 --- a/TheBank/BankContracts/DataModels/ClientDataModel.cs +++ b/TheBank/BankContracts/DataModels/ClientDataModel.cs @@ -12,7 +12,10 @@ namespace BankContracts.DataModels; /// фамилия клиента /// баланс клиента /// уникальный Guid индентификатор клерка -public class ClientDataModel(string id, string name, string surname, decimal balance, string clerkId) : IValidation +/// вклады клиента +/// кредитные программы клиента +public class ClientDataModel(string id, string name, string surname, decimal balance, string clerkId, + List depositClients, List creditProgramClients) : IValidation { public string Id { get; private set; } = id; @@ -24,6 +27,10 @@ public class ClientDataModel(string id, string name, string surname, decimal bal public string ClerkId { get; private set; } = clerkId; + public List Deposits { get; private set; } = depositClients; + + public List CreditPrograms { get; private set; } = creditProgramClients; + public void Validate() { if (Id.IsEmpty()) @@ -54,5 +61,13 @@ public class ClientDataModel(string id, string name, string surname, decimal bal { throw new ValidationException("The value in the field Clerkid is not a unique identifier"); } + if ((Deposits?.Count ?? 0) == 0) + { + throw new ValidationException("The client must include deposits"); + } + if ((CreditPrograms?.Count ?? 0) == 0) + { + throw new ValidationException("The client must include credit programs"); + } } } diff --git a/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs b/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs index e7ee5af..7553777 100644 --- a/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs +++ b/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs @@ -13,7 +13,9 @@ namespace BankContracts.DataModels; /// максимальная сумма /// уникальный Guid Индентификатор кладовщика /// уникальный Guid Индентификатор срока -public class CreditProgramDataModel(string id, string name, decimal cost, decimal maxCost, string storekeeperId, string periodId) : IValidation +/// валюты кредитной программы +public class CreditProgramDataModel(string id, string name, decimal cost, decimal maxCost, string storekeeperId, string periodId, + List 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 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?.Count ?? 0) == 0) + { + throw new ValidationException("The credit program must include currencies"); + } } } diff --git a/TheBank/BankContracts/DataModels/DepositDataModel.cs b/TheBank/BankContracts/DataModels/DepositDataModel.cs index 7dbcc47..82b49af 100644 --- a/TheBank/BankContracts/DataModels/DepositDataModel.cs +++ b/TheBank/BankContracts/DataModels/DepositDataModel.cs @@ -12,7 +12,9 @@ namespace BankContracts.DataModels; /// стоимость /// срок /// уникальный Guid индентификатор клерка -public class DepositDataModel(string id, float interestRate, decimal cost, int period, string clerkId) : IValidation +/// валюты вклада +public class DepositDataModel(string id, float interestRate, decimal cost, int period, string clerkId, + List 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 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?.Count ?? 0) == 0) + { + throw new ValidationException("The deposit must include currencies"); + } } } diff --git a/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs b/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs index b9a9037..608af2d 100644 --- a/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs +++ b/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs @@ -16,9 +16,13 @@ namespace BankContracts.DataModels; /// пароль /// адрес электронной почты /// номер телефона +/// валюты +/// сроки +/// кредитные программы public class StorekeeperDataModel( string id, string name, string surname, string middleName, - string login, string password, string email, string phoneNumber) : IValidation + string login, string password, string email, string phoneNumber, List currencies, + List periods, List creditPrograms) : IValidation { public string Id { get; private set; } = id; @@ -36,6 +40,12 @@ public class StorekeeperDataModel( public string PhoneNumber { get; private set; } = phoneNumber; + public List Currencies { get; private set; } = currencies; + + public List Periods { get; private set; } = periods; + + public List CreditPrograms { get; private set; } = creditPrograms; + public void Validate() { if (Id.IsEmpty()) @@ -82,5 +92,17 @@ public class StorekeeperDataModel( { throw new ValidationException("Field PhoneNumber is not a phone number"); } + if (Currencies is null) + { + throw new ValidationException("Field Currencies is null"); + } + if (Periods is null) + { + throw new ValidationException("Field Periods is null"); + } + if (CreditPrograms is null) + { + throw new ValidationException("Field CreditPrograms is null"); + } } } From bcb18202073807dc2b337a618deaeb41e6f9c455 Mon Sep 17 00:00:00 2001 From: xom9k Date: Sat, 26 Apr 2025 09:27:32 +0400 Subject: [PATCH 06/16] =?UTF-8?q?fix:=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B5=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80?= =?UTF-8?q?=D0=BE=D0=BA,=20=D1=83=D0=B1=D1=80=D0=B0=D0=BD=D1=8B=20=D1=81?= =?UTF-8?q?=D0=BF=D0=B8=D1=81=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataModels/ClerkDataModel.cs | 26 +------------------ .../DataModels/ClientDataModel.cs | 8 +++--- .../DataModels/CreditProgramDataModel.cs | 4 +-- .../DataModels/DepositDataModel.cs | 4 +-- .../DataModels/StorekeeperDataModel.cs | 24 +---------------- 5 files changed, 10 insertions(+), 56 deletions(-) diff --git a/TheBank/BankContracts/DataModels/ClerkDataModel.cs b/TheBank/BankContracts/DataModels/ClerkDataModel.cs index fa43b41..612f518 100644 --- a/TheBank/BankContracts/DataModels/ClerkDataModel.cs +++ b/TheBank/BankContracts/DataModels/ClerkDataModel.cs @@ -16,9 +16,6 @@ namespace BankContracts.DataModels; /// пароль /// адрес электронной почты /// номер телефона -/// вклады -/// клиенты -/// пополнения public class ClerkDataModel( string id, string name, @@ -27,10 +24,7 @@ public class ClerkDataModel( string login, string password, string email, - string phoneNumber, - List deposits, - List clients, - List replenishments + string phoneNumber ) : IValidation { public string Id { get; private set; } = id; @@ -49,12 +43,6 @@ public class ClerkDataModel( public string PhoneNumber { get; private set; } = phoneNumber; - public List Deposits { get; private set; } = deposits; - - public List Clients { get; private set; } = clients; - - public List Replenishments { get; private set; } = replenishments; - public void Validate() { if (Id.IsEmpty()) @@ -101,17 +89,5 @@ public class ClerkDataModel( { throw new ValidationException("Field PhoneNumber is not a phone number"); } - if (Deposits is null) - { - throw new ValidationException("Field Deposits is null"); - } - if (Clients is null) - { - throw new ValidationException("Field Clients is null"); - } - if (Replenishments is null) - { - throw new ValidationException("Field Replenishments is null"); - } } } diff --git a/TheBank/BankContracts/DataModels/ClientDataModel.cs b/TheBank/BankContracts/DataModels/ClientDataModel.cs index d1c5763..aa1f59a 100644 --- a/TheBank/BankContracts/DataModels/ClientDataModel.cs +++ b/TheBank/BankContracts/DataModels/ClientDataModel.cs @@ -61,13 +61,13 @@ public class ClientDataModel(string id, string name, string surname, decimal bal { throw new ValidationException("The value in the field Clerkid is not a unique identifier"); } - if ((Deposits?.Count ?? 0) == 0) + if (Deposits is null) { - throw new ValidationException("The client must include deposits"); + throw new ValidationException("Field Deposits is null"); } - if ((CreditPrograms?.Count ?? 0) == 0) + if (CreditPrograms is null) { - throw new ValidationException("The client must include credit programs"); + throw new ValidationException("Field CreditPrograms is null"); } } } diff --git a/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs b/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs index 7553777..f2d6139 100644 --- a/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs +++ b/TheBank/BankContracts/DataModels/CreditProgramDataModel.cs @@ -69,9 +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?.Count ?? 0) == 0) + if (Currencies is null) { - throw new ValidationException("The credit program must include currencies"); + throw new ValidationException("Field Currencies is null"); } } } diff --git a/TheBank/BankContracts/DataModels/DepositDataModel.cs b/TheBank/BankContracts/DataModels/DepositDataModel.cs index 82b49af..3806598 100644 --- a/TheBank/BankContracts/DataModels/DepositDataModel.cs +++ b/TheBank/BankContracts/DataModels/DepositDataModel.cs @@ -58,9 +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?.Count ?? 0) == 0) + if (Currencies is null) { - throw new ValidationException("The deposit must include currencies"); + throw new ValidationException("Field Currencies is null"); } } } diff --git a/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs b/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs index 608af2d..b9a9037 100644 --- a/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs +++ b/TheBank/BankContracts/DataModels/StorekeeperDataModel.cs @@ -16,13 +16,9 @@ namespace BankContracts.DataModels; /// пароль /// адрес электронной почты /// номер телефона -/// валюты -/// сроки -/// кредитные программы public class StorekeeperDataModel( string id, string name, string surname, string middleName, - string login, string password, string email, string phoneNumber, List currencies, - List periods, List creditPrograms) : IValidation + string login, string password, string email, string phoneNumber) : IValidation { public string Id { get; private set; } = id; @@ -40,12 +36,6 @@ public class StorekeeperDataModel( public string PhoneNumber { get; private set; } = phoneNumber; - public List Currencies { get; private set; } = currencies; - - public List Periods { get; private set; } = periods; - - public List CreditPrograms { get; private set; } = creditPrograms; - public void Validate() { if (Id.IsEmpty()) @@ -92,17 +82,5 @@ public class StorekeeperDataModel( { throw new ValidationException("Field PhoneNumber is not a phone number"); } - if (Currencies is null) - { - throw new ValidationException("Field Currencies is null"); - } - if (Periods is null) - { - throw new ValidationException("Field Periods is null"); - } - if (CreditPrograms is null) - { - throw new ValidationException("Field CreditPrograms is null"); - } } } From a3e013f5ec2d50ce34081832f5eda61de54d04ae Mon Sep 17 00:00:00 2001 From: xom9k Date: Sat, 26 Apr 2025 09:59:20 +0400 Subject: [PATCH 07/16] =?UTF-8?q?fix:=20=D0=B8=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BC=D0=BE=D0=B4=D0=B5=D0=BB=D0=B5=D0=B9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TheBank/BankDatabase/Models/Clerk.cs | 6 +++--- TheBank/BankDatabase/Models/Client.cs | 9 ++++----- TheBank/BankDatabase/Models/CreditProgram.cs | 13 +++++++------ TheBank/BankDatabase/Models/Currency.cs | 7 ++++++- TheBank/BankDatabase/Models/Deposit.cs | 11 ++++++++--- TheBank/BankDatabase/Models/Period.cs | 4 +++- TheBank/BankDatabase/Models/Replenishment.cs | 2 -- TheBank/BankDatabase/Models/Storekeeper.cs | 12 ++++++------ 8 files changed, 37 insertions(+), 27 deletions(-) diff --git a/TheBank/BankDatabase/Models/Clerk.cs b/TheBank/BankDatabase/Models/Clerk.cs index 70c98be..eb95fb6 100644 --- a/TheBank/BankDatabase/Models/Clerk.cs +++ b/TheBank/BankDatabase/Models/Clerk.cs @@ -21,12 +21,12 @@ class Clerk public required string PhoneNumber { get; set; } - [ForeignKey("ReplenishmentId")] + [ForeignKey("ClerkId")] public List? Replenishments { get; set; } - [ForeignKey("DepositId")] + [ForeignKey("ClerkId")] public List? Deposits { get; set; } - [ForeignKey("ClientId")] + [ForeignKey("ClerkId")] public List? Clients { get; set; } } diff --git a/TheBank/BankDatabase/Models/Client.cs b/TheBank/BankDatabase/Models/Client.cs index dfdc263..8fe53fd 100644 --- a/TheBank/BankDatabase/Models/Client.cs +++ b/TheBank/BankDatabase/Models/Client.cs @@ -14,12 +14,11 @@ class Client public required string ClerkId { get; set; } - [ForeignKey("ClerkId")] public Clerk? Clerk { get; set; } - [ForeignKey("DepositId")] - public List? Deposits { get; set; } + [ForeignKey("ClientId")] + public List? CreditProgramClients { get; set; } - [ForeignKey("CreditProgramId")] - public List? CreditPrograms { get; set; } + [ForeignKey("ClientId")] + public List? DepositClients { get; set; } } diff --git a/TheBank/BankDatabase/Models/CreditProgram.cs b/TheBank/BankDatabase/Models/CreditProgram.cs index 4f9b92d..1069b36 100644 --- a/TheBank/BankDatabase/Models/CreditProgram.cs +++ b/TheBank/BankDatabase/Models/CreditProgram.cs @@ -15,13 +15,14 @@ class CreditProgram public required string StorekeeperId { get; set; } public required string PeriodId { get; set; } - //надо??? - [ForeignKey("StorekeeperId")] + public Storekeeper? Storekeeper { get; set; } - //и это надо?? - [ForeignKey("PeriodId")] + public Period? Period { get; set; } - [ForeignKey("CurrencyId")] - public List? Currencies { get; set; } + [ForeignKey("CreditProgramId")] + public List? CurrencyCreditPrograms { get; set; } + + [ForeignKey("CreditProgramId")] + public List? CreditProgramClients { get; set; } } diff --git a/TheBank/BankDatabase/Models/Currency.cs b/TheBank/BankDatabase/Models/Currency.cs index 0738957..989ebf5 100644 --- a/TheBank/BankDatabase/Models/Currency.cs +++ b/TheBank/BankDatabase/Models/Currency.cs @@ -14,6 +14,11 @@ class Currency public required string StorekeeperId { get; set; } - [ForeignKey("StorekeeperId")] public Storekeeper? Storekeeper { get; set; } + + [ForeignKey("CurrencyId")] + public List? CurrencyCreditPrograms { get; set; } + + [ForeignKey("CurrencyId")] + public List? DepositCurrencies { get; set; } } diff --git a/TheBank/BankDatabase/Models/Deposit.cs b/TheBank/BankDatabase/Models/Deposit.cs index a436bf5..47851a2 100644 --- a/TheBank/BankDatabase/Models/Deposit.cs +++ b/TheBank/BankDatabase/Models/Deposit.cs @@ -14,9 +14,14 @@ class Deposit public required string ClerkId { get; set; } - [ForeignKey("ClerkId")] public Clerk? Clerk { get; set; } - [ForeignKey("CurrencyId")] - public List? Currencies { get; set; } + [ForeignKey("DepositId")] + public List? DepositClients { get; set; } + + [ForeignKey("DepositId")] + public List? DepositCurrencies { get; set; } + + [ForeignKey("DepositId")] + public List? Replenishments { get; set; } } diff --git a/TheBank/BankDatabase/Models/Period.cs b/TheBank/BankDatabase/Models/Period.cs index b17d6ad..b60dd1a 100644 --- a/TheBank/BankDatabase/Models/Period.cs +++ b/TheBank/BankDatabase/Models/Period.cs @@ -12,6 +12,8 @@ class Period public required string StorekeeperId { get; set; } - [ForeignKey("StorekeeperId")] public Storekeeper? Storekeeper { get; set; } + + [ForeignKey("PeriodId")] + public List? CreditPrograms { get; set; } } diff --git a/TheBank/BankDatabase/Models/Replenishment.cs b/TheBank/BankDatabase/Models/Replenishment.cs index 91b672c..19ac963 100644 --- a/TheBank/BankDatabase/Models/Replenishment.cs +++ b/TheBank/BankDatabase/Models/Replenishment.cs @@ -14,9 +14,7 @@ class Replenishment public required string ClerkId { get; set; } - [ForeignKey("ClerkId")] public Clerk? Clerk { get; set; } - [ForeignKey("DepositId")] public Deposit? Deposit { get; set; } } diff --git a/TheBank/BankDatabase/Models/Storekeeper.cs b/TheBank/BankDatabase/Models/Storekeeper.cs index 88c3bef..466bbc7 100644 --- a/TheBank/BankDatabase/Models/Storekeeper.cs +++ b/TheBank/BankDatabase/Models/Storekeeper.cs @@ -21,12 +21,12 @@ class Storekeeper public required string PhoneNumber { get; set; } - [ForeignKey("CurrencyId")] - public List? Currencies { get; set; } + [ForeignKey("StorekeeperId")] + public List? Currencies { get; set; } - [ForeignKey("PeriodId")] - public List? Periods { get; set; } + [ForeignKey("StorekeeperId")] + public List? Periods { get; set; } - [ForeignKey("CreditProgramId")] - public List? CreditPrograms { get; set; } + [ForeignKey("StorekeeperId")] + public List? CreditPrograms { get; set; } } From 707f74dac9bf4d709370ab490066506a0d44c595 Mon Sep 17 00:00:00 2001 From: xom9k Date: Sat, 26 Apr 2025 10:41:21 +0400 Subject: [PATCH 08/16] =?UTF-8?q?feat:=20=D0=B7=D0=B0=D0=B2=D0=B8=D1=81?= =?UTF-8?q?=D0=B8=D0=BC=D0=BE=D1=81=D1=82=D0=B8=20=D0=BC=D0=BD=D0=BE=D0=B3?= =?UTF-8?q?=D0=B8=D0=B5=20=D0=BA=D0=BE=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8?= =?UTF-8?q?=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TheBank/BankDatabase/BankDbContext.cs | 16 ++ .../Implementations/DepositStorageContract.cs | 151 ++++++++++++++++++ 2 files changed, 167 insertions(+) create mode 100644 TheBank/BankDatabase/Implementations/DepositStorageContract.cs diff --git a/TheBank/BankDatabase/BankDbContext.cs b/TheBank/BankDatabase/BankDbContext.cs index 0ab2064..ba34e52 100644 --- a/TheBank/BankDatabase/BankDbContext.cs +++ b/TheBank/BankDatabase/BankDbContext.cs @@ -67,6 +67,14 @@ internal class BankDbContext(IConfigurationDatabase configurationDatabase) : DbC .WithOne(x => x.Clerk) .HasForeignKey(x => x.ClerkId) .OnDelete(DeleteBehavior.Restrict); + + modelBuilder.Entity().HasKey(x => new { x.DepositId, x.CurrencyId }); + + modelBuilder.Entity().HasKey(x => new { x.ClientId, x.CreditProgramId }); + + modelBuilder.Entity().HasKey(x => new { x.DepositId, x.ClientId }); + + modelBuilder.Entity().HasKey(x => new { x.CreditProgramId, x.CurrencyId }); } public DbSet Clerks { get; set; } @@ -84,4 +92,12 @@ internal class BankDbContext(IConfigurationDatabase configurationDatabase) : DbC public DbSet Replenishments { get; set; } public DbSet Storekeepers { get; set; } + + public DbSet DepositCurrencies { get; set; } + + public DbSet CreditProgramClients { get; set; } + + public DbSet DepositClients { get; set; } + + public DbSet CurrencyCreditPrograms { get; set; } } diff --git a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs new file mode 100644 index 0000000..8e7c7e2 --- /dev/null +++ b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs @@ -0,0 +1,151 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +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(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + public List 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(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public DepositDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_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(_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(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.Components = _mapper.Map>(shipDataModel.Components); + } + _dbContext.SaveChanges(); + transaction.Commit(); + } + catch + { + transaction.Rollback(); + throw; + } + } + catch (ElementNotFoundException) + { + _dbContext.ChangeTracker.Clear(); + throw; + } + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Ships_Name" }) + { + _dbContext.ChangeTracker.Clear(); + throw new ElementExistsException("Name", shipDataModel.Name); + } + catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException) + { + _dbContext.ChangeTracker.Clear(); + throw; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex); + } + } + + private Deposit? GetDepositById(string id) => _dbContext.Deposits.FirstOrDefault(x => x.Id == id); +} From 3ae7c03f1cbfbfc75192a19a1c5b9e448633fa31 Mon Sep 17 00:00:00 2001 From: xom9k Date: Sat, 26 Apr 2025 11:21:39 +0400 Subject: [PATCH 09/16] =?UTF-8?q?feat:=20=D1=81=D1=82=D0=BE=D1=80=D0=B0?= =?UTF-8?q?=D0=B4=D0=B6=20=D0=BA=D0=BE=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82?= =?UTF-8?q?=D1=8B=20=D0=BA=D0=BB=D0=B5=D1=80=D0=BA=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BankBusinessLogic.csproj | 4 + .../DepositBusinessLogicContract.cs | 2 +- .../IDepositStorageContract.cs | 2 +- .../Implementations/ClientStorageContract.cs | 177 ++++++++++++++++++ .../Implementations/DepositStorageContract.cs | 18 +- .../ReplenishmentStorageContract.cs | 102 ++++++++++ 6 files changed, 289 insertions(+), 16 deletions(-) create mode 100644 TheBank/BankDatabase/Implementations/ClientStorageContract.cs create mode 100644 TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs diff --git a/TheBank/BankBusinessLogic/BankBusinessLogic.csproj b/TheBank/BankBusinessLogic/BankBusinessLogic.csproj index 1f4500e..83b7798 100644 --- a/TheBank/BankBusinessLogic/BankBusinessLogic.csproj +++ b/TheBank/BankBusinessLogic/BankBusinessLogic.csproj @@ -6,6 +6,10 @@ enable + + + + diff --git a/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs b/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs index 415572c..af3ee85 100644 --- a/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs +++ b/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs @@ -57,7 +57,7 @@ internal class DepositBusinessLogicContract( return _depositStorageContract.GetElementById(data) ?? throw new ElementNotFoundException($"element not found: {data}"); } - return _depositStorageContract.GetElementByName(data) + return _depositStorageContract.GetElementByInterestRate(data) ?? throw new ElementNotFoundException($"element not found: {data}"); } diff --git a/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs b/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs index 827f93d..3719a65 100644 --- a/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs +++ b/TheBank/BankContracts/StorageContracts/IDepositStorageContract.cs @@ -8,7 +8,7 @@ public interface IDepositStorageContract DepositDataModel? GetElementById(string id); - DepositDataModel? GetElementByName(string name); + DepositDataModel? GetElementByInterestRate(float interestRate); void AddElement(DepositDataModel depositDataModel); diff --git a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs new file mode 100644 index 0000000..ab27779 --- /dev/null +++ b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs @@ -0,0 +1,177 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Xml.Linq; + +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(); + cfg.CreateMap(); + cfg.CreateMap(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List 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(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ClientDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_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(_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(_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(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.Deposits != null && clientDataModel.CreditPrograms != null) + { + if (element.DepositClients != null || element.DepositClients?.Count >= 0) + { + _dbContext.DepositClients.RemoveRange(element.DepositClients); + } + + if (element.CreditProgramClients != null || element.CreditProgramClients?.Count >= 0) + { + _dbContext.DepositClients.RemoveRange(element.DepositClients); + } + + element.DepositClients = _mapper.Map>(clientDataModel.Deposits); + element.DepositClients = _mapper.Map>(clientDataModel.CreditPrograms); + } + _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.FirstOrDefault(x => x.Id == id); +} diff --git a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs index 8e7c7e2..48ab38a 100644 --- a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs @@ -5,11 +5,6 @@ using BankContracts.StorageContracts; using BankDatabase.Models; using Microsoft.EntityFrameworkCore; using Npgsql; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace BankDatabase.Implementations; @@ -114,7 +109,7 @@ internal class DepositStorageContract : IDepositStorageContract _dbContext.DepositCurrencies.RemoveRange(element.DepositCurrencies); } - element.Components = _mapper.Map>(shipDataModel.Components); + element.DepositCurrencies = _mapper.Map>(depositDataModel.Currencies); } _dbContext.SaveChanges(); transaction.Commit(); @@ -130,20 +125,15 @@ internal class DepositStorageContract : IDepositStorageContract _dbContext.ChangeTracker.Clear(); throw; } - catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Ships_Name" }) + catch (DbUpdateException ex) when (ex.InnerException is PostgresException { ConstraintName: "IX_Deposits_InterestRate" }) { _dbContext.ChangeTracker.Clear(); - throw new ElementExistsException("Name", shipDataModel.Name); - } - catch (Exception ex) when (ex is ElementDeletedException || ex is ElementNotFoundException) - { - _dbContext.ChangeTracker.Clear(); - throw; + throw new ElementExistsException($"InterestRate {depositDataModel.InterestRate}"); } catch (Exception ex) { _dbContext.ChangeTracker.Clear(); - throw new StorageException(ex); + throw new StorageException(ex.Message); } } diff --git a/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs b/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs new file mode 100644 index 0000000..0a1991a --- /dev/null +++ b/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs @@ -0,0 +1,102 @@ +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(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List GetList(DateTime? fromDate = null, DateTime? toDate = null, string? clerkId = null, string? depositId = null) + { + try + { + var query = _dbContext.Replenishments.Where(x => x.Date >= fromDate && x.Date <= toDate); + if (clerkId is not null) + { + query = query.Where(x => x.ClerkId == clerkId); + } + if (depositId is not null) + { + query = query.Where(x => x.DepositId == depositId); + } + return [.. query.Select(x => _mapper.Map(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public ReplenishmentDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(_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(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); +} From 853d483ea522466a937eda6ab4d91de2b22b3014 Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Sat, 26 Apr 2025 12:10:12 +0400 Subject: [PATCH 10/16] =?UTF-8?q?feat:=20=D0=BF=D0=B5=D1=80=D0=B2=D0=B0?= =?UTF-8?q?=D1=8F=20=D0=B2=D0=B5=D1=80=D1=81=D0=B8=D1=8F=20=D0=BA=D0=BE?= =?UTF-8?q?=D0=BD=D1=82=D1=80=D0=B0=D0=BA=D1=82=D0=BE=D0=B2=20=D0=B4=D0=BB?= =?UTF-8?q?=D1=8F=20=D1=85=D1=80=D0=B0=D0=BD=D0=B5=D0=BD=D0=B8=D1=8F=20?= =?UTF-8?q?=D0=BF=D0=BE=20=D0=BA=D0=BB=D0=B0=D0=B4=D0=BE=D0=B2=D1=89=D0=B8?= =?UTF-8?q?=D0=BA=D1=83?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CreditProgramStorageContract.cs | 116 +++++++++++++++++ .../CurrencyStorageContract.cs | 123 ++++++++++++++++++ .../Implementations/PeriodStorageContract.cs | 101 ++++++++++++++ 3 files changed, 340 insertions(+) create mode 100644 TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs create mode 100644 TheBank/BankDatabase/Implementations/CurrencyStorageContract.cs create mode 100644 TheBank/BankDatabase/Implementations/PeriodStorageContract.cs diff --git a/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs b/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs new file mode 100644 index 0000000..1e36c08 --- /dev/null +++ b/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs @@ -0,0 +1,116 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; +using Microsoft.EntityFrameworkCore; +using Npgsql; + +namespace BankDatabase.Implementations; + +/// +/// реализация контракта хранилища для кредитной программы +/// +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(); + x.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List 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(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public CreditProgramDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(GetCreditProgramById(id)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public void AddElement(CreditProgramDataModel creditProgramDataModel) + { + try + { + _dbContext.CreditPrograms.Add(_mapper.Map(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); +} diff --git a/TheBank/BankDatabase/Implementations/CurrencyStorageContract.cs b/TheBank/BankDatabase/Implementations/CurrencyStorageContract.cs new file mode 100644 index 0000000..82aa18f --- /dev/null +++ b/TheBank/BankDatabase/Implementations/CurrencyStorageContract.cs @@ -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; + +/// +/// реализация контракта хранилища для валюты +/// +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(); + x.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List 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(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public CurrencyDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(GetCurrencyById(id)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + public CurrencyDataModel? GetElementByAbbreviation(string abbreviation) + { + try + { + return _mapper.Map(_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(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); +} diff --git a/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs b/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs new file mode 100644 index 0000000..dbd95d6 --- /dev/null +++ b/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs @@ -0,0 +1,101 @@ +using AutoMapper; +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Models; + +namespace BankDatabase.Implementations; + +/// +/// реализация контракта хранилища для срока +/// +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(); + cfg.CreateMap(); + }); + _mapper = new Mapper(config); + } + + public List 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); + } + return [..query.Select(x => _mapper.Map(x))]; + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public PeriodDataModel? GetElementById(string id) + { + try + { + return _mapper.Map(GetPeriodById(id)); + } + catch (Exception ex) + { + _dbContext.ChangeTracker.Clear(); + throw new StorageException(ex.Message); + } + } + + public void AddElement(PeriodDataModel periodDataModel) + { + try + { + _dbContext.Periods.Add(_mapper.Map(periodDataModel)); + _dbContext.SaveChanges(); + } + 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); +} From 514eb9ed19322f31da02256875512c99d123cfd6 Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Sat, 26 Apr 2025 13:17:34 +0400 Subject: [PATCH 11/16] =?UTF-8?q?fix:=20=D1=84=D0=B8=D0=BA=D1=81=20=D0=B3?= =?UTF-8?q?=D0=B5=D1=82=20=D0=BF=D0=BE=20=D0=B0=D0=B9=D0=B4=D0=B8,=20?= =?UTF-8?q?=D0=BA=D0=BE=D1=82=D0=BE=D1=80=D1=8B=D0=B9=20=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=B0=D0=BB=20=D0=BD=D0=B0=20https://git.is.ulstu.ru/slavaxom9?= =?UTF-8?q?k/PIBD-23=5FCoursework=5FBank/pulls/5/files#issuecomment-56085?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../BankDatabase/Implementations/ClerkStorageContract.cs | 2 +- .../BankDatabase/Implementations/ClientStorageContract.cs | 6 ------ 2 files changed, 1 insertion(+), 7 deletions(-) diff --git a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs index c4a210f..26d2c5e 100644 --- a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs @@ -43,7 +43,7 @@ internal class ClerkStorageContract : IClerkStorageContract { try { - return _mapper.Map(_dbContext.Clerks.FirstOrDefault(x => x.Id == id)); + return _mapper.Map(GetClerkById(id)); } catch (Exception ex) { diff --git a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs index ab27779..fd877d4 100644 --- a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs @@ -5,12 +5,6 @@ using BankContracts.StorageContracts; using BankDatabase.Models; using Microsoft.EntityFrameworkCore; using Npgsql; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Xml.Linq; namespace BankDatabase.Implementations; From 78a053d6c0cfbb20413e6c622874ee7ef0fa7c9b Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Sat, 26 Apr 2025 17:08:45 +0400 Subject: [PATCH 12/16] =?UTF-8?q?feat:=20=D1=81=D1=82=D0=B0=D1=80=D1=82=20?= =?UTF-8?q?=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0=20=D1=82=D0=B5=D1=81?= =?UTF-8?q?=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TheBank/BankDatabase/BankDatabase.csproj | 4 + .../Implementations/ClerkStorageContract.cs | 5 + TheBank/BankTests/BankTests.csproj | 30 +++++ .../Infrastructure/BankDbContextExtension.cs | 32 ++++++ .../Infrastructure/ConfigurationDatabase.cs | 8 ++ .../BaseStorageContractTest.cs | 25 +++++ .../ClerkStorageContractTests.cs | 104 ++++++++++++++++++ TheBank/TheBank.sln | 6 + 8 files changed, 214 insertions(+) create mode 100644 TheBank/BankTests/BankTests.csproj create mode 100644 TheBank/BankTests/Infrastructure/BankDbContextExtension.cs create mode 100644 TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs create mode 100644 TheBank/BankTests/StorageContactsTests/BaseStorageContractTest.cs create mode 100644 TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs diff --git a/TheBank/BankDatabase/BankDatabase.csproj b/TheBank/BankDatabase/BankDatabase.csproj index ba7e73b..c4e8569 100644 --- a/TheBank/BankDatabase/BankDatabase.csproj +++ b/TheBank/BankDatabase/BankDatabase.csproj @@ -16,4 +16,8 @@ + + + + diff --git a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs index 26d2c5e..3b14be5 100644 --- a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs @@ -85,6 +85,11 @@ internal class ClerkStorageContract : IClerkStorageContract _dbContext.Clerks.Add(_mapper.Map(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(); diff --git a/TheBank/BankTests/BankTests.csproj b/TheBank/BankTests/BankTests.csproj new file mode 100644 index 0000000..6c2bc65 --- /dev/null +++ b/TheBank/BankTests/BankTests.csproj @@ -0,0 +1,30 @@ + + + + net9.0 + latest + enable + enable + false + + + + + + + + + + + + + + + + + + + + + + diff --git a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs new file mode 100644 index 0000000..4f42168 --- /dev/null +++ b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs @@ -0,0 +1,32 @@ +using Microsoft.EntityFrameworkCore; +using BankDatabase.Models; +using BankDatabase; + +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 void RemoveClerksFromDatabase(this BankDbContext dbContext) => dbContext.ExecuteSqlRaw("TRUNCATE \"Clerks\" CASCADE"); + + public static Clerk? GetClerkFromDatabase(this BankDbContext dbContext, string id) => dbContext.Clerks.FirstOrDefault(x => x.Id == id); + + private static void ExecuteSqlRaw(this BankDbContext dbContext, string command) => dbContext.Database.ExecuteSqlRaw(command); +} diff --git a/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs b/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs new file mode 100644 index 0000000..a558b2a --- /dev/null +++ b/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs @@ -0,0 +1,8 @@ +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"; +} diff --git a/TheBank/BankTests/StorageContactsTests/BaseStorageContractTest.cs b/TheBank/BankTests/StorageContactsTests/BaseStorageContractTest.cs new file mode 100644 index 0000000..0557dc2 --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/BaseStorageContractTest.cs @@ -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(); + } +} diff --git a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs new file mode 100644 index 0000000..c87f18b --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs @@ -0,0 +1,104 @@ +using BankContracts.DataModels; +using BankContracts.Exceptions; +using BankContracts.StorageContracts; +using BankDatabase.Implementations; +using BankDatabase.Models; +using BankTests.Infrastructure; +using Microsoft.VisualStudio.CodeCoverage; + +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_ShouldSucces_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 certificate = BankDbContext.InsertClerkToDatabaseAndReturn(); + AssertElement(_storageContract.GetElementById(certificate.Id), certificate); + } + + [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()); + } + + 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)); + }); + } +} diff --git a/TheBank/TheBank.sln b/TheBank/TheBank.sln index 7515a62..d28ceae 100644 --- a/TheBank/TheBank.sln +++ b/TheBank/TheBank.sln @@ -9,6 +9,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BankBusinessLogic", "BankBu 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 @@ -27,6 +29,10 @@ Global {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 From 46bfedef8df35f8bbeecd29c6513f7a0b21be4ef Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Mon, 28 Apr 2025 13:10:31 +0400 Subject: [PATCH 13/16] =?UTF-8?q?feat:=20=D1=81=D0=BE=D0=B7=D0=B4=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BF=D1=80=D0=BE=D0=B5=D0=BA=D1=82=D0=B0?= =?UTF-8?q?=20=D1=82=D0=B5=D1=81=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit добавление двух с половиной классов тестов, пока не проверяет многие ко многим --- .../DepositBusinessLogicContract.cs | 7 +- .../Implementations/ClerkStorageContract.cs | 5 + .../Implementations/ClientStorageContract.cs | 3 +- .../Infrastructure/BankDbContextExtension.cs | 77 +++++++++++ .../ClerkStorageContractTests.cs | 36 ++++- .../ClientStorageContractTests.cs | 125 ++++++++++++++++++ .../CreditProgramStorageContractTests.cs | 101 ++++++++++++++ 7 files changed, 348 insertions(+), 6 deletions(-) create mode 100644 TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs create mode 100644 TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs diff --git a/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs b/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs index af3ee85..cbe5702 100644 --- a/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs +++ b/TheBank/BankBusinessLogic/Implementations/DepositBusinessLogicContract.cs @@ -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.GetElementByInterestRate(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) diff --git a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs index 3b14be5..73f95ac 100644 --- a/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ClerkStorageContract.cs @@ -120,6 +120,11 @@ internal class ClerkStorageContract : IClerkStorageContract _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(); diff --git a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs index fd877d4..9e26801 100644 --- a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs @@ -31,7 +31,7 @@ internal class ClientStorageContract : IClientStorageContract { try { - var query = _dbContext.Deposits.Include(x => x.Clerk).AsQueryable(); + var query = _dbContext.Clients.Include(x => x.Clerk).AsQueryable(); if (clerkId is not null) { query = query.Where(x => x.ClerkId == clerkId); @@ -137,6 +137,7 @@ internal class ClientStorageContract : IClientStorageContract element.DepositClients = _mapper.Map>(clientDataModel.Deposits); element.DepositClients = _mapper.Map>(clientDataModel.CreditPrograms); } + _mapper.Map(element, clientDataModel); _dbContext.SaveChanges(); transaction.Commit(); } diff --git a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs index 4f42168..6afb5d0 100644 --- a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs +++ b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs @@ -1,6 +1,7 @@ using Microsoft.EntityFrameworkCore; using BankDatabase.Models; using BankDatabase; +using System.Xml.Linq; namespace BankTests.Infrastructure; @@ -24,9 +25,85 @@ internal static class BankDbContextExtension 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) + { + var client = new Client() + { + Id = id ?? Guid.NewGuid().ToString(), + Name = name, + Surname = surname, + Balance = balance, + ClerkId = clerkId ?? Guid.NewGuid().ToString(), + }; + 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) + { + 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(); + 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 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 Client? GetClientFromDatabase(this BankDbContext dbContext, string id) => dbContext.Clients.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); + private static void ExecuteSqlRaw(this BankDbContext dbContext, string command) => dbContext.Database.ExecuteSqlRaw(command); } diff --git a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs index c87f18b..428187a 100644 --- a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs @@ -4,7 +4,6 @@ using BankContracts.StorageContracts; using BankDatabase.Implementations; using BankDatabase.Models; using BankTests.Infrastructure; -using Microsoft.VisualStudio.CodeCoverage; namespace BankTests.StorageContactsTests; @@ -49,8 +48,8 @@ internal class ClerkStorageContractTests : BaseStorageContractTest [Test] public void Try_GetElementById_WhenHaveRecord_Test() { - var certificate = BankDbContext.InsertClerkToDatabaseAndReturn(); - AssertElement(_storageContract.GetElementById(certificate.Id), certificate); + var clerk = BankDbContext.InsertClerkToDatabaseAndReturn(); + AssertElement(_storageContract.GetElementById(clerk.Id), clerk); } [Test] @@ -69,6 +68,37 @@ internal class ClerkStorageContractTests : BaseStorageContractTest Assert.That(() => _storageContract.AddElement(clerk), Throws.TypeOf()); } + [Test] + public void Try_AddElement_WhenHaveRecordWithSameEmail_Test() + { + var clerk = CreateModel(); + BankDbContext.InsertClerkToDatabaseAndReturn(email: clerk.Email); + Assert.That(() => _storageContract.AddElement(clerk), Throws.TypeOf()); + } + + [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()); + } + + [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()); + } + 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); diff --git a/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs new file mode 100644 index 0000000..1103b19 --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs @@ -0,0 +1,125 @@ +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 string _clerkId; + + private IClientStorageContract _clientStorageContract; + + [SetUp] + public void SetUp() + { + _clerkId = BankDbContext.InsertClerkToDatabaseAndReturn().Id; + _clientStorageContract = new ClientStorageContract(BankDbContext); + } + + [TearDown] + public void TearDown() + { + BankDbContext.RemoveClientsFromDatabase(); + BankDbContext.RemoveClerksFromDatabase(); + } + + [Test] + public void TryGetListWhenHaveRecords_ShouldSucces_Test() + { + var client = BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId); + BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId); + BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId); + + var list = _clientStorageContract.GetList(); + Assert.That(list, Is.Not.Null); + Assert.That(list, Has.Count.EqualTo(3)); + AssertElement(list.First(x => x.Id == client.Id), 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 client = CreateModel(_clerkId); + _clientStorageContract.AddElement(client); + AssertElement(BankDbContext.GetClientFromDatabase(client.Id), client); + } + + [Test] + public void Try_UpdElement_Test() + { + var client = CreateModel(_clerkId); + BankDbContext.InsertClientToDatabaseAndReturn(id: client.Id, clerkId: _clerkId); + _clientStorageContract.UpdElement(client); + AssertElement(BankDbContext.GetClientFromDatabase(client.Id), client); + } + + [Test] + public void Try_UpdElement_WhenNoRecordWithThisId_Test() + { + Assert.That(() => _clientStorageContract.UpdElement(CreateModel(_clerkId)), Throws.TypeOf()); + } + + private static ClientDataModel CreateModel(string clerkid, string? id = null, string? name = "null", string? surname = "surname", decimal balance = 1, List? depositClients = null, List? 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)); + }); + } + + 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)); + }); + } +} diff --git a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs new file mode 100644 index 0000000..5201dc4 --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs @@ -0,0 +1,101 @@ +using BankContracts.DataModels; +using BankContracts.StorageContracts; +using BankDatabase.Implementations; +using BankDatabase.Models; +using BankTests.Infrastructure; +using System.Xml.Linq; + +namespace BankTests.StorageContactsTests; + +[TestFixture] +internal class CreditProgramStorageContractTests : BaseStorageContractTest +{ + private ICreditProgramStorageContract _storageContract; + + private string _storekeeperId; + + private string _periodId; + + [SetUp] + public void SetUp() + { + _storageContract = new CreditProgramStorageContract(BankDbContext); + _storekeeperId = BankDbContext.InsertStorekeeperToDatabaseAndReturn().Id; + _periodId = BankDbContext.InsertPeriodToDatabaseAndReturn(storekeeperId: _storekeeperId).Id; + } + + [TearDown] + public void TearDown() + { + BankDbContext.RemoveCreditProgramsFromDatabase(); + BankDbContext.RemovePeriodsFromDatabase(); + BankDbContext.RemoveStorekeepersFromDatabase(); + } + + [Test] + public void TryGetListWhenHaveRecords_ShouldSucces_Test() + { + var clerk = BankDbContext.InsertCreditProgramToDatabaseAndReturn(storeleeperId: _storekeeperId, periodId: _periodId); + 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 == 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 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); + } + + private static CreditProgramDataModel CreateModel(string? id = null, string? name = "name", decimal cost = 1, decimal maxCost = 2, string? storekeeperId = null, string? periodId = null, List? 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)); + }); + } + + 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)); + }); + } +} From 8d90b79a445349f03ad1bc8ceef34b3887f76460 Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Tue, 29 Apr 2025 15:34:46 +0400 Subject: [PATCH 14/16] =?UTF-8?q?feat:=20=D0=BD=D0=BE=D0=B2=D1=8B=D0=B5=20?= =?UTF-8?q?=D1=82=D0=B5=D1=81=D1=82=D1=8B?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Добавлены тесты для клерка, кредитной программы, валюты, вклада --- .../Implementations/DepositStorageContract.cs | 1 + .../Infrastructure/BankDbContextExtension.cs | 38 +++++ .../ClerkStorageContractTests.cs | 2 +- .../CreditProgramStorageContractTests.cs | 24 ++++ .../CurrencyStorageContractTests.cs | 134 ++++++++++++++++++ .../DepositStorageContractTests.cs | 122 ++++++++++++++++ .../PeriodStorageContractTests.cs | 52 +++++++ 7 files changed, 372 insertions(+), 1 deletion(-) create mode 100644 TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs create mode 100644 TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs create mode 100644 TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs diff --git a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs index 48ab38a..13b861a 100644 --- a/TheBank/BankDatabase/Implementations/DepositStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/DepositStorageContract.cs @@ -111,6 +111,7 @@ internal class DepositStorageContract : IDepositStorageContract element.DepositCurrencies = _mapper.Map>(depositDataModel.Currencies); } + _mapper.Map(depositDataModel, element); _dbContext.SaveChanges(); transaction.Commit(); } diff --git a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs index 6afb5d0..21af84f 100644 --- a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs +++ b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs @@ -89,6 +89,38 @@ internal static class BankDbContextExtension 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 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"); @@ -98,6 +130,8 @@ internal static class BankDbContextExtension 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 Client? GetClientFromDatabase(this BankDbContext dbContext, string id) => dbContext.Clients.FirstOrDefault(x => x.Id == id); @@ -105,5 +139,9 @@ internal static class BankDbContextExtension 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); + private static void ExecuteSqlRaw(this BankDbContext dbContext, string command) => dbContext.Database.ExecuteSqlRaw(command); } diff --git a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs index 428187a..0eb238a 100644 --- a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs @@ -25,7 +25,7 @@ internal class ClerkStorageContractTests : BaseStorageContractTest } [Test] - public void TryGetListWhenHaveRecords_ShouldSucces_Test() + public void TryGetListWhenHaveRecords_ShouldSuccess_Test() { var clerk = BankDbContext.InsertClerkToDatabaseAndReturn(); BankDbContext.InsertClerkToDatabaseAndReturn(login: "xomyak", email: "email1@email.com", phone: "+9-888-888-88-88"); diff --git a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs index 5201dc4..2311ddf 100644 --- a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs @@ -1,4 +1,5 @@ using BankContracts.DataModels; +using BankContracts.Exceptions; using BankContracts.StorageContracts; using BankDatabase.Implementations; using BankDatabase.Models; @@ -68,6 +69,29 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest 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); + Assert.That(() => _storageContract.AddElement(credit), Throws.TypeOf()); + } + + [Test] + public void Try_UpdElement_Test() + { + var credit = CreateModel(name: "unique name", periodId: _periodId, storekeeperId: _storekeeperId); + BankDbContext.InsertCreditProgramToDatabaseAndReturn(credit.Id, periodId: _periodId, storeleeperId: _storekeeperId); + _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()); + } + private static CreditProgramDataModel CreateModel(string? id = null, string? name = "name", decimal cost = 1, decimal maxCost = 2, string? storekeeperId = null, string? periodId = null, List? currency = null) => new(id ?? Guid.NewGuid().ToString(), name, cost, maxCost, storekeeperId ?? Guid.NewGuid().ToString(), periodId ?? Guid.NewGuid().ToString(), currency ?? []); diff --git a/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs new file mode 100644 index 0000000..6465903 --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs @@ -0,0 +1,134 @@ +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()); + } + + [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()); + } + + [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()); + } + + 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)); + }); + } +} \ No newline at end of file diff --git a/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs new file mode 100644 index 0000000..d7033ab --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs @@ -0,0 +1,122 @@ +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()); + } + + + [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()); + } + + + private static DepositDataModel CreateModel(string? id = null, float interestRate = 10, decimal cost = 10, int period = 10, string? clerkId = null, List? 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)); + }); + } +} \ No newline at end of file diff --git a/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs new file mode 100644 index 0000000..22a1783 --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs @@ -0,0 +1,52 @@ +using BankContracts.DataModels; +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); + + 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); + } + + 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)); + }); + } +} \ No newline at end of file From d636fb821e0d14e50a37916bd2a1e7d58e5125a4 Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Wed, 30 Apr 2025 12:35:29 +0400 Subject: [PATCH 15/16] =?UTF-8?q?feat:=20=D1=82=D0=B5=D1=81=D1=82=D1=8B=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=B2=D1=81=D0=B5=D0=B7=20=D0=BA=D0=BB?= =?UTF-8?q?=D0=B0=D1=81=D1=81=D0=BE=D0=B2,=20=D0=BF=D1=80=D0=BE=D0=B2?= =?UTF-8?q?=D0=B5=D1=80=D1=8F=D1=8E=D1=89=D0=B8=D0=B5=20=D0=BF=D0=BE=D0=BB?= =?UTF-8?q?=D1=83=D1=87=D0=B5=D0=BD=D0=B8=D0=B5=20=D1=81=D0=BF=D0=B8=D1=81?= =?UTF-8?q?=D0=BA=D0=B0,=20=D0=B4=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=B8=20=D0=BE=D0=B1=D0=BD=D0=BE=D0=B2?= =?UTF-8?q?=D0=BB=D0=B5=D0=BD=D0=B8=D0=B5,=20=D0=BD=D0=BE=20=D0=BD=D0=B5?= =?UTF-8?q?=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D1=8F=D1=8E=D1=89=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8=D0=B5=20=D0=BA=D0=BE=20?= =?UTF-8?q?=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Implementations/PeriodStorageContract.cs | 10 +- .../ReplenishmentStorageContract.cs | 10 +- .../StorekeeperStorageContract.cs | 10 + .../Infrastructure/BankDbContextExtension.cs | 167 ++++++++++++++--- .../Infrastructure/ConfigurationDatabase.cs | 3 +- .../ClerkStorageContractTests.cs | 56 +++++- .../ClientStorageContractTests.cs | 31 +++- .../CreditProgramStorageContractTests.cs | 85 +++++++-- .../CurrencyStorageContractTests.cs | 76 ++++++-- .../DepositStorageContractTests.cs | 36 +++- .../PeriodStorageContractTests.cs | 82 ++++++++- .../ReplenishmentStorageContractTests.cs | 161 ++++++++++++++++ .../StorekeeperStorageContractTests.cs | 172 ++++++++++++++++++ 13 files changed, 810 insertions(+), 89 deletions(-) create mode 100644 TheBank/BankTests/StorageContactsTests/ReplenishmentStorageContractTests.cs create mode 100644 TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs diff --git a/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs b/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs index dbd95d6..a196142 100644 --- a/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/PeriodStorageContract.cs @@ -19,7 +19,8 @@ internal class PeriodStorageContract : IPeriodStorageContract _dbContext = dbContext; var config = new MapperConfiguration(cfg => { - cfg.CreateMap(); + cfg.CreateMap() + .ConstructUsing(src => new PeriodDataModel(src.Id, src.StartTime, src.EndTime, src.StorekeeperId)); cfg.CreateMap(); }); _mapper = new Mapper(config); @@ -42,6 +43,8 @@ internal class PeriodStorageContract : IPeriodStorageContract { query = query.Where(x => x.StorekeeperId == storekeeperId); } + var test0 = query.FirstOrDefault(); + var test = _mapper.Map(test0); return [..query.Select(x => _mapper.Map(x))]; } catch (Exception ex) @@ -71,6 +74,11 @@ internal class PeriodStorageContract : IPeriodStorageContract _dbContext.Periods.Add(_mapper.Map(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(); diff --git a/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs b/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs index 0a1991a..ef1ffb4 100644 --- a/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ReplenishmentStorageContract.cs @@ -28,7 +28,7 @@ internal class ReplenishmentStorageContract : IReplenishmentStorageContract { try { - var query = _dbContext.Replenishments.Where(x => x.Date >= fromDate && x.Date <= toDate); + var query = _dbContext.Replenishments.AsQueryable(); if (clerkId is not null) { query = query.Where(x => x.ClerkId == clerkId); @@ -37,6 +37,14 @@ internal class ReplenishmentStorageContract : IReplenishmentStorageContract { 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(x))]; } catch (Exception ex) diff --git a/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs b/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs index d758b5d..c94d7da 100644 --- a/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/StorekeeperStorageContract.cs @@ -85,6 +85,11 @@ internal class StorekeeperStorageContract : IStorekeeperStorageContract _dbContext.Storekeepers.Add(_mapper.Map(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(); @@ -115,6 +120,11 @@ internal class StorekeeperStorageContract : IStorekeeperStorageContract _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(); diff --git a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs index 21af84f..788c86b 100644 --- a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs +++ b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs @@ -1,13 +1,23 @@ -using Microsoft.EntityFrameworkCore; -using BankDatabase.Models; +using System.Xml.Linq; using BankDatabase; -using System.Xml.Linq; +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") + 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() { @@ -18,14 +28,21 @@ internal static class BankDbContextExtension Login = login, Password = passwd, Email = email, - PhoneNumber = phone + PhoneNumber = phone, }; - dbContext.Clerks.Add( clerck ); + 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) + public static Client InsertClientToDatabaseAndReturn( + this BankDbContext dbContext, + string? id = null, + string? name = "slava", + string? surname = "fomichev", + decimal balance = 1_000_000, + string? clerkId = null + ) { var client = new Client() { @@ -35,12 +52,20 @@ internal static class BankDbContextExtension Balance = balance, ClerkId = clerkId ?? Guid.NewGuid().ToString(), }; - dbContext.Clients.Add( client ); + 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) + 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 + ) { var creditProgram = new CreditProgram() { @@ -56,8 +81,17 @@ internal static class BankDbContextExtension 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") + 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() { @@ -75,21 +109,34 @@ internal static class BankDbContextExtension return storekeeper; } - public static Period InsertPeriodToDatabaseAndReturn(this BankDbContext dbContext, string? id = null, DateTime? start = null, DateTime? end = null, string? storekeeperId = null) + 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() + 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) + 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() { @@ -104,7 +151,14 @@ internal static class BankDbContextExtension return currency; } - public static Deposit InsertDepositToDatabaseAndReturn(this BankDbContext dbContext, string? id = null, float interestRate = 1f, decimal cost = 10, int period = 1, string? clerkId = null) + 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() { @@ -119,29 +173,82 @@ internal static class BankDbContextExtension return deposit; } - public static void RemoveCurrenciesFromDatabase(this BankDbContext dbContext) => dbContext.ExecuteSqlRaw("TRUNCATE \"Currencies\" CASCADE"); + 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 RemoveClientsFromDatabase(this BankDbContext dbContext) => dbContext.ExecuteSqlRaw("TRUNCATE \"Clients\" CASCADE"); + public static void RemoveCurrenciesFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Currencies\" CASCADE"); - public static void RemoveStorekeepersFromDatabase(this BankDbContext dbContext) => dbContext.ExecuteSqlRaw("TRUNCATE \"Storekeepers\" CASCADE"); + public static void RemoveClientsFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Clients\" CASCADE"); - public static void RemovePeriodsFromDatabase(this BankDbContext dbContext) => dbContext.ExecuteSqlRaw("TRUNCATE \"Periods\" CASCADE"); + public static void RemoveStorekeepersFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Storekeepers\" CASCADE"); - public static void RemoveClerksFromDatabase(this BankDbContext dbContext) => dbContext.ExecuteSqlRaw("TRUNCATE \"Clerks\" CASCADE"); + public static void RemovePeriodsFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Periods\" 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 RemoveClerksFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Clerks\" CASCADE"); - public static Client? GetClientFromDatabase(this BankDbContext dbContext, string id) => dbContext.Clients.FirstOrDefault(x => x.Id == id); + public static void RemoveCreditProgramsFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"CreditPrograms\" CASCADE"); - public static Clerk? GetClerkFromDatabase(this BankDbContext dbContext, string id) => dbContext.Clerks.FirstOrDefault(x => x.Id == id); + public static void RemoveDepositsFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Deposits\" CASCADE"); - public static CreditProgram? GetCreditProgramFromDatabase(this BankDbContext dbContext, string id) => dbContext.CreditPrograms.FirstOrDefault(x => x.Id == id); + public static void RemoveReplenishmentsFromDatabase(this BankDbContext dbContext) => + dbContext.ExecuteSqlRaw("TRUNCATE \"Replenishments\" CASCADE"); - public static Currency? GetCurrencyFromDatabase(this BankDbContext dbContext, string id) => dbContext.Currencies.FirstOrDefault(x => x.Id == id); + public static Client? GetClientFromDatabase(this BankDbContext dbContext, string id) => + dbContext.Clients.FirstOrDefault(x => x.Id == id); - public static Deposit? GetDepositFromDatabase(this BankDbContext dbContext, string id) => dbContext.Deposits.FirstOrDefault(x => x.Id == id); - - private static void ExecuteSqlRaw(this BankDbContext dbContext, string command) => dbContext.Database.ExecuteSqlRaw(command); + 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); } diff --git a/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs b/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs index a558b2a..665c4a0 100644 --- a/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs +++ b/TheBank/BankTests/Infrastructure/ConfigurationDatabase.cs @@ -4,5 +4,6 @@ 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"; + public string ConnectionString => + "Host=127.0.0.1;Port=5432;Database=TitanicTest;Username=postgres;Password=admin123;Include Error Detail=true"; } diff --git a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs index 0eb238a..e277f74 100644 --- a/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/ClerkStorageContractTests.cs @@ -19,7 +19,7 @@ internal class ClerkStorageContractTests : BaseStorageContractTest } [TearDown] - public void TearDown() + public void TearDown() { BankDbContext.RemoveClerksFromDatabase(); } @@ -28,8 +28,16 @@ internal class ClerkStorageContractTests : BaseStorageContractTest 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"); + 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); @@ -65,7 +73,10 @@ internal class ClerkStorageContractTests : BaseStorageContractTest { var clerk = CreateModel(); BankDbContext.InsertClerkToDatabaseAndReturn(id: clerk.Id); - Assert.That(() => _storageContract.AddElement(clerk), Throws.TypeOf()); + Assert.That( + () => _storageContract.AddElement(clerk), + Throws.TypeOf() + ); } [Test] @@ -73,7 +84,10 @@ internal class ClerkStorageContractTests : BaseStorageContractTest { var clerk = CreateModel(); BankDbContext.InsertClerkToDatabaseAndReturn(email: clerk.Email); - Assert.That(() => _storageContract.AddElement(clerk), Throws.TypeOf()); + Assert.That( + () => _storageContract.AddElement(clerk), + Throws.TypeOf() + ); } [Test] @@ -81,7 +95,10 @@ internal class ClerkStorageContractTests : BaseStorageContractTest { var clerk = CreateModel(login: "cheburek"); BankDbContext.InsertClerkToDatabaseAndReturn(email: "email@email.ru", login: "cheburek"); - Assert.That(() => _storageContract.AddElement(clerk), Throws.TypeOf()); + Assert.That( + () => _storageContract.AddElement(clerk), + Throws.TypeOf() + ); } [Test] @@ -96,11 +113,32 @@ internal class ClerkStorageContractTests : BaseStorageContractTest [Test] public void Try_UpdElement_WhenNoRecordWithThisId_Test() { - Assert.That(() => _storageContract.UpdElement(CreateModel()), Throws.TypeOf()); + Assert.That( + () => _storageContract.UpdElement(CreateModel()), + Throws.TypeOf() + ); } - 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 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) { diff --git a/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs index 1103b19..c070afa 100644 --- a/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs @@ -52,7 +52,11 @@ internal class ClientStorageContractTests : BaseStorageContractTest [Test] public void TryGetList_ByClerk_WhenHaveRecords_Test() { - var clerk = BankDbContext.InsertClerkToDatabaseAndReturn(email: "slava@ilya.com", login: "login",phone: "+7-987-555-55-55"); + 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); @@ -91,11 +95,30 @@ internal class ClientStorageContractTests : BaseStorageContractTest [Test] public void Try_UpdElement_WhenNoRecordWithThisId_Test() { - Assert.That(() => _clientStorageContract.UpdElement(CreateModel(_clerkId)), Throws.TypeOf()); + Assert.That( + () => _clientStorageContract.UpdElement(CreateModel(_clerkId)), + Throws.TypeOf() + ); } - private static ClientDataModel CreateModel(string clerkid, string? id = null, string? name = "null", string? surname = "surname", decimal balance = 1, List? depositClients = null, List? clientCredits = null) - => new(id ?? Guid.NewGuid().ToString(), name, surname, balance, clerkid, depositClients ?? [], clientCredits ?? []); + private static ClientDataModel CreateModel( + string clerkid, + string? id = null, + string? name = "null", + string? surname = "surname", + decimal balance = 1, + List? depositClients = null, + List? clientCredits = null + ) => + new( + id ?? Guid.NewGuid().ToString(), + name, + surname, + balance, + clerkid, + depositClients ?? [], + clientCredits ?? [] + ); private static void AssertElement(ClientDataModel actual, Client? expected) { diff --git a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs index 2311ddf..7295622 100644 --- a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs @@ -1,10 +1,10 @@ -using BankContracts.DataModels; +using System.Xml.Linq; +using BankContracts.DataModels; using BankContracts.Exceptions; using BankContracts.StorageContracts; using BankDatabase.Implementations; using BankDatabase.Models; using BankTests.Infrastructure; -using System.Xml.Linq; namespace BankTests.StorageContactsTests; @@ -36,9 +36,20 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest [Test] public void TryGetListWhenHaveRecords_ShouldSucces_Test() { - var clerk = BankDbContext.InsertCreditProgramToDatabaseAndReturn(storeleeperId: _storekeeperId, periodId: _periodId); - BankDbContext.InsertCreditProgramToDatabaseAndReturn(name: "bankrot2", storeleeperId: _storekeeperId, periodId: _periodId); - BankDbContext.InsertCreditProgramToDatabaseAndReturn(name: "bankrot3", storeleeperId: _storekeeperId, periodId: _periodId); + var clerk = BankDbContext.InsertCreditProgramToDatabaseAndReturn( + storeleeperId: _storekeeperId, + periodId: _periodId + ); + 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); @@ -57,14 +68,21 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest [Test] public void Try_GetElementById_WhenHaveRecord_Test() { - var creditProgram = BankDbContext.InsertCreditProgramToDatabaseAndReturn(storeleeperId: _storekeeperId, periodId: _periodId); + 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); + var credit = CreateModel( + name: "unique name", + periodId: _periodId, + storekeeperId: _storekeeperId + ); _storageContract.AddElement(credit); AssertElement(BankDbContext.GetCreditProgramFromDatabase(credit.Id), credit); } @@ -73,15 +91,30 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest public void Try_AddElement_WhenHaveRecordWithSameName_Test() { var credit = CreateModel(name: "1", storekeeperId: _storekeeperId, periodId: _periodId); - BankDbContext.InsertCreditProgramToDatabaseAndReturn(name: "1", periodId: _periodId, storeleeperId: _storekeeperId); - Assert.That(() => _storageContract.AddElement(credit), Throws.TypeOf()); + BankDbContext.InsertCreditProgramToDatabaseAndReturn( + name: "1", + periodId: _periodId, + storeleeperId: _storekeeperId + ); + Assert.That( + () => _storageContract.AddElement(credit), + Throws.TypeOf() + ); } [Test] - public void Try_UpdElement_Test() + public void Try_UpdElement_Test() { - var credit = CreateModel(name: "unique name", periodId: _periodId, storekeeperId: _storekeeperId); - BankDbContext.InsertCreditProgramToDatabaseAndReturn(credit.Id, periodId: _periodId, storeleeperId: _storekeeperId); + var credit = CreateModel( + name: "unique name", + periodId: _periodId, + storekeeperId: _storekeeperId + ); + BankDbContext.InsertCreditProgramToDatabaseAndReturn( + credit.Id, + periodId: _periodId, + storeleeperId: _storekeeperId + ); _storageContract.UpdElement(credit); AssertElement(BankDbContext.GetCreditProgramFromDatabase(credit.Id), credit); } @@ -89,11 +122,33 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest [Test] public void Try_UpdElement_WhenNoRecordWithThisId_Test() { - Assert.That(() => _storageContract.UpdElement(CreateModel(storekeeperId: _storekeeperId, periodId: _periodId)), Throws.TypeOf()); + Assert.That( + () => + _storageContract.UpdElement( + CreateModel(storekeeperId: _storekeeperId, periodId: _periodId) + ), + Throws.TypeOf() + ); } - private static CreditProgramDataModel CreateModel(string? id = null, string? name = "name", decimal cost = 1, decimal maxCost = 2, string? storekeeperId = null, string? periodId = null, List? currency = null) - => new(id ?? Guid.NewGuid().ToString(), name, cost, maxCost, storekeeperId ?? Guid.NewGuid().ToString(), periodId ?? Guid.NewGuid().ToString(), currency ?? []); + private static CreditProgramDataModel CreateModel( + string? id = null, + string? name = "name", + decimal cost = 1, + decimal maxCost = 2, + string? storekeeperId = null, + string? periodId = null, + List? 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) { diff --git a/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs index 6465903..5e76c4c 100644 --- a/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/CurrencyStorageContractTests.cs @@ -8,7 +8,7 @@ using BankTests.Infrastructure; namespace BankTests.StorageContactsTests; [TestFixture] -internal class CurrencyStorageContractTests : BaseStorageContractTest +internal class CurrencyStorageContractTests : BaseStorageContractTest { private ICurrencyStorageContract _storageContract; @@ -31,9 +31,17 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest [Test] public void TryGetListWhenHaveRecords_ShouldSuccess_Test() { - var currency = BankDbContext.InsertCurrencyToDatabaseAndReturn(storekeeperId: _storekeeperId); - BankDbContext.InsertCurrencyToDatabaseAndReturn(abbreviation: "$", storekeeperId: _storekeeperId); - BankDbContext.InsertCurrencyToDatabaseAndReturn(abbreviation: "eur", storekeeperId: _storekeeperId); + 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); @@ -44,14 +52,19 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest [Test] public void Try_GetElementById_WhenHaveRecord_Test() { - var currency = BankDbContext.InsertCurrencyToDatabaseAndReturn(storekeeperId: _storekeeperId); + 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); + var currency = BankDbContext.InsertCurrencyToDatabaseAndReturn( + abbreviation: "X", + storekeeperId: _storekeeperId + ); AssertElement(_storageContract.GetElementByAbbreviation(currency.Abbreviation), currency); } @@ -63,7 +76,6 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest Assert.That(list, Is.Empty); } - [Test] public void Try_AddElement_Test() { @@ -76,23 +88,38 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest 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()); + BankDbContext.InsertCurrencyToDatabaseAndReturn( + id: currency.Id, + storekeeperId: _storekeeperId + ); + Assert.That( + () => _storageContract.AddElement(currency), + Throws.TypeOf() + ); } [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()); + BankDbContext.InsertCurrencyToDatabaseAndReturn( + storekeeperId: _storekeeperId, + abbreviation: currency.Abbreviation + ); + Assert.That( + () => _storageContract.AddElement(currency), + Throws.TypeOf() + ); } [Test] public void Try_UpdElement_Test() { var currency = CreateModel(storekeeperId: _storekeeperId, abbreviation: "хамстер коин"); - BankDbContext.InsertCurrencyToDatabaseAndReturn(id: currency.Id, storekeeperId: _storekeeperId); + BankDbContext.InsertCurrencyToDatabaseAndReturn( + id: currency.Id, + storekeeperId: _storekeeperId + ); _storageContract.UpdElement(currency); AssertElement(BankDbContext.GetCurrencyFromDatabase(currency.Id), currency); } @@ -100,11 +127,26 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest [Test] public void Try_UpdElement_WhenNoRecordWithThisId_Test() { - Assert.That(() => _storageContract.UpdElement(CreateModel()), Throws.TypeOf()); + Assert.That( + () => _storageContract.UpdElement(CreateModel()), + Throws.TypeOf() + ); } - 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 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) { @@ -118,7 +160,7 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId)); }); } - + private static void AssertElement(Currency actual, CurrencyDataModel? expected) { Assert.That(expected, Is.Not.Null); @@ -131,4 +173,4 @@ internal class CurrencyStorageContractTests : BaseStorageContractTest Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId)); }); } -} \ No newline at end of file +} diff --git a/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs index d7033ab..a6004e2 100644 --- a/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/DepositStorageContractTests.cs @@ -48,7 +48,7 @@ internal class DepositStorageContractTests : BaseStorageContractTest Assert.That(list, Is.Not.Null); Assert.That(list, Is.Empty); } - + [Test] public void Try_GetElementById_WhenHaveRecord_Test() { @@ -64,16 +64,17 @@ internal class DepositStorageContractTests : BaseStorageContractTest 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()); + Assert.That( + () => _storageContract.AddElement(deposit), + Throws.TypeOf() + ); } - [Test] public void Try_UpdElement_Test() { @@ -83,16 +84,31 @@ internal class DepositStorageContractTests : BaseStorageContractTest AssertElement(BankDbContext.GetDepositFromDatabase(deposit.Id), deposit); } - [Test] public void Try_UpdElement_WhenNoRecordWithThisId_Test() { - Assert.That(() => _storageContract.UpdElement(CreateModel(clerkId: _clerkId)), Throws.TypeOf()); + Assert.That( + () => _storageContract.UpdElement(CreateModel(clerkId: _clerkId)), + Throws.TypeOf() + ); } - - private static DepositDataModel CreateModel(string? id = null, float interestRate = 10, decimal cost = 10, int period = 10, string? clerkId = null, List? deposits = null) - => new (id ?? Guid.NewGuid().ToString(), interestRate, cost, period, clerkId ?? Guid.NewGuid().ToString(), deposits ?? []); + private static DepositDataModel CreateModel( + string? id = null, + float interestRate = 10, + decimal cost = 10, + int period = 10, + string? clerkId = null, + List? deposits = null + ) => + new( + id ?? Guid.NewGuid().ToString(), + interestRate, + cost, + period, + clerkId ?? Guid.NewGuid().ToString(), + deposits ?? [] + ); private static void AssertElement(DepositDataModel actual, Deposit? expected) { @@ -119,4 +135,4 @@ internal class DepositStorageContractTests : BaseStorageContractTest Assert.That(actual.ClerkId, Is.EqualTo(expected.ClerkId)); }); } -} \ No newline at end of file +} diff --git a/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs index 22a1783..09bcb4d 100644 --- a/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/PeriodStorageContractTests.cs @@ -1,4 +1,5 @@ using BankContracts.DataModels; +using BankContracts.Exceptions; using BankContracts.StorageContracts; using BankDatabase.Implementations; using BankDatabase.Models; @@ -31,6 +32,8 @@ internal class PeriodStorageContractTests : BaseStorageContractTest 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); @@ -38,6 +41,71 @@ internal class PeriodStorageContractTests : BaseStorageContractTest 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() + ); + } + + [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() + ); + } + + 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); @@ -49,4 +117,16 @@ internal class PeriodStorageContractTests : BaseStorageContractTest Assert.That(actual.StorekeeperId, Is.EqualTo(expected.StorekeeperId)); }); } -} \ No newline at end of file + + 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)); + }); + } +} diff --git a/TheBank/BankTests/StorageContactsTests/ReplenishmentStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ReplenishmentStorageContractTests.cs new file mode 100644 index 0000000..399eec7 --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/ReplenishmentStorageContractTests.cs @@ -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() + ); + } + + [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() + ); + } + + 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)); + }); + } +} diff --git a/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs new file mode 100644 index 0000000..63add5d --- /dev/null +++ b/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs @@ -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 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() + ); + } + + [Test] + public void Try_AddElement_WhenHaveRecordWithSameEmail_Test() + { + var storekeeper = CreateModel(); + BankDbContext.InsertStorekeeperToDatabaseAndReturn(email: storekeeper.Email); + Assert.That( + () => _storageContract.AddElement(storekeeper), + Throws.TypeOf() + ); + } + + [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() + ); + } + + [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() + ); + } + + 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)); + }); + } +} \ No newline at end of file From f270d36d22af421e55c9c6d7eb7a355a0947dddd Mon Sep 17 00:00:00 2001 From: DjonniStorm Date: Thu, 1 May 2025 15:24:28 +0400 Subject: [PATCH 16/16] =?UTF-8?q?feat:=20=D1=82=D0=B5=D1=81=D1=82=D1=8B,?= =?UTF-8?q?=20=D0=BD=D0=B0=D1=87=D0=B0=D0=BB=D0=BE=20=D0=BF=D1=80=D0=BE?= =?UTF-8?q?=D0=B2=D0=B5=D1=80=D0=BA=D0=B8=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8?= =?UTF-8?q?=D0=B5=20=D0=BA=D0=BE=20=D0=BC=D0=BD=D0=BE=D0=B3=D0=B8=D0=BC?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../DataModels/ClientDataModel.cs | 12 +- .../Implementations/ClientStorageContract.cs | 40 +++- .../CreditProgramStorageContract.cs | 14 +- .../Models/ClientCreditProgram.cs | 8 +- .../Models/CreditProgramCurrency.cs | 8 +- TheBank/BankDatabase/Models/DepositClient.cs | 8 +- .../Infrastructure/BankDbContextExtension.cs | 50 ++++- .../ClientStorageContractTests.cs | 173 +++++++++++++++++- .../CreditProgramStorageContractTests.cs | 70 ++++++- .../StorekeeperStorageContractTests.cs | 9 +- 10 files changed, 335 insertions(+), 57 deletions(-) diff --git a/TheBank/BankContracts/DataModels/ClientDataModel.cs b/TheBank/BankContracts/DataModels/ClientDataModel.cs index aa1f59a..b5cf443 100644 --- a/TheBank/BankContracts/DataModels/ClientDataModel.cs +++ b/TheBank/BankContracts/DataModels/ClientDataModel.cs @@ -27,9 +27,9 @@ public class ClientDataModel(string id, string name, string surname, decimal bal public string ClerkId { get; private set; } = clerkId; - public List Deposits { get; private set; } = depositClients; + public List DepositClients { get; private set; } = depositClients; - public List CreditPrograms { get; private set; } = creditProgramClients; + public List CreditProgramClients { get; private set; } = creditProgramClients; public void Validate() { @@ -61,13 +61,13 @@ public class ClientDataModel(string id, string name, string surname, decimal bal { throw new ValidationException("The value in the field Clerkid is not a unique identifier"); } - if (Deposits is null) + if (DepositClients is null) { - throw new ValidationException("Field Deposits is null"); + throw new ValidationException("Field DepositClients is null"); } - if (CreditPrograms is null) + if (CreditProgramClients is null) { - throw new ValidationException("Field CreditPrograms is null"); + throw new ValidationException("Field CreditProgramClients is null"); } } } diff --git a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs index 9e26801..bf39e35 100644 --- a/TheBank/BankDatabase/Implementations/ClientStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/ClientStorageContract.cs @@ -20,8 +20,34 @@ internal class ClientStorageContract : IClientStorageContract var config = new MapperConfiguration(cfg => { cfg.CreateMap(); - cfg.CreateMap(); - cfg.CreateMap(); + cfg.CreateMap() + .ForMember(dest => dest.DepositClients, opt => opt.MapFrom(src => src.DepositClients)) + .ForMember(dest => dest.CreditProgramClients, opt => opt.MapFrom(src => src.CreditProgramClients)); + cfg.CreateMap() + .ForMember(dest => dest.DepositClients, opt => opt.MapFrom(src => src.DepositClients)) + .ForMember(dest => dest.CreditProgramClients, opt => opt.MapFrom(src => src.CreditProgramClients)); + cfg.CreateMap() + .ForMember(dest => dest.DepositId, opt => opt.MapFrom(src => src.DepositId)) + .ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId)); + cfg.CreateMap() + .ForMember(dest => dest.DepositId, opt => opt.MapFrom(src => src.DepositId)) + .ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId)); + cfg.CreateMap() + .ForMember(dest => dest.DepositId, opt => opt.MapFrom(src => src.Id)) + .ForMember(dest => dest.ClientId, opt => opt.Ignore()); + cfg.CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.DepositId)); + cfg.CreateMap() + .ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId)) + .ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId)); + cfg.CreateMap() + .ForMember(dest => dest.ClientId, opt => opt.MapFrom(src => src.ClientId)) + .ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId)); + cfg.CreateMap() + .ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.Id)) + .ForMember(dest => dest.ClientId, opt => opt.Ignore()); + cfg.CreateMap() + .ForMember(dest => dest.Id, opt => opt.MapFrom(src => src.CreditProgramId)); cfg.CreateMap(); }); _mapper = new Mapper(config); @@ -122,7 +148,7 @@ internal class ClientStorageContract : IClientStorageContract { var element = GetClientById(clientDataModel.Id) ?? throw new ElementNotFoundException(clientDataModel.Id); //проверь пожалуйста(не уверен) - if (clientDataModel.Deposits != null && clientDataModel.CreditPrograms != null) + if (clientDataModel.DepositClients != null && clientDataModel.CreditProgramClients != null) { if (element.DepositClients != null || element.DepositClients?.Count >= 0) { @@ -131,11 +157,11 @@ internal class ClientStorageContract : IClientStorageContract if (element.CreditProgramClients != null || element.CreditProgramClients?.Count >= 0) { - _dbContext.DepositClients.RemoveRange(element.DepositClients); + _dbContext.CreditProgramClients.RemoveRange(element.CreditProgramClients); } - element.DepositClients = _mapper.Map>(clientDataModel.Deposits); - element.DepositClients = _mapper.Map>(clientDataModel.CreditPrograms); + element.DepositClients = _mapper.Map>(clientDataModel.DepositClients); + element.CreditProgramClients = _mapper.Map>(clientDataModel.CreditProgramClients); } _mapper.Map(element, clientDataModel); _dbContext.SaveChanges(); @@ -168,5 +194,5 @@ internal class ClientStorageContract : IClientStorageContract throw new StorageException(ex.Message); } } - private Client? GetClientById(string id) => _dbContext.Clients.FirstOrDefault(x => x.Id == id); + private Client? GetClientById(string id) => _dbContext.Clients.Include(client => client.DepositClients).Include(client => client.CreditProgramClients).FirstOrDefault(x => x.Id == id); } diff --git a/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs b/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs index 1e36c08..2f7a360 100644 --- a/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs +++ b/TheBank/BankDatabase/Implementations/CreditProgramStorageContract.cs @@ -22,8 +22,18 @@ internal class CreditProgramStorageContract : ICreditProgramStorageContract _dbContext = dbContext; var config = new MapperConfiguration(x => { - x.CreateMap(); - x.CreateMap(); + x.CreateMap() + .ForMember(dest => dest.Currencies, opt => opt.MapFrom(src => src.CurrencyCreditPrograms)); + x.CreateMap() + .ForMember(dest => dest.CurrencyCreditPrograms, opt => opt.MapFrom(src => src.Currencies)); + x.CreateMap() + .ForMember(dest => dest.CreditProgramId, opt => opt.MapFrom(src => src.CreditProgramId)) + .ForMember(dest => dest.CurrencyId, opt => opt.MapFrom(src => src.CurrencyId)); + x.CreateMap() + .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); } diff --git a/TheBank/BankDatabase/Models/ClientCreditProgram.cs b/TheBank/BankDatabase/Models/ClientCreditProgram.cs index 87cb933..04bd615 100644 --- a/TheBank/BankDatabase/Models/ClientCreditProgram.cs +++ b/TheBank/BankDatabase/Models/ClientCreditProgram.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BankDatabase.Models; +namespace BankDatabase.Models; class ClientCreditProgram { diff --git a/TheBank/BankDatabase/Models/CreditProgramCurrency.cs b/TheBank/BankDatabase/Models/CreditProgramCurrency.cs index 09e19dc..186f6bd 100644 --- a/TheBank/BankDatabase/Models/CreditProgramCurrency.cs +++ b/TheBank/BankDatabase/Models/CreditProgramCurrency.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BankDatabase.Models; +namespace BankDatabase.Models; class CreditProgramCurrency { diff --git a/TheBank/BankDatabase/Models/DepositClient.cs b/TheBank/BankDatabase/Models/DepositClient.cs index ff3c1a9..ba4940b 100644 --- a/TheBank/BankDatabase/Models/DepositClient.cs +++ b/TheBank/BankDatabase/Models/DepositClient.cs @@ -1,10 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace BankDatabase.Models; +namespace BankDatabase.Models; class DepositClient { diff --git a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs index 788c86b..8b857c0 100644 --- a/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs +++ b/TheBank/BankTests/Infrastructure/BankDbContextExtension.cs @@ -41,7 +41,9 @@ internal static class BankDbContextExtension string? name = "slava", string? surname = "fomichev", decimal balance = 1_000_000, - string? clerkId = null + 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() @@ -51,7 +53,31 @@ internal static class BankDbContextExtension 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; @@ -64,7 +90,8 @@ internal static class BankDbContextExtension decimal cost = 1_000_000, decimal maxCost = 10_000_000, string? storeleeperId = null, - string? periodId = null + string? periodId = null, + List<(string currencyId, string creditProgramId)>? creditProgramCurrency = null // Item1 = ClientId Item2 = CreditProgramId ) { var creditProgram = new CreditProgram() @@ -78,6 +105,20 @@ internal static class BankDbContextExtension }; 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; } @@ -220,7 +261,10 @@ internal static class BankDbContextExtension dbContext.ExecuteSqlRaw("TRUNCATE \"Replenishments\" CASCADE"); public static Client? GetClientFromDatabase(this BankDbContext dbContext, string id) => - dbContext.Clients.FirstOrDefault(x => x.Id == 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); diff --git a/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs index c070afa..09dd5e6 100644 --- a/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/ClientStorageContractTests.cs @@ -10,35 +10,70 @@ namespace BankTests.StorageContactsTests; [TestFixture] internal class ClientStorageContractTests : BaseStorageContractTest { + private IClientStorageContract _clientStorageContract; + private string _clerkId; - private IClientStorageContract _clientStorageContract; + private string _depositId; + + private string _creditProgramId; + + private string _storekeeperId; + + private string _periodId; [SetUp] public void SetUp() { - _clerkId = BankDbContext.InsertClerkToDatabaseAndReturn().Id; _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 client = BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId); - BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId); - BankDbContext.InsertClientToDatabaseAndReturn(clerkId: _clerkId); + 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 == client.Id), client); + AssertElement(list.First(x => x.Id == clientId), client); } [Test] @@ -78,7 +113,13 @@ internal class ClientStorageContractTests : BaseStorageContractTest [Test] public void Try_AddElement_Test() { - var client = CreateModel(_clerkId); + 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); } @@ -86,10 +127,20 @@ internal class ClientStorageContractTests : BaseStorageContractTest [Test] public void Try_UpdElement_Test() { - var client = CreateModel(_clerkId); - BankDbContext.InsertClientToDatabaseAndReturn(id: client.Id, clerkId: _clerkId); + 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); - AssertElement(BankDbContext.GetClientFromDatabase(client.Id), client); + BankDbContext.ChangeTracker.Clear(); + AssertElement(BankDbContext.GetClientFromDatabase(clientId), client); } [Test] @@ -131,6 +182,57 @@ internal class ClientStorageContractTests : BaseStorageContractTest 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) @@ -144,5 +246,56 @@ internal class ClientStorageContractTests : BaseStorageContractTest 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); + } } } diff --git a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs index 7295622..22356b8 100644 --- a/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/CreditProgramStorageContractTests.cs @@ -17,12 +17,15 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest 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] @@ -30,15 +33,18 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest { BankDbContext.RemoveCreditProgramsFromDatabase(); BankDbContext.RemovePeriodsFromDatabase(); + BankDbContext.RemoveCurrenciesFromDatabase(); BankDbContext.RemoveStorekeepersFromDatabase(); } [Test] public void TryGetListWhenHaveRecords_ShouldSucces_Test() { - var clerk = BankDbContext.InsertCreditProgramToDatabaseAndReturn( + var creditProgramId = Guid.NewGuid().ToString(); + var creditProgram = BankDbContext.InsertCreditProgramToDatabaseAndReturn( storeleeperId: _storekeeperId, - periodId: _periodId + periodId: _periodId, + creditProgramCurrency: [( _currenyId, creditProgramId )] ); BankDbContext.InsertCreditProgramToDatabaseAndReturn( name: "bankrot2", @@ -54,7 +60,7 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest 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); + AssertElement(list.First(x => x.Id == creditProgram.Id), creditProgram); } [Test] @@ -94,7 +100,8 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest BankDbContext.InsertCreditProgramToDatabaseAndReturn( name: "1", periodId: _periodId, - storeleeperId: _storekeeperId + storeleeperId: _storekeeperId, + creditProgramCurrency: [(_currenyId, credit.Id)] ); Assert.That( () => _storageContract.AddElement(credit), @@ -113,7 +120,8 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest BankDbContext.InsertCreditProgramToDatabaseAndReturn( credit.Id, periodId: _periodId, - storeleeperId: _storekeeperId + storeleeperId: _storekeeperId, + creditProgramCurrency: [(_currenyId, credit.Id)] ); _storageContract.UpdElement(credit); AssertElement(BankDbContext.GetCreditProgramFromDatabase(credit.Id), credit); @@ -162,6 +170,32 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest 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) @@ -176,5 +210,31 @@ internal class CreditProgramStorageContractTests : BaseStorageContractTest 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); + } } } diff --git a/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs b/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs index 63add5d..d87e5de 100644 --- a/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs +++ b/TheBank/BankTests/StorageContactsTests/StorekeeperStorageContractTests.cs @@ -11,7 +11,7 @@ namespace BankTests.StorageContactsTests; internal class StorekeeperStorageContractTests : BaseStorageContractTest { private IStorekeeperStorageContract _storageContract; - + [SetUp] public void SetUp() { @@ -94,7 +94,10 @@ internal class StorekeeperStorageContractTests : BaseStorageContractTest public void Try_AddElement_WhenHaveRecordWithSameLogin_Test() { var storekeeper = CreateModel(login: "cheburek"); - BankDbContext.InsertStorekeeperToDatabaseAndReturn(email: "email@email.ru", login: "cheburek"); + BankDbContext.InsertStorekeeperToDatabaseAndReturn( + email: "email@email.ru", + login: "cheburek" + ); Assert.That( () => _storageContract.AddElement(storekeeper), Throws.TypeOf() @@ -169,4 +172,4 @@ internal class StorekeeperStorageContractTests : BaseStorageContractTest Assert.That(actual.PhoneNumber, Is.EqualTo(expected.PhoneNumber)); }); } -} \ No newline at end of file +}