Example #1
0
        public void TotalAmount_AddNewBudgetItem_ExpectGroupListenerNotified()
        {
            var items = new List <BudgetItem>()
            {
                new BudgetItem("item name", BudgetItemType.Debt, 12.34m)
            };

            var group = new BudgetGroup("test group", budgetItems: items);

            group.AddNewBudgetItem();

            bool wasGroupNotified = false;

            group.PropertyChanged += (o, e) =>
            {
                if (e.PropertyName == nameof(group.TotalAmount))
                {
                    wasGroupNotified = true;
                }
            };

            var newAmount = 99.99m;

            group.BudgetItems.Last().Amount = newAmount;
            wasGroupNotified.Should().BeTrue();
        }
        public void TotalAmount_ChangingItemAmounts_ExpectTotalAmountChangedEvent()
        {
            // Create group with budget items
            List <BudgetItem> items = new List <BudgetItem>()
            {
                new BudgetItem("test item 1"),
                new BudgetItem("test item 2"),
                new BudgetItem("test item 3")
            };
            var group = new BudgetGroup("Housing", budgetItems: items);
            BudgetGroupViewModel viewModel = new BudgetGroupViewModel(group);

            bool wasChanged = false;

            viewModel.PropertyChanged += (o, e) =>
            {
                if (e.PropertyName == nameof(viewModel.TotalAmount))
                {
                    wasChanged = true;
                }
            };

            // TEST: changing item amounts should trigger property changed
            group.BudgetItems[1].Amount = 234.56m;

            // Validate event and final value
            wasChanged.Should().BeTrue();
            viewModel.TotalAmount.Should().Be(group.TotalAmount.ToCurrencyString());
        }
Example #3
0
        public async Task DeleteBudgetGroupByIdForUserAsync(int budgetGroupId)
        {
            BudgetGroup budgetGroup = await _context.BudgetGroups.FindAsync(budgetGroupId);

            _context.BudgetGroups.Remove(budgetGroup);
            await _context.SaveChangesAsync();
        }
        public async Task <ActionResult <BudgetGroupDto> > GetBudgetGroupForUser(int budgetGroupId)
        {
            string email = HttpContext.User.RetrieveEmailFromClaimsPrincipal();

            User user = await _userManager.Users.FirstOrDefaultAsync(u => u.Email == email);

            if (user == null)
            {
                _logger.LogError($"Unable to find User with the email '{email}'.");
                return(NotFound());
            }

            int userId = user.Id;

            bool budgetGroupExistsForUser = await _repo.BudgetGroupByIdForUserExists(budgetGroupId, userId);

            if (!budgetGroupExistsForUser)
            {
                _logger.LogError($"Unable to find BudgetGroup with the BudgetGroupId '{budgetGroupId}' for user with the user Id '{userId}'.");
                return(NotFound());
            }

            BudgetGroup budgetGroup = await _repo.GetBudgetGroupByIdForUserAsync(budgetGroupId, userId);

            _logger.LogInformation($"Returned BudgetGroup with the BudgetGroupId '{budgetGroupId}'from the user with user Id '{userId}'.");
            return(Ok(_mapper.Map <BudgetGroupDto>(budgetGroup)));
        }
        public async Task <ActionResult> DeleteBudgetGroup(int budgetGroupId)
        {
            string email = HttpContext.User.RetrieveEmailFromClaimsPrincipal();

            User user = await _userManager.Users.FirstOrDefaultAsync(u => u.Email == email);

            if (user == null)
            {
                _logger.LogError($"Unable to find User with the email '{email}'.");
                return(NotFound());
            }

            int userId = user.Id;

            BudgetGroup budgetGroup = await _repo.GetBudgetGroupByIdForUserAsync(budgetGroupId, userId);

            if (budgetGroup == null)
            {
                _logger.LogError($"Unable to find BudgetGroup with the BudgetGroupId '{budgetGroupId}' for user with the user Id '{userId}'.");
                return(NotFound());
            }

            await _repo.DeleteBudgetGroupByIdForUserAsync(budgetGroupId);

            BudgetGroupDto budgetGroupDto = _mapper.Map <BudgetGroupDto>(budgetGroup);

            _logger.LogInformation($"Deleted BudgetGroup with the BudgetGroupId '{budgetGroupId}' for user with the user Id '{userId}'.");
            return(NoContent());
        }
        public void Constructor_UnrecognizedBudgetGroup_ThrowsException()
        {
            var    groupName  = "an unknown group";
            var    group      = new BudgetGroup(groupName);
            Action testAction = () => new BudgetGroupViewModel(group);

            testAction.Should().Throw <ArgumentException>().WithMessage($"*{groupName}*");
        }
        internal bool IsRemoteBudgetItemUsedInProfile(BudgetGroup profileGroup, RemoteBudget.RemoteBudgetItem remoteItem)
        {
            // Search for matching items in the profile
            var profileItem = profileGroup.BudgetItems.Where(i => i.Name == remoteItem.Label).FirstOrDefault();

            // Only count populated budget items with non-zero values as having been used
            return(profileItem != null && profileItem.Amount != 0m);
        }
Example #8
0
        private void AddIncome()
        {
            BudgetGroup budgetGroup = BudgetGroup.TotalIncome;

            AddBudgetItem(FinanceCategory.IDS, budgetGroup, 6047.48m);
            AddBudgetItem(FinanceCategory.ChildSupport, budgetGroup, 198.00m);
            AddBudgetItem(BudgetGroup.Label, "Total Income");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #9
0
        private void AddOtherExpenses()
        {
            BudgetGroup budgetGroup = BudgetGroup.OtherExpenses;

            AddBudgetItem(BudgetGroup.Label, "Other Expenses");
            AddBudgetItem(FinanceCategory.OtherExpenses, budgetGroup, 0m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #10
0
        private void AddSavings()
        {
            BudgetGroup budgetGroup = BudgetGroup.Savings;

            AddBudgetItem(BudgetGroup.Label, "Savings");
            AddBudgetItem(FinanceCategory.EmergencyFund, budgetGroup, 100.00m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #11
0
        public void AddNewBudgetItem_ExpectNewNameOnEachAddition()
        {
            var group            = new BudgetGroup("test group");
            var firstNewItemName = group.NewBudgetItemName;

            group.AddNewBudgetItem();

            group.NewBudgetItemName.Should().NotBe(firstNewItemName);
        }
Example #12
0
        internal BudgetItem(FinanceCategory category, BudgetGroup group, decimal plannedAmount)
        {
            Category      = category;
            PlannedAmount = plannedAmount;
            SpentAmount   = 0;

            Group = group;

            Header = String.Empty;
        }
Example #13
0
        private void AddDebt()
        {
            BudgetGroup budgetGroup = BudgetGroup.Debt;

            AddBudgetItem(BudgetGroup.Label, "Debt");
            AddBudgetItem(FinanceCategory.CreditCard, budgetGroup, 100.00m);
            AddBudgetItem(FinanceCategory.CreditCardChildSupport, budgetGroup, 200.00m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #14
0
        private void AddGroceriesandEatingOut()
        {
            BudgetGroup budgetGroup = BudgetGroup.GroceriesAndEatingOut;

            AddBudgetItem(BudgetGroup.Label, "Groceries and Eating Out");
            AddBudgetItem(FinanceCategory.Groceries, budgetGroup, 370.00m);
            AddBudgetItem(FinanceCategory.EatingOut, budgetGroup, 100.00m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #15
0
        public async Task AddBudgetGroupForUserAsync(BudgetGroup budgetGroup)
        {
            if (budgetGroup == null)
            {
                throw new ArgumentNullException(nameof(budgetGroup));
            }

            _context.BudgetGroups.Add(budgetGroup);
            await _context.SaveChangesAsync();
        }
Example #16
0
        private void AddGiving()
        {
            BudgetGroup budgetGroup = BudgetGroup.Giving;

            AddBudgetItem(BudgetGroup.Label, "Giving");
            AddBudgetItem(FinanceCategory.Tithing, budgetGroup, 912.12m);
            AddBudgetItem(FinanceCategory.FastOfferings, budgetGroup, 40.00m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #17
0
        public BudgetGroupViewModel(BudgetGroup budgetGroup)
        {
            BudgetGroup  = budgetGroup ?? throw new ArgumentNullException(nameof(budgetGroup));
            presentation = BudgetGroupPresentationBuilder.Build(budgetGroup);

            budgetGroup.BudgetItems.ToList().ForEach(item => AddBudgetItemViewModel(item));
            budgetGroup.BudgetItems.CollectionChanged += BudgetItemsChanged;

            budgetGroup.PropertyChanged += (o, e) => PropertyChanged?.Invoke(this, e); // NOTE: this only works as the names in this VM are the same as the model
        }
Example #18
0
        public void CollectionOfBudgetItems_CalculateTotal_ExpectRightAmount()
        {
            var budgetItems = new List <BudgetItem>
            {
                new BudgetItem("income_1", "paycheck1", 100, BudgetItemType.Income),
                new BudgetItem("income_2", "paycheck2", 300, BudgetItemType.Income),
            };
            var budgetGroup = new BudgetGroup("id", "Income", budgetItems: budgetItems);

            budgetGroup.TotalAmount.Should().Be(400);
        }
Example #19
0
        private void AddTransportation()
        {
            BudgetGroup budgetGroup = BudgetGroup.Transportation;

            AddBudgetItem(BudgetGroup.Label, "Transportation");
            AddBudgetItem(FinanceCategory.Gas, budgetGroup, 180.00m);
            AddBudgetItem(FinanceCategory.CarMaintenance, budgetGroup, 20.00m);
            AddBudgetItem(FinanceCategory.CarPayment, budgetGroup, 660.00m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #20
0
        private void AddStreaming()
        {
            BudgetGroup budgetGroup = BudgetGroup.Streaming;

            AddBudgetItem(BudgetGroup.Label, "Streaming");
            AddBudgetItem(FinanceCategory.Netflix, budgetGroup, 10.67m);
            AddBudgetItem(FinanceCategory.Hulu, budgetGroup, 11.99m);
            AddBudgetItem(FinanceCategory.AmazonPrime, budgetGroup, 8.25m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #21
0
        private void AddInsuranceAndTax()
        {
            BudgetGroup budgetGroup = BudgetGroup.InsuranceAndTax;

            AddBudgetItem(BudgetGroup.Label, "Insurance & Tax");
            AddBudgetItem(FinanceCategory.LifeInsurance, budgetGroup, 80.48m);
            AddBudgetItem(FinanceCategory.AutoInsurance, budgetGroup, 86.10m);
            AddBudgetItem(FinanceCategory.HouseInsurance, budgetGroup, 0.00m);
            AddBudgetItem(BudgetGroup.Label, "Total");
            AddBudgetItem(BudgetGroup.EmptyLine, "EmptyLine1");
        }
Example #22
0
 public BudgetGroupViewModel(BudgetGroup budgetGroup)
 {
     BudgetGroup  = budgetGroup;
     presentation = new BudgetGroupPresentation();
     budgetGroup.BudgetItems.CollectionChanged += BudgetItemChanged;
     budgetGroup.BudgetItems.ToList().ForEach(item =>
     {
         var viewModel = new BudgetItemViewModel(item);
         BudgetItems.Add(viewModel);
     });
     budgetGroup.PropertyChanged += (o, e) => PropertyChanged?.Invoke(this, e);
 }
Example #23
0
        public void AddNewBudgetItem_ExpectAddedWithDefaultValues()
        {
            var expectedType = BudgetItemType.Debt;
            var group        = new BudgetGroup("test group", defaultItemType: expectedType);
            var expectedName = group.NewBudgetItemName;

            group.AddNewBudgetItem();

            group.BudgetItems.Count().Should().Be(1);
            group.BudgetItems.Last().Name.Should().Be(expectedName);
            group.BudgetItems.Last().Type.Should().Be(expectedType);
        }
        public static BudgetGroupPresentation Build(BudgetGroup group)
        {
            if (group == null)
            {
                throw new ArgumentNullException(nameof(group));
            }

            var budget = BudgetBuilder.Build();

            // TODO: a map pattern may be helpful here instead of the long if/if else/else, with names or other id as constants
            if (group.Name == budget.IncomeGroup.Name)
            {
                return(IncomeGroupPresentation);
            }

            if (@group.Name == budget.HousingGroup.Name)
            {
                return(HousingGroupPresentation);
            }

            if (@group.Name == budget.TransportationGroup.Name)
            {
                return(TransportationGroupPresentation);
            }

            if (@group.Name == budget.FoodGroup.Name)
            {
                return(FoodGroupPresentation);
            }

            if (@group.Name == budget.PersonalGroup.Name)
            {
                return(PersonalGroupPresentation);
            }

            if (@group.Name == budget.DebtGroup.Name)
            {
                return(DebtGroupPresentation);
            }

            if (@group.Name == budget.GivingGroup.Name)
            {
                return(GivingGroupPresentation);
            }

            if (@group.Name == budget.BasicExpensesDisplayGroup.Name)
            {
                return(BasicExpensesDisplayGroup);
            }

            throw new ArgumentException($"Group `{@group.Name}` was not in budget or does not have a presentation");
        }
Example #25
0
        public void Constructor_ValidateParameters_ExpectAssignment()
        {
            var budgetItems = new List <BudgetItem> {
                new BudgetItem("id", "name", 100.3m, BudgetItemType.Income)
            };
            var presentation = new BudgetGroupPresentation();

            var budgetGroup = new BudgetGroup("id", "name", budgetItems: budgetItems);

            budgetGroup.Id.Should().Be("id");
            budgetGroup.Name.Should().Be("name");
            budgetGroup.BudgetItems.Should().BeEquivalentTo(budgetItems);
        }
        public void AddNewBudgetItem_ExpectNewItemInViewModel()
        {
            // Create a group and view model with no budget items
            var group = new BudgetGroup("Housing");
            BudgetGroupViewModel viewModel = new BudgetGroupViewModel(group);

            // TEST: add new item from the view model
            viewModel.AddNewBudgetItem();

            // Confirm a new budget item as created in the backing group, and in the view model
            group.BudgetItems.Count.Should().Be(1);
            viewModel.BudgetItems.Count.Should().Be(1);
            viewModel.BudgetItems[0].BudgetItem.Should().Be(group.BudgetItems[0]);
        }
        public void IsTotalAmountZero_NonZeroItemAmounts_ExpectFalse()
        {
            // Create group with budget items
            List <BudgetItem> items = new List <BudgetItem>()
            {
                new BudgetItem("test item 1"),
                new BudgetItem("test item 2", amount: 123.45m),
                new BudgetItem("test item 3")
            };
            var group = new BudgetGroup("Housing", budgetItems: items);

            // TEST: a view model representing a group with all zero items
            BudgetGroupViewModel viewModel = new BudgetGroupViewModel(group);

            viewModel.IsTotalAmountZero.Should().BeFalse();
        }
Example #28
0
        protected override async Task OnInitializedAsync()
        {
            _id = 0;
            if (Int32.TryParse(Id, out _id) && (_id > 0))
            {
                IsCreateMode = false;
            }

            if (IsCreateMode)
            {
                Model = new BudgetGroup();
            }
            else
            {
                Model = await _budgetGroupsDataService.Get(id : _id, includeRelated : false);
            }
        }
Example #29
0
        public void Constructor_ValidParams_ExpectAssignment()
        {
            string            name        = "test group name";
            BudgetItemType    defaultType = BudgetItemType.Expense;
            List <BudgetItem> items       = new List <BudgetItem>()
            {
                new BudgetItem("test item 1"),
                new BudgetItem("test item 2", BudgetItemType.Debt, 12.34m)
            };

            var group = new BudgetGroup(name, defaultType, items);

            group.DefaultItemType.Should().Be(defaultType);
            group.Name.Should().Be(name);
            group.BudgetItems.Should().BeEquivalentTo(items);
            group.TotalAmount.Should().Be(items.Sum(x => x.Amount));
        }
Example #30
0
        public void Constructor_ValidParameter_PresentationSetupCorrectly(string id, string groupName)
        {
            var group = new BudgetGroup(id, groupName);
            var expectedPresentation = BudgetGroupPresentationBuilder.IncomeGroupPresentation;

            if (groupName == Constants.Housing)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.HousingGroupPresentation;
            }

            if (groupName == Constants.Transportation)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.TransportationGroupPresentation;
            }

            if (groupName == Constants.Food)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.FoodGroupPresentation;
            }

            if (groupName == Constants.Personal)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.PersonalGroupPresentation;
            }

            if (groupName == Constants.Debt)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.DebtGroupPresentation;
            }

            if (groupName == Constants.Giving)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.GivingGroupPresentation;
            }

            if (groupName == Constants.BasicExpenses)
            {
                expectedPresentation = BudgetGroupPresentationBuilder.BasicExpensesDisplayGroup;
            }

            // TEST: Construct a view model
            var presentation = BudgetGroupPresentationBuilder.Build(group);

            presentation.Should().BeEquivalentTo(expectedPresentation);
        }