private async Task PerformTest(UserType userType) { this.apiKeyRepository.Setup(v => v.GetApiKey(userType)).Returns(ApiKey); var expectedInput = new CreateRefundIn { Amount = AmountInMinorDenomination.Create(RefundCreditAmount).ToMajorDenomination(), CustomId = CreateTaxamoTransaction.CustomId }; CreateRefundIn actualInput = null; this.taxamoService.Setup(v => v.CreateRefundAsync(TaxamoTransactionKey, It.IsAny <CreateRefundIn>(), ApiKey)) .Callback <string, CreateRefundIn, string>((a, b, c) => actualInput = b) .ReturnsAsync(new CreateRefundOut { TotalAmount = 0.12m, TaxAmount = 0.02m, }); var result = await this.target.ExecuteAsync(TaxamoTransactionKey, RefundCreditAmount, userType); Assert.AreEqual( new CreateTaxamoRefund.TaxamoRefundResult( PositiveInt.Parse(12), NonNegativeInt.Parse(2)), result); Assert.AreEqual( JsonConvert.SerializeObject(expectedInput, Formatting.None), JsonConvert.SerializeObject(actualInput, Formatting.None)); }
public async Task WhenTaxamoAmountDoesNotEqualExpectedAmount_AndUserTypeIsTestUser_ItShouldCancelTransactionAndAbort() { this.getUserPaymentOrigin.Setup(v => v.ExecuteAsync(UserId)).ReturnsAsync(Origin); this.createTaxamoTransaction.Setup(v => v.ExecuteAsync( Amount, Origin.CountryCode, Origin.CreditCardPrefix, Origin.IpAddress, Origin.OriginalTaxamoTransactionKey, UserType.TestUser)) .ReturnsAsync(TaxamoTransaction); this.deleteTaxamoTransaction.Setup(v => v.ExecuteAsync(TaxamoTransaction.Key, UserType.TestUser)) .Returns(Task.FromResult(0)) .Verifiable(); await ExpectedException.AssertExceptionAsync <BadRequestException>( () => this.target.HandleAsync( UserId, PositiveInt.Parse(10), PositiveInt.Parse(11), UserType.TestUser)); this.deleteTaxamoTransaction.Verify(); }
public async Task WhenAmountIsLessThanMinimumPaymentAmount_ItShouldThrowAnException() { await this.target.HandleAsync(new ApplyCreditRequestCommand( Requester, UserId, Now, TransactionReference, PositiveInt.Parse(TopUpUserAccountsWithCredit.MinimumPaymentAmount - 1), Command.ExpectedTotalAmount)); }
public async Task WhenTotalAmountIsLessThanCreditAmount_ItShouldThrowAnException() { await this.target.ExecuteAsync( EnactingUserId, UserId, Timestamp, TotalAmount, PositiveInt.Parse(TotalAmount.Value + 1), TransactionReference, StripeChargeId, TaxamoTransactionKey, Comment); }
public async Task WhenLocationDataSupplied_ItShouldNotRequestOrigin() { this.requesterSecurity.Setup(v => v.IsInRoleAsync(Requester, FifthweekRole.TestUser)).ReturnsAsync(false); this.getUserWeeklySubscriptionCost.Setup(v => v.ExecuteAsync(UserId)).ReturnsAsync(TopUpUserAccountsWithCredit.MinimumPaymentAmount + 1); this.getTaxInformation .Setup(v => v.ExecuteAsync( PositiveInt.Parse(TopUpUserAccountsWithCredit.MinimumPaymentAmount + 1), QueryWithOverride.LocationDataOverride.CountryCode.Value, QueryWithOverride.LocationDataOverride.CreditCardPrefix.Value, QueryWithOverride.LocationDataOverride.IpAddress.Value, null, UserType.StandardUser)) .ReturnsAsync(TaxamoTransaction); var result = await this.target.HandleAsync(QueryWithOverride); Assert.AreEqual( new CreditRequestSummary(TopUpUserAccountsWithCredit.MinimumPaymentAmount + 1, TaxamoTransaction), result); }
public async Task <CreditRequestSummary> HandleAsync(GetCreditRequestSummaryQuery query) { query.AssertNotNull("query"); await this.requesterSecurity.AuthenticateAsAsync(query.Requester, query.UserId); var userType = await this.requesterSecurity.GetUserTypeAsync(query.Requester); var subscriptionsAmount = await this.getUserWeeklySubscriptionsCost.ExecuteAsync(query.UserId); var amountToCharge = Math.Max(TopUpUserAccountsWithCredit.MinimumPaymentAmount, subscriptionsAmount); UserPaymentOriginResult origin; if (query.LocationDataOverride == null) { origin = await this.getUserPaymentOrigin.ExecuteAsync(query.UserId); } else { origin = new UserPaymentOriginResult( query.LocationDataOverride.CountryCode == null ? null : query.LocationDataOverride.CountryCode.Value, query.LocationDataOverride.CreditCardPrefix == null ? null : query.LocationDataOverride.CreditCardPrefix.Value, query.LocationDataOverride.IpAddress == null ? null : query.LocationDataOverride.IpAddress.Value); } var taxInformation = await this.getTaxInformation.ExecuteAsync( PositiveInt.Parse(amountToCharge), origin.CountryCode, origin.CreditCardPrefix, origin.IpAddress, origin.OriginalTaxamoTransactionKey, userType); return(new CreditRequestSummary( subscriptionsAmount, taxInformation)); }
public async Task WhenSubscriptionCstIsLessThanMinimumCharge_ItShouldReturnTaxInformationSummaryForMinimumCharge() { this.getUserPaymentOrigin.Setup(v => v.ExecuteAsync(UserId)).ReturnsAsync(Origin); this.requesterSecurity.Setup(v => v.IsInRoleAsync(Requester, FifthweekRole.TestUser)).ReturnsAsync(false); this.getUserWeeklySubscriptionCost.Setup(v => v.ExecuteAsync(UserId)).ReturnsAsync(TopUpUserAccountsWithCredit.MinimumPaymentAmount - 1); this.getTaxInformation .Setup(v => v.ExecuteAsync( PositiveInt.Parse(TopUpUserAccountsWithCredit.MinimumPaymentAmount), Origin.CountryCode, Origin.CreditCardPrefix, Origin.IpAddress, Origin.OriginalTaxamoTransactionKey, UserType.StandardUser)) .ReturnsAsync(TaxamoTransaction); var result = await this.target.HandleAsync(Query); Assert.AreEqual( new CreditRequestSummary(TopUpUserAccountsWithCredit.MinimumPaymentAmount - 1, TaxamoTransaction), result); }
private async Task ParameterizedTestAsync( Func <UserId, UserId, IReadOnlyList <ChannelId>, IReadOnlyList <QueueId>, DateTime, bool, NonNegativeInt, PositiveInt, IReadOnlyList <NewsfeedPost>, int, Task> parameterizedTest) { var totalLivePosts = SortedLiveNewsfeedPosts.Count; NonNegativeInt noPaginationStart = NonNegativeInt.Parse(0); PositiveInt noPaginationCount = PositiveInt.Parse(int.MaxValue); var wrapper = new ParameterizedTestWrapper(parameterizedTest); parameterizedTest = wrapper.Execute; // No pagination. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts, 0); // Paginate from start. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(0), PositiveInt.Parse(10), SortedLiveNewsfeedPosts.Take(10).ToList(), 0); // Paginate from middle with different page size and page index. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(5), PositiveInt.Parse(10), SortedLiveNewsfeedPosts.Skip(5).Take(10).ToList(), 0); // Paginate from middle with same page size and page index. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(10), PositiveInt.Parse(10), SortedLiveNewsfeedPosts.Skip(10).Take(10).ToList(), 0); // Paginate from near end, requesting up to last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts - 10), PositiveInt.Parse(10), SortedLiveNewsfeedPosts.Skip(totalLivePosts - 10).Take(10).ToList(), 0); // Paginate from near end, requesting beyond last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts - 5), PositiveInt.Parse(10), SortedLiveNewsfeedPosts.Skip(totalLivePosts - 5).Take(10).ToList(), 0); // Paginate from end, requesting beyond last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts), PositiveInt.Parse(1), new NewsfeedPost[0], 0); // Paginate from beyond end, requesting beyond last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts + 1), PositiveInt.Parse(1), new NewsfeedPost[0], 0); // Unsubscribed. await parameterizedTest( UnsubscribedUserId, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, new NewsfeedPost[0], 0); // Subscribed at correct price, fetch from all subscriptions. await parameterizedTest( SubscribedUserId, null, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => !v.ChannelId.Equals(ChannelIds[2])).ToList(), 10); // Subscribed at correct price. await parameterizedTest( SubscribedUserId, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => !v.ChannelId.Equals(ChannelIds[2])).ToList(), 10); // Subscribed at zero, but on free access list. await parameterizedTest( GuestListUserId, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => !v.ChannelId.Equals(ChannelIds[2])).ToList(), 0); // Filter by channel for creator. await parameterizedTest( CreatorId, CreatorId, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0])).ToList(), 0); // Filter by channel. await parameterizedTest( SubscribedUserId, null, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0])).ToList(), 10); // Filter by channel 2. await parameterizedTest( SubscribedUserId, null, new[] { ChannelIds[1] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[1])).ToList(), 10); // Filter by unsubscribed channel 3. await parameterizedTest( SubscribedUserId, null, new[] { ChannelIds[2] }, null, Now, false, noPaginationStart, noPaginationCount, new NewsfeedPost[0], 10); // Filter by valid channel and creator combination. await parameterizedTest( SubscribedUserId, CreatorId, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0])).ToList(), 10); // Filter by invalid channel and creator combination. await parameterizedTest( SubscribedUserId, GuestListUserId, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, new NewsfeedPost[0], 10); // Search forwards from now. await parameterizedTest( CreatorId, CreatorId, null, null, Now, true, noPaginationStart, noPaginationCount, new NewsfeedPost[0], 0); // Search forwards from beginning. await parameterizedTest( CreatorId, CreatorId, null, null, SqlDateTime.MinValue.Value, true, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Reverse().ToList(), 0); // Paginate forwards from middle with different page size and page index. await parameterizedTest( CreatorId, CreatorId, null, null, SqlDateTime.MinValue.Value, true, NonNegativeInt.Parse(5), PositiveInt.Parse(10), SortedLiveNewsfeedPosts.Reverse().Skip(5).Take(10).ToList(), 0); }
private async Task ParameterizedTestAsync( Func <UserId, UserId, IReadOnlyList <ChannelId>, IReadOnlyList <QueueId>, DateTime, bool, NonNegativeInt, PositiveInt, IReadOnlyList <PreviewNewsfeedPost>, int, Task> parameterizedTest) { var totalLivePosts = SortedLiveNewsfeedPosts.Count; NonNegativeInt noPaginationStart = NonNegativeInt.Parse(0); PositiveInt noPaginationCount = PositiveInt.Parse(int.MaxValue); var wrapper = new ParameterizedTestWrapper(parameterizedTest); parameterizedTest = wrapper.Execute; var visibleSortedLiveNewsfeedPosts = SortedLiveNewsfeedPosts.Where(v => !v.ChannelId.Equals(ChannelIds[3])).ToList(); // No pagination. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, visibleSortedLiveNewsfeedPosts.ToList(), 0); // Paginate from start. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(0), PositiveInt.Parse(10), visibleSortedLiveNewsfeedPosts.Take(10).ToList(), 0); // Paginate from middle with different page size and page index. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(5), PositiveInt.Parse(10), visibleSortedLiveNewsfeedPosts.Skip(5).Take(10).ToList(), 0); // Paginate from middle with same page size and page index. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(10), PositiveInt.Parse(10), visibleSortedLiveNewsfeedPosts.Skip(10).Take(10).ToList(), 0); // Paginate from near end, requesting up to last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts - 10), PositiveInt.Parse(10), visibleSortedLiveNewsfeedPosts.Skip(totalLivePosts - 10).Take(10).ToList(), 0); // Paginate from near end, requesting beyond last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts - 5), PositiveInt.Parse(10), visibleSortedLiveNewsfeedPosts.Skip(totalLivePosts - 5).Take(10).ToList(), 0); // Paginate from end, requesting beyond last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts), PositiveInt.Parse(1), new PreviewNewsfeedPost[0], 0); // Paginate from beyond end, requesting beyond last post. await parameterizedTest( CreatorId, CreatorId, null, null, Now, false, NonNegativeInt.Parse(totalLivePosts + 1), PositiveInt.Parse(1), new PreviewNewsfeedPost[0], 0); // Unsubscribed. await parameterizedTest( UnsubscribedUserId, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, visibleSortedLiveNewsfeedPosts, 0); // Unsubscribed, fetch from all subscriptions (will ignore non-discoverable channel). await parameterizedTest( UnsubscribedUserId, null, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0]) || v.ChannelId.Equals(ChannelIds[2])).ToList(), 10); // Logged out. await parameterizedTest( null, CreatorId, null, null, Now, false, noPaginationStart, noPaginationCount, visibleSortedLiveNewsfeedPosts, 0); // Logged out, fetch from all subscriptions (will ignore non-discoverable channel). await parameterizedTest( null, null, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0]) || v.ChannelId.Equals(ChannelIds[2])).ToList(), 10); // Logged in as creator, filter by channel for creator (will ignore non-discoverable channel). await parameterizedTest( CreatorId, null, null, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0]) || v.ChannelId.Equals(ChannelIds[2])).ToList(), 0); // Filter by channel for creator. await parameterizedTest( CreatorId, CreatorId, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0])).ToList(), 0); // Filter by channel. await parameterizedTest( UnsubscribedUserId, null, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0])).ToList(), 10); // Filter by channel 2. await parameterizedTest( UnsubscribedUserId, null, new[] { ChannelIds[1] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[1])).ToList(), 10); // Filter by valid channel and creator combination. await parameterizedTest( UnsubscribedUserId, CreatorId, new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, SortedLiveNewsfeedPosts.Where(v => v.ChannelId.Equals(ChannelIds[0])).ToList(), 10); // Filter by invalid channel and creator combination. await parameterizedTest( UnsubscribedUserId, UserId.Random(), new[] { ChannelIds[0] }, null, Now, false, noPaginationStart, noPaginationCount, new PreviewNewsfeedPost[0], 10); // Search forwards from now. await parameterizedTest( CreatorId, CreatorId, null, null, Now, true, noPaginationStart, noPaginationCount, new PreviewNewsfeedPost[0], 0); // Search forwards from beginning. await parameterizedTest( CreatorId, CreatorId, null, null, SqlDateTime.MinValue.Value, true, noPaginationStart, noPaginationCount, visibleSortedLiveNewsfeedPosts.AsEnumerable().Reverse().ToList(), 0); // Paginate forwards from middle with different page size and page index. await parameterizedTest( CreatorId, CreatorId, null, null, SqlDateTime.MinValue.Value, true, NonNegativeInt.Parse(5), PositiveInt.Parse(10), visibleSortedLiveNewsfeedPosts.AsEnumerable().Reverse().Skip(5).Take(10).ToList(), 0); }
public async Task ItShouldChargeAllNecessaryUsers() { this.timestampCreator.SetupSequence(v => v.Now()).Returns(Now1).Returns(Now2); this.guidCreator.SetupSequence(v => v.CreateSqlSequential()).Returns(TransactionReference1.Value).Returns(TransactionReference2.Value); var userId1 = UserId.Random(); var userId2 = UserId.Random(); var userId3 = UserId.Random(); var userId4 = UserId.Random(); var userId5 = UserId.Random(); var input = new List <CalculatedAccountBalanceResult> { new CalculatedAccountBalanceResult(DateTime.UtcNow, UserId.Random(), LedgerAccountType.FifthweekCredit, TopUpUserAccountsWithCredit.MinimumAccountBalanceBeforeCharge), new CalculatedAccountBalanceResult(DateTime.UtcNow, UserId.Random(), LedgerAccountType.Stripe, 0), new CalculatedAccountBalanceResult(DateTime.UtcNow, userId1, LedgerAccountType.FifthweekCredit, TopUpUserAccountsWithCredit.MinimumAccountBalanceBeforeCharge - 1), new CalculatedAccountBalanceResult(DateTime.UtcNow, userId2, LedgerAccountType.FifthweekCredit, -1m), }; var usersRequiringRetry = new List <UserId> { userId3, userId4, userId5 }; this.getUsersRequiringPaymentRetry.Setup(v => v.ExecuteAsync()).ReturnsAsync(usersRequiringRetry); var usersRequiringCharge = new List <UserId> { userId1, userId2, userId3, userId4, userId5 }; this.incrementPaymentStatus.Setup(v => v.ExecuteAsync(It.IsAny <IReadOnlyList <UserId> >())) .Callback <IReadOnlyList <UserId> >(v => CollectionAssert.AreEquivalent(usersRequiringCharge, v.ToList())) .Returns(Task.FromResult(0)).Verifiable(); this.getUserWeeklySubscriptionsCost.Setup(v => v.ExecuteAsync(userId1)).ReturnsAsync(TopUpUserAccountsWithCredit.MinimumPaymentAmount - 1); this.getUserWeeklySubscriptionsCost.Setup(v => v.ExecuteAsync(userId2)).ReturnsAsync(TopUpUserAccountsWithCredit.MinimumPaymentAmount + 1); this.getUserWeeklySubscriptionsCost.Setup(v => v.ExecuteAsync(userId3)).ReturnsAsync(0); this.getUserWeeklySubscriptionsCost.Setup(v => v.ExecuteAsync(userId4)).ReturnsAsync(TopUpUserAccountsWithCredit.MinimumPaymentAmount * 2); this.getUserWeeklySubscriptionsCost.Setup(v => v.ExecuteAsync(userId5)).ReturnsAsync(TopUpUserAccountsWithCredit.MinimumPaymentAmount * 2); this.getUserPaymentOrigin.Setup(v => v.ExecuteAsync(userId1)) .ReturnsAsync(new UserPaymentOriginResult("customer1", PaymentOriginKeyType.Stripe, null, null, null, null, PaymentStatus.Retry1)); this.getUserPaymentOrigin.Setup(v => v.ExecuteAsync(userId2)) .ReturnsAsync(new UserPaymentOriginResult("customer2", PaymentOriginKeyType.Stripe, null, null, null, null, PaymentStatus.Retry1)); // Test PaymentOriginKeyType with no key. this.getUserPaymentOrigin.Setup(v => v.ExecuteAsync(userId4)) .ReturnsAsync(new UserPaymentOriginResult(null, PaymentOriginKeyType.Stripe, null, null, null, null, PaymentStatus.Retry1)); this.getUserPaymentOrigin.Setup(v => v.ExecuteAsync(userId5)) .ReturnsAsync(new UserPaymentOriginResult("customer5", PaymentOriginKeyType.Stripe, null, null, null, null, PaymentStatus.None)); this.applyUserCredit.Setup(v => v.ExecuteAsync(userId1, Now1, TransactionReference1, PositiveInt.Parse(TopUpUserAccountsWithCredit.MinimumPaymentAmount), null, UserType.StandardUser)) .Returns(Task.FromResult(0)) .Verifiable(); this.applyUserCredit.Setup(v => v.ExecuteAsync(userId2, Now2, TransactionReference2, PositiveInt.Parse(TopUpUserAccountsWithCredit.MinimumPaymentAmount + 1), null, UserType.StandardUser)) .Returns(Task.FromResult(0)) .Verifiable(); var result = await this.target.ExecuteAsync(input, new List <PaymentProcessingException>(), CancellationToken.None); this.incrementPaymentStatus.Verify(); this.applyUserCredit.Verify(); Assert.IsTrue(result); }
public async Task <bool> ExecuteAsync( IReadOnlyList <CalculatedAccountBalanceResult> updatedAccountBalances, List <PaymentProcessingException> errors, CancellationToken cancellationToken) { using (PaymentsPerformanceLogger.Instance.Log(typeof(TopUpUserAccountsWithCredit))) { updatedAccountBalances.AssertNotNull("updatedAccountBalances"); errors.AssertNotNull("errors"); var userIdsToRetry = await this.getUsersRequiringPaymentRetry.ExecuteAsync(); var newUserIds = updatedAccountBalances .Where(v => v.AccountType == LedgerAccountType.FifthweekCredit && v.Amount < MinimumAccountBalanceBeforeCharge) .Select(v => v.UserId); var allUserIds = userIdsToRetry.Concat(newUserIds).Distinct().ToList(); // Increment all billing status immediately so the user maintains access to his newsfeed. await this.incrementPaymentStatus.ExecuteAsync(allUserIds); bool recalculateBalances = false; foreach (var userId in allUserIds) { if (cancellationToken.IsCancellationRequested) { break; } try { // Work out what we should charge the user. var amountToCharge = await this.getUserWeeklySubscriptionsCost.ExecuteAsync(userId); if (amountToCharge == 0) { // No subscriptions, so no need to charge. continue; } amountToCharge = Math.Max(MinimumPaymentAmount, amountToCharge); var origin = await this.getUserPaymentOrigin.ExecuteAsync(userId); if (origin.PaymentOriginKey == null || origin.PaymentOriginKeyType == PaymentOriginKeyType.None || origin.PaymentStatus == PaymentStatus.None) { // If the user doesn't have a stripe customer ID then they haven't given us // credit card details and we can't bill them. // If the user has manually topped up since we incremented the billing status, // it will have been set back to None and we don't need to top up again. continue; } var timestamp = this.timestampCreator.Now(); var transactionReference = new TransactionReference(this.guidCreator.CreateSqlSequential()); // And apply the charge. await this.applyUserCredit.ExecuteAsync( userId, timestamp, transactionReference, PositiveInt.Parse(amountToCharge), null, UserType.StandardUser); recalculateBalances = true; } catch (Exception t) { errors.Add(new PaymentProcessingException(t, userId, null)); } } return(recalculateBalances); } }
public async Task ItShouldCallCreateCreditRefund() { this.timestampCreator.Setup(v => v.Now()).Returns(Now); this.createCreditRefund.Setup(v => v.HandleAsync( new CreateCreditRefundCommand(Requester, TransactionReference, Now, PositiveInt.Parse(Data.RefundCreditAmount), Data.Reason, Data.Comment))) .Returns(Task.FromResult(0)) .Verifiable(); await this.target.PostCreditRefundAsync(TransactionReference.Value.EncodeGuid(), Data); this.createCreditRefund.Verify(); }
public async Task ItShouldBeAbleToRefundCredit() { await this.IntegrationTestAsync(async testDatabase => { this.InitializeServices(testDatabase); var random = new Random(); TransactionReference transactionReference; using (var databaseContext = testDatabase.CreateContext()) { //var creator1 = CreateUser(databaseContext, random, CreatorId1); var subscriber1 = CreateUser(databaseContext, random, SubscriberId1); transactionReference = AddCredit(databaseContext, random, SubscriberId1, 1000); //PayCreator(databaseContext, random, SubscriberId1, CreatorId1, 10m); //PayCreatorUncommitted(databaseContext, random, SubscriberId2, CreatorId2, 5m); await databaseContext.SaveChangesAsync(); } Pause(); await this.updateAccountBalances.ExecuteAsync(SubscriberId1, DateTime.UtcNow); Assert.AreEqual(1000, (await this.getCreditTransactionInformation.ExecuteAsync(transactionReference)).CreditAmountAvailableForRefund); Assert.AreEqual(1000, (await this.getAccountSettings.ExecuteAsync(SubscriberId1, DateTime.UtcNow, 0)).AccountBalance); Assert.AreEqual(200, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.SalesTax)); Assert.AreEqual(-1200, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.Stripe)); await this.persistCreditRefund.ExecuteAsync( UserId.Random(), SubscriberId1, DateTime.UtcNow, PositiveInt.Parse((int)(100 * Tax)), PositiveInt.Parse(100), transactionReference, StripeChargeId, TaxamoTransactionKey, Comment); Pause(); await this.updateAccountBalances.ExecuteAsync(SubscriberId1, DateTime.UtcNow); Assert.AreEqual(900, (await this.getCreditTransactionInformation.ExecuteAsync(transactionReference)).CreditAmountAvailableForRefund); Assert.AreEqual(900, (await this.getAccountSettings.ExecuteAsync(SubscriberId1, DateTime.UtcNow, 0)).AccountBalance); Assert.AreEqual(180, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.SalesTax)); Assert.AreEqual(-1080, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.Stripe)); await this.persistCreditRefund.ExecuteAsync( UserId.Random(), SubscriberId1, DateTime.UtcNow, PositiveInt.Parse((int)(500 * Tax)), PositiveInt.Parse(500), transactionReference, StripeChargeId, TaxamoTransactionKey, Comment); Pause(); await this.updateAccountBalances.ExecuteAsync(SubscriberId1, DateTime.UtcNow); Assert.AreEqual(400, (await this.getCreditTransactionInformation.ExecuteAsync(transactionReference)).CreditAmountAvailableForRefund); Assert.AreEqual(400, (await this.getAccountSettings.ExecuteAsync(SubscriberId1, DateTime.UtcNow, 0)).AccountBalance); Assert.AreEqual(80, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.SalesTax)); Assert.AreEqual(-480, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.Stripe)); await this.persistCreditRefund.ExecuteAsync( UserId.Random(), SubscriberId1, DateTime.UtcNow, PositiveInt.Parse((int)(400 * Tax)), PositiveInt.Parse(400), transactionReference, StripeChargeId, TaxamoTransactionKey, Comment); Pause(); await this.updateAccountBalances.ExecuteAsync(SubscriberId1, DateTime.UtcNow); Assert.AreEqual(0, (await this.getCreditTransactionInformation.ExecuteAsync(transactionReference)).CreditAmountAvailableForRefund); Assert.AreEqual(0, (await this.getAccountSettings.ExecuteAsync(SubscriberId1, DateTime.UtcNow, 0)).AccountBalance); Assert.AreEqual(0, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.SalesTax)); Assert.AreEqual(0, await this.GetAccountBalance(SubscriberId1, LedgerAccountType.Stripe)); await testDatabase.TakeSnapshotAsync(); return(ExpectedSideEffects.None); }); }
public async Task WhenGettingPreviewNewsfeed_ItShouldReturnResultFromNewsfeedQuery() { var query = new GetNewsfeedQuery(Requester, UserId, new[] { ChannelId }, Origin, SearchForwards, NonNegativeInt.Parse(10), PositiveInt.Parse(5)); var requestData = new NewsfeedFilter { CreatorId = UserId.Value.EncodeGuid(), ChannelId = ChannelId.Value.EncodeGuid(), Origin = Origin, SearchForwards = SearchForwards, Count = 5, StartIndex = 10 }; var queryResult = new GetPreviewNewsfeedQueryResult(new[] { new GetPreviewNewsfeedQueryResult.PreviewPost(UserId, new GetPreviewNewsfeedQueryResult.PreviewPostCreator(Username, null), PostId, BlogId, new GetPreviewNewsfeedQueryResult.PreviewPostBlog(BlogName, null, null), ChannelId, new GetPreviewNewsfeedQueryResult.PreviewPostChannel(ChannelName), new PreviewText(string.Empty), null, null, null, 0, 0, 0, 0, 0, DateTime.UtcNow, 0, 0, false, false) }); this.requesterContext.Setup(_ => _.GetRequesterAsync()).ReturnsAsync(Requester); this.getPreviewNewsfeed.Setup(_ => _.HandleAsync(query)).ReturnsAsync(queryResult); var result = await this.target.GetPreviewNewsfeed(requestData); Assert.AreEqual(queryResult, result); }
public PositiveInt ToPositiveInt() { return(PositiveInt.Parse(this.Value)); }