diff --git a/README.md b/README.md index dbd1139..f1128d3 100644 --- a/README.md +++ b/README.md @@ -56,7 +56,7 @@ Given /^set the display name of user "([^"]*)" to "([^"]*)"$/ Given /^set the email of user "([^"]*)" to "([^"]*)"$/ Given sending :verb to ocs :url Given the response should have a status code :code -Given fetch field :path from prevous JSON response +Given fetch field :path from previous JSON response Given the response should contain the initial state :name with the following values: Given the response should contain the initial state :name json that match with: Given the following :appId app config is set @@ -83,7 +83,7 @@ Given sending "post" to ocs "/apps/libresign/api/v1/request-signature" | file | {"base64":""} | ``` -### Step: `fetch field :path from prevous JSON response` +### Step: `fetch field :path from previous JSON response` If the json response is an array, you can fetch specific values using this step. The fetched values is stored to be used by other steps. @@ -112,12 +112,22 @@ The alias `price` could be used in a path or body of a request: } """ And sending "POST" to "/" - And fetch field "(foo)data.0.foo" from prevous JSON response + And fetch field "(foo)data.0.foo" from previous JSON response # After fetch the field, you can use the value of field like this: And sending "POST" to "/?foo=" | field | | ``` +#### Fetch field using jq + +You can assign the return of a jq to your field using a jq like as the follow pattern: + +```gherkin +And fetch field "(foo)(jq).value" from previous JSON response +``` + +This will retrieve a specific value from json response and assign this to your desided field. + ## Parse response using jq You can use [jq](https://jqlang.github.io/jq/manual/) expression casting to check a value in a json response body of a request. To do this you will need to install the jq command. @@ -150,7 +160,7 @@ If you need to: Implement a method `parseText` like the follow code and remember to call parent method. -This methods can works together with `fetch field :path from prevous JSON response` +This methods can works together with `fetch field :path from previous JSON response` ```php protected function parseText(string $text): string { $patterns = [ diff --git a/features/test.feature b/features/test.feature index 9483028..f187f1b 100644 --- a/features/test.feature +++ b/features/test.feature @@ -78,7 +78,27 @@ Feature: Test this extension } """ And sending "POST" to "/" - And fetch field "(FIELD_FOO)data.0.foo" from prevous JSON response + And fetch field "(FIELD_FOO)data.0.foo" from previous JSON response + # After fetch the field, you can use the value of field like this: + And sending "POST" to "/?foo=" + | field | | + Then the response should be a JSON array with the following mandatory values + | key | value | + | data | [{"foo":""}] | + + Scenario: Test get field from json response using jq + When set the response to: + """ + { + "data": [ + { + "foo":"bar" + } + ] + } + """ + And sending "POST" to "/" + And fetch field "(FIELD_FOO)(jq).data[0].foo" from previous JSON response # After fetch the field, you can use the value of field like this: And sending "POST" to "/?foo=" | field | | diff --git a/src/NextcloudApiContext.php b/src/NextcloudApiContext.php index 4d3145a..59ad4f0 100644 --- a/src/NextcloudApiContext.php +++ b/src/NextcloudApiContext.php @@ -322,19 +322,28 @@ private function validateAsJsonQuery(string $expected, string $actual): void { Assert::assertTrue($result, 'The jq "' . $expected . '" do not match with: ' . $actual); } - #[Given('fetch field :path from prevous JSON response')] + #[Given('fetch field :path from previous JSON response')] public function fetchFieldFromPreviousJsonResponse(string $path): void { $this->response->getBody()->seek(0); - $responseArray = json_decode($this->response->getBody()->getContents(), true); - if (preg_match('/(?\([^)]*\))(?.*)/', $path, $matches)) { + $body = $this->response->getBody()->getContents(); + + // Is json query + if (preg_match('/(?\([^)]*\))\(jq\)(?.*)/', $path, $matches)) { + $this->fields[$matches['alias']] = $this->testAndGetActualValue( + ['key' => '(jq)' . $matches['path']], + $body + ); + return; + } + + // Is array with alias + if (preg_match('/(?\([^)]*\)){1,}(?.*)/', $path, $matches)) { $alias = $matches['alias']; - $path = $matches['patch']; + $path = $matches['path']; } $keys = explode('.', $path); - $value = $responseArray; + $value = json_decode($body, true); foreach ($keys as $key) { - $body = json_encode($responseArray); - Assert::assertIsString($body); Assert::assertArrayHasKey($key, $value, 'Key [' . $key . '] of path [' . $path . '] not found at body: ' . $body); $value = $value[$key]; }