Munit tests for the POst request end point - mule

I am very new to Mulesoft and struggling to understand how to create the MUnit Tests for the simple flow which looks like below
<sub-flow name="salesforce-Opportunity-create-flow" doc:id="bd0263bf-7880-46d0-9c83-92376caa1bbb" >
<json-logger:logger doc:name="Begin Flow (Info)" doc:id="1f263a47-bb39-4748-b5b2-9e2f946cac58" config-ref="JSON_Logger_Config" message="Starting salesforce-Opportunity-create-flow" category="${jsonlogger.category}">
<json-logger:content><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
name: payload.name,
accountId: payload.accountId,
recordTypeId: payload.recordTypeId
}]]]></json-logger:content>
</json-logger:logger>
<ee:transform doc:name="Map Request Body" doc:id="ecee64bf-1b14-4261-bb29-c22d01f89726" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
---
[{
AccountId: payload.accountId,
RecordTypeId: payload.recordTypeId,
Name: payload.name,
StageName: payload.stageName,
CloseDate: payload.closeDate as Date,
LeadSource: payload.leadSource,
Pricebook2Id: payload.priceBook2ID,
Date_of_First_Contact__c: payload.dateOfFirstContact as Date,
Contact__c: payload.contact,
Service_Type__c: payload.serviceType,
SOW_Request_Date__c: payload.SowRequestDate as DateTime,
SOW_Generation_Stage__c: payload.SowGenerationStage
}]]]></ee:set-payload>
</ee:message>
</ee:transform>
<json-logger:logger doc:name="After Map Request Body (Info)" doc:id="6ef57816-a0ba-4f62-aa66-851467799ffc" config-ref="JSON_Logger_Config" message="After Map Request Body & Before Salesforce Create Operation in salesforce-Opportunity-create-flow" category="${jsonlogger.category}" tracePoint="AFTER_TRANSFORM">
<json-logger:content><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
Name: payload.Name,
AccountId: payload.AccountId,
RecordTypeId: payload.RecordTypeId
}]]]></json-logger:content>
</json-logger:logger>
<salesforce:create doc:name="Create" doc:id="e6b01da3-e86b-4d05-966d-cc410d5a2b7d" config-ref="Salesforce_Config" type="Opportunity"/>
<json-logger:logger doc:name="After Request to Salesforce (Info)" doc:id="5f397dec-ad2b-4672-a4a6-49b7cb55eccc" config-ref="JSON_Logger_Config" message="After Salesforce Create Operation in salesforce-Opportunity-create-flow" tracePoint="AFTER_REQUEST" category="${jsonlogger.category}">
<json-logger:content><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
success: payload.successful
}]]]></json-logger:content>
</json-logger:logger>
<ee:transform doc:name="Map Salesforce Response" doc:id="882badac-042c-420e-b58d-891345a51210" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
Id: payload.items[0].id
}]]></ee:set-payload>
</ee:message>
<ee:variables >
<ee:set-variable variableName="httpStatus" ><![CDATA[%dw 2.0
output application/json
---
payload.items[0].statusCode]]></ee:set-variable>
</ee:variables>
</ee:transform>
<json-logger:logger doc:name="End Flow (Info)" doc:id="a2e40bdb-e6e3-43e0-a0b2-eb85cb8f2d64" config-ref="JSON_Logger_Config" message="After Mapping Salesforce Response & End salesforce-Opportunity-create-flow" tracePoint="END" category="${jsonlogger.category}" >
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
Id: payload.Id
}]]]></json-logger:content>
</json-logger:logger>
</sub-flow>
The above request is a POST endpoint that will create record in Salesforce. The articles I read was saying about Record Tests But I unable to do the record option for this application. The only other option I see is Create a blank test for the flow that just created the empty test
Most of the articles I referred was taking about GET. Any help/exaple of how I can mock the POST request will be great

You can use the example in the documentation to understand how to mock an HTTP Request with method POST:
<munit-tools:mock-when processor="http:request">
<munit-tools:with-attributes>
<munit-tools:with-attribute attributeName="method" whereValue="#['POST']"/>
</munit-tools:with-attributes>
<munit-tools:then-return>
<munit-tools:payload value="#['mockPayload']"/>
</munit-tools:then-return>
</munit-tools:mock-when>

Related

Deploying to Cloudhub, Munit tests fails that has Salesforce create connector

I have a flow that has the Salesforce create connector, the Munit test that references the flow Runs fine locally. But when I try to deploy them to the CloudHub using the Azure Devops CI/CD pipeline throws error like
WARN 2022-04-07 23:41:54,103 [[MuleRuntime].uber.04: [mule-salesforce-sys].salesforce-Opportunity-create-flow/processors/3.ps.BLOCKING #3c7baec] org.mule.extension.salesforce.internal.connection.provider.BasicConnectionProvider: Couldn't obtain access token because an exception has occurred. Runtime to handle the ConnectionException. Root exception was: Invalid status code: 400, response body: {"error":"invalid_client","error_description":"invalid client credentials"}
org.mule.runtime.extension.api.exception.ModuleException: Invalid status code: 400, response body: {"error":"invalid_client","error_description":"invalid client credentials"}
Flow that needs the Munit test is
<sub-flow name="salesforce-Opportunity-create-flow" doc:id="bd0263bf-7880-46d0-9c83-92376caa1bbb" >
<ee:transform doc:name="Map Request Body" doc:id="ecee64bf-1b14-4261-bb29-c22d01f89726" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/java
---
[{
AccountId: payload.accountId,
RecordTypeId: payload.recordTypeId,
Name: payload.name,
StageName: payload.stageName,
CloseDate: payload.closeDate as Date,
LeadSource: payload.leadSource,
Pricebook2Id: payload.priceBook2ID,
Date_of_First_Contact__c: payload.dateOfFirstContact as Date,
Contact__c: payload.contact,
Service_Type__c: payload.serviceType,
SOW_Request_Date__c: payload.SowRequestDate as DateTime,
SOW_Generation_Stage__c: payload.SowGenerationStage
}]]]></ee:set-payload>
</ee:message>
</ee:transform>
<salesforce:create doc:name="Create" doc:id="e6b01da3-e86b-4d05-966d-cc410d5a2b7d" config-ref="Salesforce_Config" type="Opportunity"/>
<json-logger:logger doc:name="After Request to Salesforce (Info)" doc:id="5f397dec-ad2b-4672-a4a6-49b7cb55eccc" config-ref="JSON_Logger_Config" message="After Salesforce Create Operation in salesforce-Opportunity-create-flow" tracePoint="AFTER_REQUEST" category="${jsonlogger.category}">
<json-logger:content><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
success: payload.successful
}]]]></json-logger:content>
</json-logger:logger>
<ee:transform doc:name="Map Salesforce Response" doc:id="882badac-042c-420e-b58d-891345a51210" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
Id: payload.items[0].id
}]]></ee:set-payload>
</ee:message>
<ee:variables >
<ee:set-variable variableName="httpStatus" ><![CDATA[%dw 2.0
output application/json
---
payload.items[0].statusCode]]></ee:set-variable>
</ee:variables>
</ee:transform>
<json-logger:logger doc:name="End Flow (Info)" doc:id="a2e40bdb-e6e3-43e0-a0b2-eb85cb8f2d64" config-ref="JSON_Logger_Config" message="After Mapping Salesforce Response & End salesforce-Opportunity-create-flow" tracePoint="END" category="${jsonlogger.category}" >
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
Id: payload.Id
}]]]></json-logger:content>
</json-logger:logger>
</sub-flow>
The Munit test is like below
<munit:test name="salesforce-sys-implementation-test-suite-salesforce-Opportunity-create-flowTest" doc:id="c9779a45-00fe-4e08-b3e7-2580e68352ef" description="Test">
<munit:behavior>
<munit-tools:mock-when doc:name="Mock when" doc:id="a2ff9717-a4ee-4bea-9caf-9e3d5fe591b7" processor="flow">
<munit-tools:with-attributes >
<munit-tools:with-attribute whereValue="post:\opportunity:application\json:salesforce-system-api-config" attributeName="name" />
</munit-tools:with-attributes>
<munit-tools:then-return >
<munit-tools:payload value="#[{}]" mediaType="application/json" encoding="UTF-8" />
</munit-tools:then-return>
</munit-tools:mock-when>
</munit:behavior>
<munit:execution >
<munit:set-event doc:name="Set Event" doc:id="4c21ba83-a2d8-47f7-a327-33a772f980c6" >
<munit:payload value='{
"name": "X",
"SowGenerationStage": "SOW Requested",
"dateOfFirstContact": "2022-03-28",
"closeDate": "2022-03-28",
"SowRequestDate": "2022-03-28T12:48:16Z",
"accountId": "001T7IAM",
"contact": "003U0",
"leadSource": "Project Management",
"recordTypeId": "012U0000000QBXWIA4",
"serviceType": "SPR",
"priceBook2ID": "01s",
"stageName": "Discover"
}' mediaType="application/json" />
</munit:set-event>
<flow-ref doc:name="Flow-ref to salesforce-Opportunity-create-flow" doc:id="3c3d043f-f1ad-4b8d-9290-d407400d14a6" name="salesforce-Opportunity-create-flow"/>
</munit:execution>
<munit:validation >
<munit-tools:assert-that doc:name="Assert that Not Null Response" doc:id="da165ba2-619f-462e-8278-e66ee771cb08" is="#[MunitTools::notNullValue()]" expression="#[payload.Id]"/>
</munit:validation>
</munit:test>
But before I created the MUnit tests I deployed the flow to the CloudHub and there was no issues or error with Build Pipeline. I can still access the endpoint. After adding the Munit tests and deploying it throws error. All the credentials are stored in the Pipeline Variables..
The problem is not with deployment itself, but with the MUnit test case. As you mentioned the Salesforce connector is not mocked and trying to connect. You should mock the subflow or the connector. Use the attributes of <munit-tools:mock-when> to select the right artifact to mock. As shown in the question is trying to mock a flow not shown in the question ("post:\opportunity:application\json:salesforce-system-api-config"). It seems that you really want to mock the Salesforce connector operation.
You could execute the unit test locally, or without trying to deploy to verify it is working first.

Mocking Multiple connectors in the flow

I have a flow where I have a connector to query and connector create record in Salesforce. I am a newbie to Mulesoft and the Munit tests. I just created a simple Munit tests for the flow with one connector to Salesforce. Just trying to do the same but running in to issue with the Munit tests with two mock
Flow with two Salesforce connectors
<sub-flow name="salesforce-Quote-create-flow" doc:id="310fe17f-64b3-448e-8c13-d5994352c3f5" >
<json-logger:logger doc:name="Begin Flow (Info)" doc:id="92cbe814-9391-4ef0-900b-33c72643f3d7" config-ref="JSON_Logger_Config" message="Starting salesforce-Quote-create-flow" category="${jsonlogger.category}">
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
name: payload.quoteID,
opportunityId : payload.opportunityId,
}]]]></json-logger:content>
</json-logger:logger>
<set-variable value="#[payload]" doc:name="Set the input Payload" doc:id="6b46a184-fabb-4063-a1b8-a074622f73dc" variableName="inputPayload"/>
<salesforce:query doc:name="Query Existing Quote" doc:id="19c396a3-8656-4600-beba-9e011e78d2b4" config-ref="Salesforce_Config">
<salesforce:salesforce-query ><![CDATA[Select ID,Opportunity.recordTypeID,Contact_Information__c, Executive_Summary_checkbox__c, Milestones_checkbox__c, Gantt_Chart__c,
Shipment_Schedule__c, Timeline_Tool__c, Product_Description__c, Materials_and_Pricing__c,
To_accept_this_statement_of_work__c, Animal_Health_Policy__c, Cancelation_Policy__c,
Fees_and_Invoicing__c, Terms_and_Conditions__c, Signature__c, Customer_Signature__c, Executive_Summary__c,
(SELECT id,Quote__c FROM Quote_Sent_To__r) FROM Quote WHERE OpportunityId= ':opportunityId' Order by createddate desc limit 1
]]></salesforce:salesforce-query>
<salesforce:parameters ><![CDATA[#[output application/java
---
{
"opportunityId" : vars.inputPayload.opportunityId
}]]]></salesforce:parameters>
</salesforce:query>
<set-variable value="#[payload]" doc:name="Set Variable exisingQuote" doc:id="9e591720-7e19-4f8f-b86f-98b05ee896f7" variableName="existingQuote"/>
<ee:transform doc:name="Map the Request Body to Create New Quote" doc:id="f3d95e54-95a5-466d-b3c3-7d3323aef6b0">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
---
if(payload[0].Id != null)
[{
Name : vars.inputPayload.name,
OpportunityId: vars.inputPayload.opportunityId,
Pricebook2Id: vars.inputPayload.pricebook2d,
AX_Instance__c : vars.inputPayload.axInstance,
Multiline_Discount__c : vars.inputPayload.multilineDiscount,
Total_Discount__c: vars.inputPayload.totalDiscount,
Customer_Signature__c : payload[0].Customer_Signature__c as Boolean,
Executive_Summary__c : payload[0].Executive_Summary__c
}]
else
[{
Name : vars.inputPayload.name,
OpportunityId: vars.inputPayload.opportunityId,
Pricebook2Id: vars.inputPayload.pricebook2d,
AX_Instance__c : vars.inputPayload.axInstance,
Multiline_Discount__c : vars.inputPayload.multilineDiscount,
Total_Discount__c: vars.inputPayload.totalDiscount,
}]]]></ee:set-payload>
</ee:message>
</ee:transform>
<set-variable value="#[payload[0]]" doc:name="Set Variable" doc:id="e31add26-4221-4004-9c19-b5d35d51a565" variableName="quoteBody"/>
<json-logger:logger doc:name="After Map Request Body" doc:id="381c37f1-7dfa-4085-a294-7571424bdda2" config-ref="JSON_Logger_Config" message="After Building the Request body for the in salesforce-Quote-create-flow" tracePoint="AFTER_TRANSFORM" priority="DEBUG" category="${jsonlogger.category}">
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
payload: payload
}]]]></json-logger:content>
</json-logger:logger>
<salesforce:create doc:name="Create Quote Record" doc:id="99e7fd61-af4f-4bed-bcb6-4f86e91c8a4b" config-ref="Salesforce_Config" type="Quote"/>
<json-logger:logger doc:name="After Create Request to Salesforce (INFO)" doc:id="113e7428-eb0b-48b9-b007-afc7f2e44f0d" config-ref="JSON_Logger_Config" message="After Salesforce Create Operation in salesforce-Quote-create-flow" category="${jsonlogger.category}">
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
success: payload.successful
}]]]></json-logger:content>
</json-logger:logger>
</sub-flow>
And the Munit Test is like below
<munit:test name="salesforce-sys-implementation-test-suite-salesforce-Quote-create-flowTest" doc:id="801d6bae-4579-4e52-8405-871c30fc1a98" description="Test">
<munit:behavior>
<munit-tools:mock-when doc:name="Mock when" doc:id="fe9d022f-e6c8-47a4-9a28-b1d50e72eabd" processor="salesforce:query">
<munit-tools:with-attributes >
<munit-tools:with-attribute whereValue="Query Existing Quote" attributeName="doc:name" />
<munit-tools:with-attribute whereValue="19c396a3-8656-4600-beba-9e011e78d2b4" attributeName="doc:id" />
</munit-tools:with-attributes>
</munit-tools:mock-when>
<munit-tools:mock-when doc:name="Mock when" doc:id="f1a78a02-6664-4bde-ae98-17c81eb1b181" processor="salesforce:create">
<munit-tools:with-attributes >
<munit-tools:with-attribute whereValue="Create Quote Record" attributeName="doc:name" />
<munit-tools:with-attribute whereValue="99e7fd61-af4f-4bed-bcb6-4f86e91c8a4b" attributeName="doc:id" />
</munit-tools:with-attributes>
</munit-tools:mock-when>
</munit:behavior>
<munit:execution>
<munit:set-event doc:name="Set Event" doc:id="8c0f220b-d687-4de5-ba72-7d08fb75cc17">
<munit:payload value="#[MunitTools::getResourceAsString('samples/quote.json')]" encoding="UTF-8" mediaType="application/json" />
</munit:set-event>
<flow-ref doc:name="Flow Reference" doc:id="e312ebeb-dbe5-4728-b13d-8e43d916bd84" name="salesforce-Quote-create-flow"/>
</munit:execution>
<munit:validation >
<set-variable value="#[output application/json --- readUrl('classpath://samples/quoteResponse.json', 'application/json')]" doc:name="Set Variable" doc:id="1cec72cf-dea7-4a24-935b-aa0d497930d1" variableName="expectedPayload"/>
<munit-tools:assert-that doc:name="Assert that Not Null Response" doc:id="9a66b251-8dd6-4f5a-980d-0f607de91863" is="#[MunitTools::notNullValue()]" expression="#[vars.expectedPayload.Id]"/>
</munit:validation>
</munit:test>
It thows error saying
org.mule.runtime.api.el.ExpressionExecutionException: You called the function 'Value Selector' with these arguments:
1: String ("Q138446")
2: Name ("Id")
But it expects one of these combinations:
(Array, Name)
(Array, String)
(Date, Name)
(DateTime, Name)
(LocalDateTime, Name)
(LocalTime, Name)
(Object, Name)
(Object, String)
(Period, Name)
(Time, Name)
4| if(payload[0].Id != null)
^^^^^^^^^^^^^
Trace:
at anonymous::main (line: 4, column: 4)
The transform before the create connector is erroring. How can I set the payload there and mock the create connector in my flow. Any help is greatly appreciated
It appears you are setting the condition for the mock but didn't actually set a value to replace the execution.
See this example from the documentation:
<munit-tools:mock-when processor="http:request">
<munit-tools:with-attributes>
<munit-tools:with-attribute attributeName="method" whereValue="#['POST']"/>
</munit-tools:with-attributes>
<munit-tools:then-return>
<munit-tools:payload value="#['mockPayload']"/>
</munit-tools:then-return>
</munit-tools:mock-when>
Notice that after <munit-tools:with-attributes> there is a <munit-tools:then-return> element that sets the mock payload.
Read the documentation link above to understand how to use mock and the various options it has.

Cannot make the Mock for the Salesforce Connectors work in the Munit Tests

I have been struggling with the Munit tests for the flows I created. The Flow have couple of Salesforce connectors to Query, Create. So in my Munit tests I have the Mocks added but it seems like I am missing something. The Flow is like below
<sub-flow name="salesforce-Quote-create-flow" doc:id="310fe17f-64b3-448e-8c13-d5994352c3f5" >
<json-logger:logger doc:name="Begin Flow (Info)" doc:id="92cbe814-9391-4ef0-900b-33c72643f3d7" config-ref="JSON_Logger_Config" message="Starting salesforce-Quote-create-flow" category="${jsonlogger.category}">
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
name: payload.quoteID,
opportunityId : payload.opportunityId,
}]]]></json-logger:content>
</json-logger:logger>
<set-variable value="#[payload]" doc:name="Set the input Payload" doc:id="6b46a184-fabb-4063-a1b8-a074622f73dc" variableName="inputPayload"/>
<salesforce:query doc:name="Query Existing Quote" doc:id="19c396a3-8656-4600-beba-9e011e78d2b4" config-ref="Salesforce_Config">
<salesforce:salesforce-query ><![CDATA[Select ID,Opportunity.recordTypeID,Contact_Information__c, Executive_Summary_checkbox__c, Milestones_checkbox__c, Gantt_Chart__c,
Shipment_Schedule__c, Timeline_Tool__c, Product_Description__c, Materials_and_Pricing__c,
To_accept_this_statement_of_work__c, Animal_Health_Policy__c, Cancelation_Policy__c,
Fees_and_Invoicing__c, Terms_and_Conditions__c, Signature__c, Customer_Signature__c, Executive_Summary__c,(SELECT id,Quote__c FROM Quote_Sent_To__r) FROM Quote WHERE OpportunityId= ':opportunityId' Order by createddate desc limit 1
]]></salesforce:salesforce-query>
<salesforce:parameters ><![CDATA[#[output application/java
---
{
"opportunityId" : vars.inputPayload.opportunityId
}]]]></salesforce:parameters>
</salesforce:query>
<set-variable value="#[payload]" doc:name="Set Variable exisingQuote" doc:id="9e591720-7e19-4f8f-b86f-98b05ee896f7" variableName="existingQuote"/>
<ee:transform doc:name="Map the Request Body to Create New Quote" doc:id="f3d95e54-95a5-466d-b3c3-7d3323aef6b0">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
---
if(payload[0].Id != null)
[{
Name : vars.inputPayload.name,
OpportunityId: vars.inputPayload.opportunityId,
Pricebook2Id: vars.inputPayload.pricebook2d,
AX_Instance__c : vars.inputPayload.axInstance,
Multiline_Discount__c : vars.inputPayload.multilineDiscount,
Total_Discount__c: vars.inputPayload.totalDiscount,
Customer_Signature__c : payload[0].Customer_Signature__c as Boolean,
Executive_Summary__c : payload[0].Executive_Summary__c
}]
else
[{
Name : vars.inputPayload.name,
OpportunityId: vars.inputPayload.opportunityId,
Pricebook2Id: vars.inputPayload.pricebook2d,
AX_Instance__c : vars.inputPayload.axInstance,
Multiline_Discount__c : vars.inputPayload.multilineDiscount,
Total_Discount__c: vars.inputPayload.totalDiscount
}]]]></ee:set-payload>
</ee:message>
</ee:transform>
<set-variable value="#[payload[0]]" doc:name="Set Variable" doc:id="e31add26-4221-4004-9c19-b5d35d51a565" variableName="quoteBody"/>
<json-logger:logger doc:name="After Map Request Body" doc:id="381c37f1-7dfa-4085-a294-7571424bdda2" config-ref="JSON_Logger_Config" message="After Building the Request body for the in salesforce-Quote-create-flow" tracePoint="AFTER_TRANSFORM" priority="DEBUG" category="${jsonlogger.category}">
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
payload: payload
}]]]></json-logger:content>
</json-logger:logger>
<salesforce:create doc:name="Create Quote Record" doc:id="99e7fd61-af4f-4bed-bcb6-4f86e91c8a4b" config-ref="Salesforce_Config" type="Quote"/>
<json-logger:logger doc:name="After Create Request to Salesforce (INFO)" doc:id="113e7428-eb0b-48b9-b007-afc7f2e44f0d" config-ref="JSON_Logger_Config" message="After Salesforce Create Operation in salesforce-Quote-create-flow" category="${jsonlogger.category}">
<json-logger:content ><![CDATA[#[import modules::JSONLoggerModule output application/json ---
{
success: payload.successful
}]]]></json-logger:content>
</json-logger:logger>
</sub-flow>
And Munit tests is
<munit:test name="salesforce-sys-implementation-test-suite-salesforce-Quote-create-flowTest" doc:id="40f70f6a-3453-4a8b-9ed8-673e4796c0be" description="Test">
<munit:behavior>
<munit-tools:mock-when doc:name="Mock when" doc:id="5bfeb53b-2da1-45f9-bad3-67cf4d658fc2" processor="salesforce:query">
<munit-tools:with-attributes >
<munit-tools:with-attribute whereValue="Query Existing Quote" attributeName="doc:name" />
<munit-tools:with-attribute whereValue="19c396a3-8656-4600-beba-9e011e78d2b4" attributeName="doc:id" />
</munit-tools:with-attributes>
<munit-tools:then-return >
<munit-tools:payload value="#[output application/json --- readUrl('classpath://samples/quoteQueryResp.dwl')]" mediaType="application/java" encoding="UTF-8" />
</munit-tools:then-return>
</munit-tools:mock-when>
<munit-tools:mock-when doc:name="Mock when" doc:id="2d8c3c7b-04fd-4119-a535-d8b72c3af685" processor="salesforce:create">
<munit-tools:with-attributes >
<munit-tools:with-attribute whereValue="Create Quote Record" attributeName="doc:name" />
<munit-tools:with-attribute whereValue="99e7fd61-af4f-4bed-bcb6-4f86e91c8a4b" attributeName="doc:id" />
</munit-tools:with-attributes>
<munit-tools:then-return >
<munit-tools:payload value="#[output application/json --- readUrl('classpath://samples/resp.dwl')]" mediaType="application/java" encoding="UTF-8" />
</munit-tools:then-return>
</munit-tools:mock-when>
</munit:behavior>
<munit:execution>
<munit:set-event doc:name="Set Event" doc:id="b09dba54-76cc-401b-85aa-5657849861c4">
<munit:payload value="#[MunitTools::getResourceAsString('samples/quote.json')]" encoding="UTF-8" mediaType="application/json" />
</munit:set-event>
<flow-ref doc:name="Flow Reference" doc:id="875fa5b7-290d-4d3f-abfe-3098bf6c7ce1" name="salesforce-Quote-create-flow"/>
</munit:execution>
<munit:validation >
<set-variable value="#[output application/json --- readUrl('classpath://samples/quoteResponse.json', 'application/json')]" doc:name="Set Variable" doc:id="6fd61167-5025-4da3-8277-c9303ba9da57" variableName="expectedPayload"/>
<munit-tools:assert-that doc:name="Assert that Not Null Response" doc:id="dc4d4008-83bd-4da6-8773-fc4aa0285d0c" is="#[MunitTools::notNullValue()]" expression="#[vars.expectedPayload.Id]"/>
</munit:validation>
</munit:test>
The quoteQueryResp.dwl file is like below
[
{
"Product_Description__c": "false",
"Shipment_Schedule__c": "false",
"Executive_Summary_checkbox__c": "false",
"type": "Quote",
"Milestones_checkbox__c": "false",
"Terms_and_Conditions__c": "true",
"Timeline_Tool__c": "false",
"Signature__c": "false",
"Executive_Summary__c": null,
"Quote_Sent_To__r": null,
"Contact_Information__c": "true",
"Gantt_Chart__c": "false",
"Animal_Health_Policy__c": "true",
"Opportunity": {
"RecordTypeId": "012U0000000QtmpIAC",
"Id": null,
"type": "Opportunity"
},
"Materials_and_Pricing__c": "false",
"Cancelation_Policy__c": "true",
"To_accept_this_statement_of_work__c": "true",
"Customer_Signature__c": "false",
"Id": "0Q02D0000005vu7SAA",
"Fees_and_Invoicing__c": "true"
}
]
But I keep getting the error
org.mule.runtime.api.el.ExpressionExecutionException: You called the function 'Value Selector' with these arguments:
1: String ("[")
2: Name ("Id")
4| if(payload[0].Id != null)
^^^^^^^^^^^^^
Trace:
at anonymous::main (line: 4, column: 4)
Not sure what I am missing. Any help is greatly appreciated this is my first time creating the Mulesoft application
quoteQueryResp.dwl seems to be really a JSON document, which will work a DataWeave script but is missing the headers. Then you are adding an output to JSON in the expression instead of the script, then setting the media type of the mock to application/java. Maybe all these conversions are confusing DataWeave to believe the payload is a string. Try moving the output to the script and change the media type to match what is defined as output in the script. See the MUnit examples in the documentation to guide you.
Are you trying to read the mock .dwl's as java or json? Try to give the same media type in both places. Or better, remove the output application/json --- before readUrls and just give the output type in the mediaType attribute. Like this
<munit-tools:payload value="#[readUrl('classpath://samples/quoteQueryResp.dwl')]" mediaType="application/java" encoding="UTF-8" />

Create Batch-Mulesoft-Salesforce connector

I am trying to add batches to a job using SFDC Create Batch connector.As per the documentation,it expects jobInfo object(com. sforce. async. JobInfo).Below is the payload that i am sending.Even though i typecast the object to JobInfo object,it still complains
Message : "Unable to convert Array to class 'org.mule.extension.salesforce.api.bulk.JobInfo'
I am not sure what i am missing
%dw 2.0
output application/java
var arr = []
---
({
id: "75023000002VC0rAAG"
} as Object {
class : "com.sforce.async.JobInfo"
})>> arr
Please find the sample code you can use.
<flow name="AccountAddressFlowFlow" doc:id="d164048e-ab84-42d2-b1bf-cbcdc6c8802a" >
<http:listener doc:name="Listener" doc:id="73736cd1-cc6f-425d-8a9e-b2dacb4fd1e4" config-ref="HTTP_Listener_config" path="/accountaddress"/>
<file:read doc:name="Read" doc:id="9bc9edf9-07af-4061-8d6c-c85eb254d113" path="./AccountAddress/testl2Address.csv" outputMimeType='application/csv; quote="\""; separator=|'>
<ee:repeatable-file-store-stream bufferUnit="MB" />
</file:read>
<salesforce:create-job operation="upsert" type="Account_Address__c" doc:name="Create job" doc:id="6eaef36f-719a-45c6-a4f1-e3897c85dc97" config-ref="Salesforce_Config" target="JobInfo">
<salesforce:create-job-request ><![CDATA[#[%dw 2.0
output application/java
---
{
externalIdFieldName: "ADDR_Key__c",
contentType: "JSON",
concurrencyMode: "Parallel"
}]]]></salesforce:create-job-request>
</salesforce:create-job>
<ee:transform doc:name="Transform Message" doc:id="3d6b1820-95bb-4f11-b777-6db7a79319e2" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
<batch:job jobName="AccountAddressFlowBatch_Job" doc:id="259c9a9a-72d2-4b46-85cd-6c700fe2e9f5" maxFailedRecords="-1" blockSize="10000" maxConcurrency="16">
<batch:process-records >
<batch:step name="Batch_Step" doc:id="d5599f4a-0200-410f-95a3-9a38a08173f8" >
<ee:transform doc:name="Transform Message" doc:id="245af51b-1ae7-4958-b644-f45baf7c63dd" >
<ee:message >
<ee:set-payload ><![CDATA[%dw 2.0
output application/json
---
{
Name:payload.Location_Name80,
Location_ID__c:payload.Location_ID,
Fiber_Status__c:payload.fiber_status,
Account__r:{
Sub_Account_ID__c:payload.Sub_Account_ID
},
Address_Type__c:payload.Address_Type,
Postal_Code__c:payload.Postal_Code,
FirstNet_Type__c:payload.FirstNet_Type
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<batch:aggregator doc:name="Batch Aggregator" doc:id="33855357-eb2d-4dd3-ade2-ce043530665e" size="10000">
<salesforce:create-batch doc:name="Create batch" doc:id="83d9ab61-50dd-469b-bbf8-d2f53f36b3bc" config-ref="Salesforce_Config" jobInfoBatch="#[%dw 2.0
output application/java
---
vars.JobInfo]"/>
</batch:aggregator>
</batch:step>
</batch:process-records>
<batch:on-complete >
<logger level="INFO" doc:name="Logger" doc:id="b1c1fc2d-a3f4-4bf1-8ceb-5f249df58c60" />
</batch:on-complete>
</batch:job>
<logger level="INFO" doc:name="Logger" doc:id="e2bd3d39-2fc9-46f6-a686-55531f77a2d6" message="Account Address Completed"/>
</flow>
</mule>

Cannot open a new cursor on a closed stream, what does it mean in Mule 4?

I am new to Mulesfot and Mule4 and I am still trying to understand how things works here. Check the following image:
On the first processor I am calling a Salesforce URL and getting an XML back which I am transforming to a JSON in the second processor, there I am storing/outputting the result to a variable SalesforceResponse and later on the third one I am calling a subflow which stores some values on the database. Until that point everything works as expected. The problem comes once I try to access the variable SalesforceResponse in the last processor which I need to get some values as the serverURL for example. Currently I am getting the following error:
Message : Cannot open a new cursor on a closed stream.
Element : SalesforceFlow/processors/3 # salesforcefulfillment:salesforcefulfillment.xml:340 (Transform Message)
Element XML : <ee:transform doc:name="Transform Message" doc:id="bea5898f-5aa8-4835-8e9d-fa1fd165d6d2">
<ee:message></ee:message>
<ee:variables>
<ee:set-variable variableName="SalesforceServerUrl">%dw 2.0
import * from dw::core::URL
var urlComposition = parseURI(vars.SalesforceResponse.serverUrl)
output text/plain
---
log("Houston, we have a problem.")</ee:set-variable>
</ee:variables>
</ee:transform>
Error type : MULE:UNKNOWN
What does error even means? I would expect to be able to access a "session" variable all over the places along the flow without having issues or I can't for some reason that I am not aware of?
Here is the XML definition for the image above:
<sub-flow name="SalesforceFlow" doc:id="237910c7-38c7-42bb-969b-63d6ff03bdaa">
<http:request method="POST" doc:name="Get SF SessionId" doc:id="37908152-700d-4c0e-9b52-b0de25f50fdf" config-ref="HTTP_Request_Salesforce" path="/services/Soap/u/44.0" sendCorrelationId="ALWAYS" outputMimeType="application/xml">
<http:body><![CDATA[#[%dw 2.0
ns soapenv http://schemas.xmlsoap.org/soap/envelope/
ns urn urn:partner.soap.sforce.com
output application/xml
---
soapenv#Envelope: {
soapenv#Body: {
urn#login: {
urn#username: p('SalesforceUsername'),
urn#password: p('SalesforcePassword')
}
}
}]]]>
</http:body>
</http:request>
<ee:transform doc:name="Transform Message" doc:id="b58ed3bd-7d74-4ad1-961f-8bab7a2ff128">
<ee:message>
</ee:message>
<ee:variables>
<ee:set-variable variableName="SalesforceResponse" ><![CDATA[ %dw 2.0
output application/json
ns soap http://schemas.xmlsoap.org/soap/envelope/
---
payload.soap#Envelope.soap#Body.loginResponse.result]]></ee:set-variable>
</ee:variables>
</ee:transform>
<flow-ref doc:name="Log Salesforce Response" doc:id="48326f18-a89b-49b2-ab96-ef2fe7214aaf" name="IntegrationFabricLogsFlow"/>
<ee:transform doc:name="Transform Message" doc:id="bea5898f-5aa8-4835-8e9d-fa1fd165d6d2" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="SalesforceServerUrl" ><![CDATA[%dw 2.0
import * from dw::core::URL
var urlComposition = parseURI(vars.SalesforceResponse.serverUrl)
output text/plain
---
log("Houston, we have a problem.")]]></ee:set-variable>
</ee:variables>
</ee:transform>
</sub-flow>
Can I get some help to understand how variable definition/access does work in Mule4?