2026-05-11 02:24:21 +03:00
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
declare(strict_types=1);
|
|
|
|
|
|
|
|
|
|
use App\Exceptions\Supplier\SupplierAuthException;
|
|
|
|
|
use App\Services\Supplier\PlaywrightBridge;
|
|
|
|
|
use App\Services\Supplier\ProcessFactory;
|
|
|
|
|
use Tests\TestCase;
|
|
|
|
|
use Tests\Unit\Supplier\Stubs\StubPlaywrightProcessHandle;
|
|
|
|
|
|
2026-05-11 06:51:22 +03:00
|
|
|
uses(TestCase::class);
|
|
|
|
|
|
2026-05-11 02:24:21 +03:00
|
|
|
test('PlaywrightBridge passes credentials via stdin not argv', function () {
|
|
|
|
|
$stubHandle = new StubPlaywrightProcessHandle(
|
|
|
|
|
successful: true,
|
|
|
|
|
output: json_encode([
|
|
|
|
|
'phpsessid' => 'abc123',
|
|
|
|
|
'csrf' => 'xyz789',
|
|
|
|
|
'refreshed_at' => '2026-05-11T10:00:00Z',
|
|
|
|
|
]),
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$factoryMock = Mockery::mock(ProcessFactory::class);
|
|
|
|
|
/** @var ProcessFactory $factoryMock */
|
|
|
|
|
$factoryMock->shouldReceive('create')->andReturn($stubHandle);
|
|
|
|
|
|
|
|
|
|
$bridge = new PlaywrightBridge($factoryMock);
|
|
|
|
|
$result = $bridge->refreshSession(
|
|
|
|
|
login: 'test_login',
|
|
|
|
|
password: 'test_password',
|
|
|
|
|
url: 'https://crm.bp-gr.ru'
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// Credentials must come through stdin, not argv (avoid leak in ps output)
|
|
|
|
|
$capturedInput = json_decode($stubHandle->capturedInput, true);
|
|
|
|
|
expect($capturedInput)->toBeArray()
|
|
|
|
|
->and($capturedInput['login'])->toBe('test_login')
|
|
|
|
|
->and($capturedInput['password'])->toBe('test_password')
|
|
|
|
|
->and($capturedInput['url'])->toBe('https://crm.bp-gr.ru');
|
|
|
|
|
|
|
|
|
|
expect($stubHandle->capturedTimeout)->toBe(75);
|
|
|
|
|
|
|
|
|
|
expect($result)->toHaveKeys(['phpsessid', 'csrf', 'refreshed_at'])
|
|
|
|
|
->and($result['phpsessid'])->toBe('abc123')
|
|
|
|
|
->and($result['csrf'])->toBe('xyz789');
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('PlaywrightBridge throws SupplierAuthException on non-zero exit', function () {
|
|
|
|
|
$stubHandle = new StubPlaywrightProcessHandle(
|
|
|
|
|
successful: false,
|
|
|
|
|
errorOutput: '{"error":"login rejected"}',
|
|
|
|
|
exitCode: 1,
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$factoryMock = Mockery::mock(ProcessFactory::class);
|
|
|
|
|
$factoryMock->shouldReceive('create')->andReturn($stubHandle);
|
|
|
|
|
|
|
|
|
|
$bridge = new PlaywrightBridge($factoryMock);
|
|
|
|
|
|
|
|
|
|
expect(fn () => $bridge->refreshSession('bad', 'bad', 'https://crm.bp-gr.ru'))
|
|
|
|
|
->toThrow(SupplierAuthException::class);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('PlaywrightBridge throws SupplierAuthException on invalid stdout JSON', function () {
|
|
|
|
|
$stubHandle = new StubPlaywrightProcessHandle(
|
|
|
|
|
successful: true,
|
|
|
|
|
output: 'not valid json{',
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$factoryMock = Mockery::mock(ProcessFactory::class);
|
|
|
|
|
$factoryMock->shouldReceive('create')->andReturn($stubHandle);
|
|
|
|
|
|
|
|
|
|
$bridge = new PlaywrightBridge($factoryMock);
|
|
|
|
|
|
|
|
|
|
expect(fn () => $bridge->refreshSession('a', 'b', 'https://crm.bp-gr.ru'))
|
|
|
|
|
->toThrow(SupplierAuthException::class);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
test('PlaywrightBridge throws SupplierAuthException on missing keys in stdout', function () {
|
|
|
|
|
$stubHandle = new StubPlaywrightProcessHandle(
|
|
|
|
|
successful: true,
|
|
|
|
|
output: json_encode(['phpsessid' => 'a']), // no csrf
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$factoryMock = Mockery::mock(ProcessFactory::class);
|
|
|
|
|
$factoryMock->shouldReceive('create')->andReturn($stubHandle);
|
|
|
|
|
|
|
|
|
|
$bridge = new PlaywrightBridge($factoryMock);
|
|
|
|
|
|
|
|
|
|
expect(fn () => $bridge->refreshSession('a', 'b', 'https://crm.bp-gr.ru'))
|
|
|
|
|
->toThrow(SupplierAuthException::class);
|
|
|
|
|
});
|