From df697ed37cc0f47e63df92e24c066dac1af232f8 Mon Sep 17 00:00:00 2001 From: Stevan Freeborn <65925598+StevanFreeborn@users.noreply.github.com> Date: Sun, 8 Mar 2026 07:18:27 -0500 Subject: [PATCH] tests(infra.tests): added builder classes for creating test entities --- .editorconfig | 1 + src/FiscalOS.Core/Accounts/Institution.cs | 7 -- .../Data/AccountBuilder.cs | 18 ++++- .../Data/InstitutionBuilder.cs | 8 --- .../Data/TransactionBuilder.cs | 67 +++++++++++++++++++ .../Data/TransactionMetadataBuilder.cs | 26 +++++++ .../FiscalOS.Infra.Tests/Data/UserBuilder.cs | 55 ++++----------- .../Integration/IntegrationTest.cs | 21 ++---- 8 files changed, 129 insertions(+), 74 deletions(-) create mode 100644 tests/FiscalOS.Infra.Tests/Data/TransactionBuilder.cs create mode 100644 tests/FiscalOS.Infra.Tests/Data/TransactionMetadataBuilder.cs diff --git a/.editorconfig b/.editorconfig index b43c230..5bad9d5 100644 --- a/.editorconfig +++ b/.editorconfig @@ -81,6 +81,7 @@ dotnet_remove_unnecessary_suppression_exclusions = none # analyzer settings dotnet_diagnostic.IDE0058.severity = none +dotnet_diagnostic.IDE0053.severity = when_on_single_line:suggestion dotnet_diagnostic.IDE0100.severity = none dotnet_diagnostic.CA1515.severity = none dotnet_diagnostic.CA1848.severity = none diff --git a/src/FiscalOS.Core/Accounts/Institution.cs b/src/FiscalOS.Core/Accounts/Institution.cs index 5d09ebb..60984dd 100644 --- a/src/FiscalOS.Core/Accounts/Institution.cs +++ b/src/FiscalOS.Core/Accounts/Institution.cs @@ -15,19 +15,12 @@ public sealed class Institution : Entity } public static Institution From(string? name, InstitutionMetadata metadata) - { - return From(null, name, metadata); - } - - public static Institution From(User? user, string? name, InstitutionMetadata metadata) { ArgumentNullException.ThrowIfNull(name, nameof(name)); ArgumentNullException.ThrowIfNull(metadata, nameof(metadata)); return new Institution() { - UserId = user?.Id ?? Guid.Empty, - User = user, Name = name, Metadata = metadata }; diff --git a/tests/FiscalOS.Infra.Tests/Data/AccountBuilder.cs b/tests/FiscalOS.Infra.Tests/Data/AccountBuilder.cs index 4d641b3..8778e97 100644 --- a/tests/FiscalOS.Infra.Tests/Data/AccountBuilder.cs +++ b/tests/FiscalOS.Infra.Tests/Data/AccountBuilder.cs @@ -4,6 +4,7 @@ internal sealed class AccountBuilder { private string _name = "accountName"; private AccountMetadata? _metadata; + private readonly List _transactions = []; private AccountBuilder() { @@ -28,6 +29,14 @@ internal sealed class AccountBuilder return this; } + public AccountBuilder WithTransaction(Action? action = null) + { + var tb = TransactionBuilder.Create(); + action?.Invoke(tb); + _transactions.Add(tb.Build()); + return this; + } + public Account Build() { if (_metadata is null) @@ -35,6 +44,13 @@ internal sealed class AccountBuilder throw new InvalidOperationException($"You must call {nameof(WithMetadata)} prior to building"); } - return Account.From(_name, _metadata); + var account = Account.From(_name, _metadata); + + foreach (var transaction in _transactions) + { + account.AddTransaction(transaction); + } + + return account; } } \ No newline at end of file diff --git a/tests/FiscalOS.Infra.Tests/Data/InstitutionBuilder.cs b/tests/FiscalOS.Infra.Tests/Data/InstitutionBuilder.cs index a8558e3..ffdcbf7 100644 --- a/tests/FiscalOS.Infra.Tests/Data/InstitutionBuilder.cs +++ b/tests/FiscalOS.Infra.Tests/Data/InstitutionBuilder.cs @@ -2,7 +2,6 @@ namespace FiscalOS.Infra.Tests.Data; internal sealed class InstitutionBuilder { - private User? _user; private string _name = "institutionName"; private InstitutionMetadata? _metadata; private readonly List _accounts = []; @@ -16,12 +15,6 @@ internal sealed class InstitutionBuilder return new(); } - public InstitutionBuilder WithUser(User user) - { - _user = user; - return this; - } - public InstitutionBuilder WithName(string name) { _name = name; @@ -52,7 +45,6 @@ internal sealed class InstitutionBuilder } var institution = Institution.From( - _user, _name, _metadata ); diff --git a/tests/FiscalOS.Infra.Tests/Data/TransactionBuilder.cs b/tests/FiscalOS.Infra.Tests/Data/TransactionBuilder.cs new file mode 100644 index 0000000..098420b --- /dev/null +++ b/tests/FiscalOS.Infra.Tests/Data/TransactionBuilder.cs @@ -0,0 +1,67 @@ +namespace FiscalOS.Infra.Tests.Data; + +internal sealed class TransactionBuilder +{ + private string _merchantName = "merchantName"; + private string _description = "description"; + private decimal _amount = 100; + private DateTimeOffset _date = DateTimeOffset.UtcNow; + private TransactionMetadata? _metadata; + + private TransactionBuilder() + { + } + + public static TransactionBuilder Create() + { + return new(); + } + + public TransactionBuilder WithMerchantName(string merchantName) + { + _merchantName = merchantName; + return this; + } + + public TransactionBuilder WithDescription(string description) + { + _description = description; + return this; + } + + public TransactionBuilder WithAmount(decimal amount) + { + _amount = amount; + return this; + } + + public TransactionBuilder WithDate(DateTimeOffset date) + { + _date = date; + return this; + } + + public TransactionBuilder WithMetadata(Action? action = null) + { + var tmb = TransactionMetadataBuilder.Create(); + action?.Invoke(tmb); + _metadata = tmb.Build(); + return this; + } + + public Transaction Build() + { + if (_metadata is null) + { + throw new InvalidOperationException($"You must call {nameof(WithMetadata)} prior to building"); + } + + return Transaction.From( + _merchantName, + _description, + _amount, + _date, + _metadata + ); + } +} \ No newline at end of file diff --git a/tests/FiscalOS.Infra.Tests/Data/TransactionMetadataBuilder.cs b/tests/FiscalOS.Infra.Tests/Data/TransactionMetadataBuilder.cs new file mode 100644 index 0000000..d8d0715 --- /dev/null +++ b/tests/FiscalOS.Infra.Tests/Data/TransactionMetadataBuilder.cs @@ -0,0 +1,26 @@ +namespace FiscalOS.Infra.Tests.Data; + +internal sealed class TransactionMetadataBuilder +{ + private string _plaidId = "plaidId"; + + private TransactionMetadataBuilder() + { + } + + public static TransactionMetadataBuilder Create() + { + return new(); + } + + public TransactionMetadataBuilder WithPlaidId(string plaidId) + { + _plaidId = plaidId; + return this; + } + + public PlaidTransactionMetadata Build() + { + return PlaidTransactionMetadata.From(_plaidId); + } +} \ No newline at end of file diff --git a/tests/FiscalOS.Infra.Tests/Data/UserBuilder.cs b/tests/FiscalOS.Infra.Tests/Data/UserBuilder.cs index 8483c9b..e4434e9 100644 --- a/tests/FiscalOS.Infra.Tests/Data/UserBuilder.cs +++ b/tests/FiscalOS.Infra.Tests/Data/UserBuilder.cs @@ -1,43 +1,5 @@ namespace FiscalOS.Infra.Tests.Data; -// protected async Task CreateTestUserAsync() -// { -// var user = User.From( -// "username", -// "hashedPassword", -// EncryptedDataKey.From("keyUsed", "encryptedKey") -// ); -// -// var institutionMetadata = PlaidInstitutionMetadata.From( -// "plaidId", -// "plaidName", -// "encryptedAccessToken", -// "itemId" -// ); -// var institution = Institution.From("institutionName", institutionMetadata); -// user.AddInstitution(institution); -// -// var accountMetadata = PlaidAccountMetadata.From("plaidId", "plaidName"); -// var account = Account.From("some account", accountMetadata); -// user.AddAccount(account); -// institution.AddAccount(account); -// -// var transactionMetadata = PlaidTransactionMetadata.From("plaidId"); -// var transaction = Transaction.From( -// "merchantName", -// "description", -// 100, -// DateTimeOffset.UtcNow, -// transactionMetadata -// ); -// user.AddTransaction(transaction); -// account.AddTransaction(transaction); -// -// await AppDbContext.AddAsync(user, TestContext.Current.CancellationToken); -// await AppDbContext.SaveChangesAsync(TestContext.Current.CancellationToken); -// -// return user; -// } internal sealed class UserBuilder { private string _username = "username"; @@ -46,7 +8,7 @@ internal sealed class UserBuilder "keyUsed", "encryptedKey" ); - private readonly List _instituionBuilders = []; + private readonly List _instituions = []; private UserBuilder() { @@ -79,7 +41,7 @@ internal sealed class UserBuilder { var ib = InstitutionBuilder.Create(); action?.Invoke(ib); - _instituionBuilders.Add(ib); + _instituions.Add(ib.Build()); return this; } @@ -91,10 +53,19 @@ internal sealed class UserBuilder _dataKey ); - foreach (var ib in _instituionBuilders) + foreach (var institution in _instituions) { - var institution = ib.WithUser(user).Build(); user.AddInstitution(institution); + + foreach (var account in institution.Accounts) + { + user.AddAccount(account); + + foreach (var transaction in account.Transactions) + { + user.AddTransaction(transaction); + } + } } return user; diff --git a/tests/FiscalOS.Infra.Tests/Integration/IntegrationTest.cs b/tests/FiscalOS.Infra.Tests/Integration/IntegrationTest.cs index a56953c..33fc9c3 100644 --- a/tests/FiscalOS.Infra.Tests/Integration/IntegrationTest.cs +++ b/tests/FiscalOS.Infra.Tests/Integration/IntegrationTest.cs @@ -24,28 +24,17 @@ public abstract class IntegrationTest : IAsyncLifetime .WithInstitution(static ib => { ib.WithMetadata(); - ib.WithAccount(static ab => + ib.WithAccount(static ab => { ab.WithMetadata(); + ab.WithTransaction(static tb => + { + tb.WithMetadata(); + }); }); }) .Build(); - var accountMetadata = PlaidAccountMetadata.From("plaidId", "plaidName"); - var account = Account.From("some account", accountMetadata); - user.AddAccount(account); - - var transactionMetadata = PlaidTransactionMetadata.From("plaidId"); - var transaction = Transaction.From( - "merchantName", - "description", - 100, - DateTimeOffset.UtcNow, - transactionMetadata - ); - user.AddTransaction(transaction); - account.AddTransaction(transaction); - await AppDbContext.AddAsync(user, TestContext.Current.CancellationToken); await AppDbContext.SaveChangesAsync(TestContext.Current.CancellationToken);