set('services.supplier.login', 'u'); config()->set('services.supplier.password', 'p'); config()->set('services.supplier.portal_url', 'https://crm.bp-gr.ru'); }); it('переводит остаток номеров в деньги (номера × цена)', function () { config()->set('services.supplier.number_price_rub', 20); $bridge = Mockery::mock(PlaywrightBridge::class); $bridge->shouldReceive('run')->once()->andReturn(['numbers' => 3096]); app()->instance(PlaywrightBridge::class, $bridge); $r = app(SupplierBalanceProvider::class)->fetch(); expect($r->ok)->toBeTrue(); expect($r->balance)->toBe(61920.0); // 3096 × 20 ₽ expect($r->serviceKey)->toBe('supplier'); }); it('нет числа номеров в ответе → fail', function () { $bridge = Mockery::mock(PlaywrightBridge::class); $bridge->shouldReceive('run')->once()->andReturn(['oops' => true]); app()->instance(PlaywrightBridge::class, $bridge); $r = app(SupplierBalanceProvider::class)->fetch(); expect($r->ok)->toBeFalse(); }); it('мост бросил → fail, не пробрасывает исключение', function () { $bridge = Mockery::mock(PlaywrightBridge::class); $bridge->shouldReceive('run')->andThrow(new RuntimeException('exit 2: balance not found')); app()->instance(PlaywrightBridge::class, $bridge); $r = app(SupplierBalanceProvider::class)->fetch(); expect($r->ok)->toBeFalse(); expect($r->error)->toContain('exit 2'); }); it('нет логина → fail без запуска моста', function () { config()->set('services.supplier.login', ''); $bridge = Mockery::mock(PlaywrightBridge::class); $bridge->shouldNotReceive('run'); app()->instance(PlaywrightBridge::class, $bridge); $r = app(SupplierBalanceProvider::class)->fetch(); expect($r->ok)->toBeFalse(); });