106 lines
3.3 KiB
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);
|
|
}
|
|
}
|