Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

compare result of evaluated xpath expression to value #85

Merged
merged 11 commits into from
Aug 13, 2022
61 changes: 61 additions & 0 deletions src/Codeception/Module/REST.php
Original file line number Diff line number Diff line change
Expand Up @@ -1100,6 +1100,67 @@ public function seeResponseJsonMatchesXpath(string $xPath): void
);
}

/**
* Checks if applying xpath to json structure in response matches the expected result.
* JSON is not supposed to be checked against XPath, yet it can be converted to xml and used with XPath.
* This assertion allows you to check the structure of response json.
* *
* ```json
* { "store": {
* "book": [
* { "category": "reference",
* "author": "Nigel Rees",
* "title": "Sayings of the Century",
* "price": 8.95
* },
* { "category": "fiction",
* "author": "Evelyn Waugh",
* "title": "Sword of Honour",
* "price": 12.99
* }
* ],
* "bicycle": {
* "color": "red",
* "price": 19.95
* }
* }
* }
* ```
*
* ```php
* <?php
* // at least one book in store has author
* $I->seeResponseJsonXpathEvaluatesTo('count(//store/book/author) > 0', true);
* // count the number of books written by given author is 5
* $I->seeResponseJsonMatchesXpath("//author[text() = 'Nigel Rees']", 1.0);
* ```
* @part json
*/
public function seeResponseJsonXpathEvaluatesTo(string $xPath, $expected): void
{
$response = $this->connectionModule->_getResponseContent();
$this->assertEquals(
pamoller marked this conversation as resolved.
Show resolved Hide resolved
$expected,
(new JsonArray($response))->evaluateXPath($xPath),
"Received JSON did not evualated XPath `{$xPath}` as expected.\nJson Response: \n" . $response
);
}

/**
* Opposite to seeResponseJsonXpathEvaluatesTo
*
* @part json
*/
public function dontSeeResponseJsonXpathEvaluatesTo(string $xPath, $expected): void
{
$response = $this->connectionModule->_getResponseContent();
$this->assertNotEquals(
Naktibalda marked this conversation as resolved.
Show resolved Hide resolved
$expected,
(new JsonArray($response))->evaluateXPath($xPath),
"Received JSON did not evualated XPath `{$xPath}` as expected.\nJson Response: \n" . $response
);
}

/**
* Opposite to seeResponseJsonMatchesXpath
*
Expand Down
6 changes: 6 additions & 0 deletions src/Codeception/Util/JsonArray.php
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,12 @@ public function filterByXPath(string $xPath): DOMNodeList|false
$path = new DOMXPath($this->toXml());
return $path->query($xPath);
}

public function evaluateXPath(string $xPath): mixed
{
$path = new DOMXPath($this->toXml());
return $path->evaluate($xPath);
}

public function filterByJsonPath(string $jsonPath): array
{
Expand Down
25 changes: 25 additions & 0 deletions tests/unit/Codeception/Module/RestTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -566,6 +566,31 @@ public function testSeeResponseJsonMatchesXpathCanHandleResponseWithOneSubArray(
$this->module->seeResponseJsonMatchesXpath('//array/success');
}


public function testSeeResponseJsonXpathEvaluatesToBoolean()
{
$this->setStubResponse('{"success": 1}');
$this->module->seeResponseJsonXpathEvaluatesTo('count(//success) > 0', true);
}

public function testSeeResponseJsonXpathEvaluatesToNumber()
{
$this->setStubResponse('{"success": 1}');
$this->module->seeResponseJsonXpathEvaluatesTo('count(//success)', 1.0);
}

public function testDontSeeResponseJsonXpathEvaluatesToBoolean()
{
$this->setStubResponse('{"success": 1}');
$this->module->dontSeeResponseJsonXpathEvaluatesTo('count(//success) > 0', false);
}

public function testDontSeeResponseJsonXpathEvaluatesToNumber()
{
$this->setStubResponse('{"success": 1}');
$this->module->dontSeeResponseJsonXpathEvaluatesTo('count(//success)', 0.0);
}

public function testSeeBinaryResponseEquals()
{
$data = base64_decode('/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=');
Expand Down
7 changes: 7 additions & 0 deletions tests/unit/Codeception/Util/JsonArrayTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,13 @@ public function testXmlArrayConversion2()
$this->assertSame(2, $jsonArray->filterByXPath('//user')->length);
}

public function testXPathEvaluation()
{
$this->assertSame(true, $this->jsonArray->evaluateXPath('count(//ticket/title)>0'));
$this->assertEquals(1.0 , $this->jsonArray->evaluateXPath('count(//ticket/user/name)'));
$this->assertSame(true, $this->jsonArray->evaluateXPath("count(//user/name[text() = 'Davert']) > 0"));
}

public function testXPathLocation()
{
$this->assertGreaterThan(0, $this->jsonArray->filterByXPath('//ticket/title')->length);
Expand Down