In Cypress, how do I stub a POST API request with parameters in the body? - cypress

I am writing an end-to-end test with Cypress and I would like to stub the network requests which my application makes. Specifically, I would like to stub out multiple POST requests which have parameters in the body and to change my simulated response based on those parameters.
I would like to do something like
cy.route({
method: "POST",
url: "/todos/add"
params: {
"urgency": 3,
"stakeholder_id": "SKH001"
},
response: "fixture:add1.json",
})
cy.route({
method: "POST",
url: "/todos/add"
params: {
"urgency": 1,
},
response: "fixture:add2.json",
})
But after reading through
https://docs.cypress.io/guides/guides/network-requests.html and https://docs.cypress.io/api/commands/route.html#Arguments, I do not see a supported way of checking the arguments in the request being stubbed.
Can I accomplish this by passing a function to the onRequest parameter of cy.route? If so, what would I return from that function which tells cypress "this route actually does not handle this request"?

cy.route({
method: "POST",
url: "/todos/add"
body: {
"urgency": 1,
},
response: "fixture:add2.json",
})

One option is to use Mirage.js
https://miragejs.com/docs/comparison-with-other-tools/#cypress-route-mocks
See their tutorial: https://miragejs.com/quickstarts/cypress/

You can use intercept method too.
cy.intercept('POST', <your api end point>, {response:
<your json file path>}).as('postAPI')

If your Cypress version is greater than 6, you should refactor to use intercept. Intercept handles params really cleanly and you can assign parts of output to a file using the alias or in the callback.
https://docs.cypress.io/api/commands/route
https://docs.cypress.io/api/commands/intercept#Arguments

Related

Axios AJAX call nulls parameter

I use Vuejs to create my frontend for my project.
At the creation of one component ('TimeCapsy.vue'), I make an AJAX call to my backend like this:
created: function () {
if (verify.verify_login()) {
let token = this.$cookies.get('jwt_us_cas');
let params = {'jwt': token};
console.log(params);
axios({
method: 'post',
url: dev.HOST+'getuserinfoobject',
params: queryString.stringify(params)
})
.then(response => {
console.log(response.data)
})
}
}
As you can see I use the
this.$cookies.get('jwt_us_cas');
to get the a json web token, that I set on the client at the login.
I use the queryString Library to stringify my parameters for my request.
I also tried it without the queryString.stringify(params) call, but I get the same error, e.g. the parameter still turns into null.
When I look at the console log, where I check the params variable, I get this output:
{jwt: "my token comes here"}
So I can see, that it gets the correct value from the cookie.
But when I check the answer from my backend (PHP), I get this error:
Undefined index: jwt in <b>D:\casb\public\index.php</b> on line <b>52</b>
Of course I know that it means, that jwt is null, but I can't understand why.
As I said, right before I make the call I check the params and it shows the token.
I checked the endpoint with Postman and the token as the jwt parameter and it returned a successfull call with the correct answer.
A correct answer is basically just a nested object with some information in it.
My PHP endpoint is pretty basic too:
Router::add('/getuserinfoobject', function () {
$response['response'] = User::getUserInfoObject($_POST['jwt']);
echo json_encode($response);
}, 'post');
So I guess that right before or in my call it nulls my parameter. But I can't understand how, since I make a lot of requests and never had this problem.
From axios docs
params are the URL parameters to be sent with the request
Which means, you should get the value with PHP $_GET.
Or $_REQUEST (which stores both $_GET, $_POST. Also $_COOKIE).
The other hand, you can use data key as docs says
data is the data to be sent as the request body
Only applicable for request methods PUT, POST, and PATCH
So the value would be available in $_POST
axios({
method: 'post',
url: dev.HOST+'getuserinfoobject',
data: {
jwt: token
}
})

Sending an array of string in a request made with rest-client gem

I am creating a gem to implement the Calendly API and I need to make a request like
curl --header "X-TOKEN: <your_token>"
--data "url=https://blah.foo/bar&events[]=invitee.created"
https://calendly.com/api/v1/hooks
to create a webhook.
As you may see, events is passed as an array of strings and this is indicated by the [].
I am trying to use RestClient::Request#execute to send this request, but I don't know how to pass this array of strings in this case.
I tried
RestClient::Request.execute(method: :post,
url: #uri,
params: { url: url,
events: "invitee.#{type}"
},
headers: { "X-TOKEN": "#{#api_key}" })
but then I am not sending an array as the API expects.
I also tried
RestClient::Request.execute(method: :post,
url: #uri,
params: { url: url,
'events[]': "invitee.#{type}" },
headers: { "X-TOKEN": "#{#api_key}" })
but it didn't work either. I got a bad request error and nothing else.
How should I build my request in this case?
Posted for visibility (previously answered in comment)
RestClient will appropriately serialize a native ruby Array for you meaning
events: ["invitee.#{type}"]
will be serialized into events[]=invitee.created where type == 'created'. This will work for an Array with multiple values too.
events: ["more","than","one"]
will be converted to events[]=more&events[]=than&events[]=one.
Finally it also handles an other data types inside an Array such as another Hash
events: [{first_name: 'Zaphod', last_name: 'Beeblebrox'}]
will become events[][first_name]=Zaphod&events[][last_name]=Beeblebrox

sendAJAX data parameter in CasperJs

again, I got another problem with casperjs, now with sendAJAX function.
It says that sendAJAX has 5 parameters which are these followings :
url: The url to request.
method: The HTTP method (default: GET).
data: Request parameters (default: null).
async: Flag for an asynchroneous request? (default: false)
settings: Other settings when perform the AJAX request (default:
null)
So, it says the data method is object so, it should be filled with :
var data = new Object();
data.amount= 15;
and also with this one,
var data = {amount:15};
but there were no successful value send to my web service (always send 0 as value, but ajax request successful, even returning the json data) which has an url like this
"http://localhost:9000/TempCountryAmountREST/setCountryAmount"
It will be succeed if I direct bind my data variable to my url like this :
"http://localhost:9000/TempCountryAmountREST/setCountryAmount?amount="+amount
[UPDATE]
The TempCountryAmountREST is my controller name and setCountryAmount is my function inside my controller.
[UPDATE]
I forgot to include my usage of sendAJAX(), here is the code that I use :
return JSON.parse(__utils__.sendAJAX(wsurl, "POST" , data, false, { contentType: "application/json" }));
So how does I fill the data in the sendAJAX parameter?
Thanks in advance...
Sorry, I've found what the answer is.
I make some mistakes in contentType which I was set with contentType: "application/json" instead of contentType: "application/x-www-form-urlencoded" }
If we are looking about how ajax send the content from method send(), they were use x-www-form-urlencoded. See this for more detail
When we see through casperjs clientutils.js script, we should found how sendAJAX work.
On the `this.sendAJAX = function sendAJAX(url, method, data, async, settings) {
}
there are url construction logic which transformed our Object (if so) to x-www-form-urlencoded form. So that we need to set our contentType as application/x-www-form-urlencoded
Very well, thanks for your attention...

A 405 status code from web API after trying to send PUT data in body

ok.
I'm using Web API to make AJAX requests.
I'm trying to send a PUT request to an action on a controller.
I'm using route attributes.
When I'm sending the data as part of the route data, everything is fine and the action gets the right info.
However, when I'm trying to send the data in the body, I get a 405 status ((Method is not allowed).
I'm also adding the [FromBody] attribute to the parameter. Here's by jQuery call:
type: 'PUT',
url: 'api/ServerQueue/activity',
data: "=2",
success: function (xhr) {
$("#load").hide();
},
error: function () {
$("#load").hide();
}
};
Here's my action:
[Route("status/{status}")]
public string PutStatus([FromBody]int status)
{
}
I placed a "RoutePrefix" on the controller body.
BTW, I'm using VS 2012.
Any idea what could be the source of the problem?
Try changing the route configuration from
[Route("status/{status}")]
to
[Route("status")]

Cross Domain Ajax call EasyXDM

I'm trying to make a cross domain Ajax call using EasyXDM, because this gives support for IE apparently.
I have the following code, It says in the documentation that you need to call the cors file on the other domain, but it mentions you can skip that part, I want to skip it because I can't upload the cors file there and they have allowed my domain in the headers anyway. How do I write the code without declaring the cors file?
var xhr = new easyXDM.Rpc();
var response;
function getState(){
xhr.request({
url: "http://somedomain.com/misc/promo_getstate.php",
method: "POST",
data: {
email: 'sofia#hotmail.com',
source: '1304_Spring_dly',
country: 'DE',
}
}, function(response){
alert(response.status);
alert(response.data);
});
I know it's a little late, but you might find this link helpful (it's a blog post specifically about using easyxdm to do cross-domain AJAX):
http://easyxdm.net/wp/2010/03/17/cross-domain-ajax/

Resources