public async Task GetAccountCachesCreatedProfileWhenNewAccountCreatedTest() { var provider = Guid.NewGuid().ToString(); var username = Guid.NewGuid().ToString(); var user = Model.CreateWith <User>(provider + "|" + username); var account = Model.Create <AccountResult>().Set(x => x.IsNewAccount = true); var accountStore = Substitute.For <IAccountStore>(); var profileStore = Substitute.For <IProfileStore>(); var accountCache = Substitute.For <IAccountCache>(); var profileCache = Substitute.For <IProfileCache>(); var sut = new AccountQuery(accountStore, profileStore, accountCache, profileCache); using (var tokenSource = new CancellationTokenSource()) { accountStore.GetAccount(provider, username, tokenSource.Token).Returns(account); var actual = await sut.GetAccount(user, tokenSource.Token).ConfigureAwait(false); profileCache.Received(1).StoreProfile(Arg.Any <Profile>()); profileCache.Received().StoreProfile(Arg.Is <Profile>(x => x.Id == actual.Id)); profileCache.Received().StoreProfile(Arg.Is <Profile>(x => x.Email == user.Email)); profileCache.Received().StoreProfile(Arg.Is <Profile>(x => x.FirstName == user.FirstName)); profileCache.Received().StoreProfile(Arg.Is <Profile>(x => x.LastName == user.LastName)); } }
public async Task GetAccountCachesAccountReturnedFromStoreTest() { var provider = Guid.NewGuid().ToString(); var username = Guid.NewGuid().ToString(); var user = Model.CreateWith <User>(provider + "|" + username); var expected = Model.Create <AccountResult>().Set(x => x.IsNewAccount = false); var accountStore = Substitute.For <IAccountStore>(); var profileStore = Substitute.For <IProfileStore>(); var accountCache = Substitute.For <IAccountCache>(); var profileCache = Substitute.For <IProfileCache>(); var sut = new AccountQuery(accountStore, profileStore, accountCache, profileCache); using (var tokenSource = new CancellationTokenSource()) { accountStore.GetAccount(provider, username, tokenSource.Token).Returns(expected); await sut.GetAccount(user, tokenSource.Token).ConfigureAwait(false); accountCache.Received().StoreAccount(expected); profileCache.DidNotReceive().StoreProfile(Arg.Any <Profile>()); await profileStore.DidNotReceive().StoreProfile(Arg.Any <Profile>(), Arg.Any <CancellationToken>()) .ConfigureAwait(false); } }
public void GetAccountThrowsExceptionWithNullUserTest() { var accountStore = Substitute.For <IAccountStore>(); var profileStore = Substitute.For <IProfileStore>(); var accountCache = Substitute.For <IAccountCache>(); var profileCache = Substitute.For <IProfileCache>(); var sut = new AccountQuery(accountStore, profileStore, accountCache, profileCache); Func <Task> action = async() => await sut.GetAccount(null, CancellationToken.None).ConfigureAwait(false); action.Should().Throw <ArgumentNullException>(); }
public async Task <IActionResult> GetAccountDetails([FromQuery(Name = "id")] int id = 0) { using (var db = new AppDb()) { await db.Connection.OpenAsync(); var query = new AccountQuery(db); var result = await query.GetAccount(id); if (result == null) { return(new BadRequestResult()); } return(new OkObjectResult(result)); } }
public async Task GetAccountReturnsCachedAccountTest() { var user = Model.Create <User>(); var expected = Model.Create <Account>(); var accountStore = Substitute.For <IAccountStore>(); var profileStore = Substitute.For <IProfileStore>(); var accountCache = Substitute.For <IAccountCache>(); var profileCache = Substitute.For <IProfileCache>(); var sut = new AccountQuery(accountStore, profileStore, accountCache, profileCache); using (var tokenSource = new CancellationTokenSource()) { accountCache.GetAccount(user.Username).Returns(expected); var actual = await sut.GetAccount(user, tokenSource.Token).ConfigureAwait(false); actual.Should().BeEquivalentTo(expected); } }
public async Task GetAccountCachesNewAccountTest() { var provider = Guid.NewGuid().ToString(); var username = Guid.NewGuid().ToString(); var user = Model.CreateWith <User>(provider + "|" + username); var account = Model.Create <AccountResult>().Set(x => x.IsNewAccount = true); var accountStore = Substitute.For <IAccountStore>(); var profileStore = Substitute.For <IProfileStore>(); var accountCache = Substitute.For <IAccountCache>(); var profileCache = Substitute.For <IProfileCache>(); var sut = new AccountQuery(accountStore, profileStore, accountCache, profileCache); using (var tokenSource = new CancellationTokenSource()) { accountStore.GetAccount(provider, username, tokenSource.Token).Returns(account); var actual = await sut.GetAccount(user, tokenSource.Token).ConfigureAwait(false); accountCache.Received().StoreAccount(actual); } }
public async Task GetAccountReturnsAccountByProviderAndUsernameTest() { var provider = Guid.NewGuid().ToString(); var username = Guid.NewGuid().ToString(); var user = Model.CreateWith <User>(provider + "|" + username); var expected = Model.Create <AccountResult>(); var accountStore = Substitute.For <IAccountStore>(); var profileStore = Substitute.For <IProfileStore>(); var accountCache = Substitute.For <IAccountCache>(); var profileCache = Substitute.For <IProfileCache>(); var sut = new AccountQuery(accountStore, profileStore, accountCache, profileCache); using (var tokenSource = new CancellationTokenSource()) { accountStore.GetAccount(provider, username, tokenSource.Token).Returns(expected); var actual = await sut.GetAccount(user, tokenSource.Token).ConfigureAwait(false); actual.Should().BeEquivalentTo(expected); } }
public string TopUp([FromUri(Name = "account_id")] int?accId, decimal?amount) { int _accId; if (!accId.HasValue || (accId.HasValue ? !int.TryParse(accId.Value.ToString(), out _accId) : false) || accId.Value < 1) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.INVALID_REQUEST, Status = Enum.GetName(typeof(OperationCode), OperationCode.INVALID_REQUEST), Message = "Указан некорректный параметр запроса" })); } decimal _amount; if (!amount.HasValue || (amount.HasValue ? !decimal.TryParse(amount.Value.ToString(), out _amount) : false) || amount.Value <= 0) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.INVALID_REQUEST, Status = Enum.GetName(typeof(OperationCode), OperationCode.INVALID_REQUEST), Message = "Указан некорректный параметр запроса" })); } //Получение информации о счете Account acc = new Account(); using (AccountQuery accQuery = new AccountQuery()) acc = accQuery.GetAccount(accId.Value); if (acc == null) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.SERVICE_ERROR, Status = Enum.GetName(typeof(OperationCode), OperationCode.NOT_FOUND), Message = "Счет для проведения транзакции не найден" })); } decimal currBalance = acc.Balance; try { acc.Balance += amount.Value; using (AccountQuery accQuery = new AccountQuery()) accQuery.UpdateEntity(acc); using (AccountHistoryQuery accHistQuery = new AccountHistoryQuery()) accHistQuery.CreateEntity(new AccountHistory() { AccId = acc.Id, ChangedAt = DateTime.Now, Amount = acc.Balance }); return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.OK, Status = Enum.GetName(typeof(OperationCode), OperationCode.OK), Message = $"Внесение средств на счет в сумме {amount.Value}. Баланс счета {acc.Balance}" })); } catch (Exception ex) { //Откат операции using (AccountQuery accQuery = new AccountQuery()) { acc.Balance = currBalance; accQuery.UpdateEntity(acc); } return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.SERVICE_ERROR, Status = Enum.GetName(typeof(OperationCode), OperationCode.SERVICE_ERROR), Message = $"Внутренняя ошибка работы сервиса. {ex.Message}" })); } }
public string Transfer([FromUri(Name = "source_account_id")] int?srcAccId, [FromUri(Name = "destination_account_id")] int?destAccId, decimal?amount) { int _accId; if (!srcAccId.HasValue || (srcAccId.HasValue ? !int.TryParse(srcAccId.Value.ToString(), out _accId) : false) || srcAccId.Value < 1) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.NOT_FOUND, Status = Enum.GetName(typeof(OperationCode), OperationCode.NOT_FOUND), Message = "Указан некорректный параметр запроса" })); } if (!destAccId.HasValue || (destAccId.HasValue ? !int.TryParse(destAccId.Value.ToString(), out _accId) : false) || destAccId.Value < 1) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.NOT_FOUND, Status = Enum.GetName(typeof(OperationCode), OperationCode.NOT_FOUND), Message = "Указан некорректный параметр запроса" })); } decimal _amount; if (!amount.HasValue || (amount.HasValue ? !decimal.TryParse(amount.Value.ToString(), out _amount) : false) || amount.Value <= 0) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.NOT_FOUND, Status = Enum.GetName(typeof(OperationCode), OperationCode.NOT_FOUND), Message = "Указан некорректный параметр запроса" })); } //Получение информации о счетах Account srcAcc, descAcc = new Account(); using (AccountQuery accQuery = new AccountQuery()) { srcAcc = accQuery.GetAccount(srcAccId.Value); descAcc = accQuery.GetAccount(destAccId.Value); } if (srcAcc == null || descAcc == null) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.SERVICE_ERROR, Status = Enum.GetName(typeof(OperationCode), OperationCode.NOT_FOUND), Message = "Счет для проведения транзакции не найден" })); } decimal srcAccCurrBalance = srcAcc.Balance; decimal descAccCurrBalance = descAcc.Balance; try { if (srcAcc.Balance < amount.Value || srcAcc.Balance == 0) { return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.OK, Status = Enum.GetName(typeof(OperationCode), OperationCode.OK), Message = $"Запрашиваемая для снятия сумма ({amount.Value}) превышает остаток на счете {srcAcc.Balance}" })); } srcAcc.Balance -= amount.Value; descAcc.Balance += amount.Value; using (AccountQuery accQuery = new AccountQuery()) { accQuery.UpdateEntity(srcAcc); accQuery.UpdateEntity(descAcc); } using (AccountHistoryQuery accHistQuery = new AccountHistoryQuery()) { accHistQuery.CreateEntity(new AccountHistory() { AccId = srcAcc.Id, ChangedAt = DateTime.Now, Amount = srcAcc.Balance }); accHistQuery.CreateEntity(new AccountHistory() { AccId = descAcc.Id, ChangedAt = DateTime.Now, Amount = descAcc.Balance }); } return(JsonConvert.SerializeObject(new TransferResp() { Code = (int)OperationCode.OK, Status = Enum.GetName(typeof(OperationCode), OperationCode.OK), Message = $"Перевод средств со счета {srcAcc.Id} в сумме {amount.Value} на счет {descAcc.Id}.", SourceBalance = srcAcc.Balance, DestinationBalance = descAcc.Balance })); } catch (Exception ex) { //Откат операции using (AccountQuery accQuery = new AccountQuery()) { srcAcc.Balance = srcAccCurrBalance; descAcc.Balance = descAccCurrBalance; accQuery.UpdateEntity(srcAcc); accQuery.UpdateEntity(descAcc); } return(JsonConvert.SerializeObject(new AccountHistoryResp() { Code = (int)OperationCode.SERVICE_ERROR, Status = Enum.GetName(typeof(OperationCode), OperationCode.SERVICE_ERROR), Message = $"Внутренняя ошибка работы сервиса. {ex.Message}" })); } }