diff --git a/app/Provisioning/Steps/Customer/ResizeVirtualMachine.php b/app/Provisioning/Steps/Customer/ResizeVirtualMachine.php index e2a930c..d1b582a 100644 --- a/app/Provisioning/Steps/Customer/ResizeVirtualMachine.php +++ b/app/Provisioning/Steps/Customer/ResizeVirtualMachine.php @@ -111,8 +111,19 @@ class ResizeVirtualMachine extends CustomerStep $allowance = StorageAllowance::for($instance); + // Kontingent + Blöcke + Kopfraum des Pakets + Kopfraum der Blöcke. + // + // Der letzte Summand ist der neue: ein Block gibt dem Kunden 20 GB und + // belegt 22, damit die Regel max(10 GB, 12 %) auch für ein gestapeltes + // Paket gilt. Ohne ihn hätte ein Start mit drei Blöcken 90 GB auf 100 GB + // Platte — zehn Gigabyte Kopfraum, wo die Regel zwölf verlangt. + // + // Beide Kopfräume werden gelesen, nicht abgeleitet: der des Pakets aus + // dem eingefrorenen Vertrag, der der Blöcke aus den Buchungen. $target = $allowance->totalGb() > 0 - ? $allowance->totalGb() + max(0, $planDisk - $planQuota) + ? $allowance->totalGb() + + max(0, $planDisk - $planQuota) + + max(0, $allowance->packDiskGb() - $allowance->packGb()) : $planDisk; $actual = (int) $instance->disk_gb; diff --git a/tests/Feature/Provisioning/StoragePackHeadroomTest.php b/tests/Feature/Provisioning/StoragePackHeadroomTest.php new file mode 100644 index 0000000..cea8fa1 --- /dev/null +++ b/tests/Feature/Provisioning/StoragePackHeadroomTest.php @@ -0,0 +1,66 @@ +totalGb() + + max(0, $planDisk - $planQuota) + + ($allowance->packDiskGb() - $allowance->packGb()); + + expect($target)->toBe(106); +}); + +// Den Schritt selbst fahren: reservedRun() (aus CustomerStepsTest.php) baut ein +// 'start'-Paket (100 GB Kontingent, 120 GB Platte — 20 GB Kopfraum des Pakets). +// Drei Blöcke zu 20 GB nutzbar / 22 GB belegt kommen direkt als +// SubscriptionAddon-Zeile dazu, statt über BookAddon zu buchen — das würde +// einen Lieferlauf anstoßen und Stripe befragen, was hier nichts zur Sache tut; +// gefragt ist nur, was ResizeVirtualMachine aus einer bereits gebuchten Zeile +// macht. +// +// Ziel: 100 (Kontingent) + 60 (drei Blöcke à 20) + 20 (Kopfraum des Pakets, +// 120-100) + 6 (Kopfraum der Blöcke, 66-60 belegt) = 186 GB. +it('vergrößert die Platte um Paket- und Block-Kopfraum, und nur einmal', function () { + $s = fakeServices(); + ['run' => $run, 'instance' => $instance, 'order' => $order] = reservedRun(); + + SubscriptionAddon::create([ + 'subscription_id' => $order->subscription->id, + 'addon_key' => AddonCatalogue::STORAGE, + 'price_cents' => 1000, + 'currency' => 'EUR', + 'quantity' => 3, + 'booked_at' => now(), + 'pack_gb' => 20, + 'pack_disk_gb' => 22, + ]); + + expect(app(ResizeVirtualMachine::class)->execute($run)->type)->toBe('advance') + ->and($s['pve']->resizeCalls)->toContain('101:scsi0:186G') + ->and($instance->fresh()->disk_gb)->toBe(186); + + // Wiederholungslauf: das Ziel ist absolut, nicht '+…', also darf ein + // zweiter Durchlauf nicht noch einmal vergrößern. + $s['pve']->resizeCalls = []; + expect(app(ResizeVirtualMachine::class)->execute($run->fresh())->type)->toBe('advance') + ->and($s['pve']->resizeCalls)->toBe([]) + ->and($instance->fresh()->disk_gb)->toBe(186); +});