72 lines
2.3 KiB
PHP
72 lines
2.3 KiB
PHP
<?php
|
|
|
|
use App\Actions\GrantAddon;
|
|
use App\Actions\OpenSubscription;
|
|
use App\Models\Operator;
|
|
use App\Models\Order;
|
|
use App\Models\Subscription;
|
|
use App\Services\Billing\AddonCatalogue;
|
|
|
|
/**
|
|
* "Ein Plugin schenken" — a module given for free or at a discount, booked
|
|
* through the same BookAddon a paid order uses.
|
|
*/
|
|
function subscriptionForGrant(): Subscription
|
|
{
|
|
$order = Order::factory()->create(['plan' => 'team', 'datacenter' => 'fsn', 'status' => 'paid']);
|
|
|
|
return app(OpenSubscription::class)($order);
|
|
}
|
|
|
|
it('books a module at zero cost, with provenance on the row', function () {
|
|
$subscription = subscriptionForGrant();
|
|
$owner = Operator::factory()->create();
|
|
|
|
$addon = app(GrantAddon::class)(
|
|
subscription: $subscription,
|
|
grantedBy: $owner,
|
|
addonKey: 'priority_support',
|
|
priceCents: 0,
|
|
note: 'Entschuldigung für die Störung',
|
|
);
|
|
|
|
$catalogue = app(AddonCatalogue::class)->priceCents('priority_support');
|
|
|
|
expect($addon->price_cents)->toBe(0)
|
|
->and($addon->isGranted())->toBeTrue()
|
|
->and($addon->granted_by)->toBe($owner->id)
|
|
->and($addon->grant_note)->toBe('Entschuldigung für die Störung')
|
|
->and($addon->catalogue_price_cents)->toBe($catalogue)
|
|
->and($addon->order->stripe_event_id)->toBeNull()
|
|
->and($addon->order->amount_cents)->toBe(0);
|
|
});
|
|
|
|
it('books a discounted module below the catalogue price', function () {
|
|
$subscription = subscriptionForGrant();
|
|
$owner = Operator::factory()->create();
|
|
$catalogue = app(AddonCatalogue::class)->priceCents('collabora_pro');
|
|
|
|
$addon = app(GrantAddon::class)(
|
|
subscription: $subscription,
|
|
grantedBy: $owner,
|
|
addonKey: 'collabora_pro',
|
|
priceCents: $catalogue - 500,
|
|
);
|
|
|
|
expect($addon->price_cents)->toBe($catalogue - 500)
|
|
->and($addon->isGranted())->toBeTrue();
|
|
});
|
|
|
|
it('refuses to charge more for a granted module than it actually costs', function () {
|
|
$subscription = subscriptionForGrant();
|
|
$owner = Operator::factory()->create();
|
|
$catalogue = app(AddonCatalogue::class)->priceCents('extra_backups');
|
|
|
|
expect(fn () => app(GrantAddon::class)(
|
|
subscription: $subscription,
|
|
grantedBy: $owner,
|
|
addonKey: 'extra_backups',
|
|
priceCents: $catalogue + 1,
|
|
))->toThrow(RuntimeException::class);
|
|
});
|