citrusframework / citrus

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

Groovy validation swaps expected and got when using JSON assert #1029

Open JensVanhulstSolita opened 1 year ago

JensVanhulstSolita commented 1 year ago

Citrus Version groovy: 3.4.0 citrus: 3.4.0

Question I have the following testing scenario : Inbound SFTP -> Mulesoft (SUT) -> Sends message to AMQ I need to validate if the message send to Anypoint MQ is the same as the test sample

Therefore I wrote a script that looks like this :

.... imports

// Get Response message from context
def responseText = context.getVariable("amqResponseMessage")
def responseType = context.getVariable("amqResponseType")

// Parse message body
def responseJson = new JsonSlurper().parseText(responseText)
def actualMessageBody = responseJson[0].body

// Get Comparable file from filesystem
def filePath = context.getVariable("filePathAmqResponseMessage")
def fileContent = new File(filePath).text

Logger logger = Logger.getLogger("")

// Validate messages
switch (responseType) {
    case "json":
        // Validate JSON
        logger.info("----- actual ----")
        logger.info(actualMessageBody)

        logger.info("----- expected ----")
        logger.info(fileContent)

        JSONAssert.assertEquals(actualMessageBody, fileContent, JSONCompareMode.STRICT)
        break
}

When using this script in other test scenarios it works perfect but it seems that when you have the SFTP -> AMQ the expected and got, are being swapped for some reason :

Screenshot 2023-10-19 at 11 53 04

What I've tried so far To Debug I added the loggers for actual & expected and there each file is in the proper variable (so not swapped)

Additional information

Maybe update to macOs Sonoma ?

Step for receiving & validating :

 <step then="^ape-shipments-mule4 transforms and forwards the SV033F message with payload (.*) to Anypoint MQ$" parameter-names="outboundAmqRequestMessage">
        <citrus:sleep seconds="1"/>

          <!-- Get all messages from AMQ destination -->
          <http:send-request client="amqMessageClient">
            <http:GET path="/organizations/${amqOrgId}/environments/${amqEnvId}/destinations/${amq.ape-shipments.exchange.shipments.positions}/messages">
                <http:param name="pollingTime" value="10000" />
                <http:param name="batchSize" value="1" />
                <http:param name="lockTtl" value="10000" />
                <http:headers content-type="application/json" version="HTTP/1.1" accept="*/*">
                    <http:header name="Authorization" value="Bearer ${amqAccessToken}" />
                </http:headers>
            </http:GET>
        </http:send-request>

        <!-- Validate response & conversationId -->
        <http:receive-response client="amqMessageClient" timeout="30000">
            <http:headers status="200" reason-phrase="OK" version="HTTP/1.1" />
            <http:body type="json">  
                <http:validate>
                    <http:json-path expression="$..properties.conversationId" value="@assertThat(not(isEmptyString())@"/>
                </http:validate>
            </http:body>

            <!-- Extract body into variables for later usage -->
            <http:extract>
                <http:body path="$..headers.messageId" variable="message_id" />
                <http:body path="$..headers.lockId" variable="lock_id" />
                <http:body path="$" variable="amqResponseMessage" />
            </http:extract>
        </http:receive-response>

        <!-- "Acknowledge" message and remove from AMQ destination -->
        <http:send-request client="amqMessageClient">
            <http:DELETE path="/organizations/${amqOrgId}/environments/${amqEnvId}/destinations/${amq.ape-shipments.exchange.shipments.positions}/messages">
                <http:headers content-type="application/json" version="HTTP/1.1" accept="*/*">
                    <http:header name="Authorization" value="Bearer ${amqAccessToken}" />
                </http:headers>
                <http:body type="json">
                    <http:resource file="com/aperam/citrus/${project.name}/testfiles/shared/amq/amqDELETEMessagesRequest.json" charset="UTF-8" />
                </http:body>
            </http:DELETE>
        </http:send-request>

        <!-- Validate Response message -->
        <citrus:create-variables>
            <citrus:variable name="amqResponseType" value="json" />
            <citrus:variable name="filePathAmqResponseMessage" value="src/test/resources/com/aperam/citrus/${project.name}/testfiles/${outboundAmqRequestMessage}" />
        </citrus:create-variables>
        <citrus:groovy resource="com/aperam/citrus/${project.name}/scripts/validateAMQResponseMessage.groovy" />
    </step>
bbortt commented 1 year ago

would be worth figuring out if this is still an issue with the latest mileston 2 release, I think?

JensVanhulstSolita commented 1 year ago

@bbortt it's used in company env, we use a parent pom for dependencies and updating to 4.0.0-M2 would mean updating over 100 apps and making sure they work, but I can verify with a dummy project

christophd commented 1 year ago

would be good to have the SFTP steps that extract the variables

JensVanhulstSolita commented 1 year ago

@christophd It isn't going to help in this case. The SFTP message is different from the AMQ message because Mulesoft (SUT) transforms the message to another format.

I need to check what comes out of AMQ against a sample to make sure MuleSoft made the right transformation

christophd commented 1 year ago

@JensVanhulstSolita any news on this issue. did you find out what went wrong?