From 9e2c04ed8a172b12f2435d0558651db4e2fdafed Mon Sep 17 00:00:00 2001 From: Vitor Mattos Date: Thu, 14 Mar 2024 19:20:06 -0300 Subject: [PATCH] Filter using jq Signed-off-by: Vitor Mattos --- README.md | 7 +++-- features/test.feature | 7 +++-- src/NextcloudApiContext.php | 56 +++++++++++++++++++++++++++---------- 3 files changed, 51 insertions(+), 19 deletions(-) diff --git a/README.md b/README.md index 32b2ca7..8958f0a 100644 --- a/README.md +++ b/README.md @@ -98,8 +98,11 @@ When set the response to: """ And sending "POST" to "/" Then the response should be a JSON array with the following mandatory values - | key | value | - | Foo | (jq).Bar == "33" | + | key | value | + | Foo | (jq).Bar == "33" | + | (jq).Foo | {"Bar":"33"} | + | (jq).Foo | (jq).Bar == "33" | + | (jq).Foo.Bar | 33 | ``` ## Parse initial state diff --git a/features/test.feature b/features/test.feature index 2ee0645..e152172 100644 --- a/features/test.feature +++ b/features/test.feature @@ -58,8 +58,11 @@ Feature: Test this extension """ And sending "POST" to "/" Then the response should be a JSON array with the following mandatory values - | key | value | - | Foo | (jq).Bar == "33" | + | key | value | + | Foo | (jq).Bar == "33" | + | (jq).Foo | {"Bar":"33"} | + | (jq).Foo | (jq).Bar == "33" | + | (jq).Foo.Bar | 33 | Scenario: Test initial state with string When set the response to: diff --git a/src/NextcloudApiContext.php b/src/NextcloudApiContext.php index 25309e4..bb19aa2 100644 --- a/src/NextcloudApiContext.php +++ b/src/NextcloudApiContext.php @@ -245,27 +245,17 @@ public function theResponseShouldHaveStatusCode($code): void { public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(TableNode $table): void { $this->response->getBody()->seek(0); $expectedValues = $table->getColumnsHash(); - $realResponseArray = json_decode($this->response->getBody()->getContents(), true); + $json = $this->response->getBody()->getContents(); $this->response->getBody()->seek(0); - Assert::assertIsArray($realResponseArray, 'The response is not a JSON array: ' . $this->response->getBody()->getContents()); foreach ($expectedValues as $value) { - Assert::assertArrayHasKey( - $value['key'], - $realResponseArray, - 'Not found: "' . $value['key'] . '" at array: ' . json_encode($realResponseArray) - ); - $actual = $realResponseArray[$value['key']]; + $actual = $this->testAndGetActualValue($value, $json); + // Test actual value if (str_starts_with($value['value'], '(jq)')) { $expected = substr($value['value'], 4); - $this->validateAsJsonQuery($expected, json_encode($actual)); + $this->validateAsJsonQuery($expected, $actual); continue; } - if (is_bool($realResponseArray[$value['key']]) - || is_iterable($realResponseArray[$value['key']]) - || is_numeric($realResponseArray[$value['key']]) - || (is_string($realResponseArray[$value['key']]) && $this->isJson($realResponseArray[$value['key']])) - ) { - $actual = json_encode($actual); + if ($this->isJson($actual)) { Assert::assertJsonStringEqualsJsonString($value['value'], $actual, 'Key: ' . $value['key']); continue; } @@ -273,6 +263,42 @@ public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(Tab } } + private function testAndGetActualValue(array $value, string $json): string { + $realResponseArray = json_decode($json, true); + Assert::assertIsArray($realResponseArray, 'The response is not a JSON array: ' . $json); + if (str_starts_with($value['key'], '(jq)')) { + $actual = $this->evalJsonQuery( + substr($value['key'], 4), + $json + ); + Assert::assertNotEmpty($actual, + "The follow JsonQuery returned empty value: " . $value['key'] + ); + if (!is_string($actual)) { + $actual = json_encode($actual); + } + return $actual; + } + Assert::assertArrayHasKey( + $value['key'], + $realResponseArray, + 'Not found: "' . $value['key'] . '" at array: ' . json_encode($realResponseArray) + ); + $actual = $realResponseArray[$value['key']]; + if (!is_string($actual)) { + $actual = json_encode($actual); + } + return $actual; + } + + /** + * @return mixed + */ + private function evalJsonQuery(string $jsonQuery, string $target) { + $jq = \JsonQueryWrapper\JsonQueryFactory::createWith($target); + return $jq->run($jsonQuery); + } + private function validateAsJsonQuery(string $expected, string $actual): void { if (!`which jq`) { throw new \InvalidArgumentException('Is necessary install the jq command to use jq');