Programally multi-value param - karate

I need to make a request with a multi-value param,its value must be a very big array to test an api param validation. One of my implementation:
Scenario: filter_too_long_multivalue
* def localPath = endPointBase + 'filter'
* def generateLongParam =
"""
function(){
var paramValue = [];
for(var idx = 0; idx<1002; idx++){
paramValue.push('r')
}
var params = {};
params.pl = paramValue;
return params;
}
"""
* def tooLongParam = generateLongParam()
* print tooLongParam
Given path localPath
And params tooLongParam
When method get
Then match response == authorizationSchema.empty
Then the request is:
GET http://XXXXXXXXXXXXX?pl=%5Bobject+Array%5D
I have tried differents ways, but always the same result...
How can I obtain a weel formed request?
Thank you.

Yes, you have hit one of those edge cases, can you let me know if this works, I'll also see if this can be improved.
Sometimes what is returned by a JS function is not exactly the format that Karate likes. The workaround is to use json instead of def to type-convert - refer doc: https://github.com/intuit/karate#type-conversion
* def fun =
"""
function(){
var temp = [];
for(var i = 0; i < 5; i++) {
temp.push('r');
}
return temp;
}
"""
* json array = fun()
Given url demoBaseUrl
And path 'echo'
And params { pl: '#(array)' }
When method get
Then status 200
Which resulted in:
1 > GET http://127.0.0.1:60146/echo?pl=r&pl=r&pl=r&pl=r&pl=r

Related

Is there something wrong with my code as logic in function works fine in js?

* def a = ["a","b"]
* def b = ["1","2"]
* def fun =
"""
function(a,b){
var result={}
a.forEach(function(x,i){result[x]=b[i]});
return result;}
"""
* def final = fun(a,b)
* print final
Now what I am expecting is
{
"a":"1",
"b":"2"
}
but what I got is {
"a":null,
"b":null
}?
There are limitations to the JS blocks in Karate, that's how it is.
Do this instead:
karate.forEach(a, function(x,i){result[x]=b[i]});

How to escape _ wildcard within Google app script sql?

The function to run a standard sql query within the app script throws up an error when _is used within the sql. It is used within the condition filter to look for all names with _x_. Backslashes break the app script when used.
Within Google Apps Script: var sql1 = 'sql string';
Within sql: WHERE lower(name) like "%\_x_\%"
Update: I managed to find a workaround using REGEXP_CONTAINS(LOWER(name), r"(_x_)" but am still interested to know if it works with the regular LIKE clause.
I reproduced your case using a modified sample code from the documentation.
I queried against a sample dataset using where like "%_". Then, I write the results in a Google spreadsheet.The table I am querying in BigQuery is:
Row id
1 _id_1212
2 id1212
The code I am using is below:
/**
* Runs a BigQuery query and logs the results in a spreadsheet.
*/
function runQuery() {
// Replace this value with the project ID listed in the Google
// Cloud Platform project.
var projectId = 'project_id';
//modified query
var request = {
query: 'SELECT * from `project_id.dataset.table` where id LIKE "%_id_%";'//it will also work for where like "%\_id\_%",
//configuring the query to use StandardSQL
useLegacySql: false
};
var queryResults = BigQuery.Jobs.query(request, projectId);
var jobId = queryResults.jobReference.jobId;
// Check on status of the Query Job.
var sleepTimeMs = 500;
while (!queryResults.jobComplete) {
Utilities.sleep(sleepTimeMs);
sleepTimeMs *= 2;
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId);
}
// Get all the rows of results.
var rows = queryResults.rows;
while (queryResults.pageToken) {
queryResults = BigQuery.Jobs.getQueryResults(projectId, jobId, {
pageToken: queryResults.pageToken
});
rows = rows.concat(queryResults.rows);
}
if (rows) {
var spreadsheet = SpreadsheetApp.create('BiqQuery Results');
var sheet = spreadsheet.getActiveSheet();
// Append the headers.
var headers = queryResults.schema.fields.map(function(field) {
return field.name;
});
sheet.appendRow(headers);
// Append the results.
var data = new Array(rows.length);
for (var i = 0; i < rows.length; i++) {
var cols = rows[i].f;
data[i] = new Array(cols.length);
for (var j = 0; j < cols.length; j++) {
data[i][j] = cols[j].v;
}
}
sheet.getRange(2, 1, rows.length, headers.length).setValues(data);
Logger.log('Results spreadsheet created: %s',
spreadsheet.getUrl());
} else {
Logger.log('No rows returned.');
}
}
The output,
id
_id_1212
Both where id LIKE "%_id_%" and where id LIKE "%\_id\_%" work when I set the query to use StandardSQL (useLegacySql: false).
In addition, the error GoogleJsonResponseException: API call to bigquery.jobs.query failed with error: Syntax error: Illegal escape sequence: \_ will be thrown when trying to escape the underscore using a double backslash such as where id LIKE "%\\_id\\_%".

what to use in place of Object.keys and hasOwnProperty when using karate version 0.9.5?

* def a =
"""
function(ths,tsa,hcia) {
karate.log(JSON.stringify(tsa[hcia[0]],null,2))
var fas = (Object.keys(tsa[hcia[0]]))[0]
karate.log("fas " + fas)
var art = null
for(prtsj in ths[hcia[0]]) {
karate.log(JSON.stringify(ths[hcia[0]][prtsj].sku,null,2))
if((Object.keys(ths[hcia[0]][prtsj].sku)).indexOf(fas) > -1) {
art = ths[hcia[0]][prtsj].type
}
}
return art
}
"""
Please use karate.keysOf() - which will return a JSON array of strings.
Now you can do whatever you want.
Also see: https://stackoverflow.com/a/61139167/143475

Karate: match with parametrized regex

I didn't find the right way to write a match with regexp cointaining a variable:
* def getYear =
"""
function() {
var SimpleDateFormat = Java.type('java.text.SimpleDateFormat');
var sdf = new SimpleDateFormat('yyyy');
var date = new java.util.Date();
return sdf.format(date);
}
"""
* def currentYear = getYear()
* def testmatch = { gencode: '#("000" + currentYear + "0000012345")' }
* match testmatch == { gencode: '#regex "[0-9]{3}" + currentYear + "[0-9]{10}"' }
There is a way to do this?
Thanks,
Lorenzo
First, normally when you are doing matches like this, regex is un-necessary, because you might as well do an exact match.
But anyway this is the solution, refer: https://github.com/intuit/karate#self-validation-expressions
* def isValidYear = function(x){ return new RegExp("[0-9]{3}" + currentYear + "[0-9]{10}").test(x) }
* assert isValidYear('00020190000012345')
* match testmatch == { gencode: '#? isValidYear(_)' }

realm react-native: how to query correctly an array of strings

can someone show me how to query an array of strings with realm in react-native?
assume i have an array like the following:
const preferences = ["automatic","suv","blue",eco]
What I want is to get realm results where ALL strings in the attribute "specifications" of Cars is in "preferences".
E.g.: If an instance of Cars.specifications contains ["automatic","suv"]
a result should be returned.
But if an instance of Cars.specifications contained ["automatic,"suv","green"] this instance shouldn't be returned.
The length of preferences can vary.
Thank you very much.
Update:
What i tried is the following:
const query = realm.objects("Cars").filtered('specifications = preferences[0] OR specifications = preferences[1]')
As you see it is an OR operator which is surely wrong and it is hardcoded. Looping with realm really confuses me.
This code will work!
const collection = realm.objects('Cars');
const preferences = ["automatic","suv","blue","eco"];
let queryString = 'ANY ';
for (let i = 0; i < preferences.length; i++) {
if (i === 0) {
queryString += `specifications CONTAINS '${preferences[i]}'`;
}
if (i !== 0 && i + 1 <= preferences.length) {
queryString += ` OR specifications CONTAINS '${preferences[i]}'`;
}
}
const matchedResult = collection.filtered(queryString);
example of function to test if a word is inside an array of word
function inArray(word, array) {
var lgth = array.length;
word = word.toLowerCase();
for (var i = 0; i < lgth; i++) {
array[i] = (array[i]).toLowerCase();
if (array[i] == word) return true;
}
return false;
}
const preferences = ["automatic","suv","blue","eco"];
const specifications = ["automatic","suv"] ;
const specifications2 = ["automatic","suv", "boat"] ;
function test(spec,pref){
for (var i in spec){
if(!inArray(spec[i],pref)){
return false ;
}
}
return true;
}
console.log(test(specifications,preferences));
console.log(test(specifications2,preferences));
https://jsfiddle.net/y1dz2gvu/