Skip to content

Instantly share code, notes, and snippets.

@bmadigan
Last active October 26, 2017 12:58
Show Gist options
  • Save bmadigan/6175889e677261797c157306a8900207 to your computer and use it in GitHub Desktop.
Save bmadigan/6175889e677261797c157306a8900207 to your computer and use it in GitHub Desktop.
Laravel TDD - FakePayment Gateway
<?php
namespace App\Billing;
class FakePaymentGateway implements PaymentGateway
{
const TEST_CARD_NUMBER = '4242424242424242';
private $charges;
private $tokens;
private $beforeFirstChargeCallback;
public function __construct()
{
$this->charges = collect();
$this->tokens = collect();
}
public function getValidTestToken($cardNumber = self::TEST_CARD_NUMBER)
{
$token = 'fake-tok_' . str_random(24);
$this->tokens[$token] = $cardNumber;
return $token;
}
public function charge($amount, $token)
{
if ($this->beforeFirstChargeCallback !== null) {
$callback = $this->beforeFirstChargeCallback;
$this->beforeFirstChargeCallback = null;
$callback($this);
}
if (! $this->tokens->has($token)) {
throw new PaymentFailedException;
}
return $this->charges[] = new Charge([
'amount' => $amount,
'card_last_four' => substr($this->tokens[$token], -4),
]);
}
public function newChargesDuring($callback)
{
$chargesFrom = $this->charges->count();
$callback($this);
return $this->charges->slice($chargesFrom)->reverse()->values();
}
public function totalCharges()
{
return $this->charges->map->amount()->sum();
}
public function beforeFirstCharge($callback)
{
$this->beforeFirstChargeCallback = $callback;
}
}
<?php
// THIS IS THE FAILING TEST
/** @test */
function a_user_can_make_a_payment_on_a_published_fee()
{
//$this->withoutExceptionHandling();
$fee = factory(Fee::class)->states('openlive')->create([
'fee_amount' => 2000, 'charge_app_fee' => true, 'app_fee_percent' => 2
]);
// JSON API Request from the UI
$response = $this->makeAPayment($fee, [
'email' => 'brad@me.com',
'total_paid' => 2040,
'stripeToken' => $this->paymentGateway->getValidTestToken()
]);
// FAILS Here with a 422 PaymentFailedException
// The $this->tokens() collection is always null
$response->assertStatus(201);
$response->assertJson([
'email' => 'brad@me.com',
'total_paid' => 2040
]);
// Assert - An order exists for response payment
$this->assertEquals(2040, $this->paymentGateway->totalCharges());
$payment = $fee->payments()
->where('fee_id', $fee->id)
->where('fee_type', 'FUND')
->where('email', 'brad@me.com')->first();
$this->assertNotNull($payment);
$this->assertEquals(2040, $payment->total_paid);
}
@bmadigan
Copy link
Author

bmadigan commented Oct 22, 2017

If I were to do a dd($this->tokens) right after line number 22 it will display the tokens that was added.
However, if I do the same dd() at say line 33 then the collection is empty thus it is always throwing the PaymentFailedException in all my tests. (Referring to FakePaymentGateway.php)

It used to pass but then I upgraded to Laravel 5.5 and now its failing. I went through your video upgrade and the Laravel upgrade docs but nothing is standing out to me.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment