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); } }