Skip to content

Commit

Permalink
Add tests for TransactionService #237
Browse files Browse the repository at this point in the history
  • Loading branch information
Spacelord-XaN committed Feb 5, 2024
1 parent e1354cf commit 35d92cb
Show file tree
Hide file tree
Showing 6 changed files with 325 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,12 @@ public async Task CreatesSaleTransactionWithoutDocument(BasarEntity basar, DateT
saleFromDb.Seller.Should().BeNull();
saleFromDb.SellerId.Should().BeNull();
saleFromDb.TimeStamp.Should().Be(timestamp);
saleFromDb.Type.Should().Be(TransactionType.Sale);
saleFromDb.Products.Should().AllSatisfy(pt =>
{
pt.Product.StorageState.Should().Be(StorageState.Sold);
pt.Product.ValueState.Should().Be(ValueState.NotSettled);
});
}

A.CallTo(() => NumberService.NextNumberAsync(basar.Id, TransactionType.Sale)).MustHaveHappenedOnceExactly();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
namespace BraunauMobil.VeloBasar.Tests.BusinessLogic.TransactionServiceTests;

public class GetProductsToCancelAsync
: TestBase
{
[Theory]
[VeloAutoData]
public async Task ShouldReturnProductsWhereCancellationIsAllowed(TransactionEntity transaction)
{
// Arrange
ProductEntity[] productsToCancel = Fixture.BuildProduct()
.With(product => product.StorageState, StorageState.Sold)
.With(product => product.ValueState, ValueState.NotSettled)
.CreateMany().ToArray();
Fixture.ExcludeEnumValues(StorageState.Sold);
Fixture.ExcludeEnumValues(ValueState.NotSettled);
ProductEntity[] otherProducts = Fixture.CreateMany<ProductEntity>().ToArray();

foreach (ProductEntity product in productsToCancel)
{
transaction.Products.Add(new ProductToTransactionEntity { Product = product, Transaction = transaction });
}
foreach (ProductEntity product in otherProducts)
{
transaction.Products.Add(new ProductToTransactionEntity { Product = product, Transaction = transaction });
}
Db.Transactions.Add(transaction);
await Db.SaveChangesAsync();

// Act
IReadOnlyList<ProductEntity> result = await Sut.GetProductsToCancelAsync(transaction.Id);

// Assert
result.Should().BeEquivalentTo(productsToCancel);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using Xan.AspNetCore.EntityFrameworkCore;

namespace BraunauMobil.VeloBasar.Tests.BusinessLogic.TransactionServiceTests;

public class LockAsync
: TestBase
{
[Theory]
[VeloAutoData]
public async Task AvailbleAndSettled_ShouldLock(AcceptSessionEntity acceptSession, ProductEntity product, DateTime timestamp, int number, string notes)
{
// Arrange
product.StorageState = StorageState.Available;
product.ValueState = ValueState.NotSettled;
acceptSession.Products.Add(product);
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

Clock.Now = timestamp;
A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.Lock)).Returns(number);

// Act
int result = await Sut.LockAsync(acceptSession.Basar.Id, notes, product.Id);

// Assert
TransactionEntity lockFromDb = await Db.Transactions.FirstByIdAsync(result);
using (new AssertionScope())
{
lockFromDb.Basar.Should().BeEquivalentTo(acceptSession.Basar);
lockFromDb.BasarId.Should().Be(acceptSession.Basar.Id);
lockFromDb.CanCancel.Should().BeFalse();
lockFromDb.CanHasDocument.Should().BeFalse();
lockFromDb.Change.Should().BeNull();
lockFromDb.ChildTransactions.Should().BeEmpty();
lockFromDb.DocumentId.Should().BeNull();
lockFromDb.NeedsStatusPush.Should().BeFalse();
lockFromDb.Number.Should().Be(number);
lockFromDb.Notes.Should().Be(notes);
lockFromDb.ParentTransaction.Should().BeNull();
lockFromDb.ParentTransactionId.Should().BeNull();
lockFromDb.Products.Should().HaveCount(1);
lockFromDb.Seller.Should().BeNull();
lockFromDb.SellerId.Should().BeNull();
lockFromDb.TimeStamp.Should().Be(timestamp);
lockFromDb.Type.Should().Be(TransactionType.Lock);
ProductEntity productFromDb = lockFromDb.Products.First().Product;
productFromDb.Should().BeEquivalentTo(product);
productFromDb.StorageState.Should().Be(StorageState.Locked);
productFromDb.ValueState.Should().Be(ValueState.NotSettled);
}

A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.Lock)).MustHaveHappenedOnceExactly();
}

[Theory]
[VeloAutoData]
public async Task NotAvailbleAndNotSettled_ShouldNotBeLocked(AcceptSessionEntity acceptSession, string notes)
{
// Arrange
Fixture.ExcludeEnumValues(StorageState.Available);
Fixture.ExcludeEnumValues(ValueState.NotSettled);
ProductEntity product = Fixture.Create<ProductEntity>();
acceptSession.Products.Add(product);
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

// Act
Func<Task<int>> act = async () => await Sut.LockAsync(acceptSession.Basar.Id, notes, product.Id);

// Assert
await act.Should().ThrowAsync<InvalidOperationException>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
using Xan.AspNetCore.EntityFrameworkCore;

namespace BraunauMobil.VeloBasar.Tests.BusinessLogic.TransactionServiceTests;

public class SetLostAsync
: TestBase
{
[Theory]
[VeloAutoData]
public async Task AvailbleAndSettled_ShouldSetLost(AcceptSessionEntity acceptSession, ProductEntity product, DateTime timestamp, int number, string notes)
{
// Arrange
product.StorageState = StorageState.Available;
product.ValueState = ValueState.NotSettled;
acceptSession.Products.Add(product);
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

Clock.Now = timestamp;
A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.SetLost)).Returns(number);

// Act
int result = await Sut.SetLostAsync(acceptSession.Basar.Id, notes, product.Id);

// Assert
TransactionEntity setLostFromDb = await Db.Transactions.FirstByIdAsync(result);
using (new AssertionScope())
{
setLostFromDb.Basar.Should().BeEquivalentTo(acceptSession.Basar);
setLostFromDb.BasarId.Should().Be(acceptSession.Basar.Id);
setLostFromDb.CanCancel.Should().BeFalse();
setLostFromDb.CanHasDocument.Should().BeFalse();
setLostFromDb.Change.Should().BeNull();
setLostFromDb.ChildTransactions.Should().BeEmpty();
setLostFromDb.DocumentId.Should().BeNull();
setLostFromDb.NeedsStatusPush.Should().BeFalse();
setLostFromDb.Number.Should().Be(number);
setLostFromDb.Notes.Should().Be(notes);
setLostFromDb.ParentTransaction.Should().BeNull();
setLostFromDb.ParentTransactionId.Should().BeNull();
setLostFromDb.Products.Should().HaveCount(1);
setLostFromDb.Seller.Should().BeNull();
setLostFromDb.SellerId.Should().BeNull();
setLostFromDb.TimeStamp.Should().Be(timestamp);
setLostFromDb.Type.Should().Be(TransactionType.SetLost);
ProductEntity productFromDb = setLostFromDb.Products.First().Product;
productFromDb.Should().BeEquivalentTo(product);
productFromDb.StorageState.Should().Be(StorageState.Lost);
productFromDb.ValueState.Should().Be(ValueState.NotSettled);
}

A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.SetLost)).MustHaveHappenedOnceExactly();
}

[Theory]
[VeloAutoData]
public async Task NotAvailbleAndNotSettled_ShouldNotBeSetLosted(AcceptSessionEntity acceptSession, string notes)
{
// Arrange
Fixture.ExcludeEnumValues(StorageState.Available);
Fixture.ExcludeEnumValues(ValueState.NotSettled);
ProductEntity product = Fixture.Create<ProductEntity>();
acceptSession.Products.Add(product);
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

// Act
Func<Task<int>> act = async () => await Sut.SetLostAsync(acceptSession.Basar.Id, notes, product.Id);

// Assert
await act.Should().ThrowAsync<InvalidOperationException>();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
using Xan.AspNetCore.EntityFrameworkCore;
using Xan.AspNetCore.Mvc.Abstractions;

namespace BraunauMobil.VeloBasar.Tests.BusinessLogic.TransactionServiceTests;

public class SettleAsync
: TestBase
{
[Theory]
[VeloAutoData]
public async Task ShouldSettleProducts(AcceptSessionEntity acceptSession, ProductEntity[] products, DateTime timestamp, int number)
{
// Arrange
foreach (ProductEntity product in products)
{
product.StorageState = StorageState.Available;
product.ValueState = ValueState.NotSettled;
acceptSession.Products.Add(product);
}
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

Clock.Now = timestamp;
A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.Settlement)).Returns(number);
A.CallTo(() => StatusPushService.IsEnabled).Returns(true);
A.CallTo(() => StatusPushService.PushSellerAsync(acceptSession.Basar.Id, acceptSession.Seller.Id)).DoesNothing();

// Act
int result = await Sut.SettleAsync(acceptSession.Basar.Id, acceptSession.Seller.Id, products.Ids());

// Assert
TransactionEntity settlementFromDb = await Db.Transactions.FirstByIdAsync(result);
using (new AssertionScope())
{
settlementFromDb.Basar.Should().BeEquivalentTo(acceptSession.Basar);
settlementFromDb.BasarId.Should().Be(acceptSession.Basar.Id);
settlementFromDb.CanCancel.Should().BeFalse();
settlementFromDb.CanHasDocument.Should().BeTrue();
settlementFromDb.Change.Should().BeNull();
settlementFromDb.ChildTransactions.Should().BeEmpty();
settlementFromDb.DocumentId.Should().BeNull();
settlementFromDb.NeedsStatusPush.Should().BeTrue();
settlementFromDb.Number.Should().Be(number);
settlementFromDb.Notes.Should().BeNull();
settlementFromDb.ParentTransaction.Should().BeNull();
settlementFromDb.ParentTransactionId.Should().BeNull();
settlementFromDb.Seller.Should().Be(acceptSession.Seller);
settlementFromDb.SellerId.Should().Be(acceptSession.Seller.Id);
settlementFromDb.TimeStamp.Should().Be(timestamp);
settlementFromDb.Type.Should().Be(TransactionType.Settlement);
settlementFromDb.Products.Select(pt => pt.Product).Should().BeEquivalentTo(products);
settlementFromDb.Products.Should().AllSatisfy(pt =>
{
pt.Product.StorageState.Should().Be(StorageState.Available);
pt.Product.ValueState.Should().Be(ValueState.Settled);
});
}

A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.Settlement)).MustHaveHappenedOnceExactly();
A.CallTo(() => StatusPushService.IsEnabled).MustHaveHappenedOnceExactly();
A.CallTo(() => StatusPushService.PushSellerAsync(acceptSession.Basar.Id, acceptSession.Seller.Id)).MustHaveHappenedOnceExactly();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
using Xan.AspNetCore.EntityFrameworkCore;

namespace BraunauMobil.VeloBasar.Tests.BusinessLogic.TransactionServiceTests;

public class UnlockAsync
: TestBase
{
[Theory]
[VeloInlineAutoData(StorageState.Locked)]
[VeloInlineAutoData(StorageState.Lost)]
public async Task ShouldUnlock(StorageState storageState, AcceptSessionEntity acceptSession, ProductEntity product, DateTime timestamp, int number, string notes)
{
// Arrange
product.StorageState = storageState;
product.ValueState = ValueState.NotSettled;
acceptSession.Products.Add(product);
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

Clock.Now = timestamp;
A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.Unlock)).Returns(number);

// Act
int result = await Sut.UnlockAsync(acceptSession.Basar.Id, notes, product.Id);

// Assert
TransactionEntity setLostFromDb = await Db.Transactions.FirstByIdAsync(result);
using (new AssertionScope())
{
setLostFromDb.Basar.Should().BeEquivalentTo(acceptSession.Basar);
setLostFromDb.BasarId.Should().Be(acceptSession.Basar.Id);
setLostFromDb.CanCancel.Should().BeFalse();
setLostFromDb.CanHasDocument.Should().BeFalse();
setLostFromDb.Change.Should().BeNull();
setLostFromDb.ChildTransactions.Should().BeEmpty();
setLostFromDb.DocumentId.Should().BeNull();
setLostFromDb.NeedsStatusPush.Should().BeFalse();
setLostFromDb.Number.Should().Be(number);
setLostFromDb.Notes.Should().Be(notes);
setLostFromDb.ParentTransaction.Should().BeNull();
setLostFromDb.ParentTransactionId.Should().BeNull();
setLostFromDb.Products.Should().HaveCount(1);
setLostFromDb.Seller.Should().BeNull();
setLostFromDb.SellerId.Should().BeNull();
setLostFromDb.TimeStamp.Should().Be(timestamp);
setLostFromDb.Type.Should().Be(TransactionType.Unlock);
ProductEntity productFromDb = setLostFromDb.Products.First().Product;
productFromDb.Should().BeEquivalentTo(product);
productFromDb.StorageState.Should().Be(StorageState.Available);
productFromDb.ValueState.Should().Be(ValueState.NotSettled);
}

A.CallTo(() => NumberService.NextNumberAsync(acceptSession.Basar.Id, TransactionType.Unlock)).MustHaveHappenedOnceExactly();
}

[Theory]
[VeloAutoData]
public async Task ShouldNotUnlock(AcceptSessionEntity acceptSession, string notes)
{
// Arrange
Fixture.ExcludeEnumValues(StorageState.Lost, StorageState.Locked);
Fixture.ExcludeEnumValues(ValueState.NotSettled);
ProductEntity product = Fixture.Create<ProductEntity>();
acceptSession.Products.Add(product);
Db.AcceptSessions.Add(acceptSession);
await Db.SaveChangesAsync();

// Act
Func<Task<int>> act = async () => await Sut.UnlockAsync(acceptSession.Basar.Id, notes, product.Id);

// Assert
await act.Should().ThrowAsync<InvalidOperationException>();
}
}

0 comments on commit 35d92cb

Please sign in to comment.