Roman
Roman

Reputation: 91

Json schema validation with if else condition and rest assured

I'm struggling with the json validation against json schema and Rest Assured. The thing is that I need to use if else condition in it and for some reason my test are always green even I'm defining wrong condition. I used json-schema 7 which should support if else but when I'm defining false condition and my test should be failed with some error but its actually passed according to that I can say that its not checking that condition at all.
Here is my json:

{
    "courses": [{
        "position": "1",
        "previous_course_rank": "",
        "location": "Weston, FL",
        "established": "",
        "course_name": "Weston Hills - Tour Course",
        "course_id": "056",
        "holes": [{
            "hole": "1"
        }]
    }]
}

Here is my json schema validation with the if else condition in it. As you can see from if else condition I'm expecting to have established empty string only with course_id: 056 but in other cases I'm expecting established to be year like 2022. The thing is when I'm trying to test false condition and putting in if year pattern [0-9{4} its green too and I can't understand why.

{
  "$schema": "http://json-schema.org/draft-07/schema",
  "type": "object",
  "required": [
    "courses"
  ],
  "properties": {
    "courses": {
      "type": "array",
      "items": {
        "type": "object",
        "required": [
          "position",
          "previous_course_rank",
          "location",
          "established",
          "course_name",
          "course_id",
          "holes"
        ],
        "properties": {
          "position": {
            "type": "string"
          },
          "previous_course_rank": {
            "type": "string"
          },
          "location": {
            "type": "string"
          },
          "course_name": {
            "type": "string"
          },
          "course_id": {
            "type": "string"
          },
          "holes": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "hole"
              ],
              "properties": {
                "hole": {
                  "type": "string"
                }
              }
            }
          }
        },
        "if": {
          "properties": {
            "course_id": {
              "const": "056"
            }
          }
        },
        "then": {
          "properties": {
            "established": {
              "pattern": "^$"
            }
          }
        },
        "else": {
          "properties": {
            "established": {
              "pattern": "^[0-9]{4}$"
            }
          }
        }
      }
    }
  }
}

and here is my method of checking json against json schema

ValidatableResponse response = getResponse(feedUrl);

response
.body(matchesJsonSchemaInClasspath(pathToSchema))
.assertThat();

Upvotes: 0

Views: 2063

Answers (3)

Roman
Roman

Reputation: 91

So the root cause of the issue is that restassured by default is using draft-03 schema and they can't support version draft-06 and draft-07.

This is what we have in case if you want to upgrade that draft version. So there is no way to use if else condition with rest-assured in my understanding.

JsonSchemaFactory factory = JsonSchemaFactory.newBuilder()
        .setValidationConfiguration(
                ValidationConfiguration.newBuilder()
                        .setDefaultVersion(SchemaVersion.DRAFTV3)
                        .freeze()).freeze();

So my solution is to use everit json schema https://github.com/everit-org/json-schema

Schema schema = getSchema(schemaPath);

SoftAssertions softAssertions = new SoftAssertions();
try {
    schema.validate(new JSONObject(getResponseAsString(jsonEndPointUrl)));
} catch (ValidationException e) {
    collectAllAssertions(softAssertions, e);
}

softAssertions.assertAll();

Maybe you are able to use draft-06 and draft-07 with rest-assured Feel free to post your solution.

Upvotes: 0

deadshot
deadshot

Reputation: 9061

Try below schema: json schema validator

I'm using property type for validation for if condition I'm setting type as string with maxLength is zero and for else I'm setting type as number with minimum and maximum properties, You can updated these based on your requirement

{
    "$schema": "http://json-schema.org/draft-07/schema",
    "type": "object",
    "required": [
        "courses"
    ],
    "properties": {
        "courses": {
            "type": "array",
            "items": {
                "type": "object",
                "required": [
                    "position",
                    "previous_course_rank",
                    "location",
                    "established",
                    "course_name",
                    "course_id",
                    "holes"
                ],
                "properties": {
                    "position": {
                        "type": "string"
                    },
                    "previous_course_rank": {
                        "type": "string"
                    },
                    "location": {
                        "type": "string"
                    },
                    "course_name": {
                        "type": "string"
                    },
                    "course_id": {
                        "type": "string"
                    },
                    "holes": {
                        "type": "array",
                        "items": {
                            "type": "object",
                            "required": [
                                "hole"
                            ],
                            "properties": {
                                "hole": {
                                    "type": "string"
                                }
                            }
                        }
                    }
                },
                "if": {
                    "properties": {
                        "course_id": {
                            "const": "056"
                        }
                    }
                },
                "then": {
                    "properties": {
                        "established": {
                            "type": "string",
                            "maxLength": 0
                        }
                    }
                },
                "else": {
                    "properties": {
                        "established": {
                            "type": "number",
                            "minimum": 1900,
                            "maximum": 3000
                        }
                    }
                }
            }
        }
    }
}

Upvotes: 0

Ether
Ether

Reputation: 53966

"pattern": "" means "match everything". Perhaps you meant "const": ""?

Also, if you want to match a four digit number exactly, without permitting any leading or trailing characters, you need to explicitly anchor the pattern: "pattern": "^[0-9]{4}$"

Upvotes: 2

Related Questions