NovinkaZverejnili sme 50+ Laravel balíkov ako open source
Custom AI apps, agents and automation — Roundly ConsultingRoundly
Všetky balíky

Events::fake() vymení manažéra za Testing\EventsFake a vráti ho:

use RoundlyConsulting\Events\Enums\RsvpStatus;
use RoundlyConsulting\Events\Facades\Events;
use RoundlyConsulting\Events\Models\Event;

it('lets a member join the meetup', function (): void {
    $events = Events::fake();
    $member = User::factory()->create();
    $event = Event::factory()->published()->capacity(1)->create();

    $this->actingAs($member)->post("/meetups/{$event->uuid}/join")->assertRedirect();

    $events->assertRsvped($event, $member, RsvpStatus::Going);
    $events->assertNothingCancelled();
    expect($member)->toBeGoingTo($event);
});
  • Je to nahrávací fake, ktorý operácie aj tak vykoná: riadky, miesta, policies, doménové udalosti aj notifikácie sú skutočné, nech bola operácia zavolaná akokoľvek — cez fasádu, injektovaný EventsManager, handle, pod-handle, builder alebo trait modelu. Priame volanie triedy akcie sa nezaznamená.
  • Vymení sa za fasádou aj v kontajneri, takže sa podvrhne aj injektovaný EventsManager.
  • Volanie, ktoré vyhodí výnimku, nezaznamená nič, a rovnako ani to, ktoré vráti okolitá transakcia: v transakcii sa operácia zaznamená pri commite — mimo nej hneď, pričom transakcia RefreshDatabase vášho testu sa počíta ako mimo.
  • Čítania sa nezaznamenávajú a kód pre check-in sa nezaznamená nikdy.

Asercie

Každá EventOperation má dvojicu asercií. ?$event, ?$attendee a ďalšie argumenty sú filtre a null znamená akýkoľvek. Každá asercia je aj na fasáde, takže funguje aj Events::assertRsvped(…):

OperáciaAserciaNegatívna
CreateassertCreated(?Closure)assertNothingCreated()
UpdateassertUpdated(?$event, ?array $keys)assertNothingUpdated()
Delete · RestoreassertDeleted(?$event), assertRestored(?$event)assertNothingDeleted(), assertNothingRestored()
Publish · Unpublish · Postpone · Reschedule · Cancel · CompleteassertPublished(?$event), assertUnpublished(), assertPostponed(), assertRescheduled(), assertCancelled(), assertCompleted()assertNothingPublished(), assertNothingUnpublished(), assertNothingPostponed(), assertNothingRescheduled(), assertNothingCancelled(), assertNothingCompleted()
TransitionassertTransitioned(?$event, ?string $name)assertNothingTransitioned()
MoveOnlineassertMovedOnline(?$event)assertNothingMovedOnline()
TransferOrganizerassertTransferred(?$event, ?Model $to)assertNothingTransferred()
SetPosterassertPosterChanged(?$event, ?bool $removed)assertNoPosterChanged()
CategorizeassertCategorized(?$event, ?$category)assertNothingCategorized()
AttachLabels · SyncLabelsassertLabelled(?$event, ?array $labels)assertNothingLabelled()
DetachLabelsassertUnlabelled(?$event, ?array $labels)assertNothingUnlabelled()
CreateVenue · UpdateVenue · DeleteVenue · RestoreVenue · GeocodeVenueassertVenueCreated(?Closure), assertVenueUpdated(), assertVenueDeleted(), assertVenueRestored(), assertVenueGeocoded()assertNoVenueCreated(), assertNoVenueUpdated(), assertNoVenueDeleted(), assertNoVenueRestored(), assertNoVenueGeocoded()
CreateTier · UpdateTier · DeleteTier · RestoreTierassertTierCreated(?Closure), assertTierUpdated(), assertTierDeleted(), assertTierRestored()assertNoTierCreated(), assertNoTierUpdated(), assertNoTierDeleted(), assertNoTierRestored()
ReorderTiersassertTiersReordered(?$event)assertNoTiersReordered()
RsvpassertRsvped(?$event, ?$attendee, ?RsvpStatus)assertNothingRsvped()
AddAttendee · RemoveAttendeeassertAttendeeAdded(?$event, ?$attendee), assertAttendeeRemoved(?$event, ?$attendee)assertNoAttendeeAdded(), assertNoAttendeeRemoved()
ChangeTier · ChangeGuestsassertTierChanged(?$event), assertGuestsChanged(?$event)assertNoTierChanged(), assertNoGuestsChanged()
ConfirmRsvp · ReleaseHold · RequestPayment · RotateCodeassertRsvpConfirmed(?$event), assertHoldReleased(?$event), assertPaymentRequested(?$event), assertCodeRotated(?$event)assertNoRsvpConfirmed(), assertNoHoldReleased(), assertNoPaymentRequested(), assertNoCodeRotated()
ConfirmPaymentassertPaymentConfirmed(?string $reference)assertNoPaymentConfirmed()
PromoteWaitlistassertPromoted(?$event)assertNothingPromoted()
ForgetAttendeeassertAttendeeForgotten(?$attendee)assertNoAttendeeForgotten()
CheckIn · ManualCheckInassertCheckedIn(?$event, ?$attendee)assertNothingCheckedIn()
UndoCheckInassertCheckInUndone(?$event)assertNoCheckInUndone()
AddCoHost · RemoveCoHostassertCoHostAdded(?$event, ?$host), assertCoHostRemoved(?$event, ?$host)assertNoCoHostAdded(), assertNoCoHostRemoved()
SendInvitation · RevokeInvitationassertInvited(?$event, ?$invitee), assertInvitationRevoked(?$event, ?$invitee)assertNothingInvited(), assertNoInvitationRevoked()
RespondToInvitationassertInvitationAnswered(?$event, ?RsvpResponse)assertNoInvitationAnswered()
Sweep · RepairassertSwept(), assertRepaired()assertNothingSwept(), assertNothingRepaired()
akákoľvekassertPerformed(EventOperation, ?Closure)assertNotPerformed(EventOperation)
—assertNothingHappened()—
  • Kľúče v assertUpdated() sú názvy vlastností UpdateEventData; closures pri miestach konania a typoch vstupeniek dostanú Venue alebo AdmissionTier.
  • assertPromoted() znamená ručné posunutie, ktoré niekoho posunulo; automatické sa ukáže ako operácia, ktorá ho spustila — odmietnutie, sweep, zmena kapacity. assertNothingPromoted() prejde, keď sa nikto neposunul, aj po ručnom posunutí nad prázdnou listinou.
  • assertAttendeeForgotten() je háčik AttendsEvents pri mazaní (trvalé zmazanie); assertCheckedIn() počíta prvé check-iny; assertInvitationAnswered() s RsvpResponse::NotGoing znamená odmietnutie.

Zaznamenané operácie

recorded(?EventOperation) vráti záznamy RecordedEventOperation v poradí volaní — operation, context a result, plus event(), concerns(?Event $event) a model(string $key):

use RoundlyConsulting\Events\Enums\EventOperation;
use RoundlyConsulting\Events\Testing\RecordedEventOperation;

$events->assertPerformed(EventOperation::Cancel, fn (RecordedEventOperation $op): bool => $op->context['reason'] === 'Venue flooded');
expect($events->recorded(EventOperation::Rsvp))->toHaveCount(2);

Kľúče kontextu: event, actor, system a silent pri volaniach handle; data (DTO); reason, starts_at, ends_at, transition, keep_venue, force, removed; organizer, keep_as_host; labels, category; venue, tier, order, rsvp, attendee, guests, host, invitee, response, reference a options. EventOperation má 50 hodnôt, jednu na každý zaznamenaný zápis.

Pest očakávania

Zaregistrujte ich raz — automaticky sa neregistrujú. Každé číta uložené RSVP, takže fungujú s Events::fake() aj bez neho:

// tests/Pest.php
RoundlyConsulting\Events\Testing\EventExpectations::register();

expect($user)->toBeGoingTo($event);
expect($user)->toBeWaitlistedFor($event);
expect($user)->toBeCheckedInTo($event);

Factories

use RoundlyConsulting\Events\Enums\RsvpStatus;
use RoundlyConsulting\Events\Facades\Events;
use RoundlyConsulting\Events\Models\AdmissionTier;
use RoundlyConsulting\Events\Models\Event;
use RoundlyConsulting\Events\Models\Rsvp;
use RoundlyConsulting\Events\Models\Venue;
use RoundlyConsulting\Money\Money;

Events::categories()->make('Jazz')->findOrCreate();   // categories are curated: create one before tagging

$venue = Venue::factory()->at(48.1439, 17.1097)->ownedBy($team)->create();
$event = Event::factory()->organizedBy($user)->at($venue)->capacity(60)->published()
    ->categorized('jazz')->labelled(['Live'])->create();

AdmissionTier::factory()->for($event)->key('supporter')->price(Money::ofMajor('15', 'EUR'))->create();
Rsvp::factory()->for($event)->by($member)->status(RsvpStatus::Waitlisted)->create();   // a row, no seats or counters
FactoryStavy
Event::factory()organizedBy(), at(), online(), startingAt(CarbonImmutable $start, int $hours = 2), capacity(), maxGuests(), unlisted(), private(), withoutWaitlist(), published(), postponed(), rescheduled(), cancelled(), completed(), inPhase(EventPhase $phase, ?string $stamp = null), categorized(string), labelled(array)
Venue::factory()withoutCoordinates(), at(float $latitude, float $longitude), ownedBy(Model $owner)
AdmissionTier::factory()key(string), price(Money), capacity(?int), hidden()
Rsvp::factory()by(Model $attendee), status(RsvpStatus)
EventHost::factory() · EventInvitation::factory()host(Model) · invitee(Model), status(InvitationStatus)
ReminderDelivery::factory()—

Stavy factories zapisujú riadky priamo — bez miest, počítadiel, kódov a notifikácií —, takže keď test potrebuje skutočné účinky, použite fasádu. Factories vymeniteľných modelov vytvárajú vašu nakonfigurovanú podtriedu.

Fasáda Event z Laravelu a fake z lifecycle

use Illuminate\Support\Facades\Event as EventBus;
use RoundlyConsulting\Events\Events\EventPublished;

EventBus::fake([EventPublished::class]);   // fake only what you assert — the lifecycle bridge keeps working
// never EventBus::fake() bare, and never Lifecycles::fake() in an events test
  • Vlastné účinky balíka bežia na udalostiach lifecycle a vlastných doménových udalostiach. Podvrhujte len udalosti, ktoré overujete: Event::fake([EventPublished::class]) ponechá prepojenie s lifecycle aj dôsledky zrušenia funkčné, kým holé Event::fake() umlčí každý listener — žiadne zvýšenie SEQUENCE, žiadne uvoľnené rezervácie, žiadne notifikácie.
  • Events::fake() ani žiadny test podujatí nikdy nekombinujte s Lifecycles::fake(): fake z lifecycle neuloží žiadny prechod, takže stavy sa nikdy nezmenia.
  • Notifikácie overujte cez Notification::fake().

Čas a platby

use Carbon\CarbonImmutable;

CarbonImmutable::setTestNow('2026-11-14 18:30:00');   // RSVP and check-in windows, holds, reminders, completion
config(['events.payments.collector' => FakeCollector::class]);   // your test double for paid ticket types

Zmrazte hodiny: okná RSVP, okná check-inu, rezervácie, pripomienky aj automatické ukončenie z nich čítajú a miestne časy sa čítajú v pásme podujatia. Collector platieb sa volá po commite — vo vašej testovacej transakcii alebo v transakcii aplikácie beží, keď sa táto transakcia potvrdí.

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

Odoslaním daru súhlasíte s našimi podmienkami prijímania darov.

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.