Checking for the presence of a Request header in Karate - request

I am trying to create a mock server for handling functional tests in Karate. For that purpose I need to match certain incoming requests based on certain elements like method, path and presence of "Authorization" header in the incoming requests.
The condition I have is something like:
methodIs('get') && pathMatches('/mypath')
I need to write a condition for the presence of an "Authorization" header in the request.
As per documentation, we can use:
karate.get('requestHeaders.Authorization[0]') == 'foo'
However, when I am trying to use the above, it isn't working. I checked for the presence of requestHeaders.Authorization[0] but that is being returned as Null. My idea was to modify the above to something like karate.get('requestHeaders.Authorization[0]') == '#notnull'.
I ended up trying headerContains('Authorization',''), which seems to be working - however I am not sure if that is the right way to check for the presence of that specific header. Is there any other (better) way to do this?

We are planning to improve this in a future release: https://github.com/karatelabs/karate/issues/1962
Meanwhile I would have thought that a simple JavaScript condition like requestHeaders.Authorization would work. For e.g:
Scenario: requestHeaders.Authorization && methodIs('get')
Unfortunately it is case-sensitive, which is what we plan to fix in a future release. You could use an OR condition for the time being.
For more explanation, refer: https://stackoverflow.com/a/55823180/143475

Related

how do I handle the response order of multiple API calls in React correctly (like auto-complete searching)

I'm trying to implement a search box, where every time user types something, the search result will show on the page.
JS fiddle link : https://jsfiddle.net/wsypeter/dh59Lwr2/47/
here is the code for fetching the data and setting the state
basically as I type abc the response might came back in order abc ab a and the result is finally a which is wrong.
How should I fix this ? I know one way is to use debounce, but I think it will still run into issue if the response timeout is super long.
This is an interview question, the interviewer said canceling pending request or debouncing is not the solution he's looking for.
For the above example , there must be 3 requests going out and the final result should be the response of the last request.
How do I do it?
You could use debounce for this kind of issue.
Only after the user finished typing and hasn't typed anything else for e.g. 500ms then you call the api.

Analyse gzip request

I am exploring mountebank and have a case where I need to analyse the gziped json request in order to create a predicate that returns the appropriate response. Can I unzip a json request and analyse the json with mountebank?
It does sound possible using Injection - this way, you should be able to require zlib in your JavaScript function, use it to unzip the payload, parse the result to JSON and then return a response as you see fit.
Depending on what you want to return though, you may need to use a combination of Predicate Injection (where a simple true/false determines whether or not the stub responds) and Response Injection (where you can tailor the response depending on the content of the payload).
Sorry for the late reply - but I thought I would add an answer.
Please see https://groups.google.com/forum/#!topic/mountebank-discuss/lvJq9PdIRlo for an update. There is now an open ticket to add support for this.

REST optimistic-locking and multiple PUTs

Far as I understand, PUT request is not supposed to return any content.
Consider the client wants to run this pseudo code:
x = resource.get({id: 1});
x.field1 = "some update";
resource.put(x);
x.field2 = "another update";
resource.put(x);
(Imagine I have an input control and a button "Save", this allows me to change a part of object "x" shown in an input control, then on button click PUT changes to server, then continue editing and maybe "save" another change to "x")
Following different proposals on how to implement optimistic locking in REST APIs, the above code MUST fail, because version mark (however implemented) for "x" as returned by get() will become stale after put().
Then how do you people usually make it work?
Or do you just re-GET objects after every PUT?
You can use "conditional" actions with HTTP, for example the If-Match header described here:
https://www.w3.org/Protocols/rfc2616/rfc2616-sec14.html#sec14.24
In short: You deliver an ETag with the GET request, and supply this ETag back to the server in the If-Match header. The server will respond with a failure if the resource you are trying to PUT has another ETag. You can also use simple timestamps with the If-Unmodified-Since header.
Of course you will have to make your server code understand conditional requests.
For multiple steps, the PUT can indeed return the new representation, it can therefore include the new ETag or timestamp too. Even if the server does not return the new representation for a PUT, you could still use the timestamp from the response with an If-Unmodified-Since conditional PUT.
Here is probably what I was looking for: https://www.rfc-editor.org/rfc/rfc7231#section-4.3.4
They implicitly say that we CAN return ETag from PUT. Though only in the case server applied the changes as they were given, without any corrections.
However this raises yet another question. In real world app PUT caller will run asynchronously in JS gui, like in my example in the question. So, Save button might be pressed several times with or without entering any changes. If we don't use optimistic locking, then supposed PUT idempotency makes it safe to send another PUT query with each button click, as long as the last one wins (but actually if there were changes then it's not guaranteed, so the question remains).
But with optimistic locking, when first PUT succeeds, it returns updatred ETag, ok? And if there is another PUT request running, still with outdated tag version, that latter request will get 412 and the user will see a message "someone else changed the resource" - but actually it was our former changes.
What do you usually do to prevent that? Disable the Save button until its request is fully completed? What if it times out? Or do you think it's acceptable to see concurrent-change error message if it was a timeout, because the stability is already compromised anyway?

In simple RESTful design, does PATCH imply mapping to CRUD's (ORM's) "update" and PUT to "destroy"+"create" (to replace a resource)?

I'm trying to create a simple REST API and map it to CRUD. I have an ORM (DataMapper) which has methods like create, update and destroy.
If I get it right, given a resource {a:'foo',b:'bar',c:'baz'}, performing a PUT {b:'qux'} is supposed to replace the resource and result in the same {b:'qux'}, and doing a PATCH {b:'qux'} should result in {a:'foo',b:'qux',c:'baz'}.
Would PUT be implemented with ORM's destroy+create to completely recreate a database record (with the same old id) or both PUT and PATCH would be mapped to update (and only a record's fields would be manipulated)?
Well, Both the actions actually means update, where PUT is full update and PATCH is partial update. In case of PUT you already know the identifier of the resource and the resource already exists, so it is not a create and delete action per se. Infact, you can make do with providing only PUT action for your resource. The only idiosyncrasy of put is the client is supposed to provide full representation of resource. Since all request for put, must come after the GET of the resource, thus providing full representation shouldn't be problem for client anyway.
a) what PATCH does depends on the media type in the request. AFAIK, there is no definition for application/json, so you'd need to clarify that in the question.
b) both PUT and PATCH are update operations (with an optional create if the resource doesn't exist yet)

Is it possible to detect if you are in the last processing attempt of an specific task?

When using push task queues in Google AppEngine, I know we can use the "X-AppEngine-TaskRetryCount" and "X-AppEngine-TaskExecutionCount" request header parameters to tell how many times we have tried to process an specific task.
Is it possible to detect if it's the last attempt or not?
A workaround is to pass the max retry count as a parameter in the HTTP request when you add tasks to TaskQueue. Then, you can detect if is the last attempt comparing the header attribute "X-AppEngine-TaskRetryCount" with your custom param:
Boolean isLastAttempt = (taskRetryCount == (maxRetryCount - 1));
Not exactly a good design approach though...

Resources