/**
* Assert and check unique filterable properties from requested url
*
* @param string $url Request uri
* @param ListResponse $apiResp Schema current object generated of api specification
* @param string $saveDataPath Save url for child endpoints
*/
public function assertFilterableProperties($url, $apiResp, $saveDataPath = null)
{
$entity = $apiResp->getObjectEntity();
$objectName = $entity->getObjectName();
/* @var $objectFilters FilterRule[] */
$objectFilters = [];
foreach ($this->assertGetEndpoint($url, $apiResp, [], true, static::$maxResults) as $object) {
//get list of filterable properties
$filterable = $entity->filterable;
//handle filters with singular make logic
if (isset($this->filterPropertyMap[$objectName])) {
$rules = $this->filterPropertyMap[$objectName];
foreach ($rules as $rule) {
$filterRule = new FilterRule();
foreach ($rule as $property) {
//when there is only part of the required fields - filter should be discarded
if (!isset($object->{$property})) {
$filterRule = null;
break;
}
$filterRule[$property] = $object->{$property};
}
if (count($filterRule)) {
$objectFilters[] = $filterRule;
}
//remove the fields included in complex filter from the list of filterable fields
$filterable = array_diff($filterable, $rule);
}
}
foreach ($filterable as $property) {
if (isset($object->{$property}) && !static::isRecursivelyEmpty($object->{$property})) {
$value = $object->{$property};
if (is_array($value) && isset($this->simpleFilterRules[$objectName]) && in_array($property, $this->simpleFilterRules[$objectName])) {
foreach ($value as $entry) {
$objectFilters[] = new FilterRule([$property => $entry]);
}
} else {
$objectFilters[] = new FilterRule([$property => $value]);
}
}
}
if (!is_null($saveDataPath)) {
$saveUrl = empty($this->pathMap[$objectName]) ? $saveDataPath : preg_replace($this->pathMap[$objectName]['pattern'], $this->pathMap[$objectName]['replace'], $saveDataPath);
$this->saveUrlData($saveUrl, $object, $objectName);
}
}
if (!empty($objectFilters)) {
$objectFilters = array_unique($objectFilters, SORT_STRING);
foreach ($objectFilters as $filter) {
$listResult = $this->assertGetEndpoint($url, $apiResp, $filter->getFilters(), true, static::$maxResults);
$this->assertNotEmpty($listResult);
foreach ($listResult as $filtered) {
foreach ($filter as $property => $filterValue) {
if (isset($this->propertyAssertMap[$property])) {
$assert = $this->propertyAssertMap[$property];
if (method_exists($this, $assert)) {
$this->{$assert}($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
} else {
$this->markTestIncomplete(sprintf('% assertion does not exist', $assert));
}
} else {
$this->assertEquals($filterValue, $filtered->{$property}, "Property '{$property}' mismatch");
}
}
}
}
}
}