profileShare

rasmusjy / splitapp-backend-clean-onion

Read-only snapshot

No repository description.

main default branch 429 files Expires Sep 13, 2026, 9:06 AM
SettlementServiceTests.cs 2,554 bytes
1 using App.BLL.Services;
2 using App.Domain;
3 using App.Domain.Contracts;
4 using FluentAssertions;
5 using Moq;
6
7 namespace App.Tests.BLL;
8
9 public class SettlementServiceTests
10 {
11 private readonly Mock<IAppUnitOfWork> _uow = new();
12 private readonly Mock<ITripRepository> _trips = new();
13 private readonly SettlementService _sut;
14
15 public SettlementServiceTests()
16 {
17 _uow.Setup(u => u.Trips).Returns(_trips.Object);
18 _sut = new SettlementService(_uow.Object);
19 }
20
21 [Fact]
22 public async Task CalculateBalancesAsync_WhenTripDoesNotExist_ReturnsEmptyList()
23 {
24 // Arrange
25 var tripId = Guid.NewGuid();
26 _trips.Setup(r => r.GetByIdWithDetailsAsync(tripId)).ReturnsAsync((Trip?)null);
27
28 // Act
29 var result = await _sut.CalculateBalancesAsync(tripId);
30
31 // Assert
32 result.Should().NotBeNull();
33 result.Should().BeEmpty();
34 }
35
36 [Fact]
37 public async Task CalculateBalancesAsync_WhenNoExpenses_ReturnsZeroBalanceForEachParticipant()
38 {
39 // Arrange — edge case: trip exists, has 2 participants, but nobody spent money yet.
40 // Expected: each participant has TotalPaid = 0 and TotalOwed = 0.
41 var tripId = Guid.NewGuid();
42 var userA = Guid.NewGuid();
43 var userB = Guid.NewGuid();
44 var participantsRepo = new Mock<ITripParticipantRepository>();
45 var expensesRepo = new Mock<IExpenseRepository>();
46
47 _uow.Setup(u => u.TripParticipants).Returns(participantsRepo.Object);
48 _uow.Setup(u => u.Expenses).Returns(expensesRepo.Object);
49
50 _trips.Setup(r => r.GetByIdWithDetailsAsync(tripId)).ReturnsAsync(new Trip
51 {
52 Id = tripId,
53 Name = "Test",
54 DefaultCurrency = new Currency { Code = "EUR" }
55 });
56 participantsRepo.Setup(r => r.GetByTripIdAsync(tripId)).ReturnsAsync(new List<TripParticipant>
57 {
58 new() { TripId = tripId, UserId = userA, User = new App.Domain.Identity.AppUser { Id = userA, FirstName = "A", LastName = "A" } },
59 new() { TripId = tripId, UserId = userB, User = new App.Domain.Identity.AppUser { Id = userB, FirstName = "B", LastName = "B" } }
60 });
61 expensesRepo.Setup(r => r.GetByTripIdAsync(tripId)).ReturnsAsync(new List<Expense>());
62
63 // Act
64 var result = await _sut.CalculateBalancesAsync(tripId);
65
66 // Assert
67 result.Should().HaveCount(2);
68 result.Should().OnlyContain(b => b.TotalPaid == 0m && b.TotalOwed == 0m && b.NetBalance == 0m);
69 }
70 }
71