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

oneOf never validates when one item is array type the other is scalar or null when checkMode = Constraint::CHECK_MODE_COERCE_TYPES #770

Open
jozefbriss opened this issue Dec 6, 2024 · 3 comments
Labels

Comments

@jozefbriss
Copy link

It seems that coercing scalar to array causes than oneOf never validates when one item is array type and the other is scalar or null.

The reason is that any scalar or null can be coerced to array.

Maybe there should not be toArray coercion.

$jsonSchema = <<<'JSON'
{
    "type": "object",
    "properties": {
        "data": {
            "oneOf": [{ "type": "string" }, { "type": "array" }]
        }
    },
    "required": ["data"]
}
JSON;

$jsonSchemaObject = json_decode($jsonSchema);

$schemaStorage = new SchemaStorage();
$schemaStorage->addSchema('file://mySchema', $jsonSchemaObject);

$jsonValidator = new Validator(new Factory($schemaStorage));

$jsonToValidateObject = json_decode('{"data":"ABC"}');

$jsonValidator->validate($jsonToValidateObject, $jsonSchemaObject, Constraint::CHECK_MODE_COERCE_TYPES);

print_r($jsonValidator->getErrors());

results in:

Array
(
    [0] => Array
        (
            [property] => data
            [pointer] => /data
            [message] => Failed to match exactly one schema
            [constraint] => Array
                (
                    [name] => oneOf
                    [params] => Array
                        (
                        )

                )

            [context] => 1
        )

)

version: 6.0.0

Maybe the issues is more generic than only related to array and "oneOf" and Constraint::CHECK_MODE_COERCE_TYPES may not work together.

@DannyvdSluijs
Copy link
Collaborator

Thanks for the report I'll try and find time to take a look soon. Do you perhaps also know if this occurs with earlier versions as well?

@jozefbriss
Copy link
Author

I have migrated from "5.2.13" to "6.0.0".

I've been using 5.2.13 with custom TypeConstraint class:

$factory->setConstraintClass('type', TypeConstraint::class);

Mime TypeConstraint was almost the same as there is now in the project except mine version did not have array coercion.

@madman-81
Copy link

madman-81 commented Dec 10, 2024

I think I'm running into this same issue. The following unit test passes with version 5.3 but fails with version 6.0:

<?php

namespace Tests\Unit\Validation;

use JsonSchema\Constraints\Constraint;
use JsonSchema\Validator;
use PHPUnit\Framework\TestCase;

class JsonValidateV6Test extends TestCase
{
    public function testJsonCompare()
    {
        $schema = <<<JSON
            {
                "title": "Location",
                "type": "object",
                "properties": {
                    "id": {
                        "type": "string"
                    },
                    "related_locations": {
                        "oneOf": [
                            {
                                "type": "null"
                            },
                            {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "properties": {
                                        "latitude": {
                                            "type": "string"
                                        },
                                        "longitude": {
                                            "type": "string"
                                        }
                                    }
                                }
                            }
                        ]
                    }
                }
            }
        JSON;

        $json = <<<JSON
            {
                "id": "LOC1",
                "related_locations": [
                    {
                        "latitude": "51.047598",
                        "longitude": "3.729943"
                    }
                ]
            }
        JSON;

        $jsonObj = json_decode($json);
        $schemaObj = json_decode($schema);

        $jsonSchemaValidation = new Validator();
        $jsonSchemaValidation->validate($jsonObj, $schemaObj, Constraint::CHECK_MODE_COERCE_TYPES);

        $this->assertTrue($jsonSchemaValidation->isValid());
    }
}

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants