124 lines
4.6 KiB
PHP
124 lines
4.6 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature\Api\V1\Qr;
|
|
|
|
use App\Events\QrBalanceLow;
|
|
use App\Models\Household;
|
|
use App\Models\QrCode;
|
|
use App\Models\QrCodeBatch;
|
|
use App\Models\User;
|
|
use App\Services\Qr\BatchGenerator;
|
|
use App\Services\Qr\QrAllocator;
|
|
use Database\Seeders\RoleSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\Event;
|
|
use Laravel\Sanctum\Sanctum;
|
|
use Tests\TestCase;
|
|
|
|
class MyQrCodeTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->seed(RoleSeeder::class);
|
|
}
|
|
|
|
public function test_balance_returns_zero_for_resident_without_household(): void
|
|
{
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => 'active']);
|
|
Sanctum::actingAs($resident);
|
|
|
|
$this->getJson('/api/v1/me/qr-codes/balance')
|
|
->assertOk()
|
|
->assertJsonPath('data.active', 0);
|
|
}
|
|
|
|
public function test_balance_returns_counts_by_status(): void
|
|
{
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => 'active']);
|
|
$h = Household::factory()->create(['head_user_id' => $resident->id]);
|
|
$batch = app(BatchGenerator::class)->generate(2, QrCodeBatch::PURPOSE_FREE);
|
|
QrCode::query()
|
|
->where('batch_id', $batch->id)
|
|
->update(['assigned_to_household_id' => $h->id, 'status' => 'active']);
|
|
Sanctum::actingAs($resident);
|
|
|
|
$this->getJson('/api/v1/me/qr-codes/balance')
|
|
->assertOk()
|
|
->assertJsonPath('data.active', 2)
|
|
->assertJsonPath('data.low_balance', true);
|
|
}
|
|
|
|
public function test_resident_can_list_own_codes(): void
|
|
{
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => 'active']);
|
|
$h = Household::factory()->create(['head_user_id' => $resident->id]);
|
|
$batch = app(BatchGenerator::class)->generate(3, QrCodeBatch::PURPOSE_FREE);
|
|
QrCode::query()
|
|
->where('batch_id', $batch->id)
|
|
->update(['assigned_to_household_id' => $h->id, 'status' => 'active']);
|
|
Sanctum::actingAs($resident);
|
|
|
|
$response = $this->getJson('/api/v1/me/qr-codes');
|
|
|
|
$response->assertOk();
|
|
$this->assertCount(3, $response->json('data'));
|
|
}
|
|
|
|
public function test_resident_can_activate_an_allocated_code(): void
|
|
{
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => 'active']);
|
|
$h = Household::factory()->create(['head_user_id' => $resident->id]);
|
|
$batch = app(BatchGenerator::class)->generate(1, QrCodeBatch::PURPOSE_FREE);
|
|
$code = QrCode::query()->where('batch_id', $batch->id)->first();
|
|
$code->forceFill([
|
|
'assigned_to_household_id' => $h->id,
|
|
'status' => 'allocated',
|
|
'allocated_at' => now(),
|
|
])->save();
|
|
Sanctum::actingAs($resident);
|
|
|
|
$response = $this->postJson("/api/v1/me/qr-codes/{$code->serial}/activate");
|
|
|
|
$response->assertOk()
|
|
->assertJsonPath('data.status', 'active');
|
|
$this->assertNotNull($code->fresh()->activated_at);
|
|
}
|
|
|
|
public function test_resident_cannot_activate_other_household_code(): void
|
|
{
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => 'active']);
|
|
$other = User::factory()->create(['role' => User::ROLE_RESIDENT]);
|
|
$otherHousehold = Household::factory()->create(['head_user_id' => $other->id]);
|
|
$batch = app(BatchGenerator::class)->generate(1, QrCodeBatch::PURPOSE_FREE);
|
|
$code = QrCode::query()->where('batch_id', $batch->id)->first();
|
|
$code->forceFill([
|
|
'assigned_to_household_id' => $otherHousehold->id,
|
|
'status' => 'allocated',
|
|
])->save();
|
|
Sanctum::actingAs($resident);
|
|
|
|
$this->postJson("/api/v1/me/qr-codes/{$code->serial}/activate")
|
|
->assertStatus(403);
|
|
}
|
|
|
|
public function test_low_balance_event_dispatched_when_count_below_threshold(): void
|
|
{
|
|
Event::fake([QrBalanceLow::class]);
|
|
|
|
$resident = User::factory()->create(['role' => User::ROLE_RESIDENT, 'status' => 'active']);
|
|
$h = Household::factory()->create(['head_user_id' => $resident->id]);
|
|
|
|
$batch = app(BatchGenerator::class)->generate(2, QrCodeBatch::PURPOSE_FREE);
|
|
QrCode::query()->where('batch_id', $batch->id)
|
|
->update(['assigned_to_household_id' => $h->id, 'status' => 'active']);
|
|
|
|
app(QrAllocator::class)->notifyBalanceIfLow($h);
|
|
|
|
Event::assertDispatched(QrBalanceLow::class, fn ($e) => $e->household->id === $h->id && $e->activeCount === 2,
|
|
);
|
|
}
|
|
}
|