Is there a way to modify the request body during PACT verification? - pact

I am trying to run a PACT test on the provider side and I don't know how to manipulate the request body that I get from the Pact file. I need to do this because I have to use an id from State step.
In my case, I need to perform a request in State step and afterwards to use the response of that request in the actual Pact verification test. So, I would like to replace a value from the pact file with the one obtained in the State.
Also, for being even more complicated, my body is an XML. So here it is how my pact request looks like:
"request": {
"method": "POST",
"path": "/path/url",
"headers": {
"Content-Type": "application/xml"
},
"body": "<note> <to>John</to> <from>Jane</from> <subject>Reminder</subject> </note>"
}
As I said, in the Provider State I will have a request and the response of this will be let's say 'Mary'. So my question would be how can I replace 'Jane' with 'Mary' in the Pact request body when executing the verification test? Thanks.

I have managed to solve my problem, modifying the request in TargetRequestFilter.
#TargetRequestFilter
public void updateRequest(HttpPost request) {
HttpEntity entity = request.getEntity();
String body = EntityUtils.toString(entity);
body = replace(body, "Jane", "Mary");
entity = new StringEntity(body);
request.setEntity(entity);
}
This piece of code will modify the request right before making the call and will send the desired value instead the one that we have in the Pact file.

Related

How to invoke a SignalR Core hub method from Postman WebSocket

I have a SignalR Core 5.0 app that works in Visual Studio 2019. I will deploy the SignalR server to IIS but want to do some testing in Postman using the new WebSockets.
Taking one of my hub methods in my VS project, let's call it "SomeHubMethod" that returns some data, what is the proper syntax to invoke the hub method?
For instance, how would I translate this C# invoke for Postman WebSocket?
SomeHubMethod = The hub method
groupxyz = The name of the client originating the call to SignalR server, and so the response from the server should be sent to "groupxyz". Let's say the response is "Hello World!"
"1234" = Just some test data.
In my VS project...
private async void SendSomeHubMethod()
{
await connection.InvokeAsync("SomeHubMethod", "groupxyz", "1234");
}
Where the response would be received in my class...
connection.On<string>("TheHubResponse", (m) =>
{
_ = Dispatcher.RunAsync(CoreDispatcherPriority.Normal, () => Debug.WriteLine(m));
// Hello World!
});
My assembled request that I found in link below for Postman WebSocket...
{"arguments":["groupxyz", "1234"],"invocationId":"0","target":"SomeHubMethod","type":1}
On Send, Postman shows Connected but "Hello World!" is not returned from my hub.
I found this post but it is not detailed on invoke.
reference example
You can but it's kinda problematic, so let's start from beginning..
When you have your defined SignalR hub endpoint (ie. wss://localhost:5005/hub/notifications) then
Make a POST request to following URL (notice the https, not the wss): https://localhost:5005/hub/notifications/negotiate?negotiateVersion=1.
In answer you will receive following information:
{
"negotiateVersion": 1,
"connectionId": "zJ1cqyAe4FRyLCGMzzC0Fw",
"connectionToken": "HYunLu0j0IHdBY4NNrkm0g",
"availableTransports": [
{
"transport": "WebSockets",
"transferFormats": [
"Text",
"Binary"
]
},
{
"transport": "ServerSentEvents",
"transferFormats": [
"Text"
]
},
{
"transport": "LongPolling",
"transferFormats": [
"Text",
"Binary"
]
}
]
}
Get the connectionToken from the step above and copy it. Now open a websocket connection with your hub like following:
wss://localhost:5005/hub/notifications?id={connectionToken} where connectionToken is the token from previous step. The url should look like: wss://localhost:5005/hub/notifications?id=HYunLu0j0IHdBY4NNrkm0g.
Now hold something.. according to the Microsoft documentation (https://github.com/dotnet/aspnetcore/blob/main/src/SignalR/docs/specs/HubProtocol.md#overview) we need to send a handshake request with following informations:
{
"protocol": "json",
"version": 1
}
It's hard to achieve by plain text because it needs to ends with a 0xE1 ASCII character, so we need to convert the handshake request with that character to base64 and send it. I did it for you and this string is:
eyJwcm90b2NvbCI6Impzb24iLCAidmVyc2lvbiI6MX0e
Now when we have all these info, let's deep dive into Postman:
Connect to the endpoint:
Just send a request with string I pasted above to this URL with content-type: Binary using Base64.
As you can see, we are receiving message {"type": 6} what means we are connected to the Hub and it's pinging us.
You can now send/receive any messages from your hub:
Now you can change the content-type to JSON and invoke your hub endpoints.
How to invoke a SignalR Core hub method from Postman WebSocket
Short answer, you can't.
Long answer, SignalR is a protocol that requires certain ceremony to start sending and receiving messages. For example, you need an ID in the query string that is generated by the server. Then you need to send the handshake request over the transport before you can start making invocations.

http post request to api nativescript vue

Hello I need help with http post request to my server and get response with authentication.
Look on the screens on 1 I use insomnia REST API application. Using this app I got success response with premium days and id.
In second image I got response just from my nativescript vue.js app where I got false response.
There is something wrong with my code. please tell me what.
You are sending a JSON object in your request body from {N} app, on the other hand you are using FormData with your REST client for testing.
You must either change your API to support JSON data on request body which is generally the standard way. In case if you can't do that, then you must use the nativescript-background-http plugin to send FormData. It will be something like,
var params = [
{ name: "username", value: "test" },
{ name: "password", value: "test123" },
{ name: "uuid", value: "xxxx" }
];
var task = session.multipartUpload(params, request);

How to add a request body to an IBM BPM 8.6 script task BPMRESTRequest object in order to invoke a REST api?

I am trying to invoke a REST api (POST operation) from IBM BPM 8.6, I have to use a script task, I am able to call the api no problem just that the api expects a request body with a json object in it and I have not found a way yet to add that to the request object which I create in the script. I am able to add headers and parameters but not a http body to the request.
This is my code in the script tab of the the script task, the call is received by the api but it discards it with the message that the request is missing a request body which the api expects.
var request = new BPMRESTRequest();
request.externalServiceName = "api-docs";
request.operationName="extractReporterInfoUsingPOST";
request.httpHeaders = {"Content-Type": "application/json", "Accept":
"application/json"};
request.httpMethod = "POST";
// request.body = {"test":"dummy"}; <- does not work
// request.httpBody = {"test":"dummy"}; <- does not work
var response = tw.system.invokeREST(request);
I had the same problem. I was able to solve this issue by specifying the post body like so:
request.parameters = { "body": { "key1": "val1", "key2", "val2" }}
In parameters object add the key as the name of the body you gave or mentioned in swagger files request.parameters = { "nameOfBodyAsMenitionedInSwagger": { "key1": "val1", "key2", "val2" }}

Meteor Get request

Bear with me for any mistakes/wrong terminology since I am new to all this. I am using meteor to develop my project and i need to make a get request to an external API. (I already added meteor add http) Below is my code:
HTTP.call( 'GET', 'url', {}, function( error, response ) {
if ( error ) {
console.log( error );
} else {
console.log( response );
}
});
If i use the code inside my Client folder in Meteor I get the following error No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'http://localhost:3000' is therefore not allowed access meteor It has something to do with CORS which I didn't understand how to implement. If I use the code above in my Server side I do get the correct response in the console but how do I use it as a var on my client javascript code?
Tou can use .call function of HTTP and pass your header in options:
HTTP.call(method, url, [options], [asyncCallback])
Arguments
method String
The HTTP method to use, such as "GET", "POST", or "HEAD".
url String
The URL to retrieve.
asyncCallback Function
Optional callback. If passed, the method runs asynchronously, instead of synchronously, and calls asyncCallback. On the client, this callback is required.
Options
content String
String to use as the HTTP request body.
data Object
JSON-able object to stringify and use as the HTTP request body. Overwrites content.
query String
Query string to go in the URL. Overwrites any query string in url.
params Object
Dictionary of request parameters to be encoded and placed in the URL (for GETs) or request body (for POSTs). If content or data is specified, params will always be placed in the URL.
auth String
HTTP basic authentication string of the form "username:password"
headers Object
Dictionary of strings, headers to add to the HTTP request.
timeout Number
Maximum time in milliseconds to wait for the request before failing. There is no timeout by default.
followRedirects Boolean
If true, transparently follow HTTP redirects. Cannot be set to false on the client. Default true.
npmRequestOptions Object
On the server, HTTP.call is implemented by using the npm request module. Any options in this object will be passed directly to the request invocation.
beforeSend Function
On the client, this will be called before the request is sent to allow for more direct manipulation of the underlying XMLHttpRequest object, which will be passed as the first argument. If the callback returns false, the request will be not be send.
Souce: Here
Fixed it. On client side
Meteor.call("getURL",'url',{},function(err,res){
if(err){
console.log('Error: '+err);
}
if(!err){
console.log('Response: '+res);
}
and on server
Meteor.methods({
'getURL': function(url_l){
console.log("Request: "+url_l)
return HTTP.get(url_l)
}
});

Elixir: HTTPResponseStream to consume streaming API

I want to write a client which can consume streaming APIs. Essentially, have a getter that returns an HTTPResponseStream instead of HTTPResponse. I couldn't find one in HTTPotion, so I figured I'd give it a try instead. But I have no idea how to go about it, and would really appreciate some help!
You can do async requests with HTTPotion like so:
%HTTPotion.AsyncResponse{ id: id } = HTTPotion.get "http://example.com", [], [stream_to: self]
This will send messages of three different types to the current process (which is defined above via self):
# First, the response headers
%HTTPotion.AsyncHeaders{ id: ^id, status_code: 200, headers: _headers }
# Then, one or more chunks
%HTTPotion.AsyncChunk{ id: ^id, chunk: _chunk }
# And finally, an end message
%HTTPotion.AsyncEnd{ id: ^id }
The id can be used to handle the responses from multiple ongoing requests.

Resources