citrusframework / citrus

Framework for automated integration tests with focus on messaging integration
https://citrusframework.org
Apache License 2.0
453 stars 134 forks source link

set datatype of JSON value #540

Open elvinsp opened 5 years ago

elvinsp commented 5 years ago

User story

As the a tester I want to be able to define the datatype of my JSON values, when sending them to the SUT.

With version Citrus 2.7.8 it is not possible to set the datatype of an JSON value. Numbers will be automatically set as Integer/float and doesn't give the tester the opportunity to set them as string.

Additional context

Initial Question: https://github.com/citrusframework/citrus/issues/538

<send endpoint="configRequestEndpoint">
    <message type="json">
      <resource file="file:src/test/templates/json/api/config/saveGroupTrips.json"/>
      <element path="$.data.trips[*].sourceBits" value="000110"/>
    </message>
  </send>

This request should also be considered for boolean values.

elvinsp commented 5 years ago

attributes "path" and "value" are stored in a PayloadTemplateMessageBuilder via a JsonPathMessageConstructionInterceptor with the datatype Map<String,String>, which can be found in com.consol.citrus.xml.AbstractMessageActionParser.java:155

An additional "datatype" attribute would be required to be stored in the the interceptor, so it can be used in the message construction in com.consol.citrus.validation.json.JsonPathMessageConstructionInterceptor:91

Any prefered implementations or ideas?

svettwer commented 5 years ago

Hi!

attributes "path" and "value" are stored in a PayloadTemplateMessageBuilder via a JsonPathMessageConstructionInterceptor with the datatype Map<String,String>, which can be found in com.consol.citrus.xml.AbstractMessageActionParser.java:155

That is correct. :+1:

An additional "datatype" attribute would be required to be stored in the the interceptor, so it can be used in the message construction in com.consol.citrus.validation.json.JsonPathMessageConstructionInterceptor:91

I think the easiest way would be to alter the corresponding BeanDefinitionParser and setup the JsonPathMessageConstructionInterceptor with the parsed value. But this is just the XML case. We've to consider the Java case as well.

BR, Sven

elvinsp commented 5 years ago

Hi,

I started to implement a Map in a Map for value and datatype attributes. Now I'm hitting a wall adjusting the testcases to work with this new implementation. Specifically with the testdata import via context xml file in com.consol.citrus.config.xml.JsonDataDictionaryParserTest. I have no idea how to structure test/resources/com/consol/citrus/config/xml/JsonDataDictionaryParserTest-context.xml so a Map in a Map will be generated.

BR, Elvin

svettwer commented 5 years ago

Hi!

It would be great if you could provide a little bit more context here. I've noticed you forked Citrus but I was unable to find a branch containing your implementation. It would be great if you could push your changes to your fork so that I can have a look.

BR, Sven

elvinsp commented 5 years ago

Hi Sven,

I hope you had a good transition into 2019. I would like to continue what I started last year, can you take a look? I had to adjust the schema definition of citrus-testcase.xsd and citrus-config.xsd. Where do I commit those? Right now they are lying around on my local machine.

I also solved my issue on my last post, so no troubles there.

BR Elvin

svettwer commented 5 years ago

Hi!

Thx, I hope you had a happy new year as well! :tada: Sorry for the late response. I'm currently finalizing the roadmap for 2019. I'll have a look as soon as possible. :+1:

BR, Sven

elvinsp commented 5 years ago

Hi,

in my mind I'm almost finished with this. One thing that is left from my prespective is the adaption of com.consol.citrus.variable.dictionary.json.JsonMappingDataDictionary.

At the moment it seems the data dictionary can only replace attributes to String. If it should be able to replace attributes to different datatypes, it leads to some hurdles.

The function public <T> T translate(String jsonPath, T value, TestContext context) would be the ideal place to do it so, but because it is a template function and the return value is depend on the datatype of the value parameter, the implementation has to be done in private void traverseJsonData(JSONObject jsonData, String jsonPath, TestContext context) to resolve the datatype of the value. That on the other hand would require to move the mapping strategy which is done in the translate function also into the traverseJsonData which would make tanslate obsolete. I haven't done anything yet so there is no code to review this problem. But basically it is revolving around those two functions.

Any way I won't be available for a month, so I can only do this once I'm back in Mid February. Let me know what you think of this and the rest of the code.

BR Elvin

svettwer commented 5 years ago

Hi Elvin,

thx for the information. I'll definitely have a look until your are back. I am very unhappy that I can't support you on this as much as you deserve. I am really very sorry for that! :cry: I am currently working hard to get the roadmap and 2.7.9 + 2.8.0 released, in addition to customer projects, writing articles etc.

Thx for all your patience with this! We really much appreciate your work on this issue! :+1: Have a good time then!

BR, Sven