I have a scenario to validate the "status" value in the array. The response is dynamic and # iteration may vary. I don't want to save this value in my postman environment but need to make a dynamic check. From my below API Response, I got 2 instances, 1st with AVAILABLE, 2nd with SOLDOUT. Can someone suggest to me how do I make the comparison?
Response API:
[
{
"status": "AVAILABLE",
"price": {
"baseAveragePrice": 209,
"discountedAveragePrice": 209
},
"Fee": 39,
"flag": false
},
{
"status": "SOLDOUT",
"price": {
"baseAveragePrice": 209,
"discountedAveragePrice": 209
},
"Fee": 39,
"flag": true
},
]
pm.test("status Check", function () {
var jsonData = pm.response.json();
pm.expect(jsonData.status).to.be.oneOf(["AVAILABLE", "SOLDOUT", "NOTRELEASED"]);
});
If you're trying to check all of the status value in the response, you could iterate through them like this:
pm.test("status Check", function () {
var jsonData = pm.response.json();
_.each(jsonData, (arrItem) => {
pm.expect(arrItem.status).to.be.oneOf(["AVAILABLE", "SOLDOUT", "NOTRELEASED"]);
})
});
Your snippet is actually working for one single element.
Your current response is a JSON-array. So you need to iterate your check over the whole array.
One solution ist this:
pm.test("status Check", function() {
var jsonData = pm.response.json();
jsonData.forEach(function(arrayElement) {
pm.expect(arrayElement.status).to.be.oneOf(["AVAILABLE", "SOLDOUT", "NOTRELEASED"]);
});
});
This will return one single Test "status Check" with OK, if all of them are ok, and with FAILED if one of them fails.
If you want to see more details in your test-result, i would suggest to add each one of them in one nested test. With this solution you will have 3 Tests. One general Test "status Check" and one test for each Array item (in this case 2):
pm.test("status Check", function() {
var jsonData = pm.response.json();
jsonData.forEach(function(arrayElement) {
pm.test("Status is either 'AVAILABLE','SOLDOUT' or 'NOTRELEASED'", function() {
pm.expect(arrayElement.status).to.be.oneOf(["AVAILABLE", "SOLDOUT", "NOTRELEASED"]);
});
});
});
Related
I m trying to set a global variable from a response JSON. Here is the response:
[
{
"memberDetails": [
{
"MemberId": "37e32af1-99a1-49b1-441d-08d9c636b242",
"AccountId": "9c8041df-6bf4-404e-9360-690280d627dc",
"Status": 1
}
]
}
]
The code I am using under tests
pm.test("Verify Response code", function() {
pm.response.to.have.status(data.ExpectedResult)
});
var jsonData = pm.response.json();
if(pm.response.code === 200) {
pm.test("Verify MemberId is present when response code is 200", function() {
pm.expect(jsonData).to.have.property("MemberId")
postman.setGlobalVariable("SedMemberId", jsonData['MemberId'])
});
}else{
pm.test("Verify MemberID is not present when response code is not 200", function() {
pm.expect(jsonData).to.not.have.property("MemberId");
});
}
But I am getting the following two errors:
Verify Response code | AssertionError: expected response to have status reason undefined but got 'OK'
Verify MemberId is present when response code is 200 | AssertionError: expected [ { memberDetails: [ [Object] ] } ] to have property 'MemberId'
How do I set the global variable "SedMemberID" with value "MemberID" in the response JSON.
You're not referencing the response data correctly:
pm.globals.set('sedMemberId', jsonData[0].memberDetails[0].MemberId);
You might need to take a look at how to reference different object items of JSON structures when they contain arrays.
Not sure what data.expectedResult is but it's not going to be defined unless you use a datafile. Even then, you should be using pm.iterationData.get('key_name').
I have 2 API requests. 1st one is GET, that returns a response. This response is used as a Body/Payload in the 2nd request (POST). BUT the Payload should have certain values to be replaced before used in the 2nd request (in my case below it should be value for "Status" property).
How can I do it?
Here is my example Response:
{
"Variations":[
{
"ItemIds":[
"xxx"
],
"Items":[
{
"Id":"67-V1",
"GuId":"xxx",
"Type":"Unit",
"Status":"Active"
}
],
"Name":"VAR 1",
"Id":"67-V1"
},
{
"ItemIds":[
"yyy"
],
"Items":[
{
"Id":"67-V2",
"GuId":"yyy",
"Type":"Unit",
"Status":"Active"
}
],
"Name":"VAR 2",
"Id":"67-V2"
},
{
"ItemIds":[
"zzz"
],
"Items":[
{
"Id":"67-V3",
"GuId":"zzz",
"Type":"Unit",
"Status":"Active"
}
],
"Name":"VAR 3",
"Id":"67-V3"
}
],
"ItemIds":[
],
"Items":[
],
"Name":"MAINP",
"Id":"67",
"Color":null
}
Here is my code, but it does not seem to work (the replacement part):
var jsonData = pm.response.json();
function replaceStatus() {
_.each(jsonData.Variations, (arrayItem) => {
if(arrayItem.Items.Status !== "NonActive") {
arrayItem.Items.Status == "NonActive";
console.log("arrayItem " + arrayItem);
}
});
}
pm.test("Run Function", replaceStatus ());
pm.sendRequest({
url: 'localhost:3000/post',
method: 'POST',
headers: {
"Content-Type": "application/json"
},
body: {
mode: 'raw',
raw: JSON.stringify(jsonData)
}
}, (err, res) => {
console.log(res)
})
I guess you are trying to replace all NonActive values with Active. In that case, you should use = for assignment not ==. The JSON file you provided is not valid and couldn't run your code on my machine. I am happy to have a closer look if that didn't work
Based on your updates these changes need to be made
1- in order to deal with JSON object you need to parse the response as it is string and you can't call sth like JsonData.Variations on that.make sure jsonData is a JSON object. if not add sth like this to parse it
var parsedJson = JSON.parse(jsonData)
2- It seems that you missed one array layer in your function to iterate over items. As you have two nested arrays to reach Status the replaceStatus function should be as below
function replaceStatus() {
_.each(parsedJson.Variations, (arrayItem) => {
_.each(arrayItem.Items, (item) => {
if(item.Status !== "NonActive") {
item.Status = "NonActive";
console.log("arrayItem " + item.Status);
}
});
});
}
Have you posted your entire code in the tests section or only a part of it?
I saw from one of your comments that you cannot see the output logged to the console.
This may be very trivial, but, if you did post your entire code, it looks like you may have forgotten to call your replaceStatus() function before your post call.
I wanted to check from the response format if status=AVAILABLE then arrayElement should return with roomTypeId else roomTypeId should not return for other status.
[
{
"status": "SOLDOUT",
"propertyId": "dc00e77f",
"Fee": 0,
"isComp": false
},
{
"roomTypeId": "c5730b9e",
"status": "AVAILABLE",
"propertyId": "dc00e77f",
"price": {
"baseAveragePrice": 104.71,
"discountedAveragePrice": 86.33
},
"Fee": 37,
"isComp": false
},
]
[
{
"status": "SOLDOUT",
"propertyId": "773000cc-468a-4d86-a38f-7ae78ecfa6aa",
"resortFee": 0,
"isComp": false
},
{
"roomTypeId": "c5730b9e-78d1-4c1c-a429-06ae279e6d4d",
"status": "AVAILABLE",
"propertyId": "dc00e77f-d6bb-4dd7-a8ea-dc33ee9675ad",
"price": {
"baseAveragePrice": 104.71,
"discountedAveragePrice": 86.33
},
"resortFee": 37,
"isComp": false
},
]
I tried to check this from below;
pm.test("Verify if Status is SOLDOUT, roomTypeId and price information is not returned ", () => {
var jsonData = pm.response.json();
jsonData.forEach(function(arrayElement) {
if (arrayElement.status == "SOLDOUT")
{
pm.expect(arrayElement).to.not.include("roomTypeId");
}
else if (arrayElement.status == "AVAILABLE")
{
pm.expect(arrayElement).to.include("roomTypeId");
}
});
});
You need to check if the property exists or not.
With the have.property syntax you can do that.
You can read the Postman API reference docs and also Postman uses a fork of chai internally, so ChaiJS docs should also help you.
Updated script:
pm.test("Verify if Status is SOLDOUT, roomTypeId and price information is not returned ", () => {
var jsonData = pm.response.json();
jsonData.forEach(function(arrayElement) {
if (arrayElement.status === "SOLDOUT") {
pm.expect(arrayElement).to.not.have.property("roomTypeId");
} else if (arrayElement.status === "AVAILABLE") {
pm.expect(arrayElement).to.have.property("roomTypeId");
}
});
});
I'm using Ember.js (v1.2.0) with an API which returns paginated JSON data like this:
{
"count": 5,
"next": "http://127.0.0.1:8000/some/resource/?page=2",
"previous": null,
"results": [
{
"id": 37,
"title": "Some title",
"description": "Some description",
},
{
"id": 35,
"title": "Sdflskdf",
"description": "sdfkdsjf",
},
{
"id": 34,
"title": "Some other title",
"description": "Dsdlfksdf",
},
]
}
I'm not using ember-data, so I'm using a plain ember object as my model and loading the data like this:
App.SomeResource = Ember.Object.extend({});
App.SomeResource.reopenClass({
find: function () {
return $.getJSON('/some/resource/').then(function (response) {
return response.results.map(function (data) {
return App.SomeResource.create(data);
});
});
},
});
The find method on my model class returns a promise which resolves to an array of objects. While creates SomeResource objects, all the pagination data is lost.
Is there a way to store count, next and previous page urls somewhere when the promise resolves?
I am assigning them to global object but you should do better.
App.SomeResource = Ember.Object.extend({});
App.SomeResource.reopenClass({
find: function () {
return $.getJSON('/some/resource/').then(function (response) {
return RSVP.all(response.results.map(function (data) {
return App.SomeResource.create(data);
})).then(function(createdResources) {
window.count = response.count;
window.next = response.next;
window.previous = response.previous;
return createdResources;
});
});
}
});
Rather than storing this metadata on the global window object, I came up with this:
App.SomeResource.reopenClass({
find: function () {
var url = '/some/resource/';
return Ember.$.getJSON(url).then(function (response) {
response.results = response.results.map(function (resource) {
return App.SomeResource.create(resource);
});
return response;
});
},
});
SomeResource.find() just instantiates Ember objects from the results array and then returns the response with the rest of the data untouched. The route then receives the response and sets up the pagination data and the model in the setupController function:
App.SomeResourceRoute = Ember.Route.extend({
model: function () {
return App.SomeResource.find();
},
setupController: function(controller, model) {
controller.setProperties({count: model.count,
pageCount: model.page_count,
currentPage: model.current_page,
pageRange: model.page_range,
previous: model.previous,
next: model.next,
model: model.results,});
},
});
It works, but maybe there is a better way.
My code is quite simple (Client Side):
Record.Router.map(function () {
this.resource('main', { path: '/' });
});
Record.MainRoute = Ember.Route.extend({
model: function () {
var response = Record.Rank.find();
console.log(response.get('name'));
console.log(response);
return Record.Rank.find();
}
});
My model:
Record.Rank = DS.Model.extend({
id: DS.attr('integer'),
rank: DS.attr('integer'),
content: DS.attr('string')
});
I use RESTadapter:
Record.Store = DS.Store.extend({
revision: 12,
adapter: DS.RESTAdapter.reopen({
namespace: 'recordApp'
})
});
My Server side code (PHP):
<?php
namespace RecordContainer;
echo '{"rank":
{
"id": "1",
"rank": "2",
"content": "walla"
}
}';
I expect to something after I issue Record.Rank.find() but my console.log(response.get('name')) logs undefined and the second console.log(response) show the following, no information about echo from server inside:
How do I see the response from the server, in Ember?
1st: Calling find on a DS.Model without any parameters, i.e. Record.Rank.find(), is equivalent to sending a findAll() request to your server. In other words, it should fetch all Record.Rank. Therefore ember-data expects an array in the response of the format:
{
"ranks":[
{
"id": "1",
"rank": "2",
"content": "walla"
},
{
"id": "2",
"rank": "5",
"content": "foo"
}
]
}
2nd: Even if the response from the PHP was correct (as described above), console.log(response.get('name')); would probably return undefined since the request is not yet completed and the record(s) are not available. If you really want to access the records loaded into the store you need to place your code into a Promise resolve callback:
Record.MainRoute = Ember.Route.extend({
model: function () {
var response = Record.Rank.find();
response.then(function(ranks) {
console.log(ranks.getEach('name'));
});
return response;
}
});