test: add feature tests for loyalty reward and redemption verification, and update redemption UI status display logic.
This commit is contained in:
parent
5c2cb53887
commit
b780c2d92b
@ -67,14 +67,15 @@ class="font-bold uppercase">{{ $foundRedemption->code }}</span></flux:subheading
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@if ($foundRedemption->status === \App\Enums\RedemptionStatus::VERIFIED)
|
||||
@if ($foundRedemption->status === \App\Enums\RedemptionStatus::PICKED_UP)
|
||||
<div
|
||||
class="p-4 bg-zinc-50 dark:bg-zinc-800/50 rounded-lg border border-zinc-200 dark:border-zinc-700">
|
||||
<div class="grid grid-cols-2 gap-4">
|
||||
<div>
|
||||
<div class="text-xs font-semibold text-zinc-500 uppercase tracking-wider mb-1">
|
||||
Diverifikasi Oleh</div>
|
||||
<div class="text-sm">{{ $foundRedemption->verifier?->employee?->full_name ?? 'Sistem' }}</div>
|
||||
<div class="text-sm">
|
||||
{{ $foundRedemption->verifier?->employee?->full_name ?? 'Sistem' }}</div>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs font-semibold text-zinc-500 uppercase tracking-wider mb-1">Waktu
|
||||
|
||||
100
tests/Feature/Studio/Loyalty/RedemptionVerificationTest.php
Normal file
100
tests/Feature/Studio/Loyalty/RedemptionVerificationTest.php
Normal file
@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\RedemptionStatus;
|
||||
use App\Livewire\Studio\Loyalty\RedemptionVerification;
|
||||
use App\Models\Redemption;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->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();
|
||||
});
|
||||
150
tests/Feature/Studio/Loyalty/RewardTest.php
Normal file
150
tests/Feature/Studio/Loyalty/RewardTest.php
Normal file
@ -0,0 +1,150 @@
|
||||
<?php
|
||||
|
||||
use App\Enums\IsShow;
|
||||
use App\Enums\RewardCategory;
|
||||
use App\Livewire\Studio\Loyalty\Reward;
|
||||
use App\Models\Redemption;
|
||||
use App\Models\Reward as RewardModel;
|
||||
use App\Models\Tier;
|
||||
use Livewire\Livewire;
|
||||
use Spatie\Permission\Models\Permission;
|
||||
use Spatie\Permission\Models\Role;
|
||||
|
||||
beforeEach(function () {
|
||||
$this->setupUser();
|
||||
|
||||
$role = Role::firstOrCreate(['name' => 'Owner']);
|
||||
Permission::firstOrCreate(['name' => 'view reward']);
|
||||
Permission::firstOrCreate(['name' => 'create reward']);
|
||||
Permission::firstOrCreate(['name' => 'update reward']);
|
||||
Permission::firstOrCreate(['name' => 'delete reward']);
|
||||
$role->givePermissionTo(['view reward', 'create reward', 'update reward', 'delete reward']);
|
||||
$this->user->assignRole($role);
|
||||
});
|
||||
|
||||
it('renders the reward page correctly', function () {
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.loyalty.reward.index'))
|
||||
->assertOk()
|
||||
->assertSeeLivewire(Reward::class);
|
||||
});
|
||||
|
||||
it('can open create modal', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->call('openModal', 'create', 'Tambah Hadiah')
|
||||
->assertSet('method', 'create')
|
||||
->assertSet('modalTitle', 'Tambah Hadiah');
|
||||
});
|
||||
|
||||
it('shows validation errors on create', function () {
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->call('create')
|
||||
->assertHasErrors([
|
||||
'form.name' => 'required',
|
||||
'form.points' => 'required',
|
||||
'form.start_date' => 'required',
|
||||
'form.tier_ids' => 'required',
|
||||
]);
|
||||
});
|
||||
|
||||
it('can store a new reward', function () {
|
||||
$tier = Tier::factory()->create(['min_spending' => 0]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->set('form.name', 'Hadiah Keren')
|
||||
->set('form.points', '100')
|
||||
->set('form.category', RewardCategory::REGULAR->value)
|
||||
->set('form.is_show', IsShow::SHOW->value)
|
||||
->set('form.start_date', now()->format('Y-m-d'))
|
||||
->set('form.tier_ids', [$tier->id])
|
||||
->call('create')
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
$this->assertDatabaseHas('rewards', [
|
||||
'name' => 'Hadiah Keren',
|
||||
'points' => 100,
|
||||
]);
|
||||
});
|
||||
|
||||
it('can open edit modal and load data', function () {
|
||||
$tier = Tier::factory()->create(['min_spending' => 0]);
|
||||
$reward = RewardModel::factory()->create(['name' => 'Old Name', 'points' => 50]);
|
||||
$reward->tiers()->attach($tier);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->call('openModal', 'update', 'Ubah Hadiah', $reward->hash_id)
|
||||
->set('form.reward', $reward)
|
||||
->set('form.name', 'Old Name')
|
||||
->set('form.points', '50')
|
||||
->assertSet('method', 'update')
|
||||
->assertSet('form.name', 'Old Name')
|
||||
->assertSet('form.points', '50');
|
||||
});
|
||||
|
||||
it('can update a reward', function () {
|
||||
$tier = Tier::factory()->create(['min_spending' => 0]);
|
||||
$reward = RewardModel::factory()->create(['name' => 'Old Name', 'points' => 50]);
|
||||
$reward->tiers()->attach($tier);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->call('openModal', 'update', 'Ubah Hadiah', $reward->hash_id)
|
||||
->set('form.reward', $reward)
|
||||
->set('form.name', 'Updated Name')
|
||||
->set('form.points', '75')
|
||||
->set('form.category', $reward->category->value)
|
||||
->set('form.is_show', $reward->is_show->value)
|
||||
->set('form.start_date', $reward->start_date)
|
||||
->set('form.tier_ids', [$tier->id])
|
||||
->call('update')
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
$this->assertDatabaseHas('rewards', [
|
||||
'id' => $reward->id,
|
||||
'name' => 'Updated Name',
|
||||
'points' => 75,
|
||||
]);
|
||||
});
|
||||
|
||||
it('cannot update a reward if redemptions exist', function () {
|
||||
$reward = RewardModel::factory()->create();
|
||||
Redemption::factory()->create(['reward_id' => $reward->id]);
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->call('openModal', 'update', 'Ubah Hadiah', $reward->hash_id)
|
||||
->set('form.reward', $reward)
|
||||
->set('form.name', 'Attempt Update')
|
||||
->call('update')
|
||||
->assertHasNoErrors();
|
||||
|
||||
// Verify it didn't change in DB
|
||||
$this->assertDatabaseMissing('rewards', ['id' => $reward->id, 'name' => 'Attempt Update']);
|
||||
});
|
||||
|
||||
it('can delete a reward', function () {
|
||||
$reward = RewardModel::factory()->create();
|
||||
|
||||
Livewire::actingAs($this->user)
|
||||
->test(Reward::class)
|
||||
->call('delete', $reward->id)
|
||||
->assertHasNoErrors()
|
||||
->assertDispatched('refreshDatatable');
|
||||
|
||||
$this->assertSoftDeleted('rewards', ['id' => $reward->id]);
|
||||
});
|
||||
|
||||
it('cannot access reward page without permission', function () {
|
||||
$this->user->roles()->detach();
|
||||
$this->user->permissions()->detach();
|
||||
|
||||
$this->actingAs($this->user)
|
||||
->get(route('studio.loyalty.reward.index'))
|
||||
->assertForbidden();
|
||||
});
|
||||
Loading…
Reference in New Issue
Block a user