wiremock request matching from key=value pair - wiremock

I am using json mapping to match the request. The request coming as content-type application/x-www-form-urlencoded which means as a Key=value pair and the value contains xml data. For example:
REQUEST=<?xml version="1.0" encoding="UTF-8"?>
<n:request xmlns:n="schema uri" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="schema location">
<header userId="userId" password="password" requesterId="123" version="100" language="de">
<product>xxx</product>
</header>
<subject>
<party externalIdentifier="1">
<address externalIdentifier="11">
<person>
<firstName>rinku</firstName>
<lastName>chy</lastName>
<birthDate>1973-12-10</birthDate>
</person>
<street>street</street>
<number>12</number>
<countryCode>de</countryCode>
<zipCode>123</zipCode>
<city>city</city>
</address>
</party>
</subject>
</n:request>
The purpose is to find the product name and the person's name. I have tried both xpath as well as query parameters expression to match the request as stated in http://wiremock.org/docs/request-matching/. But couldn't manage to get a solution yet.For example
{
"request": {
"method": "POST",
"urlPattern": "/mock.*",
"queryParameters": {
"product": {
"matches": "xxx"
}
},
// tried both seperately
"bodyPatterns": [
{
"matchesXPath": "//*[local-name()='request']/*[local-name()='header']/*[local-name()='product'][text()='xxx']"
}
]
},
"response": {
"status": 200,
"bodyFileName": "response.xml",
"headers": {
"Content-Type": "text/xml; charset=UTF-8",
"Content-Location": "response.xml"
}
}
}
Always getting the same error "[WireMock] (qtp2017957857-34) Warning: failed to parse the XML document. Reason: Content is not allowed in prolog.
Can anyone have a clue how to match such a request?

I found the solution. There is an option to intercept and modify requests. Visit -> http://wiremock.org/docs/extending-wiremock/ in the section "Intercepting and modifying requests".
public class RequestFilter extends StubRequestFilter {
#Override
public RequestFilterAction filter(Request request) {
// removed "REQUEST=" from request body
Request modifyRequest = RequestWrapper.create()
.transformBody(requestBody -> Body.fromOneOf(null, requestBody.asString().substring(8)), null, null))
.wrap(request);
return RequestFilterAction.continueWith(modifyRequest);
}
#Override
public String getName() {
return "my-request-filter";
}}

Related

I'm trying to the customzing the error format structure .for the Rest API

I'm trying to customize the error format with the below structure but not able to set the the error and httpCodeMessage
Error Fromat :
[
{
"headers": {},
"body": {
"timestamp": "2020-08-17T10:22:14.538+0000",
"error": null,
"message": "User Not Found in the system",
"path": "/claims/search/",
"httpCodeMessage": null
},
"statusCode": "BAD_REQUEST",
"statusCodeValue": 400
}
]
#ExceptionHandler(ValidationException.class)
public ResponseEntity<ErrorResponse[]> process(ValidationException ex, HttpServletRequest req) {
return new ResponseEntity(Arrays.asList(generateErrorResponse(ex, req)), HttpStatus.BAD_REQUEST);
}
private Object generateErrorResponse(ValidationException ex, HttpServletRequest req) {
ErrorResponse error = new ErrorResponse();
if (ex.getMessage().equalsIgnoreCase("Resource Not Found")) {
error.setTimestamp(new Date());
error.setMessage(NOT_FOUND.value(), ex.getMessage());
error.setPath(req.getRequestURI().toString());
error.setError(ResponseEntity.status(NOT_FOUND));
return ResponseEntity.status(NOT_FOUND).body(error);
}
}
Can anyone suggest how to get the error and httpCodeMessage values .Is it possible to remove the statusCode and statusCodeValue attributes.
You normally have to go to the original HttpClientErrorException and getRawStatusCode() to get the HTTP error code
javadoc

how to access specific team site in share-point using rest apis

goal: I'm trying to access a specific team site which created in my share-point account using REST APIs and create a folder inside there (Documents folder - default location)
actual results: I'm getting 403 error code. following is the response body which I'm getting.
{
"error": {
"code": "-2147024891, System.UnauthorizedAccessException",
"message": {
"lang": "en-US",
"value": "Access denied. You do not have permission to perform this action or access this resource."
}
}
}
expected result: specified folder should be created and response code should be 201 or 200
what I've tried:
first registered the app in both share-point as well as Azure
get the bearer token calling share-point rest api
tested get apis for share-point and all are worked as expected.
before each request I set the bearer token in the request header
following are the other request headers which I'm setting
Content-Type : application/json;odata=verbose
X-RequestDigest : some random string
Accept : application/json;odata=verbose
following is the share-point REST API, I used POST method for creating a folder
https://***.sharepoint.com/sites/TeamSite_ForB/_api/web/folders
following is the request body which I'm sending
{
"__metadata":{
"type":"SP.Folder"
},
"ServerRelativeUrl":"/Shared Documents/buddhika-test-folder-03"
}
In the share-point documentation site they've provided the API format.
I tried with that format , but couldn't get the result as well.
following is from share-point documentation.
To access a specific site, use the following construction:
http://server/site/_api/web
in that case I have tried as following
https://***.sharepoint.com/TeamSite_ForB/_api/web/folders
I'm getting response as 404 Not found with no response message.
I have searched through many documents but couldn't find how to access a specific team site.
Any help would be appreciated.
The request REST API URL as below.
https://***.sharepoint.com/sites/TeamSite_ForB/_api/web/folders
The request body as following.
{
"__metadata":{
"type":"SP.Folder"
},
"ServerRelativeUrl":"Shared Documents/buddhika-test-folder-03"
}
Example code:
<script src="//code.jquery.com/jquery-3.1.0.min.js" type="text/javascript"></script>
<script type="text/javascript">
function getFormDigest() {
return $.ajax({
url: _spPageContextInfo.webAbsoluteUrl + "/_api/contextinfo",
method: "POST",
headers: { "Accept": "application/json; odata=verbose" }
});
}
function createFolderTest() {
var documentLibraryName = "Shared Documents";
var folderName="buddhika-test-folder-03";
if(folderName!=""){
createfolder(documentLibraryName,folderName).done(function (data) {
console.log('Folder creted succesfully');
}).fail(function (error) {
console.log(JSON.stringify(error));
});
}
return true;
}
function createfolder(documentLibraryName,folderName){
var requestUri = _spPageContextInfo.webAbsoluteUrl + "/_api/web/folders";
return getFormDigest().then(function (data) {
return $.ajax({
url: requestUri,
type: "POST",
contentType: "application/json;odata=verbose",
data:JSON.stringify({'__metadata': { 'type': 'SP.Folder' }, 'ServerRelativeUrl': documentLibraryName+'/'+folderName}),
headers: {
"accept":"application/json;odata=verbose",
"X-RequestDigest":data.d.GetContextWebInformation.FormDigestValue
}
});
});
}
</script>
<input type="button" onclick="createFolderTest()" value="Create Folder"/>

Adding document in Couchbase and missing JSON body

I am trying to use Couchbase REST API to add a document to the existing documents. I am just testing this in Postman while writing on the code.
POST:
http://<ip>:8091/pools/default/buckets/<bucketname>/docs/testdoc1?rev=1
Headers:
Accept: application/json
Authorization : xxxxx
Body:
Raw JSON (application/json)
{
"Name": "xxx",
"Address": "yyy",
"Phone number": "xxxx",
"Badge": "yyy",
"BadgeType": "xxx"
}
When I send above in Postman, It is adding this new doc. under couchbase documents/bucket, but on the body field it shows like, "Binary Document, base64 not available"
I tried even from my html code, but json body didn't receive at couchbase end.
<!DOCTYPE html>
<html>
<body>
<input type="submit" value="Start" onclick="submit()">
<script type="text/javascript">
var params = {
"Name": "xxx",
"Address": "yyy",
"Phone number": "xxxx",
"Badge": "yyy",
"BadgeType": "xxx"
}
function submit() {
var xhr = new XMLHttpRequest();
xhr.onreadystatechange = function () {
if (xhr.readyState === 4) {
alert(xhr.response);
}
}
xhr.open('post', 'http://<ip>:8091/pools/default/buckets/<buckname>/docs/testdochtml?rev=1', true);
xhr.setRequestHeader('Content-Type', 'application/json');
xhr.setRequestHeader('Accept', 'application/json');
xhr.setRequestHeader('Authorization', 'Basic ' + 'xxxxxxx');
xhr.send(JSON.stringify(params));
}
</script>
<p>Click on the submit button.</p>
</body>
</html>
Can someone guide me why is that JSON not going to couchbase in a correct way?
First off: as far as I know, this endpoint is not supported and it is not documented. If you see somewhere that it is supported, let me know, because I think that needs corrected. You should use one of the SDKs (Java, .NET, Node, etc) instead.
That being said, I was able to get it working via Postman. You can't just send raw JSON as the document. You need to POST encoded form data. One of the values this endpoint expects is "value", which contains the encoded JSON document.
Here's an example of what I did (I called my bucket "so"):
POST /pools/default/buckets/so/docs/testdoc2 HTTP/1.1
Host: localhost
cache-control: no-cache
Postman-Token: ba87ef4e-4bba-42b4-84da-ae775b26dbcb
value=%7B%0A%09%22Name%22%3A+%22xxx%22%2C%0A%09%22Address%22%3A+%22yyy%22%2C%0A%09%22Phone+number%22%3A+%22xxxx%22%2C%0A%09%22Badge%22%3A+%22yyy%22%2C%0A%09%22BadgeType%22%3A+%22xxx%22%0A%7D%0A
Note that value above is just the URL-encoded JSON from your question (Postman encoded it for me, and Postman must have added the cache-control header on its own too, because I did not specify that):

How to validate response in Postman?

I am trying to validate response body including errors in postman. How can I validate the response and text below?
{
"responseHeader": {
"publisherId": "12345",
"responseId": "abbcb15d79d54f5dbc473e502e2242c4abbcb15d79d54f5dbc473e502e224264",
"errors": [
{
"errorCode": "1004",
"errorMessage": "XXXX Not Found"
}
]
}
}
These are my tests which are failing:
tests['response json contains responseHeader'] = _.has(responseJSON, 'responseHeader');
tests['response json contains errors'] = _.has(responseJSON, 'responseHeader.publisherId');
tests["Response has publisher id"] = responseJSON.publisherId === 10003;
In the "Test" tab, parse your response body into an object, then use JavaScript to perform your tests.
var data = JSON.parse(responseBody);
tests["publisherId is 12345"] = data.responseHeader.publisherId === "12345";
Take a look at the test examples at the Postman site:
https://www.getpostman.com/docs/postman/scripts/test_scripts
https://www.getpostman.com/docs/postman/scripts/test_examples

Different authorization header for each operation in a Guzzle client service description

The API I'm accessing requires a custom authorization header that is a combination of the publicKey that is passed in when the client is instantiated and the complete URI of the API endpoint. I want to pull the baseUrl and operation uri out of the service description and use them to create the authorization header, but I can't figure out how to do this when calling the instantiated client.
This is the service description:
{
"name": "FranchiseSystem",
"apiVersion": "1",
"baseUrl": "https://apidev.example.com",
"description": "REST API client",
"operations": {
"GetFranchiseList": {
"httpMethod": "GET",
"uri": "v1/franchise",
"summary": "Returns an array of franchises."
},
"GetReviews": {
"httpMethod": "GET",
"uri": "v1/review",
"summary": "Returns an array of reviews."
}
}
}
This is the client setup:
$testClient = new JunknetClient([
'publicKey' => '1234567890',
]);
This is the call to the instantiated client with the name of the operation:
$result = $testClient->GetFranchiseList();
or:
$result = $testClient->GetReviews();
When testClient->GetFranchiseList is called, I need to create the authorization header using the publicKey and the values of baseUrl and uri for GetFranchiseList.
When testClient->GetReviews is called, I need to create the authorization header using the publicKey and the values of baseUrl and uri for GetReviews.
You might want to have a look at the following links from the Guzzle docs.
Request Options - Headers
Authentication Parameters
I was able to solve my problem by using and event emitter and subscriber. It's a bit messy, but it get's the job done.
private function handleCredentialsOptions(Collection $config) {
//Build authorization header from $config values
$this->getHttpClient()->getEmitter()->on('before',
function (BeforeEvent $e) use(&$config) {
$this->getHttpClient()->setDefaultOption('headers', [
'Authentication' => '',
]);
$path = $e->getRequest()->getUrl();
$authValue = $config['publicKey'].';;';
$authValue .= time().';';
$authValue .= strtoupper(md5($config['privateKey'] . $path));
$this->getHttpClient()->setDefaultOption('headers', [
'Authentication' => $authValue,
]);
});
}