feat: add recurring places and transaction pagination
Build MoneyMap image / build-and-push (push) Failing after 4s

This commit is contained in:
aj
2026-08-17 06:42:08 -04:00
parent 2356b7d5c9
commit 1cc0a355f2
175 changed files with 34411 additions and 34039 deletions
+188 -188
View File
@@ -1,188 +1,188 @@
using MoneyMap.Models;
using MoneyMap.Services;
using MoneyMap.Tests.TestHelpers;
namespace MoneyMap.Tests.Services;
public class MerchantServiceTests
{
[Fact]
public async Task GetOrCreateAsync_CreatesNewMerchant_WhenDoesNotExist()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
// Act
var result = await service.GetOrCreateAsync("Walmart");
// Assert
Assert.NotNull(result);
Assert.Equal("Walmart", result.Name);
Assert.Single(context.Merchants);
}
[Fact]
public async Task GetOrCreateAsync_ReturnsExistingMerchant_WhenExists()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var existingMerchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(existingMerchant);
await context.SaveChangesAsync();
// Act
var result = await service.GetOrCreateAsync("Walmart");
// Assert
Assert.NotNull(result);
Assert.Equal(1, result.Id);
Assert.Single(context.Merchants);
}
[Fact]
public async Task GetAllMerchantsWithStatsAsync_ReturnsMerchantsWithStats()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var account = new Account
{
Id = 1,
Institution = "Test Bank",
AccountType = AccountType.Checking,
Last4 = "1234",
Owner = "Test Owner"
};
context.Accounts.Add(account);
var merchant1 = new Merchant { Id = 1, Name = "Walmart" };
var merchant2 = new Merchant { Id = 2, Name = "Target" };
context.Merchants.AddRange(merchant1, merchant2);
var transaction = new Transaction
{
Date = DateTime.Now,
Amount = -50.00m,
Name = "Test",
Memo = "Test",
AccountId = 1,
MerchantId = 1
};
context.Transactions.Add(transaction);
await context.SaveChangesAsync();
// Act
var result = await service.GetAllMerchantsWithStatsAsync();
// Assert
Assert.Equal(2, result.Count);
var walmart = result.First(m => m.Name == "Walmart");
Assert.Equal(1, walmart.TransactionCount);
var target = result.First(m => m.Name == "Target");
Assert.Equal(0, target.TransactionCount);
}
[Fact]
public async Task UpdateMerchantAsync_SuccessfullyUpdatesName()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var merchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(merchant);
await context.SaveChangesAsync();
// Act
var result = await service.UpdateMerchantAsync(1, "Walmart Supercenter");
// Assert
Assert.True(result.Success);
var updated = await context.Merchants.FindAsync(1);
Assert.Equal("Walmart Supercenter", updated!.Name);
}
[Fact]
public async Task UpdateMerchantAsync_FailsWhenDuplicateName()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var merchant1 = new Merchant { Id = 1, Name = "Walmart" };
var merchant2 = new Merchant { Id = 2, Name = "Target" };
context.Merchants.AddRange(merchant1, merchant2);
await context.SaveChangesAsync();
// Act
var result = await service.UpdateMerchantAsync(1, "Target");
// Assert
Assert.False(result.Success);
Assert.Contains("already exists", result.Message);
}
[Fact]
public async Task DeleteMerchantAsync_SuccessfullyDeletes()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var merchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(merchant);
await context.SaveChangesAsync();
// Act
var result = await service.DeleteMerchantAsync(1);
// Assert
Assert.True(result.Success);
Assert.Empty(context.Merchants);
}
[Fact]
public async Task DeleteMerchantAsync_ReportsTransactionAndMappingCounts()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var account = new Account
{
Id = 1,
Institution = "Test Bank",
AccountType = AccountType.Checking,
Last4 = "1234",
Owner = "Test Owner"
};
context.Accounts.Add(account);
var merchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(merchant);
var transaction = new Transaction
{
Date = DateTime.Now,
Amount = -50.00m,
Name = "Test",
Memo = "Test",
AccountId = 1,
MerchantId = 1
};
context.Transactions.Add(transaction);
await context.SaveChangesAsync();
// Act
var result = await service.DeleteMerchantAsync(1);
// Assert
Assert.True(result.Success);
Assert.Equal(1, result.TransactionCount);
Assert.Contains("1 transaction", result.Message);
}
}
using MoneyMap.Models;
using MoneyMap.Services;
using MoneyMap.Tests.TestHelpers;
namespace MoneyMap.Tests.Services;
public class MerchantServiceTests
{
[Fact]
public async Task GetOrCreateAsync_CreatesNewMerchant_WhenDoesNotExist()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
// Act
var result = await service.GetOrCreateAsync("Walmart");
// Assert
Assert.NotNull(result);
Assert.Equal("Walmart", result.Name);
Assert.Single(context.Merchants);
}
[Fact]
public async Task GetOrCreateAsync_ReturnsExistingMerchant_WhenExists()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var existingMerchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(existingMerchant);
await context.SaveChangesAsync();
// Act
var result = await service.GetOrCreateAsync("Walmart");
// Assert
Assert.NotNull(result);
Assert.Equal(1, result.Id);
Assert.Single(context.Merchants);
}
[Fact]
public async Task GetAllMerchantsWithStatsAsync_ReturnsMerchantsWithStats()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var account = new Account
{
Id = 1,
Institution = "Test Bank",
AccountType = AccountType.Checking,
Last4 = "1234",
Owner = "Test Owner"
};
context.Accounts.Add(account);
var merchant1 = new Merchant { Id = 1, Name = "Walmart" };
var merchant2 = new Merchant { Id = 2, Name = "Target" };
context.Merchants.AddRange(merchant1, merchant2);
var transaction = new Transaction
{
Date = DateTime.Now,
Amount = -50.00m,
Name = "Test",
Memo = "Test",
AccountId = 1,
MerchantId = 1
};
context.Transactions.Add(transaction);
await context.SaveChangesAsync();
// Act
var result = await service.GetAllMerchantsWithStatsAsync();
// Assert
Assert.Equal(2, result.Count);
var walmart = result.First(m => m.Name == "Walmart");
Assert.Equal(1, walmart.TransactionCount);
var target = result.First(m => m.Name == "Target");
Assert.Equal(0, target.TransactionCount);
}
[Fact]
public async Task UpdateMerchantAsync_SuccessfullyUpdatesName()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var merchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(merchant);
await context.SaveChangesAsync();
// Act
var result = await service.UpdateMerchantAsync(1, "Walmart Supercenter");
// Assert
Assert.True(result.Success);
var updated = await context.Merchants.FindAsync(1);
Assert.Equal("Walmart Supercenter", updated!.Name);
}
[Fact]
public async Task UpdateMerchantAsync_FailsWhenDuplicateName()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var merchant1 = new Merchant { Id = 1, Name = "Walmart" };
var merchant2 = new Merchant { Id = 2, Name = "Target" };
context.Merchants.AddRange(merchant1, merchant2);
await context.SaveChangesAsync();
// Act
var result = await service.UpdateMerchantAsync(1, "Target");
// Assert
Assert.False(result.Success);
Assert.Contains("already exists", result.Message);
}
[Fact]
public async Task DeleteMerchantAsync_SuccessfullyDeletes()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var merchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(merchant);
await context.SaveChangesAsync();
// Act
var result = await service.DeleteMerchantAsync(1);
// Assert
Assert.True(result.Success);
Assert.Empty(context.Merchants);
}
[Fact]
public async Task DeleteMerchantAsync_ReportsTransactionAndMappingCounts()
{
// Arrange
using var context = DbContextHelper.CreateInMemoryContext();
var service = new MerchantService(context);
var account = new Account
{
Id = 1,
Institution = "Test Bank",
AccountType = AccountType.Checking,
Last4 = "1234",
Owner = "Test Owner"
};
context.Accounts.Add(account);
var merchant = new Merchant { Id = 1, Name = "Walmart" };
context.Merchants.Add(merchant);
var transaction = new Transaction
{
Date = DateTime.Now,
Amount = -50.00m,
Name = "Test",
Memo = "Test",
AccountId = 1,
MerchantId = 1
};
context.Transactions.Add(transaction);
await context.SaveChangesAsync();
// Act
var result = await service.DeleteMerchantAsync(1);
// Assert
Assert.True(result.Success);
Assert.Equal(1, result.TransactionCount);
Assert.Contains("1 transaction", result.Message);
}
}