Exact matching for headers with MockServer - mockserver

I use MockServer to test my application and I need the request definition to match only if the exact headers set was matched, i.e. there are no missing nor extra headers in the request.
Using this Kotlin code it matches any request that contains at least specified headers, so if the request has other headers, it matches it too:
mockServer
.`when`(
request()
.withPath("/somePath")
.withHeaders(
Headers(
header("header1", "value1")
header("header2", "value2")
).withKeyMatchStyle(KeyMatchStyle.MATCHING_KEY)
)
)
.respond(
response()
.withContentType(MediaType.APPLICATION_JSON_UTF_8)
.withBody("OK")
)
Is there a way to configure MockServer to fail if a request contains unspecified headers? After reading the docs, I didn't find how to do this.

I also tried to solve same problem and bumped into that question.
The simplest solution is just to remove .withKeyMatchStyle(KeyMatchStyle.MATCHING_KEY).
But you can also write something like that:
mockServer.when(
request()
.withPath("/somePath")
.withHeader(NottableString.not("header1"), NottableString.string(".*"))
.withHeader(NottableString.not("header2"), NottableString.string(".*"))
.withHeaders(
Headers(
header("header1", "value1")
header("header2", "value2")
).withKeyMatchStyle(KeyMatchStyle.MATCHING_KEY)
)
)

Related

Path parameters being passed as a String with comma not read properly in rest assured

I have a code where I am passing path parameters in the GET request in Rest Assured. But I see the path parameters aren't read properly and I see some gibberish text being read. Actually the String I am passing as path parameter contains a comma in it. Below is my code.
ValidatableResponse response = given().header("Authorization", token).header("Content-type", "application/json")
.when().log().all().pathParam("CalendarId", testCaseBean.getCalendarId().toString())
.queryParam("from", testCaseBean.getStartDate()).queryParam("to", testCaseBean.getEndDate())
.queryParam("monthEnd", testCaseBean.getMonthEndBusinessDay())
.get(EndPoint.GET_CALENDAR_BUSINESS_DAY_INFO_DATE_PARAM).then().log().all();
The path param I am passing is "AUS,EUR" and it is being read as AUS%2CEUR. I am passing this path parameter as test data from the CSV file. Below is the request being formed on the console.
https://portculation-qa.us-east-1.m5435454345.easn.mss.com/master-data/v1/calendars/AUS%2CEUR?from=2022-11-01&to=2022-11-01&monthEnd=false
My expected request URI is https://portculation-qa.us-east-1.m5435454345.easn.mss.com/master-data/v1/calendars/AUS,EUR?from=2022-11-01&to=2022-11-01&monthEnd=false
You can see the only difference in the expected and actual URI is the gibberish path param which isn't read properly. Any solution to tackle this issue?
Try adding this:
.urlEncodingEnabled(false)
RestAssured.given()
.contentType(JSON)
.log()
.all()
.urlEncodingEnabled(false)
or:
RestAssured.urlEncodingEnabled = false;
By default it set to true.

AWS API Gateway issue for HTTP Method

I created an AWS API-gateway for an HTTP method PUT. When I do a test in API-gateway, that works fine, but when I call it from a REST client, I get 404 bad-request and missing authentication token errors. I didn't set any authorization to true or a required API key to true.
I passed these query parameters to a REST client:
auth_id : 8798iuyiu123123
time_stamp :1231231
test_json : [{"id"=>"1","value"=>"mount"},{"id"=>"2","value"=>"chart"}]
HEADER
content-type : application/json
When I change the test_json value to %5B%7B%22id%22:%221%22,%22value%22:%22test%22%7D,%7B%22id%22:%222%22,%22value%22:%2213+%D8%B4%D8%A7%D8%B1%D8%, then I get the response.
i am new to react, calling from react
Request.put('https://api-gateway.sqwdwed123.com/eretw/update-chart')
.set('Content-Type', 'application/json')
.query({ auth_id: localStorage.auth_id})
.query({ time_stamp:this.props.time_stamp})
.query({ test_json:JSON.stringify(newadd)})
should i pass this test_json through body?
Am I doing anything wrong?
This is usually related to requesting a URL that doesn't exist. Please make sure you're using the correct HTTP method and resource path to a valid resource (the sample invoke URL does not include any resource path). If this still doesn't work. Make sure you actually deployed your API.
The HTTP Response of Bad Request is because you have the Query Parameter that are not URL Encoded. There are 2 things that you can do now:
Pass the test_json as Query Param but making sure that they are URL Encoded. This will put a restriction on the size of the string and hence Not Recommended.
Pass the test_json as Request Body. (Recommended)

How to use REST assured?

I have never used JUnit or other testing frameworks. All i know is how to develop rest service. I recently saw REST assured framework to test REST api. But all the articles that i found looks like below. But i don't know how to pass request xml and how will i get response and when should i call this method.?
Do i need to use some other tool before this REST assured.? I am completely beginner in this kind of testing frameworks. Please show me some light in this world. All i know is how to send request and check values in the response in SOAPUI. I have never tried this.
expect().
statusCode(200).
body(
"user.email", equalTo("test#hascode.com"),
"user.firstName", equalTo("Tim"),
"user.lastName", equalTo("Testerman"),
"user.id", equalTo("1")).
when().
get("/service/single-user/xml");
expect() /* what u expect after sending a request to REST Service */
statusCode(200) /*you are expecting 200 as statuscode which tells request handled successfully at server */
body()
/* the conditions given in body are compare the value with expected values. "equalTo" hamcrest matcher condition (you need to have hamcrest jar in java classpath).*/
when(). /* as is name says above all will be done after sending get/post/put/delete request right so before you put these get,post,put,delete you will have this method as prefix */
get("/service/single-user/xml")
/* the actual REST API request url goes here. can be GET/POST/PUT/DELETE. the confusion for you is its only showing half part which is base path.you can give entire request url in get() method.*/
more on:
http://rest-assured.googlecode.com/svn/tags/1.8.1/apidocs/com/jayway/restassured/RestAssured.html
I hope this helps.

Quickbooks v3 query url returning Error

First - my question:
When accessing the Quickbooks API, v3 (as has been forced on me as of this weekend by Intuit) I am trying to access Journal Entries (but the following problem persists across any other query) and I'm trying to use the prescribed query?query=SELECT * FROM JournalEntry (what?).
https://qb.sbfinance.intuit.com/v3/company/<id>/query?query=SELECT * FROM JournalEntry
I get as result:
{"Fault":{"Error":[{"Message":"message=Exception authenticating OAuth; errorCode=003200; statusCode=401","code":"3200"}],"type":"AUTHENTICATION"},"requestId":"6f5e5f14af7d4867ad0d8f639ade7d04","time":"2013-11-12T16:10:44.724Z"}
Which, yes, tells me that there was an error with authentication. However, when I access a URL that doesn't include this ridiculous query syntax, everything works fine:
https://qb.sbfinance.intuit.com/v3/company/<id>/journalentry/<id>
I had a similar error when accessing the v2 API, and that was bad formatting on my part, but I don't see what's wrong with my query.
And because my code for generating the authentication tokens etc is identical for both types of request, I doubt that the problem is with how I'm authenticating. Similarly "exception" tells me that there's something going wrong that the API isn't identifying. Probably a formatting of the URL that is going wrong.
I've tried replacing the query URL spaces with both a '+' and a '%20', which returns the same error.
I'm using python and rauth. The code works fine for v2 (but that was deprecated over the weekend without warning, and now is no longer documented).
As a bonus, and because apparently this is Intuit's primary mode of communication with their clients: I'm shocked that Intuit no longer has private support tickets available on their website, and that they rely on a community environment like SO to provide support. The least they could do is provide their own support. Especially if we're paying for use of the API. This is absolutely shocking.
On top of that, the API returns inconsistent responses (the same request will return an error or a valid result, depending on... no change at all). An error I have reported through their support tickets, and they have duly ignored.
Oh, and the documentation says to use
https://quickbooks.api.intuit.com/v3/v3/company/companyID/query?query=selectStmt
while the API Explorer uses:
https://qb.sbfinance.intuit.com/v3/company/<id>/query?query=SELECT * FROM JournalEntry
Anyone know which one I should actually use?
Edit
For the response that is failing, my request headers are:
{
'Content-Length': u'62',
'Accept-Encoding': 'gzip,
deflate,
compress',
'accept': 'application/json',
'User-Agent': 'python-requests/1.2.3CPython/2.7.5Darwin/13.0.0',
'Content-Type': 'application/x-www-form-urlencoded',
'authorization': 'OAuthrealm="<companyId>",
oauth_nonce="3ad98c5f71bc9f102cc31ac9815cb6d08994454e",
oauth_timestamp="1384280420",
oauth_consumer_key="<consumerKey>",
oauth_signature_method="HMAC-SHA1",
oauth_version="1.0",
oauth_token="<oauthToken>",
oauth_signature="<oauthSignature"'
}
My url is:
https://quickbooks.api.intuit.com/v3/company/<id>/query?query=SELECT+*+FROM+JournalEntry&
And my response headers are:
{'content-length': '227', 'server': 'Apache/2.2.22 (Unix)', 'connection': 'close', 'date': 'Tue, 12 Nov 2013 18:20:20 GMT', 'content-type': 'application/json;charset=ISO-8859-1', 'www-authenticate': 'OAuth oauth_problem="signature_invalid"'}
My signature hashing function is correct. It's the standard function used by Rauth, and works fine for more standard API calls (that don't have spaces or SQL select queries in them).
Pass the URL to your HTTP call without encoding:
URL = https://quickbooks.api.intuit.com/v3/company/123456789/query?query="Select * from Customer"
But to build the signature, separate the parameters from the URL, then encode separately, you should get:
"GET" + "&" +
URLEncode(https://quickbooks.api.intuit.com/v3/company/123456789/query) + "&" +
URLEncode(query=Select%20%2A%20from%20Customer), where Select%20%2A%20from%20Customer is the encoding of Select * from Customer
Note the SQL gets encoded a second time, when generating the signature.
Et voila ! I spent a week on this, I know what I'm talking about.
(notations are from VBA language, so replace as appropriate)
It turns out that the actual problem is that the Quickbooks documentation is wrong as of this writing (2013/11/14).
The documentation says that the query URL expects a GET request, which is not the case. This works when submitting SELECT statement as part of the body of a POST request.
See here for more details: https://intuitpartnerplatform.lc.intuit.com/questions/786661-python-script-to-integrate-with-quickbook
I had tried this API call using Java devkit.
JournalEntry je = GenerateQuery.createQueryEntity(JournalEntry.class);
String jeQuery = select($(je)).generate();
System.out.println("Query - " + jeQuery);
QueryResult JournalEntryRes = service.executeQuery(jeQuery);
Request URI : https://quickbooks.api.intuit.com/v3/company/688779980/query?query=SELECT+*+FROM+JournalEntry&
Response XML
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<IntuitResponse xmlns="http://schema.intuit.com/finance/v3" time="2013-11-12T09:50:39.836-08:00">
<QueryResponse startPosition="1" maxResults="1" totalCount="1">
<JournalEntry domain="QBO" sparse="false">
<Id>22734</Id>
<SyncToken>0</SyncToken>
<MetaData>
<CreateTime>2013-10-15T08:42:12-07:00</CreateTime>
<LastUpdatedTime>2013-10-15T08:42:12-07:00</LastUpdatedTime>
</MetaData>
<TxnDate>2013-10-15</TxnDate>
<Line>
<Id>0</Id>
<Amount>100.00</Amount>
<DetailType>JournalEntryLineDetail</DetailType>
<JournalEntryLineDetail>
<PostingType>Debit</PostingType>
<AccountRef name="Advertising">9</AccountRef>
</JournalEntryLineDetail>
</Line>
<Line>
<Id>1</Id>
<Amount>100.00</Amount>
<DetailType>JournalEntryLineDetail</DetailType>
<JournalEntryLineDetail>
<PostingType>Credit</PostingType>
<AccountRef name="Advertising">9</AccountRef>
</JournalEntryLineDetail>
</Line>
<Adjustment>false</Adjustment>
</JournalEntry>
</QueryResponse>
</IntuitResponse>
You can try this call from V3 QBO ApiExplorer as well.
Query - SELECT * FROM JournalEntry
Thanks
you need to encode the query, but not the whole url
https://quickbooks.api.intuit.com/v3/company/123456789/query?query=" & URLEncode("Select * from Customer")
see sample explained here :
https://developer.intuit.com/docs/0100_quickbooks_online/0300_references/0000_programming_guide/0050_data_queries

HttpException: HTTP headers are not mutable

I can't figure out why I'm getting this error in Dart:
HttpException: HTTP headers are not mutable
I have an instance of HttpResponse and I try to add some headers to it:
response.outputStream.writeString(responseData);
response.headers.add('Content-Type', 'text/html');
response.outputStream.close();
What am I supposed to do then if not add to the headers?
It's simple to solve, just make sure you add headers before outputting anything:
response.headers.add('Content-Type', 'text/html'); // <-- this line first.
response.write(responseData);
response.close();
All I did was change the order of the lines.
The reason is that if you start outputting the body, you can't simply modify the headers anymore (because the headers are already sent down the wire!). This is how HTTP works. First the headers then the body.
More background:
Sometimes HTTP libraries (generally in different programming languages) may be buffering the output data and do not flush the content immediately, resulting in a scenario where you can seemingly modify the headers even after outputting something. In your case that's not happening. The output seems to be flushed already.

Resources