lan_kiosk/tests/Feature/SwishTestCase.php
Anna-Sara Sélea df9f1cf17e Swish feature
2026-08-22 16:13:42 +02:00

122 lines
4 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Customer;
use App\Models\Transaction;
use GuzzleHttp\Client;
use GuzzleHttp\Handler\MockHandler;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use GuzzleHttp\Psr7\Response as GuzzleResponse;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;
/**
* Shared setup for the Swish tests.
*
* Runs against an in-memory sqlite database (see phpunit.xml), so nothing here
* can touch the real one, and no call ever leaves the machine.
*/
abstract class SwishTestCase extends TestCase
{
use RefreshDatabase;
/** Requests the fake Swish API received */
protected array $swishRequests = [];
protected function setUp(): void
{
parent::setUp();
config([
'app.swish_api_url' => 'https://mss.cpc.getswish.net',
'app.swish_payee_alias' => '1231181189',
'app.swish_callback_url' => 'https://swish.example.se/webhook/swish',
]);
}
/**
* Stand in for the Swish API. Without a queued response the controller would
* make a real call, so every test that reaches it has to set this up.
*/
protected function fakeSwish(GuzzleResponse $response): void
{
$stack = HandlerStack::create(new MockHandler([$response]));
$stack->push(Middleware::history($this->swishRequests));
$this->app->instance(Client::class, new Client(['handler' => $stack]));
}
protected function fakeSwishAcceptsWithToken(string $token = 'TOKEN123'): void
{
$this->fakeSwish(new GuzzleResponse(201, ['PaymentRequestToken' => $token]));
}
/** The JSON body of the last request sent to Swish */
protected function lastSwishBody(): array
{
$request = end($this->swishRequests)['request'];
return json_decode((string) $request->getBody(), true);
}
protected function customer(array $attributes = []): Customer
{
$customer = new Customer();
// forceFill because the model's $fillable spells amount_left with a space
$customer->forceFill(array_merge([
'lan_id' => 1,
'name' => 'Erik Olsson',
'guardian_name' => 'Vårdnadshavare',
'deposit' => 0,
'amount_left' => 0,
'give_leftover' => 0,
'is_in_group' => 0,
], $attributes))->save();
return $customer;
}
protected function transaction(array $attributes = []): Transaction
{
return Transaction::create(array_merge([
'payment_reference' => 'LAN-TEST0001',
'customer_id' => 1,
'expected_amount' => 100,
'status' => 'pending',
'give_leftover' => 0,
'source' => 'kiosk',
'instruction_uuid' => 'AB23D7406ECE4542A80152D909EF9F6B',
'callback_identifier' => 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee',
], $attributes));
}
/**
* Post a callback the way Swish would, with the identifier as a header.
*/
protected function postCallback(array $payload, ?string $identifier = 'aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee')
{
$headers = $identifier === null ? [] : ['callbackIdentifier' => $identifier];
return $this->postJson('/api/swish', $payload, $headers);
}
protected function paidPayload(array $overrides = []): array
{
return array_merge([
'id' => 'AB23D7406ECE4542A80152D909EF9F6B',
'payeePaymentReference' => 'LAN-TEST0001',
'paymentReference' => '6D6CD7406ECE4542A80152D909EF9F6B',
'payerAlias' => '46701234567',
'payeeAlias' => '1231181189',
'amount' => 100,
'currency' => 'SEK',
'message' => 'vBytes LAN',
'status' => 'PAID',
'errorCode' => null,
'errorMessage' => '',
], $overrides);
}
}