pboettch / json-schema-validator

JSON schema validator for JSON for Modern C++
Other
466 stars 134 forks source link

Invalid patch generated when using oneOf for array #248

Open xamix opened 1 year ago

xamix commented 1 year ago

Hi,

EDIT: Maybe related to https://github.com/pboettch/json-schema-validator/issues/229

I use the latest 2.2.0 validator. Also tested with latest master on commit cae6fad80001510077a7f40e68477a31ec443add, same behavior I think I have found a bug on the generated patch which generate not needed field when using oneOf in an array with default value:

I have an array of messages with only two different item type:

To reproduce the bug, I have generated a small example to explain this:

#include <iostream>
#include <nlohmann/json-schema.hpp>

using nlohmann::json;
using nlohmann::json_schema::json_validator;

// The schema is defined based upon a string literal
static json message_schema = R"(
{
    "$schema": "http://json-schema.org/draft-07/schema#",
    "title": "A message list",
    "properties": {
        "messages": {
                    "type": "array",
                    "items": {
                        "type": "object",
                        "oneOf": [
                            {
                                "properties": {
                                    "data1": {
                                        "type": [
                                            "string", 
                                            "null"
                                        ],
                                        "default": null
                                    }
                                },
                                "additionalProperties": false,
                                "required": [
                                    "data1"
                                ] 
                            },
                            {
                                "properties": {
                                    "event": {
                                        "type": "object",
                                        "properties": {
                                            "scheduled": {
                                                "type": "boolean",
                                                "default": false
                                            } 
                                        },
                                        "additionalProperties": false,
                                        "default": {
                                            "scheduled": false
                                        }
                                    }
                                },
                                "additionalProperties": false,
                                "required": [
                                  "event"
                                ]
                            }
                        ]
                    }
                }
        }
})"_json;

int main()
{
    try
    {
        json_validator validator{message_schema};
        json message = R"({
            "messages": [
                {
                    "data1": "My data1"
                }
            ]
        })"_json;

        const auto default_patch = validator.validate(message);
        if (!default_patch.empty())
        {
            std::cerr << "Generated invalid patch: " << default_patch.dump(4) << std::endl;
            message = message.patch(default_patch);
        }
        std::cout << "Patched message: " << message.dump(4) << std::endl;
    }
    catch (const std::exception &e)
    {
        std::cerr << "Validation of schema failed: " << e.what() << "\n";
        return EXIT_FAILURE;
    }
}

The problem is when I add the default for the 2nd object i.e:

"default": {
    "scheduled": false
}

It output the following :

Generated invalid patch: [
    {
        "op": "add",
        "path": "/messages/0/event",
        "value": {
            "scheduled": false
        }
    }
]
Patched message: {
    "messages": [
        {
            "data1": "My data1",
            "event": {
                "scheduled": false
            }
        }
    ]
}

I expected that the message will not be patched at all since it validate the first item schema fully, however here my message got the event field added which is not needed

Is this a bug? Regards