Exemple #1
0
        public void ShouldThrowExceptionIfndHandlerIsCalledWithTaxCalculationTypesOfNull()
        {
            incomeTaxRepo = A.Fake <IRepository <IncomeTax> >();
            //Arrange

            TaxCalculationType taxCalculationType = new TaxCalculationType {
                ID = 1, Name = "Name", PostCode = "7441"
            };

            var incomeTaxTypeCollection = new List <TaxCalculationType> {
                taxCalculationType
            };


            A.CallTo(() => taxCalculationTypeRepo.GetAllAsync(A <CancellationToken> ._)).ThrowsAsync(x =>
            {
                return(new ArgumentNullException());
            });

            var commandHandler = new CalculateIncomeTaxCommandHandler(taxCalculationTypeRepo, progressiveTaxRepo, incomeTaxRepo);

            //Act
            void action() => commandHandler.Handle(command, cancellationToken).GetAwaiter().GetResult();


            //Assert
            Assert.Throws <ArgumentNullException>(action);
        }
 public void AddCalculatedResult(string postalCode, decimal salary, TaxCalculationType taxCalculationType, decimal taxAmount)
 {
     using (var connection = new SqlConnection(_dbConnection))
     {
         connection.Execute("insert into dbo.[TaxCalculationResult](PostalCode, Salary, TaxCalculationType, TaxAmount)	values(@postalCode, @salary, @taxCalculationType, @taxAmount)", new { postalCode, salary, taxCalculationType, taxAmount });
     }
 }
Exemple #3
0
        public async Task GetByPostalCodeAsync_Should_Return_Mapping()
        {
            //Arrange
            const string             postalCode = "1232";
            const TaxCalculationType expectedCalculationType = TaxCalculationType.PROGRESSIVE_TAX;

            var options = new DbContextOptionsBuilder <ApplicationContext>()
                          .UseInMemoryDatabase(databaseName: nameof(PostalCodeTaxCalculationMappingRepositoryTests) + Guid.NewGuid())
                          .Options;

            await using var context = new ApplicationContext(options);

            var mapping = new PostalCodeCalculationTypeMapping()
            {
                CalculationType = expectedCalculationType,
                PostalCode      = postalCode
            };

            context.PostalCodeCalculationTypeMappings.Add(mapping);
            await context.SaveChangesAsync();

            _repository = new PostalCodeTaxCalculationMappingRepository(context);

            //Act
            PostalCodeCalculationTypeMapping entity = await _repository.GetByPostalCodeAsync(postalCode);

            //Assert
            Assert.AreEqual(postalCode, entity.PostalCode);
            Assert.AreEqual(expectedCalculationType, entity.CalculationType);
        }
Exemple #4
0
        public void GetCalculator_Should_Process_All_Enum_Values([Values] TaxCalculationType calculationType)
        {
            //Act
            var result = _taxCalculator.GetCalculator(calculationType);

            //Assert
            Assert.IsInstanceOf<ITaxCalculator>(result);
        }
Exemple #5
0
 public ITaxCalculator GetCalculator(TaxCalculationType calculationType)
 {
     return(calculationType switch
     {
         TaxCalculationType.FLAT_RATE => new FlatRateCalculator(_flatRateSettingRepository),
         TaxCalculationType.FLAT_VALUE => new FlatValueCalculator(_flatValueSettingRepository),
         TaxCalculationType.PROGRESSIVE_TAX =>
         new ProgressiveTaxCalculator(_progressiveTaxRateSettingRepository),
         _ => throw new NotSupportedException("Calculation type is not supported")
     });
Exemple #6
0
        public static SimpleTaxCalculous InstanceOf(TaxCalculationType type)
        {
            switch (type)
            {
            case TaxCalculationType.SIMPLE:
                return(new SimpleTaxCalculous());

            case TaxCalculationType.COMPLETE:
                return(new CompleteTaxCalculous());
            }
            return(null);
        }
        public ICalculator GetCalculator(TaxCalculationType taxCalculationType)
        {
            switch (taxCalculationType)
            {
            case TaxCalculationType.FlatRate:
                return(new FlatRateCalculator(_taxCalculatorRepository.GetFlatRate()));

            case TaxCalculationType.Progressive:
                return(new ProgressiveCalculator(_taxCalculatorRepository.GetProgressiveTaxTable()));

            case TaxCalculationType.FlatValue:
                return(new FlatValueCalculator(_taxCalculatorRepository.GetFlatValue()));
            }

            throw new CalculatorNotFoundException(taxCalculationType);
        }
Exemple #8
0
        public async Task Calculate_Should_Calculate()
        {
            //Arrange
            const decimal            annualIncome            = 250000;
            const string             postalCode              = "1234";
            const string             expectedTaxYear         = "Tax Year";
            const decimal            expectedTaxAmount       = 234.56M;
            const TaxCalculationType expectedCalculationType = TaxCalculationType.PROGRESSIVE_TAX;
            string expectedCalculationTypeDescription        = expectedCalculationType.GetDescription();

            TaxCalculationRequestModel model = new TaxCalculationRequestModel
            {
                AnnualIncome = annualIncome,
                PostalCode   = postalCode
            };

            TaxCalculationRequest actualManagerRequest = null;

            TaxCalculationResponse managerResponse = new TaxCalculationResponse
            {
                CalculationType = expectedCalculationType,
                TaxAmount       = expectedTaxAmount,
                TaxYear         = expectedTaxYear
            };

            _manager.Setup(r => r.CalculateTax(It.IsAny <TaxCalculationRequest>()))
            .Callback((TaxCalculationRequest r) => actualManagerRequest = r)
            .ReturnsAsync(() => new OperationResult <TaxCalculationResponse>(managerResponse));

            //Act
            var result = await _controller.Calculate(model);

            //Assert
            Assert.IsInstanceOf <OkObjectResult>(result.Result);
            TaxCalculationResponseModel
                responseMode = (TaxCalculationResponseModel)((OkObjectResult)result.Result).Value;

            Assert.AreEqual(expectedCalculationTypeDescription, responseMode.CalculationType);
            Assert.AreEqual(expectedTaxYear, responseMode.TaxYear);
            Assert.AreEqual(expectedTaxAmount, responseMode.TaxAmount);

            _manager.Verify(f => f.CalculateTax(It.IsAny <TaxCalculationRequest>()), Times.Once);
            Assert.AreEqual(annualIncome, actualManagerRequest.AnnualIncome);
            Assert.AreEqual(postalCode, actualManagerRequest.PostalCode);
        }
Exemple #9
0
        public async Task ShouldReturnTheCorrectProgressiveIncomeTax(decimal income, decimal tax)
        {
            //Arrange
            command = new CalculateIncomeTaxCommand {
                AnnualIncome = income, PostCode = "7441"
            };

            IncomeTax incomeTax = new IncomeTax {
                IncomeAmount = income, PostCode = "7441", Tax = tax
            };


            TaxCalculationType taxCalculationType = new TaxCalculationType {
                ID = 1, Name = "Progressive", PostCode = "7441"
            };

            var incomeTaxTypeCollection = new List <TaxCalculationType> {
                taxCalculationType
            };
            var incomeTaxCollection = new List <IncomeTax> {
                incomeTax
            };

            A.CallTo(() => taxCalculationTypeRepo.GetAllAsync(A <CancellationToken> ._)).ReturnsLazily(x =>
            {
                return(Task.FromResult(incomeTaxTypeCollection.AsEnumerable()));
            });


            A.CallTo(() => incomeTaxRepo.GetAllAsync(A <CancellationToken> ._)).ReturnsLazily(x =>
            {
                return(Task.FromResult(incomeTaxCollection.AsEnumerable()));
            });


            var commandHandler = new CalculateIncomeTaxCommandHandler(taxCalculationTypeRepo, progressiveTaxRepo, incomeTaxRepo);
            //Act
            var result = await commandHandler.Handle(command, cancellationToken);

            //Assert
            Assert.AreEqual(incomeTax.IncomeAmount, result.IncomeAmount);
            Assert.AreEqual(incomeTax.PostCode, result.PostCode);
            Assert.AreEqual(incomeTax.Tax, result.Tax);
        }
Exemple #10
0
        public async Task ShouldCallSaveIncomeTax()
        {
            //Arrange
            IncomeTax incomeTax = new IncomeTax {
                IncomeAmount = 20000, PostCode = "7441", Tax = 1000
            };


            TaxCalculationType taxCalculationType = new TaxCalculationType {
                ID = 1, Name = "Name", PostCode = "7441"
            };

            var incomeTaxTypeCollection = new List <TaxCalculationType> {
                taxCalculationType
            };
            var incomeTaxCollection = new List <IncomeTax> {
                incomeTax
            };

            A.CallTo(() => taxCalculationTypeRepo.GetAllAsync(A <CancellationToken> ._)).ReturnsLazily(x =>
            {
                return(Task.FromResult(incomeTaxTypeCollection.AsEnumerable()));
            });


            A.CallTo(() => incomeTaxRepo.GetAllAsync(A <CancellationToken> ._)).ReturnsLazily(x =>
            {
                return(Task.FromResult(incomeTaxCollection.AsEnumerable()));
            });

            var commandHandler = new CalculateIncomeTaxCommandHandler(taxCalculationTypeRepo, progressiveTaxRepo, incomeTaxRepo);

            //Act
            var result = await commandHandler.Handle(command, cancellationToken);

            //Assert
            A.CallTo(() => incomeTaxRepo.SaveAsync(A <IncomeTax> ._, A <CancellationToken> ._)).MustHaveHappened();
        }
Exemple #11
0
 public CalculatorNotFoundException(TaxCalculationType taxCalculationType) : base($"Calculator not found for type {taxCalculationType.ToString()}")
 {
 }
Exemple #12
0
 public TaxCalculator(TaxCalculationType type, OrderHistory <BaseOrder> allTrades)
 {
     _calcType = type;
 }
Exemple #13
0
 public Type GetCalculator_Returns_Correct_Type(TaxCalculationType calculationType)
 {
     //Act
     return _taxCalculator.GetCalculator(calculationType).GetType();
 }
 public void SaveTaxResult(TaxCalculationType taxCalculationType, decimal salary, string postalCode, decimal taxAmount)
 {
     _taxCalculatorDb.AddCalculatedResult(postalCode, salary, taxCalculationType, taxAmount);
 }
Exemple #15
0
        public async Task CalculateTax_Should_Save_Successfully_Calculated_Tax()
        {
            //Arrange
            const string             expectedPostalCode      = "12234";
            const decimal            expectedAnnualIncome    = 23000M;
            const int                expectedTaxAmount       = 100;
            const TaxCalculationType expectedCalculationType = TaxCalculationType.PROGRESSIVE_TAX;
            DateTime expectedCreationDate = new DateTime(2020, 12, 16);
            Guid     expectedRequestedBy  = Guid.Parse("e64a32e6-f2a9-43d5-b87b-79c845955f93");

            var calculationRequest = new TaxCalculationRequest()
            {
                AnnualIncome = expectedAnnualIncome,
                PostalCode   = expectedPostalCode,
                RequestedBy  = expectedRequestedBy
            };

            TaxCalculation savedRecord = null;

            var taxYear = new TaxYear
            {
                FromDate = new DateTime(2020, 01, 01),
                ToDate   = new DateTime(2021, 01, 02),
                Name     = "Tax Year"
            };

            var taxCalculationResult = new OperationResult <decimal>
            {
                Response = expectedTaxAmount
            };

            _clock.Setup(c => c.GetCurrentDateTime()).Returns(expectedCreationDate);

            _validationRuleEngine.Setup(s => s.Validate(It.IsAny <TaxCalculationRequest>()))
            .Returns(new OperationResult <TaxCalculationResponse>());

            _calculationMappingRepository.Setup(f => f.GetByPostalCodeAsync(It.IsAny <string>()))
            .ReturnsAsync(new PostalCodeCalculationTypeMapping {
                CalculationType = expectedCalculationType
            });

            _taxCalculatorFactory.Setup(f => f.GetCalculator(It.IsAny <TaxCalculationType>()))
            .Returns(_taxCalculator.Object);

            _taxYearRepository.Setup(t => t.GetTaxYearAsync(It.IsAny <DateTime>()))
            .ReturnsAsync(taxYear);

            _taxCalculator.Setup(t => t.CalculateTaxAsync(It.IsAny <TaxYear>(), It.IsAny <decimal>()))
            .ReturnsAsync(taxCalculationResult);

            _calculationRepository.Setup(r => r.AddAsync(It.IsAny <TaxCalculation>()))
            .Callback((TaxCalculation c) => savedRecord = c);

            //Act
            var operationResult = await _calculatorManager.CalculateTax(calculationRequest);

            //Assert
            Assert.IsNotNull(operationResult?.Response);
            Assert.IsFalse(operationResult.HasErrors);

            _calculationRepository.Verify(r => r.AddAsync(It.IsAny <TaxCalculation>()), Times.Once);

            Assert.IsNotNull(savedRecord);
            Assert.AreEqual(expectedAnnualIncome, savedRecord.AnnualIncome);
            Assert.AreEqual(expectedTaxAmount, savedRecord.TaxAmount);
            Assert.AreEqual(expectedCalculationType, savedRecord.CalculationType);
            Assert.AreEqual(expectedRequestedBy, savedRecord.CreatedBy);
            Assert.AreEqual(expectedCreationDate, savedRecord.CreationDate);
            Assert.AreEqual(expectedPostalCode, savedRecord.PostalCode);
            Assert.AreEqual(taxYear, savedRecord.TaxYear);
        }
Exemple #16
0
        public async Task CalculateTax_Should_Successfully_Calculate_Tax()
        {
            //Arrange
            const string  postalCode   = "12234";
            const decimal incomeAmount = 23000M;
            var           requestDate  = new DateTime(2020, 12, 15);

            var calculationRequest = new TaxCalculationRequest()
            {
                AnnualIncome = incomeAmount,
                PostalCode   = postalCode
            };

            const int expectedTaxAmount = 100;
            const TaxCalculationType expectedCalculationType = TaxCalculationType.PROGRESSIVE_TAX;
            const string             expectedTaxYear         = "Tax Year (01-Jan-2020 - 02-Jan-2021)";

            var taxYear = new TaxYear
            {
                FromDate = new DateTime(2020, 01, 01),
                ToDate   = new DateTime(2021, 01, 02),
                Name     = "Tax Year"
            };

            var taxCalculationResult = new OperationResult <decimal>
            {
                Response = expectedTaxAmount
            };

            _clock.Setup(c => c.GetCurrentDateTime()).Returns(requestDate);

            _validationRuleEngine.Setup(s => s.Validate(It.IsAny <TaxCalculationRequest>()))
            .Returns(new OperationResult <TaxCalculationResponse>());

            _calculationMappingRepository.Setup(f => f.GetByPostalCodeAsync(It.IsAny <string>()))
            .ReturnsAsync(new PostalCodeCalculationTypeMapping {
                CalculationType = expectedCalculationType
            });

            _taxCalculatorFactory.Setup(f => f.GetCalculator(It.IsAny <TaxCalculationType>()))
            .Returns(_taxCalculator.Object);

            _taxYearRepository.Setup(t => t.GetTaxYearAsync(It.IsAny <DateTime>()))
            .ReturnsAsync(taxYear);

            _taxCalculator.Setup(t => t.CalculateTaxAsync(It.IsAny <TaxYear>(), It.IsAny <decimal>()))
            .ReturnsAsync(taxCalculationResult);

            //Act
            var operationResult = await _calculatorManager.CalculateTax(calculationRequest);

            //Assert
            Assert.IsNotNull(operationResult?.Response);
            Assert.IsFalse(operationResult.HasErrors);

            _validationRuleEngine.Verify(s => s.Validate(calculationRequest), Times.Once);
            _calculationMappingRepository.Verify(f => f.GetByPostalCodeAsync(postalCode),
                                                 Times.Once);
            _taxCalculatorFactory.Verify(f => f.GetCalculator(expectedCalculationType), Times.Once);

            _taxYearRepository.Verify(t => t.GetTaxYearAsync(requestDate), Times.Once);

            _taxCalculator.Verify(t => t.CalculateTaxAsync(taxYear, incomeAmount), Times.Once());

            Assert.AreEqual(expectedTaxAmount, operationResult.Response.TaxAmount);
            Assert.AreEqual(expectedCalculationType, operationResult.Response.CalculationType);
            Assert.AreEqual(expectedTaxYear, operationResult.Response.TaxYear);
        }