I'm trying to create a test under a token-based authorization mechanism. Everything is almost working fine until the accesstoken is expired. Then I'm trying to refresh it, however it seems some piece of the test is not performed.
This is the Authorization dance:
foreach user in users.csv:
{
Get Authorization Code: Http sampler
Extract AuthzCode on ${authorizationcode}: JSON extractor
if ${JMeterThread.last_sample_ok}
{
Get Access Token: Http sampler
Extract AccessToken on ${accesstoken}: JSON extractor
Extract RefreshToken on ${refreshtoken}: JSON extractor
if ${JMeterThread.last_sample_ok}
{
foreach data in data.csv
{
Send data in body: Http sampler
if ${JMeterThread.last_sample_ok} == false *******************
{
Extract error on ${expiredaccesstokenerror}: JSON extractor
if (${expiredaccesstokenerror} == "expired_accesstoken")
{
Get new accessToken using ${refreshtoken}: Http Request
Extract AccessToken on ${accesstoken}: JSON extractor
Extract RefreshToken on ${refreshtoken}: JSON extractor
}
}
}
}
}
}
Everything works fine until the AccessToken expires and server returns me this body:
{
"error_description":"Access token expired",
"suberror":"expired_accesstoken",
"error":"invalid_grant"
}
After that, I'm expecting JMeter reach the inside if controller with ${JMeterThread.last_sample_ok} == false and then the next if controller with condition ${expiredaccesstokenerror} == "expired_accesstoken". However I'm not able to figure out why this code is not reached.
As you can see in the herewith image, I've implemented this process in JMeter as:
Change your 2nd condition to:
"${expiredaccesstokenerror}" == "expired_accesstoken"
Mind quotation marks around the variable. If Controller's conditions are evaluated by JavaScript engine (Rhino or Nashorn) and if you compare something with string you'll get "blabla is not defined" exception. When it was about 2 boolean types (${JMeterThread.last_sample_ok} and false) - it was fine, but if you want to compare a JMeter Variable to some string - you need to explicitly cast the variable to string. See How to Use JMeter's 'IF' Controller and get Pie article for more details.
Few more tips:
In every situation when JMeter test is not working as expected take a look into jmeter.log file
If jmeter.log file doesn't contain anything suspicious - go for Debug Sampler and View Results Tree listener combination.
Related
I am testing search functionality in one of my Cypress tests and having trouble getting to all parts of the request url. On my page, I have a form that a user can enter a number to search for. When a user clicks "Search", the system makes an ajax request with the appropriate data. Everything is working great.
In my Cypress test, I'm intercepting a GET request in one of my tests like this:
cy.intercept('GET', '/api/v1/foo/?include=**').as('myRequest');
...
That is the GET request that is made when a user clicks the submit button to search.
Within my test, I am entering text into a text field like this:
...
cy.get('[data-cy="number"]').type('12345');
The text is getting properly interred into the input.
Next, I am triggering an ajax request like this:
...
cy.get('[data-cy="search"]').should('exist').click();
cy.wait('#myRequest').then((interception) => {
console.log(interception.request.url); // /api/v1/forms/?include=foo <-- does not have filter[number]...
expect(interception.request.url).to
.include('filter[number]=12345');
});
When submitting a real request (not through cypress) the request url looks like this:
https://example.com/api/v1/foo/?include=bar&filter[number]=12345
However, when cypress makes the request, it's seemingly not picking up the query field and my test is failing.
I've also tried using expect(interception.request.query) but it is always undefined.
How can I properly pick up the filter[number] query param in my test?
It looks like there's preceding requests that are using up your cy.wait('#myRequest').
Query parameter matching is a bit tricky, but it works using a routeMatcher function and checking for the correct params, then assigning a dynamic alias.
cy.intercept('/api/v1/foo/?include=**', (req) => {
if (req.query.include === 'bar' && req.query["filter[number]"] === '12345') {
req.alias = 'myRequest' // alias for only these parameters
}
req.continue()
})
cy.get('[data-cy="search"]').should('exist').click();
cy.wait('#myRequest').then((interception) => {
...
})
I have a very simple spring boot web application which consumes requests with json body.
For each json which the application will receive (from any client) I would like to manipulate it as a first step.
For example if the client sends the following body:
{
"hello": "world!!!"
}
I would like to replace each ! with a ?. In this case the result is:
{
"hello": "world???"
}
This json transformation should be valid for each controller and for any json entering the system.
Is this kind of operation possible?
Thanks.
You may use string.replace to do the same.
Or also you can add custom annotation to manipulate the values of any keys.
You can use any replacement methods or regex in your classes.
#GetMapping
public String replace(RequestItem item){
// item = item.regex/replacement method
// call your service or whatever
return item;
}
When you got the data, you can do whatever you want to do.
I intend to send my server response in the following format
Api Doc
I did the following
headersR.add("response_code", "OK");
headersR.add("cmd_code", "SET_FK_NAME");
headersR.add("trans_id", Long.toString(System.currentTimeMillis()/1000000));
JSONPObject map1 = new JSONPObject("fk_name", "jj");
return new ResponseEntity<>(map1, headersR, HttpStatus.OK);
I was getting a negative response from the other side so I checked Wireshark(Had a hard time logging my response body). And I got this in Wireshark.
Wirehark Screenshot
The response body is Definitely not JSON.
How can I fix this?
The response body fk_name("jj") is not JSON, it's JSONP -- Browser would take the function name fk_name and try to execute it with "jj" as parameter.
The root cause is you are using JSONPObject, whose constructor accepts 2 parameters: a function name, and the data value. Not the expected JSON key and value.
To fix this issue and return {"fk_name":"jj"}, remove the JSONPObject stuff and use code as follow:
return new ResponseEntity<>("{\"fk_name\":\"jj\"}", headersR, HttpStatus.OK);
I am trying to pass a URL as a input parameter to a ApiController from an Angular REST call. The URL comes as a query string (this is a Provider Hosted app in SharePoint, I need the URL to query SP FWIW).
Here is the method signature in the ApiController:
// GET: api/ProjectSite/5
public IEnumerable<ProjectSite> Get(string id)
{
return ProjectSite.GetAllProjectSites(id);
}
And here is where I am making the call in Angular:
var spUrl = "'" + getParameterByName("SPHostUrl") + "'";
var queryUrl = "/api/ProjectSite/" + encodeURIComponent(spUrl);
return $http.get(queryUrl);
This generates a GET request that looks like this:
https://localhost:12345/api/ProjectSite/https%3A%2F%2Fcompany.sharepoint.com%2Fsites%2Fsite_dev%2Fweb
When I do I get 'HTTP 400 (Bad Request)' back. If I stop on a break point in the Angular code and change the input param to a simple string (e.g. 'asdf') the REST call is made and I see the Api is called. If I do not change the string and put a breakpoint inside the Get Api method the breakpoint is not reached, indicating that the code is blowing up somewhere in the route engine.
What I don't get is, while its encoded, the string I am trying to pass in should still be treated as a string, right? I also tried changing the input to Uri but that doesn't appear to work (and Uri isn't listed as a supported input type, anyways).
Anyone know how to pass a URL as input parameter?
Have you tried calling it using a query string?
var queryUrl = "/api/ProjectSite?id=" + encodeURIComponent(spUrl);
Web API allows me to capture the body of a POST request in a JObject:
$.post('/api/Query/DoSomething', { Foo: "one", Bar: 4 });
public string Post(JObject data)
{
// data is populated
}
However the same technique does not work with a get request and URI parameters.
$.get('/api/Controller', { Foo : "one", Bar : 4 });
public string Get([FromUri]JObject data)
{
// data is empty
}
Any workaround here?
It doesn't work because a GET request does not have a body, and hence no content type. Therefore, Web API does not know that you have JSON in your URL. You have a few choices:
Pass your data as query string parameters, as is traditionally done in GET requests, and change your method to accept those parameters individually, or in a regular class (POCO).
Change your GET method to accept a string instead of a JObject, then use JSON.Net to deserialize it manually, e.g. JObject obj = JObject.Parse(data);
If you're feeling ambitious, you might be able to implement a custom binder to do this.
My recommendation is option 1. Traditionally, a GET method is just intended to look something up, so you really should only be passing IDs and simple query options anyway. It is unusual to be passing JSON data in a URL. Also the length of URLs can be limited by some browsers. If you find you are needing to pass JSON data, use POST (or PUT) instead.
You can create an object and bind to it using the FromUri.
Check out this solution which I am using https://stackoverflow.com/a/49632564/2463156.