homeos/tests/Feature/PresenceTest.php

106 lines
3.3 KiB
PHP

<?php
namespace Tests\Feature;
use App\Livewire\Modals\ManagePerson;
use App\Livewire\Persons\Index;
use App\Models\Person;
use App\Models\User;
use App\Services\UnifiClient;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\Storage;
use Livewire\Livewire;
use Tests\TestCase;
class PresenceTest extends TestCase
{
use RefreshDatabase;
protected function setUp(): void
{
parent::setUp();
// Never touch a real UniFi controller in tests.
$this->app->bind(UnifiClient::class, fn () => new class extends UnifiClient
{
public function __construct() {}
public function clients(): array
{
return [];
}
public function connectedMacs(): array
{
return [];
}
public function isConfigured(): bool
{
return true;
}
});
}
public function test_person_flips_to_away_only_after_the_debounce(): void
{
config()->set('homeos.presence.away_debounce_minutes', 3);
// Seen 1 min ago (within debounce) → still home.
$recent = Person::create(['name' => 'A', 'mac' => 'aa:bb', 'presence' => 'home', 'last_seen_home_at' => now()->subMinute()]);
// Seen 10 min ago (past debounce) and off wifi → away.
$stale = Person::create(['name' => 'B', 'mac' => 'cc:dd', 'presence' => 'home', 'last_seen_home_at' => now()->subMinutes(10)]);
$this->artisan('presence:poll')->assertSuccessful();
$this->assertSame('home', $recent->fresh()->presence);
$this->assertSame('away', $stale->fresh()->presence);
}
public function test_manage_person_creates_with_an_avatar(): void
{
Storage::fake('public');
$this->actingAs(User::factory()->create());
Livewire::test(ManagePerson::class)
->set('name', 'Boban')
->set('avatar', UploadedFile::fake()->create('me.jpg', 200, 'image/jpeg'))
->call('save')
->assertRedirect(route('persons.index'));
$person = Person::where('name', 'Boban')->first();
$this->assertNotNull($person->avatar_path);
Storage::disk('public')->assertExists($person->avatar_path);
}
public function test_manage_person_edits_an_existing_person(): void
{
$this->actingAs(User::factory()->create());
$person = Person::create(['name' => 'Old', 'presence' => 'unknown']);
Livewire::test(ManagePerson::class, ['person' => $person->uuid])
->assertSet('editing', true)
->set('name', 'New')
->call('save');
$this->assertSame('New', $person->fresh()->name);
}
public function test_deleting_a_person_removes_it_and_its_avatar(): void
{
Storage::fake('public');
$this->actingAs(User::factory()->create());
$path = UploadedFile::fake()->create('a.jpg', 200, 'image/jpeg')->store('avatars', 'public');
$person = Person::create(['name' => 'X', 'presence' => 'home', 'avatar_path' => $path]);
Livewire::test(Index::class)
->set('pendingDelete', $person->uuid)
->call('deletePerson');
$this->assertModelMissing($person);
Storage::disk('public')->assertMissing($path);
}
}