8383 */
8484class REST extends CodeceptionModule implements DependsOnModule, PartedModule, API , ConflictsWithModule
8585{
86- const QUERY_PARAMS_AWARE_METHODS = ['GET ' , 'HEAD ' , 'DELETE ' ];
86+ const QUERY_PARAMS_AWARE_METHODS = ['GET ' , 'HEAD ' , 'DELETE ' , ' OPTIONS ' ];
8787
8888 protected $ config = [
8989 'url ' => '' ,
@@ -400,7 +400,7 @@ public function amNTLMAuthenticated($username, $password)
400400 * ?>
401401 * ```
402402 * @param array $additionalAWSConfig
403- * @throws ModuleException
403+ * @throws ConfigurationException
404404 */
405405 public function amAWSAuthenticated ($ additionalAWSConfig = [])
406406 {
@@ -453,7 +453,7 @@ public function amAWSAuthenticated($additionalAWSConfig = [])
453453 * ```
454454 *
455455 * @param $url
456- * @param array|\JsonSerializable $params
456+ * @param array|string| \JsonSerializable $params
457457 * @param array $files A list of filenames or "mocks" of $_FILES (each entry being an array with the following
458458 * keys: name, type, error, size, tmp_name (pointing to the real file path). Each key works
459459 * as the "name" attribute of a file input field.
@@ -511,7 +511,7 @@ public function sendGet($url, $params = [])
511511 * Sends PUT request to given uri.
512512 *
513513 * @param $url
514- * @param array $params
514+ * @param array|string|\JsonSerializable $params
515515 * @param array $files
516516 * @part json
517517 * @part xml
@@ -525,7 +525,7 @@ public function sendPut($url, $params = [], $files = [])
525525 * Sends PATCH request to given uri.
526526 *
527527 * @param $url
528- * @param array $params
528+ * @param array|string|\JsonSerializable $params
529529 * @param array $files
530530 * @part json
531531 * @part xml
@@ -554,14 +554,14 @@ public function sendDelete($url, $params = [], $files = [])
554554 *
555555 * @param $method
556556 * @param $url
557- * @param array|\JsonSerializable $params
557+ * @param array|string| \JsonSerializable $params
558558 * @param array $files
559559 * @part json
560560 * @part xml
561561 */
562562 public function send ($ method , $ url , $ params = [], $ files = [])
563563 {
564- $ this ->execute ($ method , $ url , $ params , $ files );
564+ $ this ->execute (strtoupper ( $ method) , $ url , $ params , $ files );
565565 }
566566
567567 /**
@@ -632,25 +632,34 @@ protected function execute($method, $url, $parameters = [], $files = [])
632632 // allow full url to be requested
633633 if (!$ url ) {
634634 $ url = $ this ->config ['url ' ];
635+ } elseif (!is_string ($ url )) {
636+ throw new ModuleException (__CLASS__ , 'URL must be string ' );
635637 } elseif (strpos ($ url , ':// ' ) === false && $ this ->config ['url ' ]) {
636638 $ url = rtrim ($ this ->config ['url ' ], '/ ' ) . '/ ' . ltrim ($ url , '/ ' );
637639 }
638640
639641 $ this ->params = $ parameters ;
640642
641- $ parameters = $ this ->encodeApplicationJson ($ method , $ parameters );
642643 $ isQueryParamsAwareMethod = in_array ($ method , self ::QUERY_PARAMS_AWARE_METHODS , true );
643644
644- if (is_array ($ parameters ) || $ isQueryParamsAwareMethod ) {
645- if (!empty ($ parameters ) && $ isQueryParamsAwareMethod ) {
646- if (strpos ($ url , '? ' ) !== false ) {
647- $ url .= '& ' ;
648- } else {
649- $ url .= '? ' ;
650- }
651- $ url .= http_build_query ($ parameters );
645+ if ($ isQueryParamsAwareMethod ) {
646+ if (!is_array ($ parameters )) {
647+ throw new ModuleException (__CLASS__ , $ method . ' parameters must be passed in array format ' );
652648 }
649+ } else {
650+ $ parameters = $ this ->encodeApplicationJson ($ method , $ parameters );
651+ }
652+
653+ if (is_array ($ parameters ) || $ isQueryParamsAwareMethod ) {
653654 if ($ isQueryParamsAwareMethod ) {
655+ if (!empty ($ parameters )) {
656+ if (strpos ($ url , '? ' ) !== false ) {
657+ $ url .= '& ' ;
658+ } else {
659+ $ url .= '? ' ;
660+ }
661+ $ url .= http_build_query ($ parameters );
662+ }
654663 $ this ->debugSection ("Request " , "$ method $ url " );
655664 $ files = [];
656665 } else {
@@ -707,7 +716,6 @@ protected function encodeApplicationJson($method, $parameters)
707716 {
708717 if (
709718 array_key_exists ('Content-Type ' , $ this ->connectionModule ->headers )
710- && !in_array ($ method , self ::QUERY_PARAMS_AWARE_METHODS , true )
711719 && ($ this ->connectionModule ->headers ['Content-Type ' ] === 'application/json '
712720 || preg_match ('!^application/.+\+json$! ' , $ this ->connectionModule ->headers ['Content-Type ' ])
713721 )
@@ -720,6 +728,15 @@ protected function encodeApplicationJson($method, $parameters)
720728 return json_encode ($ parameters );
721729 }
722730 }
731+
732+ if ($ parameters instanceof \JsonSerializable) {
733+ throw new ModuleException (__CLASS__ , $ method . ' parameters is JsonSerializable object, but Content-Type header is not set to application/json ' );
734+ }
735+
736+ if (!is_string ($ parameters ) && !is_array ($ parameters )) {
737+ throw new ModuleException (__CLASS__ , $ method . ' parameters must be array, string or object implementing JsonSerializable interface ' );
738+ }
739+
723740 return $ parameters ;
724741 }
725742
@@ -982,7 +999,6 @@ protected function decodeAndValidateJson($jsonString, $errorFormat="Invalid json
982999 * @return string
9831000 * @part json
9841001 * @part xml
985- * @version 1.1
9861002 */
9871003 public function grabResponse ()
9881004 {
@@ -1006,7 +1022,6 @@ public function grabResponse()
10061022 * @return array Array of matching items
10071023 * @throws \Exception
10081024 * @part json
1009- * @version 2.0.9
10101025 */
10111026 public function grabDataFromResponseByJsonPath ($ jsonPath )
10121027 {
@@ -1052,7 +1067,6 @@ public function grabDataFromResponseByJsonPath($jsonPath)
10521067 * ```
10531068 * @param string $xpath
10541069 * @part json
1055- * @version 2.0.9
10561070 */
10571071 public function seeResponseJsonMatchesXpath ($ xpath )
10581072 {
@@ -1119,7 +1133,6 @@ public function dontSeeResponseJsonMatchesXpath($xpath)
11191133 *
11201134 * @param string $jsonPath
11211135 * @part json
1122- * @version 2.0.9
11231136 */
11241137 public function seeResponseJsonMatchesJsonPath ($ jsonPath )
11251138 {
@@ -1244,7 +1257,6 @@ public function dontSeeResponseContainsJson($json = [])
12441257 * @param array $jsonType
12451258 * @param string $jsonPath
12461259 * @see JsonType
1247- * @version 2.1.3
12481260 */
12491261 public function seeResponseMatchesJsonType (array $ jsonType , $ jsonPath = null )
12501262 {
@@ -1260,12 +1272,11 @@ public function seeResponseMatchesJsonType(array $jsonType, $jsonPath = null)
12601272 * Opposite to `seeResponseMatchesJsonType`.
12611273 *
12621274 * @part json
1263- * @param $jsonType jsonType structure
1264- * @param null $jsonPath optionally set specific path to structure with JsonPath
1275+ * @param array $jsonType JsonType structure
1276+ * @param string $jsonPath
12651277 * @see seeResponseMatchesJsonType
1266- * @version 2.1.3
12671278 */
1268- public function dontSeeResponseMatchesJsonType ($ jsonType , $ jsonPath = null )
1279+ public function dontSeeResponseMatchesJsonType (array $ jsonType , $ jsonPath = null )
12691280 {
12701281 $ jsonArray = new JsonArray ($ this ->connectionModule ->_getResponseContent ());
12711282 if ($ jsonPath ) {
@@ -1566,8 +1577,8 @@ public function dontSeeXmlResponseIncludes($xml)
15661577 * ?>
15671578 * ```
15681579 *
1569- * @param $hash the hashed data response expected
1570- * @param $algo the hash algorithm to use. Default md5.
1580+ * @param string $hash the hashed data response expected
1581+ * @param string $algo the hash algorithm to use. Default md5.
15711582 * @part json
15721583 * @part xml
15731584 */
@@ -1587,8 +1598,8 @@ public function seeBinaryResponseEquals($hash, $algo = 'md5')
15871598 * ```
15881599 * Opposite to `seeBinaryResponseEquals`
15891600 *
1590- * @param $hash the hashed data response expected
1591- * @param $algo the hash algorithm to use. Default md5.
1601+ * @param string $hash the hashed data response expected
1602+ * @param string $algo the hash algorithm to use. Default md5.
15921603 * @part json
15931604 * @part xml
15941605 */
0 commit comments