package org.mockserver.matchers; import org.junit.Before; import org.junit.Test; import org.mockito.Mock; import org.slf4j.Logger; import static org.junit.Assert.*; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.verifyNoMoreInteractions; import static org.mockito.MockitoAnnotations.initMocks; /** * @author jamesdbloom */ public class JsonSchemaMatcherTest { @Mock protected Logger logger; public static final String JSON_SCHEMA = "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}"; @Before public void createMocks() { initMocks(this); } @Test public void shouldMatchJson() { assertTrue(new JsonSchemaMatcher(JSON_SCHEMA).matches("{arrayField: [ \"one\" ], enumField: \"one\"}")); } @Test public void shouldNotMatchJsonMissingRequiredFields() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{}")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with schema \"{}\" because {}", "{}", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "com.github.fge.jsonschema.core.report.ListProcessingReport: failure\n" + "--- BEGIN MESSAGES ---\n" + "error: object has missing required properties ([\"arrayField\",\"enumField\"])\n" + " level: \"error\"\n" + " schema: {\"loadingURI\":\"#\",\"pointer\":\"\"}\n" + " instance: {\"pointer\":\"\"}\n" + " domain: \"validation\"\n" + " keyword: \"required\"\n" + " required: [\"arrayField\",\"enumField\"]\n" + " missing: [\"arrayField\",\"enumField\"]\n" + "--- END MESSAGES ---\n" + ""); } @Test public void shouldNotMatchJsonTooFewItems() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ ], enumField: \\\"one\\\"}")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ ], enumField: \\\"one\\\"}", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ ], enumField: \\\"one\\\"}; line: 1, column: 39]"); } @Test public void shouldNotMatchJsonTooLongString() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", stringField: \\\"1234567\\\"}")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", stringField: \\\"1234567\\\"}", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", stringField: \\\"1234567\\\"}; line: 1, column: 17]"); } @Test public void shouldNotMatchJsonIncorrectEnum() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ \\\"one\\\" ], enumField: \\\"four\\\"}")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ \\\"one\\\" ], enumField: \\\"four\\\"}", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ \\\"one\\\" ], enumField: \\\"four\\\"}; line: 1, column: 17]"); } @Test public void shouldNotMatchJsonExtraField() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", extra: \\\"field\\\"}")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", extra: \\\"field\\\"}", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", extra: \\\"field\\\"}; line: 1, column: 17]"); } @Test public void shouldNotMatchJsonIncorrectSubField() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", objectField: {stringField: \\\"1234\\\"} }")); // and verify(logger).trace( "Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", objectField: {stringField: \\\"1234\\\"} }", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", objectField: {stringField: \\\"1234\\\"} }; line: 1, column: 17]"); } @Test public void shouldNotMatchJsonMissingSubField() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", objectField: { } }")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", objectField: { } }", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ \\\"one\\\" ], enumField: \\\"one\\\", objectField: { } }; line: 1, column: 17]"); } @Test public void shouldNotMatchJsonMultipleErrors() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(JSON_SCHEMA); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("{arrayField: [ ], stringField: \\\"1234\\\"}")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "{arrayField: [ ], stringField: \\\"1234\\\"}", "{\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"enumField\": {\n" + " \"enum\": [ \"one\", \"two\" ]\n" + " },\n" + " \"arrayField\": {\n" + " \"type\": \"array\",\n" + " \"minItems\": 1,\n" + " \"items\": {\n" + " \"type\": \"string\"\n" + " },\n" + " \"uniqueItems\": true\n" + " },\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 5,\n" + " \"maxLength\": 6\n" + " },\n" + " \"booleanField\": {\n" + " \"type\": \"boolean\"\n" + " },\n" + " \"objectField\": {\n" + " \"type\": \"object\",\n" + " \"properties\": {\n" + " \"stringField\": {\n" + " \"type\": \"string\",\n" + " \"minLength\": 1,\n" + " \"maxLength\": 3\n" + " }\n" + " },\n" + " \"required\": [ \"stringField\" ]\n" + " }\n" + " },\n" + " \"additionalProperties\" : false,\n" + " \"required\": [ \"enumField\", \"arrayField\" ]\n" + "}", "Unexpected character ('\\' (code 92)): expected a valid value (number, String, array, object, 'true', 'false' or 'null')\n" + " at [Source: {arrayField: [ ], stringField: \\\"1234\\\"}; line: 1, column: 34]"); } @Test public void shouldNotMatchIllegalJson() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher("illegal_json"); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("illegal_json")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "illegal_json", "illegal_json", "Unrecognized token 'illegal_json': was expecting ('true', 'false' or 'null')\n" + " at [Source: illegal_json; line: 1, column: 25]"); // and assertFalse(jsonSchemaMatcher.matches("some_other_illegal_json")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "some_other_illegal_json", "illegal_json", "Unrecognized token 'illegal_json': was expecting ('true', 'false' or 'null')\n" + " at [Source: illegal_json; line: 1, column: 25]"); } @Test public void shouldNotMatchNullExpectation() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(null); jsonSchemaMatcher.logger = logger; // then assertFalse(new JsonSchemaMatcher(null).matches("some_value")); // and verifyNoMoreInteractions(logger); } @Test public void shouldNotMatchEmptyExpectation() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher(""); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("some_value")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "some_value", "", "No content to map due to end-of-input\n" + " at [Source: ; line: 1, column: 0]"); } @Test public void shouldNotMatchNullTest() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher("some_value"); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches(null)); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", null, "some_value", "Unrecognized token 'some_value': was expecting ('true', 'false' or 'null')\n" + " at [Source: some_value; line: 1, column: 21]"); } @Test public void shouldNotMatchEmptyTest() { // given JsonSchemaMatcher jsonSchemaMatcher = new JsonSchemaMatcher("some_value"); jsonSchemaMatcher.logger = logger; // then assertFalse(jsonSchemaMatcher.matches("")); // and verify(logger).trace("Failed to perform JSON match \"{}\" with \"{}\" because {}", "", "some_value", "Unrecognized token 'some_value': was expecting ('true', 'false' or 'null')\n" + " at [Source: some_value; line: 1, column: 21]"); } @Test public void showHaveCorrectEqualsBehaviour() { assertEquals(new JsonSchemaMatcher("some_value"), new JsonSchemaMatcher("some_value")); } }