Karate: combine data driven with request in external file? [duplicate] - request

This question already has an answer here:
Karate: Using data-driven embedded template approach for API testing
(1 answer)
Closed 1 year ago.
I am looking for a way to use data driven in combination with an external request file.
So my feature file looks like this:
Feature: EPOS UNIT test - GetSpendingLimit
Background:
* url 'http://xxx-yyy-zzz'
* def GetSpendingLimit_request = read('classpath:examples/EPOS/request/GetSpendingLimit-dd-request.xml')
* def GetSpendingLimit_data = read('classpath:examples/EPOS/data/GetSpendingLimit.csv')
Scenario Outline: GetSpendingLimit External Request Datadriven
Given request GetSpendingLimit_request
When soap action 'TotalAmount'
Then status 200
# define a variable to check the response
* def total_amount = /Envelope/Body/GetSpendingLimitResponse/spendingLimit/totalAmount
# to print the result to the report
* print '\nTotal Amount is: ', total_amount
Examples:
|read('classpath:examples/EPOS/data/GetSpendingLimit.csv')|
And my request looks like this:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:req="http://xxx-yyy-zzz/GetSpendingLimit/Request" xmlns:com="http://xxx-yyy-zzz/Common" xmlns:ser="http://xxx-yyy-zzz/Common/ServiceContext">
<soapenv:Header/>
<soapenv:Body>
<req:GetSpendingLimitRequest>
<ser:productServiceContext>
<ser:conversationId>GetSpendingLimit_1_1</ser:conversationId>
<ser:deviceTypeId>1</ser:deviceTypeId>
<ser:entityId>nl</ser:entityId>
<ser:product>
<ser:id><product-id></ser:id>
</ser:product>
<ser:user>
<ser:id><user-id></ser:id>
</ser:user>
</ser:productServiceContext>
</req:GetSpendingLimitRequest>
</soapenv:Body>
</soapenv:Envelope>
Notice that I have added product-id and user-id as variable which should be replaced by data driven input from the csv. But I get the following error:
[Fatal Error] :10:43: The element type "product-id" must be terminated by the matching end-tag "</product-id>".
11:35:18.404 [main] ERROR com.intuit.karate - src/test/java/examples/EPOS/GetSpendingLimit-external-request-datadriven.feature:5
* def GetSpendingLimit_request = read('classpath:examples/EPOS/request/GetSpendingLimit-dd-request.xml')
js failed:
>>>>
01: read('classpath:examples/EPOS/request/GetSpendingLimit-dd-request.xml')
<<<<
I have tried the request in the feature file and this works fine. But the request in external file fails.

The error is clearly saying the XML is not well-formed. Use some XML tool and fix it, for e.g. something like this: https://www.freeformatter.com/xml-formatter.html
For example this should be:
<ser:id><product-id/></ser:id>

Related

Mule 4 dynamic queries in the Database Connector

In my flow in Mule 4 I am trying to query a database for specific data.
For example I want to run a query like this:
SELECT * FROM mulesoft WHERE plant = CCCNNB;
The thing is both plant and CCNNB need to be dynamic. They will come through an API request. I can handle the value to be dynamic, but I get empty results whenever I try to make the field dynamic.
I first create a variable which stores the json from the request:
set-variable value="#[payload]" doc:name="Set Variable" doc:id="8ed26865-d722-4fdb-9407-1f629b45d318" variableName="SORT_KEY"/>
Request looks like this:
{
"FILTER_KEY": "plant",
"FILTER_VALS": "CCNNB"
}
Afterwards in the db connector I configure the following:
<db:select doc:name="Select" doc:id="13a66f51-2a4e-4949-b383-86c43056f7a3" config-ref="Database_Config">
<db:sql><![CDATA[SELECT * FROM mulesoft WHERE :filter_key = :filter_val;]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"filter_val": vars.SORT_KEY.FILTER_VALS,
"filter_key": vars.SORT_KEY.FILTER_KEY
}]]]></db:input-parameters>
Replacing :filter_key with plant works but as soon as I try to make it dynamic I get nothing in the response. It does not fail though, response code is 200 but I get nothing inside it.
How can I make this work?
You can directly use the stored variables in the query itself.
Query Should be an expression in DataWeave.
#["SELECT * FROM $(vars.table) WHERE $(vars.SORT_KEY.FILTER_KEY) = :filter_val"]
<db:select config-ref="Database_Config">
<db:sql><![CDATA[#["SELECT * FROM $(vars.table) WHERE $(vars.SORT_KEY.FILTER_KEY) = :filter_val"]]]></db:sql>
<db:input-parameters ><![CDATA[#[{
"filter_val": vars.SORT_KEY.FILTER_VALS
}]]]>
</db:input-parameters>
</db:select>
There is another way also to read values from payload to build a dynamic query as below
#["SELECT * FROM mulesoft
WHERE " ++ vars.SORT_KEY.FILTER_KEY ++ " = '" ++ vars.SORT_KEY.FILTER_VALS ++ "'"]
Below is the XML that is created for this, as a POC
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:os="http://www.mulesoft.org/schema/mule/os"
xmlns:salesforce="http://www.mulesoft.org/schema/mule/salesforce"
xmlns:db="http://www.mulesoft.org/schema/mule/db"
xmlns:xml-module="http://www.mulesoft.org/schema/mule/xml-module"
xmlns:http="http://www.mulesoft.org/schema/mule/http"
xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd
http://www.mulesoft.org/schema/mule/db http://www.mulesoft.org/schema/mule/db/current/mule-db.xsd
http://www.mulesoft.org/schema/mule/os http://www.mulesoft.org/schema/mule/os/current/mule-os.xsd">
<http:listener-config name="HTTP_Listener_config1"
doc:name="HTTP Listener config"
doc:id="6d5de64b-1355-4967-9352-4b324f02c7ad">
<http:listener-connection host="0.0.0.0"
port="8081" />
</http:listener-config>
<db:config name="Database_Config" doc:name="Database Config"
doc:id="d5c4d49c-aef3-4d4a-a7b5-470da3354127">
<db:my-sql-connection host="localhost"
port="3306" user="root" password="admin123" database="Mysql" />
</db:config>
<flow name="testFlow"
doc:id="8cfea1b0-d244-40d9-989c-e136af0d9f80" initialState="started">
<http:listener doc:name="Listener"
doc:id="265e671b-7d2f-4f3a-908c-8065a5f36a07"
config-ref="HTTP_Listener_config1" path="test" />
<set-variable value="#[payload]" doc:name="Set Variable"
doc:id="265a16c5-68d4-4217-8626-c4ab0a3e38e5" variableName="SORT_KEY" />
<db:select doc:name="Select"
doc:id="bdf4a59c-0bcc-46ac-8258-f1f1762c4e7f"
config-ref="Database_Config">
<db:sql><![CDATA[#["SELECT * FROM mulesoft.mulesoft WHERE " ++ vars.SORT_KEY.FILTER_KEY ++ " = '" ++ vars.SORT_KEY.FILTER_VALS ++ "'"]]]></db:sql>
</db:select>
<ee:transform doc:name="Transform Message"
doc:id="72cbe69f-c52e-4df9-ba5b-dd751990bc08">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/json
---
payload]]></ee:set-payload>
</ee:message>
</ee:transform>
</flow>
</mule>
Explanation of the Flow
I am using the payload that is in Question
Seting a variable name "SORT_KEY", value of this varibale is complete payload that we receive.
then creating a dynamic query inside the Db connector
using transform message sending the data as response, that we received from DataBase
So, there are several issues here. One, the creation of the sql statement.
You can do DW inside the DB:SELECT component if you want, as shown by previous answers. Either the
#["SELECT * FROM myTable" ++ vars.myWhere]
OR
#["SELECT * FROM myTable $(vars.myWhere)"]
work.
The problem you will run into is that DataSense doesn't like this. Without the literal text for the column names, DataSense can't figure out what columns to retrieve so it raises an error "Unable to resolve value for the prameter: sql". This leaves an error in your code, which always gives me angst. I wish Mulesoft would resolve this problem.
BTW, if you do dynamic SQL, you should STILL use input parameters for each value to avoid SQL injections.
I have an "Idea" posted here to fix the bogus error: https://help.mulesoft.com/s/ideas#0872T000000XbjkQAC

MuleSoft 4 http request

I am new to MuleSoft
when i am giving output expression like below i am getting an data sense error, can you please help
#[output application/json --- {errorType:error.errorType, error:error.description}]
Description Resource Path Location Type Scripting language error on
expression '#[output application/json --- {errorType:error.errorType,
error:error.descrip...'. Reason: Invalid input '#', expected using,
if, ???, unless or not (line 1, column 1): . validations.xml
/validations/src/main/mule Listener Message Flow Error
It is hard to know without a snippet from the configuration XML exactly what your issue is, but one problem I see is that your dataweave does not start with a
"%dw 2.0" In mule 4 there are two languages. Mule Expression language, which is default in most components (ie #[vars.name] is MEL), and dataweave 2.0 which is default in Transform Message components. You can however, as you've attempted to do, use dataweave inside of Mule Expressions. You have it mostly right, but it must start with "%dw 2.0" at the beginning. So it should look like this.
#[%dw 2.0 output application/json --- {errorType:error.errorType, error:error.description}]
However, judging by the error message, it looks like you're attempting to use MEL in a place where it is not allowed. If you provide a snippet of the configuration XML for this component, I can be more helpful.
There is no MEL in Mule 4. It is migrated to DW2.0. Please refer link https://docs.mulesoft.com/mule-runtime/4.2/migration-mel

gatling checking if soap response contains node

I use Gatling to test against an API responding with this:
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<SOAP-ENV:Body>
<sam:HentAktiveSamtykkerMedPartrefResponse xmlns:sam="urn:gjensidige:forsikring:samtykke">
<sam:samtykke>
<sam:idNr>01018448285</sam:idNr>
<sam:partref>0005009147</sam:partref>
<sam:utfortAv></sam:utfortAv>
<sam:navn></sam:navn>
<sam:navnUtvidet></sam:navnUtvidet>
<sam:svar>J</sam:svar>
How can I script that the response must contain the element:
<sam:svar>
?
I guess something in the lines of:
.check(xpath("whathere").exists)
But what should be stated as "whathere"?
The xpath would look something like : /*/SOAP-ENV:Body/descendant::*[name()='sam:navn']/text() this should extract the value from <sam:navn></sam:navn>.

Salesforce Bulk API - "missing a mapping for the external id field" error

I'm starting a bulk API job and passing a spec file. Here is the job.txt file I'm using to create the job:
<?xml version="1.0" encoding="UTF-8"?>
<jobInfo xmlns="http://www.force.com/2009/06/asyncapi/dataload">
<operation>upsert</operation>
<object>Contact</object>
<externalIdFieldName>Unique_Email__c</externalIdFieldName>
<contentType>CSV</contentType>
</jobInfo>
Then, I'm posting a spec file as follows:
Salesforce Field,Csv Header,Value,Hint
Unique_Email__c,email1,,
Name,Full Name,,
And I get the error "Transformation specification is missing a mapping for the external id field" but that's very strange because the Unique_Email__c is actually there. What's going on?

How to Print SOAP Message Request Body generated using GSOAP when calling service

I have a java Service and i am calling it from my C program . I generated stubs using GSOAP and when i call the service i get the error message as :
Error -21 in function "SOAPDataAdapter::getFieldValueFromXSDElement (XSD -> Dataset conversion)": Feature "12xsd__anyType" is not supported
N5vasco20InvalidDataExceptionE: Error -17 in function "SOAPDataAdapter::getVASCOAttributeFromGSOAP (Attempting to insert WSDL attribute 'User ID' (attribute ID 0) as a dataset value)": The supplied data contains invalid characters
My question is how can i print the Soap Message object that is going through GSOAP call . I want to compare it with my SOAPUI request which is working fine.
Any help will be highly appreciated.
Thanks
I was able to view the SOAP message using WIreShark

Resources