Iterate through dynamic array and re-use values in next request - karate

I would like to do the following:
Send a request to a server and retrieve details of animals available in a petstore.
post /getAnimalStatus response:
"animals": [
{
"animalId": "567839",
"gender": "Female",
"age": 2,
"isEligibleAsPet": true,
"animalStatus": "AVAILABLE"
},
{
"animalId": "648562",
"gender": "Male",
"age": 3,
"isEligibleAsPet": true,
"animalStatus": "AVAILABLE"
},
{
"animalId": "965895",
"gender": "Female",
"age": 5,
"isEligibleAsPet": false,
"animalStatus": "UNAVAILABLE"
}
]
}
I would then like to:
Search for all animals which are UNAVAILABLE in the response and store the array value in a variable.
Send a request to a server to update all unavailable animals' statuses to 'AVAILABLE'
This request will be formatted as below where we are using the array value from the response above in the animal object below.:
put /updateAnimals
"animal": {
"animalId": "965895",
"gender": "Female",
"age": 5,
"isEligibleAsPet": false,
"animalStatus": "UNAVAILABLE"
},
"updateStatus": "AVAILABLE"
}

use JsonPath (or karate.filter()) to do it: https://github.com/intuit/karate#jsonpath-filters
use a second feature file and call to iterate: https://github.com/intuit/karate#data-driven-features
Also look at this answer for ideas: https://stackoverflow.com/a/60358697/143475
Please ask a more specific question to get a more specific answer.

Related

Querying using query parameters in Postman

As a beginner to Postman, I am trying to use Query Parameters to search via filtering by keys. COnsider the following content of a certain endpoint.
[
{
"id": 1,
"name": "The Russian",
"type": "fiction",
"available": true
},
{
"id": 2,
"name": "Just as I Am",
"type": "non-fiction",
"available": false
}
]
1st scenario :
Doing a GET on the endpoint with the syntax {{baseURL}}/books?type=fiction, I get
[
{
"id": 1,
"name": "The Russian",
"type": "fiction",
"available": true
}
]
which is correct.
2nd scenario :
Doing a GET on the endpoint with the syntax {{baseURL}}/books?id=1, I get
[
{
"id": 1,
"name": "The Russian",
"type": "fiction",
"available": true
},
{
"id": 2,
"name": "Just as I Am",
"type": "non-fiction",
"available": false
}
]
which is not filtering by id = 1. It display id = 2 item as well. I was expecting it to show item base on id = 1 only.
AM I missing anything in understanding on how to use the query parameters ?

Get the value from the response based on a condition and store it to a variable

I would like to get the value from the response based on a condition and store it to a variable.
In the below JSON, I would like to store the value when the name matches to something I prefer. Is there a way to achieve this using Karate API?
{
"results": [
{
"name": "Sample1",
"email": "sample1#text.com",
"id": "U-123"
},
{
"name": "Sample2",
"email": "sample2#text.com",
"id": "U-456"
},
{
"name": "Sample3",
"email": "sample3#text.com",
"id": "U-789"
}
]
}
So after reading the comment, my interpretation is to "find" the id where name is Sample2. Easy, just use a filter() operation, refer the docs: https://github.com/karatelabs/karate#jsonpath-filters
Instead of using a filter, I'm using the JS Array find() method as a very concise example below:
* def response =
"""
{ "results": [
{ "name": "Sample1", "email": "sample1#text.com", "id": "U-123" },
{ "name": "Sample2", "email": "sample2#text.com", "id": "U-456" },
{ "name": "Sample3", "email": "sample3#text.com", "id": "U-789" }
]
}
"""
* def id = response.results.find(x => x.name == 'Sample2').id
* match id == 'U-456'
Take some time to understand how it works. Talk to someone who knows JS if needed.

Get all API fields definitions from Podio application

Responses from Podio API returns an JSON array of items with a fields property. Each field carries its values and its config.
For example a category field for the Gender:
{
"type": "category",
"field_id": 219922852,
"label": "Gender",
"values": [
{
"value": {
"status": "active",
"text": "Prefer not to say",
"id": 3,
"color": "F7F0C5"
}
}
],
"config": {
"settings": {
"multiple": true,
"options": [
{
"status": "active",
"text": "Male",
"id": 1,
"color": "DCEBD8"
},
{
"status": "active",
"text": "Female",
"id": 2,
"color": "F7F0C5"
},
{
"status": "active",
"text": "Prefer not to say",
"id": 3,
"color": "F7F0C5"
}
],
"display": "inline"
},
"mapping": null,
"label": "Gender"
},
"external_id": "gender"
},
How can I fetch the config without having to query a specific item?
Is there a way to get every field in the response? Because if the queried item does not have a field value set, Podio doesn't return it in the response.
I would like to get the field config for ALL the fields. If possible, with a single API request. In particular I am interested in all the possible values (in case of Category or Relationship fields) so that I could match them with local values I have.
This way I can use the field structure to programmatically map some local values to the format required by the Podio API; and then generate a fields payload that to update/create Podio items via an API calls.
You can request the Podio Get App method to get the app configuration.
Podio Doc Ref: https://developers.podio.com/doc/applications/get-app-22349

Inserting and removing values within a collection array

I'm new to working with MongoDb using Express. I currently have a collection that has an array within an object. The array is meant to hold an unlimited number of values.
My question is when I add a new item to that array in the collection, do I always have to pass all the values in the object?
For example, with the following collection. Say I wanted to add a new contact.
{
"owner": "Tom Smith",
"age": "29",
"contacts": [
{
"firstname": "Fred",
"lastname": "Anderson",
"age": "22"
},
{
"firstname": "Linda",
"lastname": "Smith",
"age": "32"
},
{
"firstname": "Tom",
"lastname": "James",
"age": "42"
},
{
"firstname": "Cal",
"lastname": "Hallaway",
"age": "57"
}
],
"city": "New York"
}
Do I need to explicitly declare all my values in the object I pass to the end point?
Example:
obj.owner = 'Tom Smith';
obj.age = '29';
obj.contacts.firstname = 'Fred';
obj.contacts.lastname = 'Anderson';
obj.contacts.age = '22';
... etc.
and then add my new contact and push the full object to the endpoint to update?
Is there a way that I can just add a new contact without pushing all the data that already exists in the collection?
To add a new data in a nested attribute array:
Model.findOneAndUpdate({
_id: 'THE ID OF YOUR GYUS'
}, {
$push: {
contacts: {
firstname: 'TOTO',
lastname: 'TITI',
age: 42,
},
},
});

Is it possible to extend graphql response other than just data for pagination?

In GraphQL response normally looks like followings.
{
"data": [{
"id": 1,
"username": "Jon Snow",
"email": "crow#northofthew.all",
"age": 20
}, {
"id": 2,
"username": "Tyrion Lannister",
"email": "drunk#i.mp",
"age": 34
}, {
"id": 3,
"username": "Sansa Stark",
"email": "redhead#why.me",
"age": 17
}]
}
Is it possible to add meta data to your response such as pagination like this.
{
"pagination": {
"total": 14,
"count": 230,
},
"data": [{
"id": 1,
"username": "Jon Snow",
"email": "crow#northofthew.all",
"age": 20
}, {
"id": 2,
"username": "Tyrion Lannister",
"email": "drunk#i.mp",
"age": 34
}]
}
I'm using express-graphql and currently put those pagination to custom response header, which is fine but it can be better. Since GraphQL response is already wrapped with "data", it is not very strange to add more "data" to its response.
Reenforcing what #CommonsWare already stated, according to the specification that would a be an invalid GraphQL response. Regarding pagination, Relay has its own pagination approach called connections, but indeed, several other approaches are possible and even more suitable in some situtations (connections aren't a silver bullet).
I want to augment what was already said by adding that the hierarchical nature of GraphQL incites related data to be at the same level. An example is worth a thousands words, so here it goes:
query Q {
pagination_info { # what is this info related to? completely unclear
total
count
}
user {
friends {
id
}
}
}
Instead...
query Q {
user {
friends {
pagination_info { # fairly obvious that this is related to friends
total
count
}
friend {
id
}
}
}
}