Merge pull request #10164 from owncloud/tests/json-schema-errors

[tests-only] custom error message for json validation error
This commit is contained in:
Sawjan Gurung
2024-09-26 15:33:35 +05:45
committed by GitHub

View File

@@ -34,7 +34,6 @@ use GuzzleHttp\Cookie\CookieJar;
use Psr\Http\Message\ResponseInterface;
use PHPUnit\Framework\Assert;
use Swaggest\JsonSchema\Schema as JsonSchema;
use TestHelpers\OcsApiHelper;
use Laminas\Ldap\Ldap;
use TestHelpers\SetupHelper;
use TestHelpers\HttpRequestHelper;
@@ -44,6 +43,17 @@ use TestHelpers\GraphHelper;
use TestHelpers\WebDavHelper;
use TestHelpers\SettingsHelper;
use TestHelpers\OcisConfigHelper;
use Swaggest\JsonSchema\InvalidValue as JsonSchemaException;
use Swaggest\JsonSchema\Exception\ArrayException;
use Swaggest\JsonSchema\Exception\ConstException;
use Swaggest\JsonSchema\Exception\ContentException;
use Swaggest\JsonSchema\Exception\EnumException;
use Swaggest\JsonSchema\Exception\LogicException;
use Swaggest\JsonSchema\Exception\NumericException;
use Swaggest\JsonSchema\Exception\ObjectException;
use Swaggest\JsonSchema\Exception\StringException;
use Swaggest\JsonSchema\Exception\TypeException;
use Swaggest\JsonSchema\Exception\Error as JsonSchemaError;
require_once 'bootstrap.php';
@@ -1240,9 +1250,93 @@ class FeatureContext extends BehatVariablesContext {
* @throws Exception
*/
public function assertJsonDocumentMatchesSchema(object|array $json, object $schema): void {
$schema = JsonSchema::import($schema);
$this->validateSchemaRequirements($schema);
$schema->in($json);
try {
$schema = JsonSchema::import($schema);
$this->validateSchemaRequirements($schema);
$schema->in($json);
} catch (JsonSchemaException $e) {
$this->throwJsonSchemaException($e);
}
}
/**
* @param JsonSchemaException $error
*
* @return array
*/
public function getJsonSchemaErrors(JsonSchemaException $error): array {
$errors = [];
if (\property_exists($error, "subErrors") && $error->subErrors) {
foreach ($error->subErrors as $subError) {
$errors = \array_merge($errors, $this->getJsonSchemaErrors($subError));
}
} else {
$errors[] = $error;
}
return $errors;
}
/**
* @param JsonSchemaException $e
*
* @return void
* @throws Exception
*/
public function throwJsonSchemaException(JsonSchemaException $e): void {
$errors = $this->getJsonSchemaErrors($e);
$messages = ["JSON Schema validation failed:"];
$previousPointer = '';
$errorCount = 0;
foreach ($errors as $error) {
$expected = $error->constraint;
$actual = $error->data;
$errorMessage = $error->error;
$schemaPointer = \str_replace("/", ".", \trim($error->getSchemaPointer(), "/"));
$dataPointer = \str_replace("/", ".", \trim($error->getDataPointer(), "/"));
$pointer = \str_contains($schemaPointer, "additionalProperties") ? $dataPointer : $schemaPointer;
if ($pointer === $previousPointer) {
continue;
}
$previousPointer = $pointer;
$message = ++$errorCount . ". ";
switch (true) {
case $error instanceof ArrayException:
case $error instanceof LogicException:
case $error instanceof NumericException:
case $error instanceof StringException:
case $error instanceof ContentException:
break;
case $error instanceof ConstException:
$errorMessage .= "\n\t Expected: $expected"
. "\n\t Received: $actual";
break;
case $error instanceof EnumException:
$errorMessage .= "\n\t Expected (One of): " . \join(", ", $expected)
. "\n\t Received: $actual";
break;
case $error instanceof ObjectException:
if (\str_starts_with($errorMessage, "Required property missing")) {
$properties = \join(", ", \array_keys((array)$actual));
$pointer .= "->required";
$errorMessage = "Required property missing: id"
. "\n\t Received: $properties";
}
break;
case $error instanceof TypeException:
if (\in_array(\gettype($actual), ['object', 'array'])) {
$actual = \json_encode($actual, JSON_PRETTY_PRINT);
}
break;
default:
break;
}
$message .= "$pointer:\n\t - $errorMessage\n";
$messages[] = $message;
}
Assert::fail(\join("\n", $messages));
}
/**