using BudgetApp.Data.Entities; using BudgetApp.Data.Repositories; using BudgetApp.Tests.Helpers; using Xunit; namespace BudgetApp.Tests.Services; public class AccountServiceTests { [Fact] public async Task GetAccountsAsync_ReturnsOnlyUserAccounts() { using var factory = new TestDbContextFactory(); using (var ctx = factory.CreateContext()) { ctx.Accounts.AddRange( new Account { Name = "Mine", UserId = TestDbContextFactory.TestUserId }, new Account { Name = "Theirs", UserId = TestDbContextFactory.OtherUserId }); await ctx.SaveChangesAsync(); } using var context = factory.CreateContext(); var service = new AccountRepository(context); var result = await service.GetAccountsAsync(TestDbContextFactory.TestUserId); Assert.Single(result); Assert.Equal("Mine", result[0].Name); } [Fact] public async Task GetAccountsAsync_OrderedByName() { using var factory = new TestDbContextFactory(); using (var ctx = factory.CreateContext()) { ctx.Accounts.AddRange( new Account { Name = "Zebra", UserId = TestDbContextFactory.TestUserId }, new Account { Name = "Alpha", UserId = TestDbContextFactory.TestUserId }); await ctx.SaveChangesAsync(); } using var context = factory.CreateContext(); var service = new AccountRepository(context); var result = await service.GetAccountsAsync(TestDbContextFactory.TestUserId); Assert.Equal("Alpha", result[0].Name); Assert.Equal("Zebra", result[1].Name); } [Fact] public async Task GetAccountAsync_ReturnsMatchingAccount() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Test", UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); var result = await service.GetAccountAsync(accountId, TestDbContextFactory.TestUserId); Assert.NotNull(result); Assert.Equal("Test", result.Name); } [Fact] public async Task GetAccountAsync_WrongUser_ReturnsNull() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Test", UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); var result = await service.GetAccountAsync(accountId, TestDbContextFactory.OtherUserId); Assert.Null(result); } [Fact] public async Task CreateAccountAsync_AddsToDatabase() { using var factory = new TestDbContextFactory(); using var context = factory.CreateContext(); var service = new AccountRepository(context); var account = new Account { Name = "New", UserId = TestDbContextFactory.TestUserId, CurrencyCode = "GBP" }; await service.CreateAccountAsync(account); using var verifyCtx = factory.CreateContext(); Assert.Single(verifyCtx.Accounts); } [Fact] public async Task UpdateBalanceAsync_UpdatesBalance() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Test", CurrentBalance = 100m, UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); await service.UpdateBalanceAsync(accountId, TestDbContextFactory.TestUserId, 250m); using var verifyCtx = factory.CreateContext(); var updated = verifyCtx.Accounts.Single(); Assert.Equal(250m, updated.CurrentBalance); } [Fact] public async Task UpdateBalanceAsync_WrongUser_DoesNothing() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Test", CurrentBalance = 100m, UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); await service.UpdateBalanceAsync(accountId, TestDbContextFactory.OtherUserId, 999m); using var verifyCtx = factory.CreateContext(); Assert.Equal(100m, verifyCtx.Accounts.Single().CurrentBalance); } [Fact] public async Task UpdateAccountDetailsAsync_UpdatesFields() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Old", Color = "#000", CurrencyCode = "GBP", UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); await service.UpdateAccountDetailsAsync(accountId, TestDbContextFactory.TestUserId, "New", "#fff", "USD"); using var verifyCtx = factory.CreateContext(); var updated = verifyCtx.Accounts.Single(); Assert.Equal("New", updated.Name); Assert.Equal("#fff", updated.Color); Assert.Equal("USD", updated.CurrencyCode); } [Fact] public async Task UpdateAccountDetailsAsync_WrongUser_DoesNothing() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Original", Color = "#000", CurrencyCode = "GBP", UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); await service.UpdateAccountDetailsAsync(accountId, TestDbContextFactory.OtherUserId, "Hacked", "#fff", "USD"); using var verifyCtx = factory.CreateContext(); Assert.Equal("Original", verifyCtx.Accounts.Single().Name); } [Fact] public async Task DeleteAccountAsync_RemovesAccount() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "ToDelete", UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); await service.DeleteAccountAsync(accountId, TestDbContextFactory.TestUserId); using var verifyCtx = factory.CreateContext(); Assert.Empty(verifyCtx.Accounts); } [Fact] public async Task DeleteAccountAsync_WrongUser_DoesNothing() { using var factory = new TestDbContextFactory(); int accountId; using (var ctx = factory.CreateContext()) { var account = new Account { Name = "Protected", UserId = TestDbContextFactory.TestUserId }; ctx.Accounts.Add(account); await ctx.SaveChangesAsync(); accountId = account.Id; } using var context = factory.CreateContext(); var service = new AccountRepository(context); await service.DeleteAccountAsync(accountId, TestDbContextFactory.OtherUserId); using var verifyCtx = factory.CreateContext(); Assert.Single(verifyCtx.Accounts); } }