JsonTextMessageValidator extends AbstractMessageValidator<JsonMessageValidationContext> implements ApplicationContextAware { @Override @SuppressWarnings("unchecked") public void validateMessage(Message receivedMessage, Message controlMessage, TestContext context, JsonMessageValidationContext validationContext) { if (controlMessage == null || controlMessage.getPayload() == null) { log.debug("Skip message payload validation as no control message was defined"); return; } log.debug("Start JSON message validation ..."); if (validationContext.isSchemaValidationEnabled()) { performSchemaValidation(receivedMessage, context, validationContext); } if (log.isDebugEnabled()) { log.debug("Received message:\n" + receivedMessage); log.debug("Control message:\n" + controlMessage); } String receivedJsonText = receivedMessage.getPayload(String.class); String controlJsonText = context.replaceDynamicContentInString(controlMessage.getPayload(String.class)); try { if (!StringUtils.hasText(controlJsonText)) { log.debug("Skip message payload validation as no control message was defined"); return; } else { Assert.isTrue(StringUtils.hasText(receivedJsonText), "Validation failed - " + "expected message contents, but received empty message!"); } JSONParser parser = new JSONParser(JSONParser.MODE_JSON_SIMPLE); Object receivedJson = parser.parse(receivedJsonText); ReadContext readContext = JsonPath.parse(receivedJson); Object controlJson = parser.parse(controlJsonText); if (receivedJson instanceof JSONObject) { validateJson("$.", (JSONObject) receivedJson, (JSONObject) controlJson, validationContext, context, readContext); } else if (receivedJson instanceof JSONArray) { JSONObject tempReceived = new JSONObject(); tempReceived.put("array", receivedJson); JSONObject tempControl = new JSONObject(); tempControl.put("array", controlJson); validateJson("$.", tempReceived, tempControl, validationContext, context, readContext); } else { throw new CitrusRuntimeException("Unsupported json type " + receivedJson.getClass()); } } catch (IllegalArgumentException e) { throw new ValidationException(String.format("Failed to validate JSON text:%n%s", receivedJsonText), e); } catch (ParseException e) { throw new CitrusRuntimeException("Failed to parse JSON text", e); } log.info("JSON message validation successful: All values OK"); } JsonTextMessageValidator(); @Override @SuppressWarnings("unchecked") void validateMessage(Message receivedMessage, Message controlMessage,
                                TestContext context, JsonMessageValidationContext validationContext); @SuppressWarnings("rawtypes") void validateJson(String elementName, JSONObject receivedJson, JSONObject controlJson, JsonMessageValidationContext validationContext, TestContext context, ReadContext readContext); boolean isIgnored(String controlKey, Object controlValue, Object receivedJson, Set<String> ignoreExpressions, ReadContext readContext); @Override boolean supportsMessageType(String messageType, Message message); void setStrict(boolean strict); JsonTextMessageValidator strict(boolean strict); @Override void setApplicationContext(ApplicationContext applicationContext);  }
@Test public void testJsonValidation() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationNestedObjects() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"person\":{\"name\":\"John\",\"surname\":\"Doe\"}, \"index\":5, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"person\":{\"name\":\"John\",\"surname\":\"Doe\"}, \"index\":5, \"id\":\"x123456789x\"}"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationWithArrays() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}]"); Message controlMessage = new DefaultMessage("[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}]"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationWithNestedArrays() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationVariableSupport() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello ${world}!\", \"index\":${index}, \"id\":\"${id}\"}"); context.setVariable("world", "World"); context.setVariable("index", "5"); context.setVariable("id", "x123456789x"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationWrongNumberOfEntries() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\", \"missing\":\"this is missing\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected '4'")); Assert.assertTrue(e.getMessage().contains("but was '3'")); return; } Assert.fail("Missing validation exception due to wrong number of JSON entries"); }
@Test public void testJsonValidationWrongValue() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"wrong\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected 'x123456789x'")); Assert.assertTrue(e.getMessage().contains("but was 'wrong'")); return; } Assert.fail("Missing validation exception due to wrong value"); }
@Test public void testJsonValidationWrongValueInNestedObjects() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"person\":{\"name\":\"John\",\"surname\":\"wrong\"}, \"index\":5, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"person\":{\"name\":\"John\",\"surname\":\"Doe\"}, \"index\":5, \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected 'Doe'")); Assert.assertTrue(e.getMessage().contains("but was 'wrong'")); return; } Assert.fail("Missing validation exception due to wrong value"); }
@Test public void testJsonValidationWrongValueInArrays() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":0}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected '2'")); Assert.assertTrue(e.getMessage().contains("but was '0'")); return; } Assert.fail("Missing validation exception due to wrong value"); }
@Test public void testJsonValidationWrongArraySize() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}], \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected '3'")); Assert.assertTrue(e.getMessage().contains("but was '2'")); return; } Assert.fail("Missing validation exception due to wrong array size"); }
@Test public void testJsonValidationArrayTypeMismatch() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"greetings\":{\"text\":\"Hello World!\", \"index\":1}, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected 'JSONArray'")); Assert.assertTrue(e.getMessage().contains("but was 'JSONObject'")); return; } Assert.fail("Missing validation exception due to type mismatch"); }
@Test public void testJsonValidationObjectTypeMismatch() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}], \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"greetings\":{\"text\":\"Hello World!\", \"index\":1}, \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected 'JSONObject'")); Assert.assertTrue(e.getMessage().contains("but was 'JSONArray'")); return; } Assert.fail("Missing validation exception due to type mismatch"); }
@Test public void testJsonValidationIgnorePlaceholder() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"object\":{\"id\":\"x123456789x\"}, \"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}],}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":\"@ignore@\", \"object\":{\"id\":\"@ignore@\"}, \"greetings\":\"@ignore@\"}"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationIgnoreEntries() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"object\":{\"id\":\"x123456789x\"}, \"greetings\":[" + "{\"text\":\"Hello World!\", \"index\":1}, " + "{\"text\":\"Hallo Welt!\", \"index\":2}, " + "{\"text\":\"Hola del mundo!\", \"index\":3}],}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":\"?\", \"object\":{\"id\":\"?\"}, \"greetings\":\"?\"}"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validationContext.getIgnoreExpressions().add("$..index"); validationContext.getIgnoreExpressions().add("$.object.id"); validationContext.getIgnoreExpressions().add("$.greetings"); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonValidationInvalidJsonText() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"wrong\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":invalid, \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); } catch (CitrusRuntimeException e) { Assert.assertTrue(e.getCause() instanceof ParseException); return; } Assert.fail("Missing validation exception due to wrong value"); }
@Test public void testJsonNullValueValidation() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":null}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":null}"); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonEmptyMessageValidation() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage(""); Message controlMessage = new DefaultMessage(""); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonEmptyMessageValidationError() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage(""); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); Assert.fail("Missing validation exception due to validation error"); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected message contents, but received empty message")); } receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); controlMessage = new DefaultMessage(""); JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); }
@Test public void testJsonNullValueMismatch() { JsonTextMessageValidator validator = new JsonTextMessageValidator(); Message receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); Message controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":null}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); Assert.fail("Missing validation exception due to wrong value"); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected 'null' but was 'x123456789x'")); } receivedMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":null}"); controlMessage = new DefaultMessage("{\"text\":\"Hello World!\", \"index\":5, \"id\":\"x123456789x\"}"); try { JsonMessageValidationContext validationContext = new JsonMessageValidationContext(); validator.validateMessage(receivedMessage, controlMessage, context, validationContext); Assert.fail("Missing validation exception due to wrong value"); } catch (ValidationException e) { Assert.assertTrue(e.getMessage().contains("expected 'x123456789x' but was 'null'")); } }