setupUser(); $role = Role::firstOrCreate(['name' => 'Owner']); Permission::firstOrCreate(['name' => 'view redemption']); Permission::firstOrCreate(['name' => 'update redemption']); $role->givePermissionTo(['view redemption', 'update redemption']); $this->user->assignRole($role); }); it('renders the redemption verification page correctly', function () { $this->actingAs($this->user) ->get(route('studio.loyalty.redemption.index')) ->assertOk() ->assertSeeLivewire(RedemptionVerification::class); }); it('can search for a redemption code', function () { $redemption = Redemption::factory()->create(['code' => 'ABC123XYZ']); Livewire::actingAs($this->user) ->test(RedemptionVerification::class) ->set('searchCode', 'abc123xyz ') // Testing case insensitivity and trimming ->call('search') ->assertSet('foundRedemption.id', $redemption->id); }); it('shows error if redemption code not found', function () { Livewire::actingAs($this->user) ->test(RedemptionVerification::class) ->set('searchCode', 'NONEXISTENT') ->call('search') ->assertSet('foundRedemption', null); }); it('can verify a redemption', function () { $redemption = Redemption::factory()->create([ 'code' => 'TESTCODE', 'status' => RedemptionStatus::WAITING_PICKUP, 'expires_at' => now()->addDay(), ]); Livewire::actingAs($this->user) ->test(RedemptionVerification::class) ->set('searchCode', 'TESTCODE') ->call('search') ->call('verify'); $redemption->refresh(); expect($redemption->status)->toBe(RedemptionStatus::PICKED_UP); expect($redemption->verified_by)->toBe($this->user->id); }); it('cannot verify expired redemption', function () { $redemption = Redemption::factory()->create([ 'code' => 'EXPIRED', 'status' => RedemptionStatus::WAITING_PICKUP, 'expires_at' => now()->subDay(), ]); Livewire::actingAs($this->user) ->test(RedemptionVerification::class) ->set('searchCode', 'EXPIRED') ->call('search') ->call('verify'); $redemption->refresh(); expect($redemption->status)->toBe(RedemptionStatus::EXPIRED); }); it('cannot verify already processed redemption', function () { $redemption = Redemption::factory()->verified($this->user)->create(['code' => 'PROCESSED']); Livewire::actingAs($this->user) ->test(RedemptionVerification::class) ->set('searchCode', 'PROCESSED') ->call('search') ->call('verify'); $redemption->refresh(); expect($redemption->status)->toBe(RedemptionStatus::PICKED_UP); // Remains picked up }); it('cannot access redemption verification without permission', function () { $this->user->roles()->detach(); $this->user->permissions()->detach(); $this->actingAs($this->user) ->get(route('studio.loyalty.redemption.index')) ->assertForbidden(); });