Testing

Use the array store

Keep wizard state in memory during tests:

// tests/TestCase.php or a Pest beforeEach()
config(['wizard.default' => 'array']);

The session store works in tests too: Laravel’s array session driver keeps the state for the duration of a test.

Test a flow through the wizard API

use App\Wizards\OrderWizard;
use Invelity\WizardPackage\Facades\Wizard;

it('quotes the price of a parcel', function () {
    $wizard = Wizard::for(OrderWizard::class);

    $data = $wizard->process('calculator', ['weight' => '2']);

    expect($data['price'])->toBe(9.0)
        ->and($wizard->current()->id())->toBe('personal-data');
});

it('refuses the summary before the calculator', function () {
    expect(Wizard::for(OrderWizard::class)->canAccess('summary'))->toBeFalse();
});

Validation failures throw Laravel’s ValidationException:

it('requires a weight', function () {
    Wizard::for(OrderWizard::class)->process('calculator', []);
})->throws(Illuminate\Validation\ValidationException::class);

Test your controllers

it('moves to the next step', function () {
    $this->post('/order/calculator', ['weight' => '2'])
        ->assertRedirect('/order/personal-data');
});

it('keeps visitors on the steps they may open', function () {
    $this->get('/order/summary')->assertRedirect('/order/calculator');
});

Arrange a wizard in a given state

Drive the wizard instead of writing raw state. That way the arrangement goes through the same rules as production:

beforeEach(function () {
    $this->wizard = Wizard::for(OrderWizard::class);
    $this->wizard->process('calculator', ['weight' => '2']);
    $this->wizard->process('personal-data', ['name' => 'Jane', 'email' => 'jane@example.com']);
});

Wizards of other visitors, in tests for jobs or admin screens:

$wizard = Wizard::for(OrderWizard::class, $user);

Assert events

use Illuminate\Support\Facades\Event;
use Invelity\WizardPackage\Events\WizardCompleted;

Event::fake([WizardCompleted::class]);

// ... complete the wizard ...

Event::assertDispatched(fn (WizardCompleted $event) => $event->wizard === OrderWizard::class);