How to fix nested 'if, else if, else' test scripts in Postman - postman-testcase

I have a nested 'if, else if, else' test script for #Postman tests but i get some condition executed when it is not meant to be and others not executed properly.
When I comment some section out of the condition in the test, it works as desired.
var jsonData = JSON.parse(responseBody);
if (responseCode.code === 200){
tests["Http status is 200"] = responseCode.code === 200;
try{
tests["ID: "] = jsonData.id === jsonData.id;
tests["Name is: "] = jsonData.name === jsonData.name;
tests["Description is: "]= jsonData.description === jsonData.description;
}
catch(e){}
}
else if (responseCode.code !== 200){
//using invalid token
tests["Http status is 401"] = responseCode.code === 401;
try{
tests["Response Message is: " + jsonData.error] = jsonData.error;
}
catch(e){}
}
else(responseCode.code !== 200){
//record not found
tests["Http status is 404"] = responseCode.code === 404;
try{
tests["Status Code is " + responseStatus.status] = responseStatus.status;
tests["Response Message is: " + jsonData.message] = jsonData.message;
tests["Time is " + jsonData.timestamp] = jsonDat.timestamp;
}catch(e){}
}
See Sample result

Related

QSH Verification, I have tried to verify qsh string but i get a "abc" qsh instead of the "def" qsh from the JWT token

I have used this video to properly understand how JWT QSH is created from a SHA hashed conical request
https://www.youtube.com/watch?v=5EpEMKPbUjU
I also have gone through, this site Understanding JWT. https://developer.atlassian.com/cloud/jira/platform/understanding-jwt-for-connect-apps/.
I have replicated everything done there, and still confused. I have never been able to reproduce the qsh.
if (verifiedClaims.qsh) {
const { baseUrl } = payload;
const url = JWTHelper.decodeUrlToMatchJWTQueryStringHash(baseUrl);
logger.debug(`url[${url}]`);
const req = jwt.fromMethodAndUrl("GET", url);
logger.debug(`req[${JSON.stringify(req)}]`);
let expectedHash = jwt.createQueryStringHash(req);
logger.debug(`expectedHash[${expectedHash}]`);
let signatureHashVerified = verifiedClaims.qsh === expectedHash;
logger.json("signatureHashVerified", { qsh: verifiedClaims.qsh, expectedHash, signatureHashVerified });
if (!signatureHashVerified) {
// If signatureVerified is false, then check the url if its a PUT/POST
expectedHash = jwt.createQueryStringHash(req, url);
signatureHashVerified = verifiedClaims.qsh === expectedHash;
logger.json("signatureHashVerified", { qsh: verifiedClaims.qsh, expectedHash, signatureHashVerified });
if (verifiedClaims.qsh !== expectedHash && verifiedClaims.qsh !== "context-qsh") {
const canonicalRequest = jwt.createCanonicalRequest(req, true, url);
logger.error(
'Auth failure: Query hash mismatch: Received: "' + verifiedClaims.qsh + '" but calculated "' + expectedHash + '". ' +
'Canonical query was: "' + canonicalRequest);
throw new Error("Authentication failed: query hash does not match.");
}
}
}
The code above is from the Link, understanding jwt. I am using atlassian-jwt npm package
https://www.npmjs.com/package/atlassian-jwt.
Please where am I getting it all wrong, from my codes or from any perspective what can I do to fix the issue and verify qsh

protractor promises - querying an API using "request"

I am trying to use protractor to call an api - it will return some JSON to me and I want to assert against it. I thought I had this working, until I tried to take it further and realised I hadn't got it right, but having a bit of a time trying to work out why.
I have placed some console.logs in and expected the sequence to be 1,2,3 however it appears to be 3 (test finished) then 2 and 1. So I suspect a promise issue.
code below:
'use strict';
var request = require('request');
var path = require('path');
var info;
//var fname = null;
var fname = 'joe';
describe("Sample test", function() {
var request = require('request');
var options = {
method: 'GET',
url: 'URL here',
headers: {
'Accept': 'application/json',
'Content-Type': 'application/json'
},
body: '{ "pay_load": [] }'
};
function callback(error, response, body) {
if (!error && response.statusCode == 200) {
info = JSON.parse(body);
console.log('in the callback now');
//console.log('body :' + body);
//var count = Object.keys(info).length;
//console.log('body len:' + count);
//console.log('info :' + info);
fname = info.firstname;
console.log('firstname1 : ' + info.firstname);
console.log('firstname2 : ' + fname);
} else {
console.log('there was some error');
}
}
it("proves the API is alive - firstname is null", function() {
request(options, callback);
//expect(fname).toBe(null);
console.log('firstname3 : ' + fname);
//expect(fname).toBe(null);
//var common = new Common();
//common.checkForAPI();
});
So in my head I thought I would see "in the callback", then "firstname1", "firstname2" and finally "firstname3"
No, firstname3 will always get printed first, the way you have it. The reason for it as that all http requests in nodejs are async, so while your request is processing (or in flight), firstname3 will be printed. Then console.logs in your request callback.
Edit1 - Addressing the comment
Simple example which would print firstname1,2,3 in sequence (tested)
var request = function(cb) {
//basically call your request stuff and then when you are done call cb
console.log('firstname 1');
console.log('firstname 2');
cb();
};
request(function() {
console.log('firstname 3');
});
This prints
firstname 1
firstname 2
firstname 3
Or you can use a third party library called async and use async.tryEach to run tasks in series.
async.tryEach([
function getDataFromFirstWebsite(callback) {
// Try getting the data from the first website
callback(err, data);
},
function getDataFromSecondWebsite(callback) {
// First website failed,
// Try getting the data from the backup website
callback(err, data);
}
],
// optional callback
function(err, results) {
Now do something with the data.
});

How to wait for Rest API to respond in Protractor

I am using following function to call API in my Protractor test, and sometimes API takes time to respond.
var request = require( "superagent" );
var PostUrl = browser.baseUrl + 'rest/1.0/dev/users';
var CreateTenantUrl = browser.baseUrl + 'rest/1.0/tenant';
exports.CreateTenant = function(body){
var data = '{' + body + '}';
request.post(CreateTenantUrl).set('Content-Type', 'application/json').set('serviceSharedSecret', 'sharedsecret').send(data).end(function(err,res){
if(err){
console.log("CreateTenant post error= ", err )
} else{
console.log("CreateTenant post response = ", res.status)
}
expect(res.status).toEqual(200)
});
};
exports.CreateUsers = function(body){
var data = '{' +body + '}';
request.post( PostUrl ).set('Content-Type', 'application/json').send(data).end(function(err,res){
if(err){
console.log("CreateUsers post error= ", err )
} else{
console.log("CreateUsers post response = ", res.status)
}
expect(res.status).toEqual(202)
});
};
Call these functions in test script:
Common.CreateTenant('"tid": "1","long_name": "test tenant"');
Common.CreateUsers('"userName": "test1", "tenantKey": "1", "password": "Test1", "userID": "1"');
is there any way to put wait for each API call to complete and then execute the next one?
If you need your second API call to only fire after the first one completes, send the second API call in the callback method of the first API call.
'Waiting' for an API call to complete is tpyically bad practice. An example of what not to do is the following: send one API call wait 10 seconds, check if first call completed, if it has, send second api call, otherwise wait another 10 seconds and repeat the process.
Its almost always a better approach is to use callbacks where you are alerted when the API call completes.
For your example, you should do the following:
var request = require( "superagent" );
var PostUrl = browser.baseUrl + 'rest/1.0/dev/users';
var CreateTenantUrl = browser.baseUrl + 'rest/1.0/tenant';
exports.CreateTenant = function(body){
var data = '{' + body + '}';
request.post(CreateTenantUrl).set('Content-Type', 'application/json').set('serviceSharedSecret', 'sharedsecret').send(data).end(function(err,res){
if(err){
console.log("CreateTenant post error= ", err )
} else{
console.log("CreateTenant post response = ", res.status)
//Create user once tenant has been successfully created
Commons.CreateUsers('"userName": "test1", "tenantKey": "1", "password": "Test1", "userID": "1"');
}
expect(res.status).toEqual(200)
});
};
exports.CreateUsers = function(body){
var data = '{' +body + '}';
request.post( PostUrl ).set('Content-Type', 'application/json').send(data).end(function(err,res){
if(err){
console.log("CreateUsers post error= ", err )
} else{
console.log("CreateUsers post response = ", res.status)
}
expect(res.status).toEqual(202)
});
};
In order to wait for the request to complete you need to wrap it in a promise. See How to make superagent return a promise for more information

401 when calling WLAuthorizationManager.login("scope")

I have implemented the new MFP 8 Beta security concept. The positive case, with valid credentials is working fine and the processSuccess method that I have defined is executed.
Unfortunately, the negative case doesn’t work.
After calling the WLAuthorizationManager.login("scope"), I am getting a 401 in the console:
2016-05-20 13:48:41.965 Inspector[98311:1660747] [DEBUG] [WL_AFHTTPSessionManagerWrapper_PACKAGE] -[WLAFHTTPSessionManagerWrapper start] in WLAFHTTPSessionManagerWrapper.m:376 :: Starting the request with URL http://172.20.10.4:9080/mfp/api/preauth/v1/preauthorize
2016-05-20 13:48:41.983 Inspector[98311:1655477] [DEBUG] [WL_AFHTTPSessionManagerWrapper_PACKAGE] -[WLAFHTTPSessionManagerWrapper requestFailed:responseObject:error:] in WLAFHTTPSessionManagerWrapper.m:419 :: Request Failed
2016-05-20 13:48:41.984 Inspector[98311:1655477] [DEBUG] [WL_AFHTTPSessionManagerWrapper_PACKAGE] -[WLAFHTTPSessionManagerWrapper requestFailed:responseObject:error:] in WLAFHTTPSessionManagerWrapper.m:422 :: Response Status Code : 401
2016-05-20 13:48:41.984 Inspector[98311:1655477] [DEBUG] [WL_AFHTTPSessionManagerWrapper_PACKAGE] -[WLAFHTTPSessionManagerWrapper requestFailed:responseObject:error:] in WLAFHTTPSessionManagerWrapper.m:424 :: Response Error : Request failed: unauthorized (401)
Here is my implementation:
WLAuthorizationManager.login("UserLogin",{
'username':$scope.username,
'password':$scope.password
}).then( function () {
console.log(">> WLAuthorizationManager.login - onSuccess");
$scope.getInspectorDetails().then(
function(){
$scope.loginInProgress = false;
$state.go("inspectionList");
}
);
},
function (response) {
console.log(">> WLAuthorizationManager.login - onFailure: " + JSON.stringify(response));
$scope.loginInProgress = false;
if (!$scope.loginError){
$scope.loginError = "Could not connect to server. Please try again later.";
}
$scope.$apply();
});
}
And the Challenge handler:
$scope.registerChallengeHandler = function(){
console.log(">> in $scope.registerChllangeHandler ... ");
$scope.userLoginChallengeHandler = WL.Client.createWLChallengeHandler($scope.securityCheckName);
$scope.userLoginChallengeHandler.securityCheckName = $scope.securityCheckName;
$scope.userLoginChallengeHandler.handleChallenge = function(challenge) {
console.log(">> in UserLoginChallengeHandler - userLoginChallengeHandler.handleChallenge ...");
// When a session has expired, this will be our entry point into automatically logging back in
// (since the next server call the user tries to make will end up being flagged as a 'custom response'
// which will trigger the challenge hander. Thus, we need to turn on the progress spinner...
$scope.$apply(function(){
$scope.loginInProgress = true;
});
//show the login ...
$scope.user = { username: "", password: ""};
$scope.currentPath = $location.path();
console.log(">> $location.path(): " + $location.path());
if (!$state.is("login")){
$state.go("login");
}
$scope.isChallenged = true;
var statusMsg = "Remaining Attempts: " + challenge.remainingAttempts;
if (challenge.errorMsg !== null){
statusMsg = statusMsg + "<br/>" + challenge.errorMsg;
$timeout(function(){
//want to show only when submit user/pass not when token expired ...
if($scope.currentPath == "/"){
$scope.loginError = statusMsg;
}
}, 300);
}
console.log(">>> statusMsg : " + statusMsg);
};
$scope.userLoginChallengeHandler.processSuccess = function(data) {
console.log(">> in UserLoginChallengeHandler - userLoginChallengeHandler.processSuccess ...");
$scope.isChallenged = false;
$timeout(function(){
$scope.user = { username: "", password: ""};
}, 200);
$state.transitionTo("inspectionList");
};
$scope.userLoginChallengeHandler.handleFailure = function(error) {
console.log(">> in UserLoginChallengeHandler - userLoginChallengeHandler.handleFailure ...");
console.log(">> handleFailure: " + error.failure);
$scope.isChallenged = false;
if (error.failure !== null){
alert(error.failure);
} else {
alert("Failed to login.");
}
};
}
I would have expected that the handleFailure Method is called, but in the debugger I saw that it is not being executed. After the call of WLAuthorizationManager it just stops, so even the WLAuthorizationManager.login – onFailure is not called.
Edit:
Captured the traffic with Wireshark: https://ibm.box.com/s/7mtwsgea06i4bpdbdz0wvyhy3wpma58r
When using WLAuthorizationManager.login() with wrong credentials, the normal flow is that the challenge handler's handleChallenge will be called, to allow the user to try again.
In some cases, the security check might send a failure, such as "maximum attempt reached". In this case, the challenge handler's handleFailure is called.
WLAuthorizationManager.login() has its own failure scenarios. For example, let's say your server is down, there is no network, the security check does not exist, etc. In those cases, since there is no challenge involved, the login's failure will be called. That's when your then promise will come in handy.

SOAP Request to Wemo switch from Pebble returns status 500

Been trying to write a pebble app for wemo switches, currently this is the code i'm using:
function WemoRequest(callback) {
if (SOAPData === false || SOAPData === undefined) {
console.log("Invalid SOAP data: " + JSON.stringify(SOAPData));
return;
}
var url = "http://192.168.1.230:49153/upnp/control/basicevent1";
try {
var request = new XMLHttpRequest();
request.open("POST", url, false);
request.setRequestHeader("SOAPAction", "urn:Belkin:service:basicevent:1#GetBinaryState");
request.setRequestHeader("Content-Type", "text/xml; charset=utf-8");
request.onreadystatechange = function() {
if (request.readyState == 4 && request.status === 200 && callback) {
callback(request, SOAPData);
}else{console.log("Status: "+request.status + " State: "+request.readyState+" Callback: "+callback);}
};
var packet = '<?xml version="1.0" encoding="utf-8"?>'+
'<s:Envelope xmls:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">'+
'<s:Body>'+
'<u:GetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"></u:GetBinaryState>'+
'</s:Body>'+
'</s:Envelope>';
request.send(packet);
} catch (error) {
console.log("Error in XMLHttpRequest: " + error);
}}
I currently get status 500 from OnReadyStateChange and have no idea what I'm doing wrong. If this isn't enough code, app code is available here:https://github.com/dmf444/Webble
So...I know this is from 4 years ago lol, but I found this during a google search and just found the answer, so I figured I would respond for that reason: I think your header just needs an extra set of quotes around "urn:Belkin:service:basicevent:1#SetBinaryState" so that the string specifying the soapaction literally starts and ends with quotes.
I'm working in Python (because that's what all the kids seem to be doing these days), but I too was getting the 500 error until I made a very subtle change (the single quote marks around my double quotes) and almost cried tears of joy when my light turned off:
"SOAPACTION": '"urn:Belkin:service:basicevent:1#SetBinaryState"'
So here's the working version of the code (in Python lol):
import http.client
#Variables (value=on/off, ipaddress=address of your wemo)
value = 0 #1=ON, 0=OFF
ipAddress = "192.168.0.108"
#Build the SOAP Envelope (data)
data = '<?xml version="1.0" encoding="utf-8"?><s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/" s:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"><s:Body><u:SetBinaryState xmlns:u="urn:Belkin:service:basicevent:1"><BinaryState>' + str(value) + '</BinaryState></u:SetBinaryState></s:Body></s:Envelope>'
#Build the Header (headers)
headers = {"Content-type" : 'text/xml; charset="utf-8"', "SOAPACTION": '"urn:Belkin:service:basicevent:1#SetBinaryState"', "Content-Length": len(data)}
#Send request and check response data (resp_data)
conn = http.client.HTTPConnection(ipAddress, 49153)
conn.request("POST", "/upnp/control/basicevent1", data, headers)
response = conn.getresponse()
resp_data = response.read()
if response.status == 200:
conn.close()
print("SUCCESS!")
elif response.status == 403:
print("ERROR: 403 (FORBIDDEN)")
else:
print("ERROR: " + str(response.status))