Genral clean up and moving of code.
This commit is contained in:
+6
@@ -118,6 +118,12 @@ public class ApplyFeeHandlerTests
|
|||||||
using var _ = new AssertionScope();
|
using var _ = new AssertionScope();
|
||||||
customerWrite.Entity.Balance.Should()
|
customerWrite.Entity.Balance.Should()
|
||||||
.Be(expectedBalance);
|
.Be(expectedBalance);
|
||||||
|
revenueWrite.Entity.Balance.Should()
|
||||||
|
.Be(feeAmount);
|
||||||
|
journalWrite.Should()
|
||||||
|
.NotBeNull();
|
||||||
|
@event.Should()
|
||||||
|
.NotBeNull();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+1
-1
@@ -1,8 +1,8 @@
|
|||||||
using FinancialApi.Application.Commands;
|
using FinancialApi.Application.Commands;
|
||||||
using FinancialApi.Application.Events;
|
|
||||||
using FinancialApi.Application.Handlers;
|
using FinancialApi.Application.Handlers;
|
||||||
using FinancialApi.Application.Models;
|
using FinancialApi.Application.Models;
|
||||||
using FinancialApi.Domain.Entities;
|
using FinancialApi.Domain.Entities;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
using FluentAssertions;
|
using FluentAssertions;
|
||||||
using FluentAssertions.Execution;
|
using FluentAssertions.Execution;
|
||||||
using Microsoft.Extensions.Time.Testing;
|
using Microsoft.Extensions.Time.Testing;
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using FinancialApi.Application.Commands;
|
using FinancialApi.Application.Commands;
|
||||||
using FinancialApi.Application.Events;
|
|
||||||
using FinancialApi.Application.Interfaces;
|
using FinancialApi.Application.Interfaces;
|
||||||
using FinancialApi.Application.Models;
|
using FinancialApi.Application.Models;
|
||||||
using FinancialApi.Domain.Aggregates;
|
using FinancialApi.Domain.Aggregates;
|
||||||
using FinancialApi.Domain.Entities;
|
using FinancialApi.Domain.Entities;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
using Wolverine.Persistence;
|
using Wolverine.Persistence;
|
||||||
|
|
||||||
namespace FinancialApi.Application.Handlers;
|
namespace FinancialApi.Application.Handlers;
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
using FinancialApi.Application.Events;
|
using FinancialApi.Domain.Events;
|
||||||
using Microsoft.Extensions.Logging;
|
using Microsoft.Extensions.Logging;
|
||||||
|
|
||||||
namespace FinancialApi.Application.Handlers;
|
namespace FinancialApi.Application.Handlers;
|
||||||
|
|||||||
+1
-1
@@ -1,9 +1,9 @@
|
|||||||
using FinancialApi.Application.Commands;
|
using FinancialApi.Application.Commands;
|
||||||
using FinancialApi.Application.Events;
|
|
||||||
using FinancialApi.Application.Interfaces;
|
using FinancialApi.Application.Interfaces;
|
||||||
using FinancialApi.Application.Models;
|
using FinancialApi.Application.Models;
|
||||||
using FinancialApi.Domain.Aggregates;
|
using FinancialApi.Domain.Aggregates;
|
||||||
using FinancialApi.Domain.Entities;
|
using FinancialApi.Domain.Entities;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
using Wolverine.Persistence;
|
using Wolverine.Persistence;
|
||||||
|
|
||||||
namespace FinancialApi.Application.Handlers;
|
namespace FinancialApi.Application.Handlers;
|
||||||
|
|||||||
+1
-1
@@ -1,9 +1,9 @@
|
|||||||
using FinancialApi.Application.Commands;
|
using FinancialApi.Application.Commands;
|
||||||
using FinancialApi.Application.Events;
|
|
||||||
using FinancialApi.Application.Interfaces;
|
using FinancialApi.Application.Interfaces;
|
||||||
using FinancialApi.Application.Models;
|
using FinancialApi.Application.Models;
|
||||||
using FinancialApi.Domain.Aggregates;
|
using FinancialApi.Domain.Aggregates;
|
||||||
using FinancialApi.Domain.Entities;
|
using FinancialApi.Domain.Entities;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
using Wolverine.Persistence;
|
using Wolverine.Persistence;
|
||||||
|
|
||||||
namespace FinancialApi.Application.Handlers;
|
namespace FinancialApi.Application.Handlers;
|
||||||
|
|||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
namespace FinancialApi.Application.Events;
|
namespace FinancialApi.Domain.Events;
|
||||||
|
|
||||||
public record FeeAppliedEvent(int AccountId, decimal Amount);
|
public record FeeAppliedEvent(int AccountId, decimal Amount);
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
namespace FinancialApi.Application.Events;
|
namespace FinancialApi.Domain.Events;
|
||||||
|
|
||||||
public record FundsTransferredEvent(int SourceAccountId, int DestinationAccountId, decimal Amount);
|
public record FundsTransferredEvent(int SourceAccountId, int DestinationAccountId, decimal Amount);
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
namespace FinancialApi.Application.Events;
|
namespace FinancialApi.Domain.Events;
|
||||||
|
|
||||||
public interface IEventTracker
|
public interface IEventTracker
|
||||||
{
|
{
|
||||||
+1
-1
@@ -1,3 +1,3 @@
|
|||||||
namespace FinancialApi.Application.Events;
|
namespace FinancialApi.Domain.Events;
|
||||||
|
|
||||||
public record JournalReversedEvent(Guid OriginalJournalId, Guid ReversalJournalId);
|
public record JournalReversedEvent(Guid OriginalJournalId, Guid ReversalJournalId);
|
||||||
+35
@@ -0,0 +1,35 @@
|
|||||||
|
using FinancialApi.Application.Commands;
|
||||||
|
using FinancialApi.Application.Interfaces;
|
||||||
|
using FinancialApi.Domain.Entities;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
|
using FluentAssertions;
|
||||||
|
using Wolverine;
|
||||||
|
using Wolverine.Tracking;
|
||||||
|
|
||||||
|
namespace FinancialApi.Infrastructure.Tests;
|
||||||
|
|
||||||
|
internal class FakeAccountQuery : IAccountQuery
|
||||||
|
{
|
||||||
|
public Task<Account?> FindByIdAsync(int id) => Task.FromResult(new Account(id, 100.00m, AccountType.Debit))!;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ApplyFeeIntegrationTests(WolverineTestFixture fixture) : IClassFixture<WolverineTestFixture>
|
||||||
|
{
|
||||||
|
[Fact]
|
||||||
|
public async Task GivenValidCommand_WhenApplyingFee_ShouldPublishFeeAppliedEvent()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var command = new ApplyFeeCommand(1, 100);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var session = await fixture.Host.InvokeMessageAndWaitAsync(command);
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
session.Sent.AllMessages()
|
||||||
|
.ShouldHaveMessageOfType<FeeAppliedEvent>();
|
||||||
|
session.Sent.MessagesOf<FeeAppliedEvent>()
|
||||||
|
.Count()
|
||||||
|
.Should()
|
||||||
|
.Be(1);
|
||||||
|
}
|
||||||
|
}
|
||||||
+41
@@ -0,0 +1,41 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>net10.0</TargetFramework>
|
||||||
|
<ImplicitUsings>enable</ImplicitUsings>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="coverlet.collector" Version="6.0.4"/>
|
||||||
|
<PackageReference Include="FluentAssertions" Version="8.10.0" />
|
||||||
|
<PackageReference Include="Microsoft.Extensions.Hosting.Abstractions" Version="10.0.10" />
|
||||||
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.14.1"/>
|
||||||
|
<PackageReference Include="NSubstitute" Version="6.0.0" />
|
||||||
|
<PackageReference Include="WolverineFx" Version="6.24.1" />
|
||||||
|
<PackageReference Include="WolverineFx.RuntimeCompilation" Version="6.24.1" />
|
||||||
|
<PackageReference Include="xunit" Version="2.9.3"/>
|
||||||
|
<PackageReference Include="xunit.runner.visualstudio" Version="3.1.4"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Using Include="Xunit"/>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<Reference Include="Microsoft.Extensions.Hosting">
|
||||||
|
<HintPath>..\..\..\..\..\..\.nuget\packages\microsoft.extensions.hosting\10.0.0\lib\net10.0\Microsoft.Extensions.Hosting.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.Extensions.Hosting.Abstractions" />
|
||||||
|
<Reference Include="Microsoft.Extensions.TimeProvider.Testing">
|
||||||
|
<HintPath>..\..\..\..\..\..\.nuget\packages\microsoft.extensions.timeprovider.testing\10.6.0\lib\net10.0\Microsoft.Extensions.TimeProvider.Testing.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\FinancialApi.Application\FinancialApi.Application.csproj" />
|
||||||
|
<ProjectReference Include="..\FinancialApi.Infrastructure\FinancialApi.Infrastructure.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
||||||
+34
@@ -0,0 +1,34 @@
|
|||||||
|
using FinancialApi.Application.Handlers;
|
||||||
|
using FinancialApi.Application.Interfaces;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
|
using Microsoft.Extensions.DependencyInjection;
|
||||||
|
using Microsoft.Extensions.Hosting;
|
||||||
|
using Microsoft.Extensions.Time.Testing;
|
||||||
|
using Wolverine;
|
||||||
|
|
||||||
|
namespace FinancialApi.Infrastructure.Tests;
|
||||||
|
|
||||||
|
public class WolverineTestFixture : IDisposable
|
||||||
|
{
|
||||||
|
public IHost Host { get; }
|
||||||
|
|
||||||
|
public WolverineTestFixture()
|
||||||
|
{
|
||||||
|
// We build and start the host ONCE here
|
||||||
|
Host = Microsoft.Extensions.Hosting.Host.CreateDefaultBuilder()
|
||||||
|
.ConfigureServices((context, services) =>
|
||||||
|
{
|
||||||
|
services.AddSingleton<IAccountQuery>(_ => new FakeAccountQuery());
|
||||||
|
services.AddSingleton<TimeProvider>(_ => new FakeTimeProvider());
|
||||||
|
services.AddSingleton<IEventTracker>(_ => new DemoEventStore());
|
||||||
|
}
|
||||||
|
)
|
||||||
|
.UseWolverine(opts => { opts.Discovery.IncludeAssembly(typeof(ApplyFeeHandler).Assembly); })
|
||||||
|
.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
Host.Dispose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -6,9 +6,9 @@ namespace FinancialApi.Infrastructure;
|
|||||||
|
|
||||||
public class AccountQuery(AccountDbContext db) : IAccountQuery
|
public class AccountQuery(AccountDbContext db) : IAccountQuery
|
||||||
{
|
{
|
||||||
public Task<Account?> FindByIdAsync(int id)
|
public async Task<Account?> FindByIdAsync(int id)
|
||||||
{
|
{
|
||||||
return db.Accounts.AsNoTracking()
|
return await db.Accounts.AsNoTracking()
|
||||||
.FirstOrDefaultAsync(x => x.Id == id);
|
.FirstOrDefaultAsync(x => x.Id == id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+2
-2
@@ -1,6 +1,6 @@
|
|||||||
using FinancialApi.Application.Events;
|
using FinancialApi.Domain.Events;
|
||||||
|
|
||||||
namespace FinancialApi;
|
namespace FinancialApi.Infrastructure;
|
||||||
|
|
||||||
public class DemoEventStore : IEventTracker
|
public class DemoEventStore : IEventTracker
|
||||||
{
|
{
|
||||||
@@ -1,3 +1,4 @@
|
|||||||
|
using FinancialApi.Domain.Exceptions;
|
||||||
using Microsoft.AspNetCore.Diagnostics;
|
using Microsoft.AspNetCore.Diagnostics;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
|
|
||||||
@@ -11,7 +12,7 @@ public class DomainExceptionHandler : IExceptionHandler
|
|||||||
CancellationToken cancellationToken
|
CancellationToken cancellationToken
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
if (exception is not (InvalidOperationException or ArgumentException))
|
if (exception is not (InvalidOperationException or ArgumentException or GaapViolationException))
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,8 +7,8 @@ Accept: application/json
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"accountId": 1,
|
"accountId": 2,
|
||||||
"amount": 50.0
|
"amount": 100
|
||||||
}
|
}
|
||||||
|
|
||||||
### Transfer Between Accounts
|
### Transfer Between Accounts
|
||||||
@@ -28,7 +28,7 @@ POST {{FinancialApi_HostAddress}}/journal/reverse
|
|||||||
Content-Type: application/json
|
Content-Type: application/json
|
||||||
|
|
||||||
{
|
{
|
||||||
"originalJournalId": "B65EB28C-7EC1-4B70-9069-06A61A4FE857",
|
"originalJournalId": "E7FB25DB-406F-4063-A4B0-DE6BB8292437",
|
||||||
"reason": "Incorrect Account Fee"
|
"reason": "Incorrect Account Fee"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using FinancialApi;
|
using FinancialApi;
|
||||||
using FinancialApi.Application.Commands;
|
using FinancialApi.Application.Commands;
|
||||||
using FinancialApi.Application.Events;
|
|
||||||
using FinancialApi.Application.Handlers;
|
using FinancialApi.Application.Handlers;
|
||||||
using FinancialApi.Application.Interfaces;
|
using FinancialApi.Application.Interfaces;
|
||||||
|
using FinancialApi.Domain.Events;
|
||||||
using FinancialApi.Infrastructure;
|
using FinancialApi.Infrastructure;
|
||||||
using FinancialApi.ServiceDefaults;
|
using FinancialApi.ServiceDefaults;
|
||||||
using JasperFx.Resources;
|
using JasperFx.Resources;
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinancialApi.Application.Un
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinancialApi.Domain.Tests", "FinancialApi.Domain.Tests\FinancialApi.Domain.Tests.csproj", "{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinancialApi.Domain.Tests", "FinancialApi.Domain.Tests\FinancialApi.Domain.Tests.csproj", "{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "FinancialApi.Infrastructure.Tests", "FinancialApi.Infrastructure.Tests\FinancialApi.Infrastructure.Tests.csproj", "{8C1BA932-16F2-42B3-A07C-C589C31044B3}"
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
@@ -48,5 +50,9 @@ Global
|
|||||||
{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}.Release|Any CPU.Build.0 = Release|Any CPU
|
{C15E3FE0-6E3D-4FFC-892E-D469536ADC13}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{8C1BA932-16F2-42B3-A07C-C589C31044B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{8C1BA932-16F2-42B3-A07C-C589C31044B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{8C1BA932-16F2-42B3-A07C-C589C31044B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{8C1BA932-16F2-42B3-A07C-C589C31044B3}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|||||||
Reference in New Issue
Block a user