# Feature & Integration Tests
public class TopupNewTest : OneCaseFeatureTest, IRequiresAuthenticatedUser
{
private TopupNew.Command _command;
private PayPauResult _payment;
public override async Task Given()
{
// arrange
var provider = _.MakeSaving<Provider>(m => m.Amounts = "20");
_payment = _.Make<PayPauResult>();
_command = _.Make<TopupNew.Command>(m =>
{
m.ProviderId = provider.Id;
m.Amount = 20;
});
_.Get<IPayPau>().Charge(_command.CreditCard, _command.Amount).Returns(_payment);
// act
await _.Send(_command);
}
[Test]
public void Credit_card_charged_by_Paypau()
{
_payment.TransactionId.ShouldNotBeNull();
}
/// <summary>
/// Check only some properties that matters for the operation
/// All properties are tested at DomainTest
/// </summary>
[Test]
public void New_topup_saved()
{
var saved = _.Db(db => db.Topups.First());
saved.Status.ShouldBe(TopupStatus.Paid);
saved.PaymentId.ShouldBe(_payment.TransactionId);
saved.ProviderId.ShouldBe(_command.ProviderId);
saved.PhoneNumber.ShouldBe(_command.PhoneNumber);
saved.Amount.ShouldBe(_command.Amount);
saved.UserId.ShouldBe(_.CurrentUserId());
saved.Email.ShouldBe(_.CurrentUser<User>().Email);
saved.CreatedAt.ShouldBeSecondsAgo();
saved.UpdatedAt.ShouldBeSecondsAgo();
}
[Test]
public void Topup_job_enqueued()
{
_.EnqueuedOneJobFor<TopupComplete>().ShouldBeTrue();
}
public class Errors : FeatureTest, IRequiresAuthenticatedUser
{
[Test]
public async Task Do_not_save_topup_if_credit_card_charge_fails()
{
// arrange
var provider = _.MakeSaving<Provider>();
var command = _.Make<TopupNew.Command>(m => m.ProviderId = provider.Id);
_.Get<IPayPau>()
.When(m => m.Charge(command.CreditCard, command.Amount))
.Do(m => throw new DomainException("Payment failed"));
// act
await Should.ThrowAsync<DomainException>(async () => await _.Send(command));
// assert
_.Db(db => db.Topups.ToList()).ShouldBeEmpty();
}
}
public class Query : FeatureTest
{
[Test]
public async Task Query_new_topup()
{
// arrange
var providers = _.MakeMany<Provider>();
var user = _.Make<User>();
_.SaveSync(providers, user);
_.LoginAs(user);
// act
var command = await _.Send(new TopupNew.Query());
// assert
command.Name.ShouldBe(user.Name);
command.Email.ShouldBe(user.Email);
command.Providers.Count().ShouldBe(3);
}
}
public class Validation : OneCaseFeatureTest
{
private TopupNew.Command _request;
public override void GivenSync()
{
_request = _.Make<TopupNew.Command>();
}
[Test]
public void Phone_is_required()
{
_.ShouldBeInvalid(_request, x => x.PhoneNumber, string.Empty);
_.ShouldBeValid(_request, x => x.PhoneNumber, _.Fab().Faker.Phone.PhoneNumber());
}
[Test]
public void Credit_card_is_required()
{
_.ShouldBeInvalid(_request, x => x.CreditCard, string.Empty);
_.ShouldBeValid(_request, x => x.CreditCard, _.Faker().Finance.CreditCardNumber());
}
[Test]
public void Amount_is_required_higher_than_5()
{
_.ShouldBeInvalid(_request, x => x.Amount, 0);
_.ShouldBeInvalid(_request, x => x.Amount, -10);
_.ShouldBeInvalid(_request, x => x.Amount, 4);
_.ShouldBeValid(_request, x => x.Amount, 5);
}
}
}