create(['balance_rub' => '500.00', 'balance_leads' => 7]); $tx = app(BillingTopupService::class)->topup($tenant->id, '250.00', null); expect($tx->type)->toBe('topup') ->and($tx->amount_rub)->toBe('250.00') ->and($tx->amount_leads)->toBe(0) ->and($tx->balance_rub_after)->toBe('750.00') ->and($tx->balance_leads_after)->toBe(7); expect((string) $tenant->fresh()->balance_rub)->toBe('750.00'); }); test('topup использует bcmath — нет float-дрейфа на 0.1 + 0.2', function () { $tenant = Tenant::factory()->create(['balance_rub' => '0.10']); app(BillingTopupService::class)->topup($tenant->id, '0.20', null); expect((string) $tenant->fresh()->balance_rub)->toBe('0.30'); }); test('topup фиксирует user_id инициатора', function () { $tenant = Tenant::factory()->create(['balance_rub' => '0.00']); $user = User::factory()->create(['tenant_id' => $tenant->id]); $tx = app(BillingTopupService::class)->topup($tenant->id, '100.00', $user->id); expect($tx->user_id)->toBe($user->id); }); test('topup-строка получает log_hash через append-only hash-chain триггер', function () { $tenant = Tenant::factory()->create(['balance_rub' => '0.00']); $tx = app(BillingTopupService::class)->topup($tenant->id, '100.00', null); $hasHash = DB::table('balance_transactions') ->where('id', $tx->id) ->whereNotNull('log_hash') ->exists(); expect($hasHash)->toBeTrue(); });