Karate - Conditional logic with string and array - soap

This question derives from this question asked earlier. I am making a Soap request, and I am receiving the response as either an Array, or String.
[print] [ "M4205N", "M4206U" ]
[print] M5967H
When I get the response as an array, I figured out how to loop through it, and pass the values to another request. However, sometimes the response will come back as a single Code, and it will be returned as a String. In that case, I cannot perform the same logic as I did with the array. I've read about Karate conditional logic, but I cannot figure out how to make it do what I want.
I want to do something like this:
If the response is returned as a String, then call this method with the one value.
If the response is returned as an array, then call this method and pass each value from the array.
This is one of the ways I had in mind, but it does not work because of the Type difference:
* def memberCodes = memberCodes.size() > 1 ? karate.mapWithKey(memberCodes, 'memberCode') : {}
* def result = call read('OtherRequest.feature') memberCodes
This works if the response is returned as an array, but obviously if it's returned as a String it will break.
What is the right way to perform this conditional logic? Also, please refer to my previous question for more context if needed. Thanks!

Interesting. This check should work for testing if (not) a string:
* def memberCodes = typeof memberCodes != 'string' ? karate.mapWithKey(memberCodes, 'memberCode') : {}
Also refer this somewhat related question: https://stackoverflow.com/a/58543843/143475

Related

How to use object filter with softlayer rest api?

I read this article and have some problems trying to follow the examples. The following is one of the examples given in that article. The first parameter in the object filter is virtualGuests. This object filter can be used in api https://api.softlayer.com/rest/v3/SoftLayer_Account/VirtualGuests.
object_filter = {
'virtualGuests': {
'datacenter': {
'name': {'operation': 'dal05'}
}
}
}
I want to use the object filter in other api methods, like SoftLayer_Account/getBlockDeviceTemplateGroups for example. My question is how to get/set the first parameter like virtualGuests? I tried several times but failed.
Try to follow these recomendations: Getting first parameter through Service Datatype or How to define the first parameter as simple way?
Getting first parameter through Service Datatype
You are trying to get
SoftLayer_Account::getBlockDeviceTemplateGroups
As you see, you are using SoftLayer_Account service, you need to open its datatype from this service:
You can go here:
http://sldn.softlayer.com/reference/services/SoftLayer_Account and
click on "datatypes" label/option
Or go directly here:
SoftLayer_Account
So, you need to start here, the method that you are using is getBlockDeviceTemplateGroups, if you want to get this information in the datatypes, you should skip the word "get" and looking for "BlockDeviceTemplateGroups" property, so you will have the correct parameter that you need to set at first.
How to define the first parameter as simple way?
If you notice, the only changes were: skip "get" word from the method, in this case is "getBlockDeviceTemplateGroups", so it will be:
"BlockDeviceTemplateGroups"
The next step should be set the first char in lowercase like:
"blockDeviceTemplateGroups"
So, it should be the filter:
object_filter = {
'blockDeviceTemplateGroups': {
'datacenter': {
'name': {'operation': 'dal05'}
}
}
}
References:
Object Filters
Going Further with the SoftLayer API Python Client - Part
1

Multiple Conditions in one expect

I want to Verify text of AssignedAllUsers List can contains test1 or test2 but it should not contain test3
I am using following but not sure what is the problem with the code I am getting following error : AllAssignee.toContain is not a function
this.IncList = element.all(by.repeater("incident in $ctrl.allIncidents"));
this.AssignedAllUsers = this.IncList.all(by.css('[aria-label="Change assignee to "]'));
AssignedAllUsers.getText().then(function(AllAssignee){
console.log("AllAssignee = "+AllAssignee);
expect((AllAssignee.toContain(Logindata.Username0)) || (AllAssignee.toContain(Logindata.Username1)) && (AllAssignee.not.toContain(Logindata.Username2)));
});
Your error is a syntax issue. toContain belongs outside the value being tested, in other words outside of the first set of parentheses following your expect statement.
You have this:
expect((AllAssignee.toContain(Logindata.Username0)). You also have an extra set of parentheses, though I don't think that really matters.
You need to close the AllAssignee call, it should be: expect(AllAssignee).toContain(Logindata.Username0)
To answer your other question, there's no need to do it in one expect statement really. Since the list should never contain test3, thats your first assertion:
expect(AllAssignee).not.toContain(test3);
As for your other expected values, if you do not know which one will be present, just create an array and put both possible values inside of that. Then you can assert against the array to contain either test1 or test2:
var myArray = ['test1', 'test2'];
expect(myArray).toContain(AllAssignee);
Also see this related question about expecting items items in an array
Able to fix the problem with the code:
expect(AllAssignee).toContain('test1' || 'test2');

Codeception - how to check response doesn't match xpath

I have the following problem - I want to test REST api with Codeception.
When I want to make sure in JSON response I have array:
'data' => [
'sth' => 'whathever'
]
I can use seeResponseJsonMatchesXpath this way:
$I->seeResponseJsonMatchesXpath('//data/sth');
But what to do if I want to make sure I don't have in response sth? I would like to use for example:
$I->seeResponseJsonMatchesXpath('//data');
$I->dontSeeResponseJsonMatchesXpath('//data/sth');
but obviously there is no dontSeeResponseJsonMatchesXpath method in Codeception.
I also don't know what will be exact value in sth so probably I cannot use here dontSeeResponseContainsJson.
The question is - how to make the following check?
(Disclaimer: Entirely unfamiliar with codeception, only with XPath)
JSON is not supposed to be checked against XPath. But the check you could probably do is
$I->seeResponseJsonMatchesXpath('not(//data/sth)');
Which would return true or 1 if there is no data and sth - and false or 0 if there is.
EDIT: As a response to your comments:
Probably this is something close I need but I want to make sure only sth is not present inside data whereas data should exist (but I don't need to check it in this expression)
The expression already does exactly that - not(//data/sth) returns false for a document like
<data>
<sth/>
</data>
but returns true for a document containing data only:
<data/>
or anything else. But it seems to me there could be pitfalls with converting JSON to XML.
I checked both solutions - yours and //data/not(sth) but it doesn't seem to work
Yes, that does not work because you are using an XPath 1.0 engine. Your attempt would be a valid XPath 2.0 expression. Use the following expression to independently test data and sth:
//data and not(//data/sth)
This only returns true if at least one data element exists and if there is no data element that has an sth element as a child.

FindBy property in TYPO3 Extbase MVC is not working

I'm unable to run the FindBy magic function property in Extbase MVC
$title=array(0 =>'Books Day');
$each_event=$this->eventRepository->findByTitle($title);
$each_event is returning an object of type TYPO3\CMS\Extbase\Persistence\Generic\QueryResult .
How do I make this work?
I also tried passing in a string to findByTitle and findByOne. Both don;t work! :(
I'm using TYPO3 6.1 and extension builder.
The last part of those magic functions always needs to be a field in the database. So "title" must be in your model. You might have a field "one" for your object, but I guess you meant findOneByTitle?
The object type QueryResult is correct. You can turn it into an array for debugging purpose for example:
$foo = $query->execute()->toArray();
By the way: check wether your eventRepository is null or not and you could try this to see if it works at all:
$result = $this->myRepository->findAll();
Try
$each_event=$this->eventRepository->findByTitle($title)->toArray();
Reference to the QueryResult.
As said in the documentation, it returns a QueryResultInterface|array.
As a consequence you have to loop over the result like this:
foreach($each_event as $single_event) {
$single_event->getProperty();
}
If you are sure that it returns only one single value you could also access it by the index 0:
$each_event[0]->getProperty();

In Sinatra, how to make filters dependent of request method?

I've been using filters in Sinatra the way it has been declared in the documentation: with no match string, with a match string or with a match regexp. It has been working fine til now. Now, I have a particular use case. Let's say I have this route:
/resources/1
According to REST, and depending of the request method, this can either be a GET method, PUT method or DELETE method. First question is: How to write filters that are only called when it is a GET request? (currently I'm letting all of them get filtered and only then I test the method. It works, but I don't like it). Second question, and more important: let's say a PUT request like this is triggered:
/resources/
This is of course wrong, because the PUT request has no resource id associated. I would like to know if there is something in Sinatra that enables me to do something like this:
before "/resources/", :method => :put do
error_message
end
just this possibility does not exist (before accepts only one argument). How could I achieve this result at best?
Actually, filters do take conditions. You don't have to use a condition though, you could use a conditional within the filter:
before "/path/" do
if request.request_method == "PUT"
# do something
end
end
If you want to use a condition, I think you'll need to write one, perhaps something like this:
set(:accepted_verbs) {|*verbs|
condition {
verbs.any?{|v| v == request.request_method }
}
}
before "/path/", :accepted_verbs => ["GET","POST"] do
# do something
end
before "/path/", :accepted_verbs => ["PUT"] do
# do something else
end
See conditions for more.