public RatesService(ILogger <RatesService> logger, IHttpClientFactory clientFactory, RatesApiOption options) { _logger = logger; _options = options; _clientFactory = clientFactory; }
public AccountController(ILogger <AccountController> logger, IAccountService accountService, IRatesService ratesService, RatesApiOption options) { _logger = logger; _accountService = accountService; _ratesService = ratesService; _options = options; }
// This method gets called by the runtime. Use this method to add services to the container. public void ConfigureServices(IServiceCollection services) { //Enable Cors services.AddCors(opt => { opt.AddPolicy("CorsPolicy", builder => builder.AllowAnyOrigin() .AllowAnyMethod() .AllowAnyHeader() ); }); services.Configure <KestrelServerOptions>(options => { options.AllowSynchronousIO = true; }); services.AddDbContext <DataContext>(opt => opt.UseInMemoryDatabase(databaseName: "BankAccounts") ); services.AddHttpClient(); string rateApiUrl = Configuration.GetSection("RatesApiUrl").Value; string applicationBaseCurrency = Configuration.GetSection("BaseCurrency").Value; var apiOptions = new RatesApiOption(rateApiUrl, applicationBaseCurrency); services.AddSingleton(apiOptions); services.AddTransient <IRepository <Account>, AccountRepository>(); services.AddTransient <IRepository <Transaction>, TransactionRepository>(); services.AddTransient <IAccountService, AccountService>(); services.AddTransient <IRatesService, RatesService>(); services.AddTransient <IUnitOfWork, UnitOfWork>(); services.AddTransient <IGenerateId, IdGenerator>(); services.AddControllers(); services.AddSwaggerGen(c => { c.SwaggerDoc("v1", new OpenApiInfo { Title = "BankingSolution.Api", Version = "v1" }); }); }
public async Task Deposit_RatesApi_Is_Invoked_Only_If_Currency_Is_Not_Base_Currency() { //Arrange var dataContext = new DataContext(_dataContextOptions.Options); IRepository <Account> accountRepository = new AccountRepository(dataContext); IRepository <Transaction> transactionRepository = new TransactionRepository(dataContext); IUnitOfWork unitOfWork = new UnitOfWork(dataContext, accountRepository, transactionRepository); IGenerateId idGenerator = new IdGenerator(); CancellationToken token = new CancellationToken(); var mockRates = new Mock <IRatesService>(); mockRates.Setup(a => a.GetExchangeRate(It.IsAny <Currency>(), It.IsAny <Currency>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => new Rate("GBP", "GBP", 0.79m, DateTime.Now)); //Act RatesApiOption ratesApiOption = new RatesApiOption("someurl", "USD"); IAccountService accountService = new AccountService(_mockAccountActionLogger.Object, unitOfWork, idGenerator); AccountCreationSummary accountCreationSummary = await accountService.CreateAccount(new CreateAccount("Jared", Amount.FromInput(100m))); AccountController accountController = new AccountController(_mockAccountControllerLogger.Object, accountService, mockRates.Object, ratesApiOption); CreateDepositRequest request = new CreateDepositRequest { AccountId = accountCreationSummary.AccountId, Amount = 30m, Currency = Currencies.EUR }; var result = (await accountController.Deposit(request, token) as ObjectResult); Assert.That(accountCreationSummary, Is.Not.Null); Assert.That(accountCreationSummary.AccountId, Is.Not.Empty); Assert.That(result, Is.Not.Null); mockRates.Verify(a => a.GetExchangeRate(It.IsAny <Currency>(), It.IsAny <Currency>(), It.IsAny <CancellationToken>()), Times.AtLeastOnce); }
public async Task Withdrawal_Amount_Cannot_Leave_Account_In_Negative() { //Arrange var dataContext = new DataContext(_dataContextOptions.Options); IRepository <Account> accountRepository = new AccountRepository(dataContext); IRepository <Transaction> transactionRepository = new TransactionRepository(dataContext); IUnitOfWork unitOfWork = new UnitOfWork(dataContext, accountRepository, transactionRepository); IGenerateId idGenerator = new IdGenerator(); CancellationToken token = new CancellationToken(); var mockRates = new Mock <IRatesService>(); mockRates.Setup(a => a.GetExchangeRate(It.IsAny <Currency>(), It.IsAny <Currency>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => new Rate("GBP", "GBP", 0.79m, DateTime.Now)); //Act RatesApiOption ratesApiOption = new RatesApiOption("someurl", "USD"); IAccountService accountService = new AccountService(_mockAccountActionLogger.Object, unitOfWork, idGenerator); AccountCreationSummary accountCreationSummary = await accountService.CreateAccount(new CreateAccount("Jared", Amount.FromInput(100m))); AccountController accountController = new AccountController(_mockAccountControllerLogger.Object, accountService, mockRates.Object, ratesApiOption); CreateWithdrawalRequest request = new CreateWithdrawalRequest { AccountId = accountCreationSummary.AccountId, Amount = 101m }; var result = (await accountController.Withdraw(request, token) as ObjectResult); Assert.That(accountCreationSummary, Is.Not.Null); Assert.That(accountCreationSummary.AccountId, Is.Not.Empty); Assert.That(result, Is.Not.Null); Assert.That(result.Value, Contains.Substring("amount is greater than balance")); }
public async Task Withdrawal_Fails_If_Account_Id_Is_Invalid() { //Arrange var dataContext = new DataContext(_dataContextOptions.Options); IRepository <Account> accountRepository = new AccountRepository(dataContext); IRepository <Transaction> transactionRepository = new TransactionRepository(dataContext); IUnitOfWork unitOfWork = new UnitOfWork(dataContext, accountRepository, transactionRepository); IGenerateId idGenerator = new IdGenerator(); CancellationToken token = new CancellationToken(); string accountIdInvalid = "Invalid account id"; var mockRates = new Mock <IRatesService>(); mockRates.Setup(a => a.GetExchangeRate(It.IsAny <Currency>(), It.IsAny <Currency>(), It.IsAny <CancellationToken>())) .ReturnsAsync(() => new Rate("GBP", "GBP", 0.79m, DateTime.Now)); //Act RatesApiOption ratesApiOption = new RatesApiOption("someurl", "USD"); IAccountService accountService = new AccountService(_mockAccountActionLogger.Object, unitOfWork, idGenerator); AccountController accountController = new AccountController(_mockAccountControllerLogger.Object, accountService, mockRates.Object, ratesApiOption); CreateWithdrawalRequest request = new CreateWithdrawalRequest { AccountId = accountIdInvalid, Amount = 101m }; var result = (await accountController.Withdraw(request, token) as ObjectResult); Assert.That(result, Is.Not.Null); Assert.That(result.Value, Contains.Substring("Account id not be found")); }