Postman conditional tests if json body array is empty = skip tests - javascript

I want to integrate Postman/ Newman API tests into CICD, so the test results should always be passed (or skipped). Therefor I want to use conditional tests, dependent on the data of the response.
I tried the method described on GitHub, but the condition in my case is very different.
So if the json body of the response contains an empty array, tests should be skipped. If not, perform tests...
Empty data
{
"data": []
}
Testable data
{
"data": [
{
"key1": "value1",
"key2": {
"amount": 1357,
"unit": "units"
},
"from": "2019-08-01",
"to": "2019-08-31",
}
]
}
Test script
let response = JSON.parse(responseBody);
pm.test("Status code is 200", function() {
pm.expect(pm.response.code).to.equal(200);
});
(pm.expect(pm.response.json().data).to.be.empty === true ? pm.test.skip : pm.test)('Body is empty', function () {
pm.environment.set("key2Amount", response.data[0].key2.amount);
var key2Amount = pm.environment.get("key2Amount");
pm.test("Response includes corresponding amount", function () {
pm.expect(pm.response.json().data[0].key2.amount).to.eql(key2Amount);
});
});
Empty data: TypeError: Cannot read property 'key2' of undefined.
Testable data: AssertionError: expected [ Array(1) ] to be empty.
I've also tried it with
(pm.expect([]).to.be.an('array').that.is.empty ? pm.test : pm.test.skip)
Testable data: Tests performed positive.
Empty data: TypeError: Cannot read property 'key2' of undefined. Why not skipped?
Further
(pm.expect([]).to.be.empty ? pm.test.skip : pm.test)
Empty data: skipped tests
Testable data: skipped tests
What would be the correct condition on the array to make the tests run or skipped?

Could you use something like this:
let response = pm.response.json();
pm.test("Status code is 200", function() {
pm.expect(pm.response.code).to.equal(200);
});
let skipTest = (response.data === undefined || response.data.length === 0);
(skipTest ? pm.test.skip : pm.test)('Body is empty', function () {
pm.environment.set("key2Amount", response.data[0].key2.amount);
pm.test("Response includes corresponding amount", function () {
pm.expect(response.data[0].key2.amount).to.eql(pm.environment.get("key2Amount"));
});
});

Related

cause of TypeError: Cannot read properties of undefined

I'm trying to fetch some data from an API. The below code "works" when I log the results to console like console.log(liveInfo.tracks), but when I try to do console.log(liveInfo.tracks.current) it fails with this error: TypeError: Cannot read properties of undefined (reading 'current'). Isn't liveInfo.tracks.current how one would normally access the key-value pair?
componentDidMount() {
fetch('https://kchungradio.airtime.pro/api/live-info-v2')
.then(res => res.json())
.then(
(result) => {
this.setState({
isLoaded: true,
liveInfo: result
})
}
)
}
The json looks more or less like this:
{
"station": {
"env": "production",
},
"tracks": {
"previous": {
"name": "a",
"metadata": {
"id": 1,
},
},
"current": {
"name": "b",
"metadata": {
"id": 2,
}
}
}
}
Because at some point liveInfo.tracks was undefined
Although there is a lack of hints, a common mistake when fetching data from lifecycle is trying to retrieve the value through the state before setData occurs.
Before you use liveInfo, make sure that data fetching is finished
like this
class SomeComponent = {
render() {
if(!this.state.liveInfo?.tracks?.current) return null
....
}
}
It looks you are trying to access to the current before it is filled on the componentDidMount, it means before the fetch has been performed. I suggest you to initialize the state like this:
state = {
isLoaded: false,
liveInfo: {
tracks: {
curent: {}
}
}
};
So you will be able to access the current property inside tracks without facing the TypeError. I made a codesandbox, so you can check an example there.
If this does not solve your problem, please let me know ;)
Your call looks right,
another way to get the value is console.log(liveInfo.tracks["current"]);
but I think your tracks has no value at runtime. Maybe you can show us more code where you are call console.log.
Maybe you run twice in your statement and at first time it is undefined and throw the error. So add a null check like this console.log(liveInfo?.tracks?.current);
Use Question mark (?)
? will check for null. If your object is null ? will handle it.
liveInfo?.tracks?.current
this is the right approach.
Further -
liveInfo?.tracks?.current?.metadata

Uncaught TypeError: b.toLowerCase is not a function

I am fetching some records :
$companies = \App\User::where('type', 'pet-salon')->orWhere('type', 'veterinarian')->get();
return response()->json($companies);
The data coming back is an array of objects:
[{
id: 2,
type: "xxx",
deactivate: 0,
xxx: "Hello",
middle_name: "Mid",
lastname: "xxx",
//...
}]
This is the jQuery typeahead code:
$('#getCompaniesForConnection').typeahead({
source: function (query, process) {
return $.get('/all/companies', { query: query }, function (data) {
return process(data);
});
}
});
The exception its giving me :
Uncaught TypeError: b.toLowerCase is not a function
And the results drop-down is not showing too, What am i missing here ?
Yes, you need to json_encode your companies.
$companies = \App\User::where('type', 'pet-salon')->orWhere('type',
'veterinarian')->get();
$result = json_encode($companies ); // return this or echo
First, the PHP code looks like it's a laravel code, so you can just return the $companies variable like so:
$companies = \App\User::where('type', 'pet-salon')->orWhere('type', 'veterinarian')->get();
return $companies;
Since models and collections are converted to JSON when cast to a string, you can return Eloquent objects directly from your application's routes or controllers.
And also, let's see the definition of the process function to be sure that's not where the error is coming from.

filter JSON response by javascript object property value

I'm currently pulling the below response outputs; I am trying to create 2 simple filters, so that only 'healthyMeals' that pass these 2 filters, will display, or output.
Current working output (before 2 filter):
{
"healthyMeals" : [
{
"id": 310,
"avRating": 2.2,
"name": "Peanut butter soup",
"expireDate": "12-02-2017",
"difficulty": "easy",
"reviews": 999
},
Attempt (trying to add 2 filters).
this.getHealthy = function(res, req) {
var checkReview;
var checkRating;
function checkRating() {
if (averageRating > 4.1){
res.res.json({
"message" : "pass",
});
}
else {
res.res.json({
"message" : "Could not find meal",
});
}
};
function checkReview() {
if (reviews >= 5){
res.res.json({
"message" : "pass",
});
}
else {
res.res.json({
"message" : "Could not find meal",
});
}
};
db.Meals.findAll({
where: {
id : givenId,
// averageRating : checkRating(),
// reviews : checkReview()
}
})
The above two properties with comments, breaks app and doesn't work when uncommented out.
How could I loop through all healthyMeals property values of 'averageRating' and 'reviews' and if they pass the 2 filter tests, then, and only then display? If not message 'Not found' displays.
You have declared your variables as checkReview and checkRating (which are also same as your function names) but you are using averageRating and reviews. You should declare the below variables:
var averageRating,
reviews;

How to store values from an array consisting of 2 elements from a system response in Postman test script

I am trying the below code to store the token for "TokenType": "UserAccount"into a variable but it doesn't seem to work.Please help.
My Code:
if (responseCode.code === 200) {
try {
var tokenValue = JSON.parse(responseBody);
} catch (e) {
if (e) {
console.log(e);
}
}
}
postman.setGlobalVariable("Acc_Token", tokenValue[0].value);
Array consisting of token values:
"value": [
{
"Expires": "2017-09-05T05:07:11.0778675Z",
"IsRefreshable": false,
"Token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJhdWQiOiJodHRwOi8vcWEubWFzc2l2ZWF4aXMuY29tL0lTTC9BcGkvVjEvRGF0YXNlcnZpY2UiLCJzdWIiOiJTZXR0aW5ncyIsImV4cCI6MTUwNDU4ODAzMSwidXNlckFjY291bnRJZCI6Ijg5MjRkMzFkLWFhYjktNDkzYy05N2NlLWRkMTc5NzQyNGE3ZSIsInVzZXJQcm9maWxlSWQiOiIyY2YyZWEyNC01NTRmLTQzYzktYjA1NS1hMjM2NGVjYWY0ZjkiLCJlbWFpbCI6ImFwYXJuYTExNEBtYXNzaXZlLmNvbS5hdSIsImRldmljZSI6IndlYl9icm93c2VyIiwidmFsaWRVbnRpbCI6MTUzNjEyMzQzMSwic3Vic2NyaXB0aW9uIjoiUmVnaXN0ZXJlZCJ9.J7CT2nCrnNOxQI4kHyyIVt4ASfd6dl_ZNnAO5azZ5p49w3fa-B2FTGYmiC8A8S4aACt6g4MGKjqfEn8X7vBofxEnL9DcfSDK4ZTqZ2J-XTVGSVafAp6YU05DMlpUFYNdDjx8b2eRJhvCH2NR3zaD68fiemezbYBzxw_J35i01tOL6H8odSgvhxwAKfONWhH04_nm2P1PUue0EKtcdvz7FAKcwpF9EOjxCXVMwmfQOH8C2FD91s94_p-q4l0MW3Y2Vonlw-q2nzK5ZN17F38wQOyvnjGeeQFBxa1bYkj3h3qnhy1Z80Ka6Gcpk5dbEbfYT5DU4zqXM4uIZHQzzivo2g",
"TokenType": "UserAccount"
},
{
"Expires": "2017-09-05T05:07:11.0828684Z",
"IsRefreshable": false,
"Token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzUxMiJ9.eyJhdWQiOiJodHRwOi8vcWEubWFzc2l2ZWF4aXMuY29tL0lTTC9BcGkvVjEvRGF0YXNlcnZpY2UiLCJzdWIiOiJTZXR0aW5ncyIsImV4cCI6MTUwNDU4ODAzMSwidXNlckFjY291bnRJZCI6Ijg5MjRkMzFkLWFhYjktNDkzYy05N2NlLWRkMTc5NzQyNGE3ZSIsImRlZmF1bHRVc2VyUHJvZmlsZUlkIjoiMmNmMmVhMjQtNTU0Zi00M2M5LWIwNTUtYTIzNjRlY2FmNGY5IiwidXNlclByb2ZpbGVJZCI6IjJjZjJlYTI0LTU1NGYtNDNjOS1iMDU1LWEyMzY0ZWNhZjRmOSIsImVtYWlsIjoiYXBhcm5hMTE0QG1hc3NpdmUuY29tLmF1IiwiZmlyc3RMb2dpbkRhdGUiOjE1MDQ1ODYxNjcsImxhc3RMb2dpbkRhdGUiOjE1MDQ1ODc0MTEsInNlc3Npb25EYXRlIjoxNTA0NTg3NDMxLCJzZXNzaW9uQ291bnQiOjcsImRldmljZSI6IndlYl9icm93c2VyIn0.JoaEijd6baSsHiVofeP3jUowJxp91SDcFb4zANj_ZnR0gHpp2yqCBQD4zh22maB7Yp4m5TD8jkfOuj9id2TD0N6pCa8Y9fXNQGAnZy963XrwnRz14AEfg954AGeAHSw6_qQGxh-xlc63rlsn62gnmZ0yPZZDHHbjYngJKsr8Kv_5qBNjZ9TX2y8H0PAm_STkw5PXqaCjtfMFPVyGFvDpVzx2wj1mMwnAS7V6Ftnr1-flaIjRmGXv0XQiND-uzxEZa8wjfLOEbayNS1IgbBRuiixaOKUvul14FwxasdojnZ5UOB5R_I4OUzp6WjWTax2rjbvIXxdlj0iyLeL7WD6egQ",
"TokenType": "UserProfile"
}
]
Error:
There was an error in evaluating the test script: TypeError: Cannot read property 'value' of undefined
Your value property is not in the first item. It is in the object itself
Accessing via tokenValue.value[0] will give you that object which has "TokenType": "UserAccount".
And also move your postman.setGlobalVariable into the if statement.

how to access json data contained in a GET response

Continuing yesterday's saga, now I can retrieve json objects in a response but I can't extract the data from them.
The following node.js snippet is from the file "accounts.js" which is in an ETrade api library that exists in the path /lib. It returns json containing data about the accounts of the authenticated user. The authentication part is working great.
exports.listAccounts = function(successCallback,errorCallback)
{
var actionDescriptor = {
method : "GET",
module : "accounts",
action : "accountlist",
useJSON: true,
};
this._run(actionDescriptor,{},successCallback,errorCallback);
};
The ETrade website says this call will produce the following sample response:
{
"AccountListResponse": {
"Account": [
{
"accountDesc": "MyAccount-1",
"accountId": "83405188",
"marginLevel": "MARGIN",
"netAccountValue": "9999871.82",
"registrationType": "INDIVIDUAL"
},
{
"accountDesc": "MyAccount-3",
"accountId": "83405553",
"marginLevel": "CASH",
"netAccountValue": "100105468.99",
"registrationType": "INDIVIDUAL"
},
{
"accountDesc": "SIMPLE IRA",
"accountId": "83405188",
"marginLevel": "CASH",
"netAccountValue": "99794.13",
"registrationType": "IRA"
}
]
}
}
In my app.js file, I have the following:
var etrade = require('./lib/etrade');
var et = new etrade(configuration);
et.listAccounts(
function(res){
var listAccountsRes = res;
console.log('account list success!');
console.log(listAccountsRes)
},
function(error) {
console.log("Error encountered while attempting " +
"to retrieve account list: " +
error);
});
When I run this code, the console log shows the following message:
{ 'json.accountListResponse':
{ response:
[ [Object],
[ [Object],
[ [Object],
[ [Object],
[ [Object],
[ [Object],
[ [Object],
[ [Object] ] } }
Suppose in app.js I want to put the accounts data in a variable called myAccounts.
One of our members, Jack, solved yesterday's problem and when I commented that I still couldn't access the data in the response, he suggested this: "That property has a dot in it so you'll have to use [ ... ] rather than dot notation to access it. See what's inside the objects with a['json.accountListResponse'].response." So far I have not been able to get that to work, even when I use ['json.accountListResponse'].res like this:
var listAccountsRes = [json.accountListResponse].res;
This returns undefined when printed to the console.
Thanks to Adam for his suggestion which led to this which works:
var listAccountsRes = res['json.accountListResponse'];
var listAccounts = listAccountsRes['response'];
console.log('account list success!');
console.log(listAccounts)
Now the console log reports almost exactly what ETrade says I should get. (They appear to have changed the name "Account" to "response"). I presume my variable listAccounts now contains the json with eight sample accounts in it that I can see in my console log. But I still don't know how to access individual elements. There should be some simple code that will iterate over the json file and produce an array of arrays that I could actually use for something. I tried accessing it like an array: console.log(listAccounts[0]) but that returns undefined. Do I need to stringify it or something?

Categories