Skip to content

Commit

Permalink
Merge pull request #53 from LibreSign/feature/implement-jq
Browse files Browse the repository at this point in the history
Implement jq expression
  • Loading branch information
vitormattos authored Mar 9, 2024
2 parents 232409b + d5098d1 commit e1e9089
Show file tree
Hide file tree
Showing 7 changed files with 163 additions and 48 deletions.
21 changes: 20 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,26 @@ When sending "post" to ocs "/apps/libresign/api/v1/request-signature"
| file | {"base64":""} |
```

By this way you will receive on your controller method 2 values, status as integer and file as array.
## 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.

Example:

```gherkin
When set the response to:
"""
{
"Foo": {
"Bar": "33"
}
}
"""
And sending "POST" to "/"
Then the response should be a JSON array with the following mandatory values
| key | value |
| Foo | (jq).Bar == "33" |
```

## Parse initial state
If you need to parse the initial state to use placeholder or get any value from current initial state, implement a method `parseText` like this:
Expand Down
5 changes: 3 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
"cs:check": "php-cs-fixer fix --dry-run --diff",
"cs:fix": "php-cs-fixer fix",
"psalm": "psalm --threads=1",
"psalm:update-baseline": "psalm --threads=1 --update-baseline --set-baseline=tests/psalm-baseline.xml",
"psalm:update-baseline": "psalm --threads=1 --update-baseline --set-baseline=psalm-baseline.xml",
"psalm:clear": "psalm --clear-cache && psalm --clear-global-cache",
"post-install-cmd": [
"@composer bin all install --ansi",
Expand All @@ -36,7 +36,8 @@
"guzzlehttp/guzzle": "^7.8",
"phpunit/phpunit": "^9.6",
"behat/behat": "^3.13",
"libresign/behat-builtin-extension": "^0.6.1"
"libresign/behat-builtin-extension": "^0.6.1",
"estahn/json-query-wrapper": "*"
},
"require-dev": {
"bamarni/composer-bin-plugin": "^1.8",
Expand Down
41 changes: 10 additions & 31 deletions features/bootstrap/FeatureContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -78,45 +78,24 @@ public function sendRequest(string $verb, string $url, $body = null, array $head
}

/**
* @inheritDoc
* @when set the response to:
*/
public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(TableNode $table): void {
$lastRequest = $this->getLastRequest();
public function setTheResponseTo(PyStringNode $response): void {
// Mock response to be equal to body of request
$this->mockServer->setDefaultResponse(new MockWebServerResponse(
json_encode($lastRequest->getParsedInput())
(string) $response
));
parent::theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues($table);
}

/**
* @inheritDoc
*/
public function theResponseShouldContainTheInitialStateWithTheFollowingValues(string $name, PyStringNode $expected): void {
switch ($name) {
case 'appid-string':
$value = base64_encode((string) $expected);
break;
case 'appid-json-object':
$value = base64_encode(json_encode(['fruit' => 'orange']));
break;
case 'appid-json-array':
$value = base64_encode(json_encode(['orange']));
break;
default:
$value = '';
}
$this->response = new Response(
200,
[],
<<<HTML
<html>
<body>
<input type="hidden" id="initial-state-{$name}" value="{$value}">
</body>
</html>
HTML
);
parent::theResponseShouldContainTheInitialStateWithTheFollowingValues($name, $expected);
public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(TableNode $table): void {
$lastRequest = $this->getLastRequest();
// Mock response to be equal to body of request
$this->mockServer->setDefaultResponse(new MockWebServerResponse(
json_encode($lastRequest->getParsedInput())
));
parent::theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues($table);
}
}
115 changes: 104 additions & 11 deletions features/test.feature
Original file line number Diff line number Diff line change
Expand Up @@ -8,59 +8,143 @@ Feature: Test this extension
| status | 1 |

Scenario: Test response of POST is numeric
When sending "POST" to "/"
| status | 1 |
When set the response to:
"""
{"status":1}
"""
And sending "POST" to "/"
Then the response should be a JSON array with the following mandatory values
| status | 1 |
| key | value |
| status | 1 |

Scenario: Test response of POST is string
When sending "POST" to "/"
| status | "string" |
When set the response to:
"""
{"status":"string"}
"""
And sending "POST" to "/"
Then the response should be a JSON array with the following mandatory values
| status | "string" |
| key | value |
| status | string |

Scenario: Test response of POST is boolean
When sending "POST" to "/"
| status | true |
When set the response to:
"""
{"status":true}
"""
And sending "POST" to "/"
Then the response should be a JSON array with the following mandatory values
| status | true |
| key | value |
| status | true |

Scenario: Test response of POST is json
When sending "POST" to "/"
| status | (string){"string": "test"} |
When set the response to:
"""
{"status":{"string": "test"}}
"""
And sending "POST" to "/"
Then the response should be a JSON array with the following mandatory values
| key | value |
| status | {"string": "test"} |

Scenario: Test response of POST is json that match using jq
When set the response to:
"""
{
"Foo": {
"Bar": "33"
}
}
"""
And sending "POST" to "/"
Then the response should be a JSON array with the following mandatory values
| key | value |
| Foo | (jq).Bar == "33" |

Scenario: Test initial state with string
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-string" value="ZGVmYXVsdA==">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-string" with the following values:
"""
default
"""

Scenario: Test initial state with string
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-string" value="InRleHQgYXMganNvbiBzdHJpbmci">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-string" with the following values:
"""
"text as json string"
"""

Scenario: Test initial state with boolean
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-string" value="dHJ1ZQ==">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-string" with the following values:
"""
true
"""

Scenario: Test initial state with null
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-string" value="bnVsbA==">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-string" with the following values:
"""
null
"""

Scenario: Test initial state with empty
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-string" value="">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-string" with the following values:
"""
"""

Scenario: Test initial state with json
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-json-object" value="eyJmcnVpdCI6ICJvcmFuZ2UifQ==">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-json-object" with the following values:
"""
{
Expand All @@ -69,6 +153,15 @@ Feature: Test this extension
"""

Scenario: Test initial state with array
When set the response to:
"""
<html>
<body>
<input type="hidden" id="initial-state-appid-json-array" value="WyJvcmFuZ2UiXQ==">
</body>
</html>
"""
And sending "POST" to "/"
Then the response should contain the initial state "appid-json-array" with the following values:
"""
[
Expand Down
8 changes: 8 additions & 0 deletions psalm-baseline.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<files psalm-version="5.22.2@d768d914152dbbf3486c36398802f74e80cfde48">
<file src="src/NextcloudApiContext.php">
<ForbiddenCode>
<code><![CDATA[`which jq`]]></code>
</ForbiddenCode>
</file>
</files>
1 change: 1 addition & 0 deletions psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="psalm-baseline.xml"
>
<projectFiles>
<directory name="features/bootstrap" />
Expand Down
20 changes: 17 additions & 3 deletions src/NextcloudApiContext.php
Original file line number Diff line number Diff line change
Expand Up @@ -254,20 +254,34 @@ public function theResponseShouldBeAJsonArrayWithTheFollowingMandatoryValues(Tab
$realResponseArray,
'Not found: "' . $value['key'] . '" at array: ' . json_encode($realResponseArray)
);
$actual = $realResponseArray[$value['key']];
if (str_starts_with($value['value'], '(jq)')) {
$expected = substr($value['value'], 4);
$this->validateAsJsonQuery($expected, json_encode($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']]))
) {
$actualJson = json_encode($realResponseArray[$value['key']]);
Assert::assertJsonStringEqualsJsonString($value['value'], $actualJson, 'Key: ' . $value['key']);
$actual = json_encode($actual);
Assert::assertJsonStringEqualsJsonString($value['value'], $actual, 'Key: ' . $value['key']);
continue;
}
$actual = $realResponseArray[$value['key']];
Assert::assertEquals($value['value'], $actual, 'Key: ' . $value['key']);
}
}

private function validateAsJsonQuery(string $expected, string $actual): void {
if (!`which jq`) {
throw new \InvalidArgumentException('Is necessary install the jq command to use jq');
}
$jq = \JsonQueryWrapper\JsonQueryFactory::createWith($actual);
$result = $jq->run($expected);
Assert::assertTrue($result, 'The jq "' . $expected . '" do not match with: ' . $actual);
}

/**
* @When the response should contain the initial state :name with the following values:
*/
Expand Down

0 comments on commit e1e9089

Please sign in to comment.