70 lines
2.5 KiB
PHP
70 lines
2.5 KiB
PHP
<?php
|
|
|
|
use App\Models\Host;
|
|
use App\Models\ProvisioningRun;
|
|
use App\Models\RunResource;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
|
|
it('auto-assigns a uuid and routes by it', function () {
|
|
$host = Host::factory()->create();
|
|
|
|
expect($host->uuid)->not->toBeNull()
|
|
->and($host->getRouteKeyName())->toBe('uuid');
|
|
});
|
|
|
|
it('encrypts api_token_ref at rest but reads it back in clear', function () {
|
|
$host = Host::factory()->create(['api_token_ref' => 'automation@pve!clupilot=s3cr3t']);
|
|
|
|
$raw = DB::table('hosts')->where('id', $host->id)->value('api_token_ref');
|
|
|
|
expect($raw)->not->toContain('s3cr3t')
|
|
->and($host->fresh()->api_token_ref)->toBe('automation@pve!clupilot=s3cr3t');
|
|
});
|
|
|
|
it('casts run context to an array and resolves the polymorphic subject', function () {
|
|
$host = Host::factory()->create();
|
|
$run = ProvisioningRun::factory()->forHost($host)->create(['context' => ['reboot_issued' => true]]);
|
|
|
|
expect($run->fresh()->context)->toBe(['reboot_issued' => true])
|
|
->and($run->fresh()->subject->is($host))->toBeTrue();
|
|
});
|
|
|
|
it('merges and forgets context keys', function () {
|
|
$run = ProvisioningRun::factory()->create(['context' => ['root_password' => 'x']]);
|
|
|
|
$run->mergeContext(['wg_ip' => '10.66.0.5']);
|
|
expect($run->fresh()->context)->toBe(['root_password' => 'x', 'wg_ip' => '10.66.0.5']);
|
|
|
|
$run->forgetContext('root_password');
|
|
expect($run->fresh()->context)->toBe(['wg_ip' => '10.66.0.5']);
|
|
});
|
|
|
|
it('logs append-only step events without an updated_at column', function () {
|
|
$run = ProvisioningRun::factory()->create();
|
|
$event = $run->events()->create(['step' => 'validate_host_input', 'attempt' => 0, 'outcome' => 'advanced']);
|
|
|
|
expect($event->created_at)->not->toBeNull()
|
|
->and(Schema::hasColumn('provisioning_step_events', 'updated_at'))->toBeFalse();
|
|
});
|
|
|
|
it('keeps exactly one run_resource per kind on re-run (idempotency)', function () {
|
|
$host = Host::factory()->create();
|
|
$run = ProvisioningRun::factory()->forHost($host)->create();
|
|
|
|
foreach (range(1, 2) as $_) {
|
|
RunResource::firstOrCreate(
|
|
['run_id' => $run->id, 'kind' => 'wg_peer'],
|
|
['host_id' => $host->id, 'external_id' => 'pubkeyAAA'],
|
|
);
|
|
}
|
|
|
|
expect(RunResource::where('run_id', $run->id)->where('kind', 'wg_peer')->count())->toBe(1);
|
|
});
|
|
|
|
it('computes free committable storage from total minus reserve', function () {
|
|
$host = Host::factory()->create(['total_gb' => 1000, 'reserve_pct' => 15]);
|
|
|
|
expect($host->freeGb())->toBe(850);
|
|
});
|