Skip to content

Commit 2535889

Browse files
pamollerNaktibalda
andauthored
Add (dont)seeResponseJsonXpathEvaluatesTo methods
* compare result of evaluated xpath expression to value * replace same instead equal * bug fix tests * bug fix docu * Change assertions to stricter * Revert test change, because evalueXpath returns float * expect float * revert to assertEquals * Use assertEquals in new methods because float can be returned when integer is expected * Remoce unnecessary space Co-authored-by: Gintautas Miselis <[email protected]>
1 parent 2b21087 commit 2535889

File tree

4 files changed

+99
-0
lines changed

4 files changed

+99
-0
lines changed

src/Codeception/Module/REST.php

+61
Original file line numberDiff line numberDiff line change
@@ -1100,6 +1100,67 @@ public function seeResponseJsonMatchesXpath(string $xPath): void
11001100
);
11011101
}
11021102

1103+
/**
1104+
* Checks if applying xpath to json structure in response matches the expected result.
1105+
* JSON is not supposed to be checked against XPath, yet it can be converted to xml and used with XPath.
1106+
* This assertion allows you to check the structure of response json.
1107+
* *
1108+
* ```json
1109+
* { "store": {
1110+
* "book": [
1111+
* { "category": "reference",
1112+
* "author": "Nigel Rees",
1113+
* "title": "Sayings of the Century",
1114+
* "price": 8.95
1115+
* },
1116+
* { "category": "fiction",
1117+
* "author": "Evelyn Waugh",
1118+
* "title": "Sword of Honour",
1119+
* "price": 12.99
1120+
* }
1121+
* ],
1122+
* "bicycle": {
1123+
* "color": "red",
1124+
* "price": 19.95
1125+
* }
1126+
* }
1127+
* }
1128+
* ```
1129+
*
1130+
* ```php
1131+
* <?php
1132+
* // at least one book in store has author
1133+
* $I->seeResponseJsonXpathEvaluatesTo('count(//store/book/author) > 0', true);
1134+
* // count the number of books written by given author is 5
1135+
* $I->seeResponseJsonMatchesXpath("//author[text() = 'Nigel Rees']", 1.0);
1136+
* ```
1137+
* @part json
1138+
*/
1139+
public function seeResponseJsonXpathEvaluatesTo(string $xPath, $expected): void
1140+
{
1141+
$response = $this->connectionModule->_getResponseContent();
1142+
$this->assertEquals(
1143+
$expected,
1144+
(new JsonArray($response))->evaluateXPath($xPath),
1145+
"Received JSON did not evualated XPath `{$xPath}` as expected.\nJson Response: \n" . $response
1146+
);
1147+
}
1148+
1149+
/**
1150+
* Opposite to seeResponseJsonXpathEvaluatesTo
1151+
*
1152+
* @part json
1153+
*/
1154+
public function dontSeeResponseJsonXpathEvaluatesTo(string $xPath, $expected): void
1155+
{
1156+
$response = $this->connectionModule->_getResponseContent();
1157+
$this->assertNotEquals(
1158+
$expected,
1159+
(new JsonArray($response))->evaluateXPath($xPath),
1160+
"Received JSON did not evualated XPath `{$xPath}` as expected.\nJson Response: \n" . $response
1161+
);
1162+
}
1163+
11031164
/**
11041165
* Opposite to seeResponseJsonMatchesXpath
11051166
*

src/Codeception/Util/JsonArray.php

+6
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,12 @@ public function filterByXPath(string $xPath): DOMNodeList|false
7575
$path = new DOMXPath($this->toXml());
7676
return $path->query($xPath);
7777
}
78+
79+
public function evaluateXPath(string $xPath): mixed
80+
{
81+
$path = new DOMXPath($this->toXml());
82+
return $path->evaluate($xPath);
83+
}
7884

7985
public function filterByJsonPath(string $jsonPath): array
8086
{

tests/unit/Codeception/Module/RestTest.php

+25
Original file line numberDiff line numberDiff line change
@@ -567,6 +567,31 @@ public function testSeeResponseJsonMatchesXpathCanHandleResponseWithOneSubArray(
567567
$this->module->seeResponseJsonMatchesXpath('//array/success');
568568
}
569569

570+
571+
public function testSeeResponseJsonXpathEvaluatesToBoolean()
572+
{
573+
$this->setStubResponse('{"success": 1}');
574+
$this->module->seeResponseJsonXpathEvaluatesTo('count(//success) > 0', true);
575+
}
576+
577+
public function testSeeResponseJsonXpathEvaluatesToNumber()
578+
{
579+
$this->setStubResponse('{"success": 1}');
580+
$this->module->seeResponseJsonXpathEvaluatesTo('count(//success)', 1.0);
581+
}
582+
583+
public function testDontSeeResponseJsonXpathEvaluatesToBoolean()
584+
{
585+
$this->setStubResponse('{"success": 1}');
586+
$this->module->dontSeeResponseJsonXpathEvaluatesTo('count(//success) > 0', false);
587+
}
588+
589+
public function testDontSeeResponseJsonXpathEvaluatesToNumber()
590+
{
591+
$this->setStubResponse('{"success": 1}');
592+
$this->module->dontSeeResponseJsonXpathEvaluatesTo('count(//success)', 0.0);
593+
}
594+
570595
public function testSeeBinaryResponseEquals()
571596
{
572597
$data = base64_decode('/9j/2wBDAAMCAgICAgMCAgIDAwMDBAYEBAQEBAgGBgUGCQgKCgkICQkKDA8MCgsOCwkJDRENDg8QEBEQCgwSExIQEw8QEBD/yQALCAABAAEBAREA/8wABgAQEAX/2gAIAQEAAD8A0s8g/9k=');

tests/unit/Codeception/Util/JsonArrayTest.php

+7
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,13 @@ public function testXmlArrayConversion2()
3636
$this->assertSame(2, $jsonArray->filterByXPath('//user')->length);
3737
}
3838

39+
public function testXPathEvaluation()
40+
{
41+
$this->assertSame(true, $this->jsonArray->evaluateXPath('count(//ticket/title)>0'));
42+
$this->assertEquals(1.0 , $this->jsonArray->evaluateXPath('count(//ticket/user/name)'));
43+
$this->assertSame(true, $this->jsonArray->evaluateXPath("count(//user/name[text() = 'Davert']) > 0"));
44+
}
45+
3946
public function testXPathLocation()
4047
{
4148
$this->assertGreaterThan(0, $this->jsonArray->filterByXPath('//ticket/title')->length);

0 commit comments

Comments
 (0)