diff --git a/composer.json b/composer.json index 214190a..8e2514c 100644 --- a/composer.json +++ b/composer.json @@ -32,9 +32,9 @@ "php": ">=8.2", "guzzlehttp/guzzle": "^7.10 || ^8.0", "phpunit/phpunit": "*", - "behat/behat": "^3.29", + "behat/behat": "^3.29 || ^4.0", "libresign/behat-builtin-extension": "^0.7.1", - "estahn/json-query-wrapper": "*" + "symfony/process": "^6.4 || ^7.0" }, "require-dev": { "bamarni/composer-bin-plugin": "^1.9", diff --git a/psalm-baseline.xml b/psalm-baseline.xml index b6fd750..2ca56b7 100644 --- a/psalm-baseline.xml +++ b/psalm-baseline.xml @@ -1,9 +1,3 @@ - - - - - - diff --git a/src/NextcloudApiContext.php b/src/NextcloudApiContext.php index e2dd98a..64efc99 100644 --- a/src/NextcloudApiContext.php +++ b/src/NextcloudApiContext.php @@ -19,6 +19,8 @@ use PhpBuiltin\RunServerListener; use PHPUnit\Framework\Assert; use Psr\Http\Message\ResponseInterface; +use Symfony\Component\Process\ExecutableFinder; +use Symfony\Component\Process\Process; /** * Defines application features from the specific context. @@ -26,8 +28,8 @@ class NextcloudApiContext implements Context { protected string $testPassword = '123456'; protected string $adminPassword = 'admin'; - protected string $baseUrl; - protected RunServerListener $server; + protected string $baseUrl = ''; + protected ?RunServerListener $server = null; protected string $currentUser = ''; protected array $fields = []; protected static array $environments = []; @@ -47,8 +49,6 @@ class NextcloudApiContext implements Context { protected array $requestOptions = []; public function __construct(?array $parameters = []) { - $this->server = RunServerListener::getInstance(); - $this->baseUrl = RunServerListener::getServerRoot(); $this->response = new Response(); $this->cookieJars = []; if (isset($parameters['test_password'])) { @@ -223,6 +223,11 @@ public function sendRequest(string $verb, string $url, $body = null, array $head if (strpos($url, '/ocs/v2.php') === false) { $url = '/index.php' . $url; } + if ($this->baseUrl === '') { + // Behat 4 may instantiate contexts before the server listener exists. + $this->server = RunServerListener::getInstance(); + $this->baseUrl = RunServerListener::getServerRoot(); + } if (str_ends_with($this->baseUrl, '/')) { $this->baseUrl = rtrim($this->baseUrl, '/'); } @@ -443,15 +448,20 @@ private function testAndGetActualValue(array $value, string $json): string { * @return mixed */ private function evalJsonQuery(string $jsonQuery, string $target) { - Assert::assertNotEmpty(`which jq`, 'Is necessary install the jq command to use jq'); - $jq = \JsonQueryWrapper\JsonQueryFactory::createWith($target); - return $jq->run($jsonQuery); + return $this->runJsonQuery($target, $jsonQuery); + } + + private function runJsonQuery(string $json, string $filter): mixed { + Assert::assertNotEmpty((new ExecutableFinder())->find('jq'), 'Is necessary install the jq command to use jq'); + $process = new Process(['jq', '-M', $filter], null, null, $json); + $process->mustRun(); + $output = trim($process->getOutput()); + $decoded = json_decode($output, true); + return json_last_error() === JSON_ERROR_NONE ? $decoded : $output; } private function validateAsJsonQuery(string $expected, string $actual): void { - Assert::assertNotEmpty(`which jq`, 'Is necessary install the jq command to use jq'); - $jq = \JsonQueryWrapper\JsonQueryFactory::createWith($actual); - $result = $jq->run($expected); + $result = $this->runJsonQuery($actual, $expected); Assert::assertTrue($result, 'The jq "' . $expected . '" do not match with: ' . $actual); } @@ -682,13 +692,13 @@ public static function createAnEnvironmentWithValueToBeUsedByOccCommand(string $ self::$environments[$name] = $value; } - #[Given('/^wait for ([0-9]+) (second|seconds)$/')] + #[Given('/^wait for ([0-9]+) seconds?$/')] public function waitForXSecond(int $seconds): void { $this->startWaitFor = $seconds; sleep($seconds); } - #[Given('/^past ([0-9]+) (second|seconds) since wait step$/')] + #[Given('/^past ([0-9]+) seconds? since wait step$/')] public function pastXSecondsSinceWaitStep(int $seconds): void { $currentTime = time(); $startTime = $currentTime - $this->startWaitFor;