---
title: "Testovanie — Purchases for Laravel | Roundly"
description: "Testujte nákupné toky bez skutočných platieb a sieťových volaní — Purchases::fake() zaznamená handle(), sync() aj replay(); FakeResult a PayloadFactory."
url: https://roundly-consulting.com/sk/open-source/navody/purchases-for-laravel/testovanie
language: sk
---

[Všetky balíky](https://roundly-consulting.com/sk/open-source.md)

[Purchases for Laravel](https://roundly-consulting.com/sk/open-source/navody/purchases-for-laravel.md)

# Testovanie

Purchases::fake() nahradí manažéra — za fasádou aj všade, kde sa injektuje PurchasesManager (webhook controller, purchases:replay, vaše vlastné služby) — spy objektom PurchasesFake a vráti ho. Zaznamená každé volanie handle(), sync() a replay() a pritom stále beží skutočný pipeline ukladania, takže sa zapíšu riadky a spustia vaše listenery (ak ich nechcete, pridajte Event::fake()). Výsledky zaradené cez push() preskočia overenie podpisu; handle() vo fake navyše vynechá auditný log aj frontu, kým sync() a replay() bežia presne ako v produkcii:

```php
use Illuminate\Http\Request;
use RoundlyConsulting\Purchases\Facades\Purchases;
use RoundlyConsulting\Purchases\Models\Subscription;
use RoundlyConsulting\Purchases\Testing\FakeResult;

it('starts a subscription from a Stripe webhook', function () {
    $fake = Purchases::fake();
    $fake->push('stripe', FakeResult::subscription('stripe', 'sub_1'));

    $model = Purchases::handle('stripe', Request::create('/', 'POST'));
    Purchases::sync(FakeResult::purchase('apple', 'txn_1'));

    expect($model)->toBeInstanceOf(Subscription::class);

    $fake->assertHandled('stripe');
    $fake->assertHandledCount(1);
    $fake->assertSubscriptionStarted('stripe');    // SubscriptionStarted really fired
    $fake->assertSubscriptionRecorded('stripe');   // a subscription result arrived
    $fake->assertSynced('apple');
    $fake->assertPurchaseRecorded('apple');
});
```

## Asercie

| Metóda | Prejde, keď / vracia |
| --- | --- |
| `push($provider, $result)` | Zaradí výsledok, ktorý vráti najbližšie result() / handle() pre daného poskytovateľa — bez overenia podpisu. |
| `handledResults() / syncedResults()` | Kolekcia všetkých výsledkov z handle() / sync() pre vlastné asercie. |
| `assertHandled($provider)` | handle() dostalo výsledok pre daného poskytovateľa. |
| `assertHandledCount($count)` | handle() dostalo presne $count výsledkov. |
| `assertNothingHandled()` | handle() sa nikdy nezavolalo. |
| `assertSynced(?$provider)` | sync() dostalo výsledok (pre daného poskytovateľa). |
| `assertNothingSynced()` | sync() sa nikdy nezavolalo. |
| `assertReplayed(?$notification)` | Niečo sa znova spracovalo — alebo práve táto notifikácia (model alebo id). |
| `assertNothingReplayed()` | Nič sa znova nespracovalo. |
| `assertPurchaseRecorded(?$provider)` | Nákup prišiel cez handle(), sync() alebo replay(). |
| `assertSubscriptionStarted(?$provider)` | SubscriptionStarted sa naozaj spustila (pre daného poskytovateľa) — predplatné vzniklo aktívne alebo prvýkrát začalo platiť, nejde o obnovu ani zrušenie. Zachytí ju aj pod Event::fake(). |
| `assertSubscriptionRecorded(?$provider)` | Výsledok typu predplatné prišiel ktoroukoľvek z nich, nech s predplatným urobil čokoľvek. |
| `assertRefundRecorded(?$provider)` | Refundácia alebo chargeback prišli ktoroukoľvek z nich. |

Zaznamenajú sa aj opätovné spracovania, vrátane tých, ktoré spustí príkaz:

```php
$fake = Purchases::fake();

$this->artisan('purchases:replay', ['id' => $notification->id]);   // the command injects PurchasesManager

$fake->assertReplayed($notification);   // or its id; assertReplayed() alone = anything replayed
$fake->assertNothingHandled();
$fake->assertNothingSynced();
```

Odmietnuté opätovné spracovanie sa nezaznamená. Pomocníky z HasPurchases iba čítajú, takže nezaznamenajú nič — delegujú však na manažéra, a preto používajú fake.

## FakeResult

FakeResult vytvára hotové GenericResult tak, ako to robia skutoční poskytovatelia: jedno id — zadané alebo vygenerované — je providerId() aj transactionId() a occurredAt() je čas, ktorý odovzdáte, inak aktuálny čas, takže poradie udalostí platí aj pre falošné doručenia:

```php
use RoundlyConsulting\Purchases\Enum\Status;
use RoundlyConsulting\Purchases\Testing\FakeResult;

FakeResult::purchase('stripe', 'pi_1');                                    // Completed, 9.99 USD
FakeResult::purchase('apple', status: Status::Failed);
FakeResult::subscription('google', 'sub_1', Status::InGracePeriod, 'pro'); // 19.99 USD, ends in a month
FakeResult::refund('stripe', 're_1');                                      // reason requested_by_customer
FakeResult::refund('stripe', 'dp_1', chargeback: true);                    // a dispute

// One id is both providerId() and transactionId(); occurredAt() is now unless given.
FakeResult::subscription('stripe', 'sub_1', occurredAt: now()->subHour()); // older than the last applied event: changes nothing
```

## Payloady poskytovateľov

PayloadFactory vytvára surové payloady v tvare obchodov — appleNotification(), googleEnvelope(), googleSubscriptionNotification(), googleVoidedNotification() a stripeEvent() — na end-to-end testy skutočných poskytovateľov. Notifikácia Google sa po vypnutí autentifikácie pushov dekóduje bez siete; uloženie RTDN o predplatnom navyše číta subscriptionsv2, preto toto volanie nahraďte cez Http::fake():

```php
use Illuminate\Http\Request;
use RoundlyConsulting\Purchases\Providers\Google\Google;
use RoundlyConsulting\Purchases\Testing\PayloadFactory;

it('decodes a Google renewal notification', function () {
    // Proving the push came from Google is not this test's job.
    config()->set('purchases.settings.google.push.authenticate', false);

    $request = new Request(PayloadFactory::googleEnvelope(
        PayloadFactory::googleSubscriptionNotification(type: 2, token: 'token-1'),   // 2 = renewed
    ));

    $notification = app(Google::class)->notification($request);

    expect($notification->subscriptionNotification?->purchaseToken)->toBe('token-1');
});
```

Obe metódy pre RTDN z Google uvádzajú nakonfigurované purchases.settings.google.package\_name (com.example.app, ak nie je nastavené) — RTDN pre iný package name sa len zaznamená do auditu.

Pri Stripe podpíšte payload testovacím webhook kľúčom presne tak, ako to robí Stripe. Objektu payment\_intent.\* dajte výslovné pole invoice a objektu invoice.paid výslovné pole payment\_intent — bez nich sa balík pýta Invoice Payments API v Stripe, preto toto volanie nahraďte cez Http::fake() alebo ich nastavte na null:

```php
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Event;
use RoundlyConsulting\Purchases\Events\PurchaseCompleted;
use RoundlyConsulting\Purchases\Facades\Purchases;
use RoundlyConsulting\Purchases\Testing\PayloadFactory;

it('records a signed Stripe payment', function () {
    Event::fake([PurchaseCompleted::class]);
    config()->set('purchases.settings.stripe.webhook_secret', 'whsec_test');

    $payload = (string) json_encode(PayloadFactory::stripeEvent('payment_intent.succeeded', [
        'id' => 'pi_1', 'status' => 'succeeded', 'amount' => 1000, 'currency' => 'usd',
        'invoice' => null,   // pays no invoice — no Invoice Payments lookup needed
    ]));

    $timestamp = now()->getTimestamp();
    $signature = hash_hmac('sha256', "{$timestamp}.{$payload}", 'whsec_test');

    $request = Request::create('/', 'POST', content: $payload);
    $request->headers->set('Stripe-Signature', "t={$timestamp},v1={$signature}");

    $purchase = Purchases::handle('stripe', $request);

    expect($purchase->price->minor())->toBe('1000');
    Event::assertDispatched(PurchaseCompleted::class);
});
```

Testy spúšťajte s načítanými publikovanými migráciami (RefreshDatabase).

## Prejavte lásku k open source

Tento balík je zadarmo pod licenciou MIT. Ak vám šetrí čas, jednorazový príspevok alebo členstvo na Patreone nám pomôže ho ďalej udržiavať, testovať a dokumentovať.

[Ďalšie spôsoby podpory vrátane kryptomien](https://roundly-consulting.com/sk/podporte-nas.md)

Odoslaním daru súhlasíte s našimi [podmienkami prijímania darov](https://roundly-consulting.com/sk/podmienky-darov.md).

[Podporte našu open-source prácu (otvorí sa v novej karte)](https://donate.stripe.com/dRmeVe8FX5PF1Qd9pXcEw00) [Pridajte sa k nám na Patreone (otvorí sa v novej karte)](https://www.patreon.com/cw/roundly)

## Chcete to zabudovať do svojho produktu?

Naše balíky integrujeme do zákazkových Laravel a AI riešení. Napíšte nám, na čom pracujete, a ozveme sa do 48 hodín.

[Ponuka do 48 hodín](https://roundly-consulting.com/sk/kontakt.md) [Prezrieť všetky balíky](https://roundly-consulting.com/sk/open-source/navody/purchases-for-laravel.md)
