83 lines
3.4 KiB
PHP
83 lines
3.4 KiB
PHP
|
|
<?php
|
||
|
|
|
||
|
|
declare(strict_types=1);
|
||
|
|
|
||
|
|
use App\Exceptions\Billing\InsufficientBalanceException;
|
||
|
|
use App\Models\BalanceTransaction;
|
||
|
|
use App\Models\SalesSmsCampaign;
|
||
|
|
use App\Models\Tenant;
|
||
|
|
use App\Services\Sms\SmsChargeService;
|
||
|
|
use Illuminate\Foundation\Testing\DatabaseTransactions;
|
||
|
|
use Tests\Concerns\SharesSupplierPdo;
|
||
|
|
|
||
|
|
uses(DatabaseTransactions::class, SharesSupplierPdo::class);
|
||
|
|
|
||
|
|
it('пока клиента нет — с баланса не списывает, но кампанию не ломает', function () {
|
||
|
|
$campaign = SalesSmsCampaign::create([
|
||
|
|
'title' => 'Своя', 'body' => 'текст', 'created_by' => 1, 'tenant_id' => null,
|
||
|
|
]);
|
||
|
|
|
||
|
|
(new SmsChargeService)->charge($campaign, '150.00');
|
||
|
|
|
||
|
|
expect($campaign->refresh()->balance_transaction_id)->toBeNull();
|
||
|
|
});
|
||
|
|
|
||
|
|
it('списывает с баланса клиента и пишет операцию', function () {
|
||
|
|
$tenant = Tenant::factory()->create(['balance_rub' => '1000.00']);
|
||
|
|
$campaign = SalesSmsCampaign::create([
|
||
|
|
'title' => 'Клиентская', 'body' => 'текст', 'created_by' => 1, 'tenant_id' => $tenant->id,
|
||
|
|
]);
|
||
|
|
|
||
|
|
(new SmsChargeService)->charge($campaign, '150.00');
|
||
|
|
|
||
|
|
expect((string) $tenant->refresh()->balance_rub)->toBe('850.00')
|
||
|
|
->and($campaign->refresh()->balance_transaction_id)->not->toBeNull();
|
||
|
|
|
||
|
|
$tx = BalanceTransaction::find($campaign->balance_transaction_id);
|
||
|
|
expect($tx->type)->toBe(BalanceTransaction::TYPE_SMS_CHARGE)
|
||
|
|
->and($tx->amount_rub)->toBe('-150.00');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('повторный запуск не списывает второй раз', function () {
|
||
|
|
$tenant = Tenant::factory()->create(['balance_rub' => '1000.00']);
|
||
|
|
$campaign = SalesSmsCampaign::create([
|
||
|
|
'title' => 'Повтор', 'body' => 'текст', 'created_by' => 1, 'tenant_id' => $tenant->id,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$service = new SmsChargeService;
|
||
|
|
$service->charge($campaign, '150.00');
|
||
|
|
$service->charge($campaign->refresh(), '150.00');
|
||
|
|
|
||
|
|
expect((string) $tenant->refresh()->balance_rub)->toBe('850.00');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('не списывает второй раз, даже если пометка на кампании потерялась', function () {
|
||
|
|
$tenant = Tenant::factory()->create(['balance_rub' => '1000.00']);
|
||
|
|
$campaign = SalesSmsCampaign::create([
|
||
|
|
'title' => 'Обрыв', 'body' => 'текст', 'created_by' => 1, 'tenant_id' => $tenant->id,
|
||
|
|
]);
|
||
|
|
|
||
|
|
(new SmsChargeService)->charge($campaign, '150.00');
|
||
|
|
|
||
|
|
// Имитируем обрыв: деньги списаны, а пометка на кампании не доехала.
|
||
|
|
$campaign->refresh()->update(['balance_transaction_id' => null]);
|
||
|
|
|
||
|
|
(new SmsChargeService)->charge($campaign->refresh(), '150.00');
|
||
|
|
|
||
|
|
// Списание должно остаться ОДНО.
|
||
|
|
expect((string) $tenant->refresh()->balance_rub)->toBe('850.00');
|
||
|
|
});
|
||
|
|
|
||
|
|
it('при нехватке денег не списывает ничего', function () {
|
||
|
|
$tenant = Tenant::factory()->create(['balance_rub' => '10.00']);
|
||
|
|
$campaign = SalesSmsCampaign::create([
|
||
|
|
'title' => 'Бедная', 'body' => 'текст', 'created_by' => 1, 'tenant_id' => $tenant->id,
|
||
|
|
]);
|
||
|
|
|
||
|
|
expect(fn () => (new SmsChargeService)->charge($campaign, '150.00'))
|
||
|
|
->toThrow(InsufficientBalanceException::class);
|
||
|
|
|
||
|
|
expect((string) $tenant->refresh()->balance_rub)->toBe('10.00')
|
||
|
|
->and($campaign->refresh()->balance_transaction_id)->toBeNull();
|
||
|
|
});
|