Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions RefactorThis.Application/CommandInterface/ICommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace RefactorThis.Application.CommandInterface
{
public interface ICommandHandler<TCommand, TResult>
{
TResult Handle(TCommand command);
}
}
10 changes: 10 additions & 0 deletions RefactorThis.Application/Commands/ProcessPaymentCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
using RefactorThis.Domain.Entities;

namespace RefactorThis.Application.Commands
{
public class ProcessPaymentCommand
{
public Payment Payment { get; set; }
public Invoice Invoice{ get; set; }
}
}
32 changes: 32 additions & 0 deletions RefactorThis.Application/Commands/ProcessPaymentCommandHandler.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using RefactorThis.Application.CommandInterface;
using RefactorThis.Persistence.Interfaces;

namespace RefactorThis.Application.Commands
{
public class ProcessPaymentCommandHandler : ICommandHandler<ProcessPaymentCommand, string>
{
private readonly IInvoiceRepository _invoiceRepository;

public ProcessPaymentCommandHandler(IInvoiceRepository invoiceRepository)
{
_invoiceRepository = invoiceRepository;
}

public string Handle(ProcessPaymentCommand command)
{
var invoice = _invoiceRepository.GetByReference(command.Invoice);


if (invoice == null)
{
throw new InvalidOperationException("There is no invoice matching this payment");
}
var result = invoice.ApplyPayment(command.Payment);


_invoiceRepository.Save(invoice);

return result;
}
}
}
14 changes: 14 additions & 0 deletions RefactorThis.Application/RefactorThis.Application.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<ItemGroup>
<ProjectReference Include="..\RefactorThis.Domain\RefactorThis.Domain.csproj" />
<ProjectReference Include="..\RefactorThis.Persistence\RefactorThis.Persistence.csproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{"RootPath":"C:\\Users\\ajcon\\Source\\Repos\\refactorthis\\RefactorThis.Domain.Tests","ProjectFileName":"RefactorThis.Domain.Tests.csproj","Configuration":"Debug|AnyCPU","FrameworkPath":"","Sources":[{"SourceFile":"InvoicePaymentProcessorTests.cs"},{"SourceFile":"Properties\\AssemblyInfo.cs"},{"SourceFile":"obj\\Debug\\.NETFramework,Version=v4.7.2.AssemblyAttributes.cs"}],"References":[{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\mscorlib.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Users\\ajcon\\Source\\Repos\\refactorthis\\RefactorThis.Domain\\bin\\Debug\\RefactorThis.Domain.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":true,"ProjectPath":"C:\\Users\\ajcon\\Source\\Repos\\refactorthis\\RefactorThis.Domain\\bin\\Debug\\RefactorThis.Domain.dll"},{"Reference":"C:\\Users\\ajcon\\Source\\Repos\\refactorthis\\RefactorThis.Persistence\\bin\\Debug\\net472\\RefactorThis.Persistence.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":true,"ProjectPath":"C:\\Users\\ajcon\\Source\\Repos\\refactorthis\\RefactorThis.Persistence\\bin\\Debug\\net472\\RefactorThis.Persistence.dll"},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Core.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Data.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""},{"Reference":"C:\\Program Files (x86)\\Reference Assemblies\\Microsoft\\Framework\\.NETFramework\\v4.7.2\\System.Xml.dll","ResolvedFrom":"","OriginalItemSpec":"","Name":"","EmbedInteropTypes":false,"CopyLocal":false,"IsProjectReference":false,"ProjectPath":""}],"Analyzers":[],"Outputs":[{"OutputItemFullPath":"C:\\Users\\ajcon\\Source\\Repos\\refactorthis\\RefactorThis.Domain.Tests\\bin\\Debug\\RefactorThis.Domain.Tests.dll","OutputItemRelativePath":"RefactorThis.Domain.Tests.dll"},{"OutputItemFullPath":"","OutputItemRelativePath":""}],"CopyToOutputEntries":[]}
232 changes: 11 additions & 221 deletions RefactorThis.Domain.Tests/InvoicePaymentProcessorTests.cs
Original file line number Diff line number Diff line change
@@ -1,247 +1,37 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
using RefactorThis.Persistence;

using RefactorThis.Domain.Entities;
using RefactorThis.Persistence.Repository;
using RefactorThis.Application.Commands;
namespace RefactorThis.Domain.Tests
{
[TestFixture]
public class InvoicePaymentProcessorTests
{
[Test]
public void ProcessPayment_Should_ThrowException_When_NoInoiceFoundForPaymentReference( )
public void ProcessPayment_Should_ThrowException_When_NoInoiceFoundForPaymentReference()
{
var repo = new InvoiceRepository( );
var repo = new InvoiceRepository();

Invoice invoice = null;
var paymentProcessor = new InvoiceService( repo );
var paymentProcessor = new ProcessPaymentCommandHandler(repo);

var payment = new Payment( );
var payment = new Payment();
var failureMessage = "";

try
{
var result = paymentProcessor.ProcessPayment( payment );
var result = paymentProcessor.ProcessPayment(payment);
}
catch ( InvalidOperationException e )
catch (InvalidOperationException e)
{
failureMessage = e.Message;
}

Assert.AreEqual( "There is no invoice matching this payment", failureMessage );
Assert.AreEqual("There is no invoice matching this payment", failureMessage);
}

[Test]
public void ProcessPayment_Should_ReturnFailureMessage_When_NoPaymentNeeded( )
{
var repo = new InvoiceRepository( );

var invoice = new Invoice( repo )
{
Amount = 0,
AmountPaid = 0,
Payments = null
};

repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( );

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "no payment needed", result );
}

[Test]
public void ProcessPayment_Should_ReturnFailureMessage_When_InvoiceAlreadyFullyPaid( )
{
var repo = new InvoiceRepository( );

var invoice = new Invoice( repo )
{
Amount = 10,
AmountPaid = 10,
Payments = new List<Payment>
{
new Payment
{
Amount = 10
}
}
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( );

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "invoice was already fully paid", result );
}

[Test]
public void ProcessPayment_Should_ReturnFailureMessage_When_PartialPaymentExistsAndAmountPaidExceedsAmountDue( )
{
var repo = new InvoiceRepository( );
var invoice = new Invoice( repo )
{
Amount = 10,
AmountPaid = 5,
Payments = new List<Payment>
{
new Payment
{
Amount = 5
}
}
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( )
{
Amount = 6
};

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "the payment is greater than the partial amount remaining", result );
}

[Test]
public void ProcessPayment_Should_ReturnFailureMessage_When_NoPartialPaymentExistsAndAmountPaidExceedsInvoiceAmount( )
{
var repo = new InvoiceRepository( );
var invoice = new Invoice( repo )
{
Amount = 5,
AmountPaid = 0,
Payments = new List<Payment>( )
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( )
{
Amount = 6
};

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "the payment is greater than the invoice amount", result );
}

[Test]
public void ProcessPayment_Should_ReturnFullyPaidMessage_When_PartialPaymentExistsAndAmountPaidEqualsAmountDue( )
{
var repo = new InvoiceRepository( );
var invoice = new Invoice( repo )
{
Amount = 10,
AmountPaid = 5,
Payments = new List<Payment>
{
new Payment
{
Amount = 5
}
}
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( )
{
Amount = 5
};

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "final partial payment received, invoice is now fully paid", result );
}

[Test]
public void ProcessPayment_Should_ReturnFullyPaidMessage_When_NoPartialPaymentExistsAndAmountPaidEqualsInvoiceAmount( )
{
var repo = new InvoiceRepository( );
var invoice = new Invoice( repo )
{
Amount = 10,
AmountPaid = 0,
Payments = new List<Payment>( ) { new Payment( ) { Amount = 10 } }
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( )
{
Amount = 10
};

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "invoice was already fully paid", result );
}

[Test]
public void ProcessPayment_Should_ReturnPartiallyPaidMessage_When_PartialPaymentExistsAndAmountPaidIsLessThanAmountDue( )
{
var repo = new InvoiceRepository( );
var invoice = new Invoice( repo )
{
Amount = 10,
AmountPaid = 5,
Payments = new List<Payment>
{
new Payment
{
Amount = 5
}
}
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( )
{
Amount = 1
};

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "another partial payment received, still not fully paid", result );
}

[Test]
public void ProcessPayment_Should_ReturnPartiallyPaidMessage_When_NoPartialPaymentExistsAndAmountPaidIsLessThanInvoiceAmount( )
{
var repo = new InvoiceRepository( );
var invoice = new Invoice( repo )
{
Amount = 10,
AmountPaid = 0,
Payments = new List<Payment>( )
};
repo.Add( invoice );

var paymentProcessor = new InvoiceService( repo );

var payment = new Payment( )
{
Amount = 1
};

var result = paymentProcessor.ProcessPayment( payment );

Assert.AreEqual( "invoice is now partially paid", result );
}

}
}
Loading