homeos/tests/Feature/AddonTest.php

111 lines
3.8 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\Addon;
use App\Services\AddonRegistry;
use App\Services\AddonService;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\DB;
use Tests\TestCase;
class AddonTest extends TestCase
{
use RefreshDatabase;
public function test_registry_exposes_ring_with_state_defaults(): void
{
$addons = AddonRegistry::withState();
$this->assertCount(1, $addons);
$ring = $addons[0];
$this->assertSame('ring', $ring['key']);
$this->assertTrue($ring['cloud']);
$this->assertFalse($ring['installed']);
$this->assertSame('disconnected', $ring['status']);
}
public function test_install_marks_installed(): void
{
app(AddonService::class)->install('ring');
$this->assertDatabaseHas('addons', ['key' => 'ring', 'installed' => true]);
}
public function test_installing_unknown_addon_aborts(): void
{
$this->expectException(\Symfony\Component\HttpKernel\Exception\HttpException::class);
app(AddonService::class)->install('nope');
}
public function test_save_connection_encrypts_config_and_sets_connecting(): void
{
app(AddonService::class)->saveConnection('ring', [
'email' => 'me@example.com',
'password' => 'secret-pw',
'code' => '123456',
]);
$addon = Addon::where('key', 'ring')->first();
$this->assertSame('connecting', $addon->status);
$this->assertSame('me@example.com', $addon->config['email']);
$this->assertSame('secret-pw', $addon->config['password']);
// Stored ciphertext must not contain the plaintext secret.
$raw = DB::table('addons')->where('key', 'ring')->value('config');
$this->assertStringNotContainsString('secret-pw', $raw);
}
public function test_blank_password_keeps_previously_stored_one(): void
{
$service = app(AddonService::class);
$service->saveConnection('ring', ['email' => 'me@example.com', 'password' => 'first-pw']);
$service->saveConnection('ring', ['email' => 'me@example.com', 'password' => '']);
$addon = Addon::where('key', 'ring')->first();
$this->assertSame('first-pw', $addon->config['password']);
}
public function test_uninstall_wipes_secrets(): void
{
$service = app(AddonService::class);
$service->saveConnection('ring', ['email' => 'me@example.com', 'password' => 'secret-pw']);
$service->uninstall('ring');
$addon = Addon::where('key', 'ring')->first();
$this->assertFalse($addon->installed);
$this->assertSame('disconnected', $addon->status);
$this->assertNull($addon->config);
}
public function test_install_and_uninstall_invalidate_the_ingest_gate_cache(): void
{
$key = AddonService::installedCacheKey('ring');
$service = app(AddonService::class);
// Prime a stale "not installed" value, then install → cache must be cleared.
Cache::put($key, false, 60);
$service->install('ring');
$this->assertFalse(Cache::has($key));
// Prime a stale "installed" value, then uninstall → cache must be cleared.
Cache::put($key, true, 60);
$service->uninstall('ring');
$this->assertFalse(Cache::has($key));
}
public function test_mark_status_only_applies_to_installed_addons(): void
{
$service = app(AddonService::class);
// Not installed → ignored.
$service->markStatus('ring', 'connected');
$this->assertNull(Addon::where('key', 'ring')->first()?->connected_at);
$service->install('ring');
$service->markStatus('ring', 'connected');
$this->assertNotNull(Addon::where('key', 'ring')->first()->connected_at);
}
}