How to parse below JSON response using Karate API - karate

Can anyone to how to part below response in Karate API
Here I want to extract partNumber and productTitle from the response, where initial numeric number in the response is dynamic nature, for every get method the number changes.
{"items":{'41651625424': {itemCore: {partNumber: '1234567', productTitle: 'Karate API Testing'}}}}

There are multiple ways, but in this case, the best option to me is to use JsonPath:
* def response = { "items": { '41651625424': { itemCore: { partNumber: '1234567', productTitle: 'Karate API Testing' }}}}
* def itemCore = get[0] response..itemCore
* match itemCore == { partNumber: '1234567', productTitle: 'Karate API Testing' }
Refer to the documentation: https://github.com/intuit/karate#get-plus-index

Related

django rest pagination on api view decorator

im trying to do pagination on my django rest code, but i get the same code when i change the number of the page, this is what im doing to get that page: http://localhost:8000/movies?page=3
When i change the page number i get the same response, idk if i have to send the number of the page or something but i do the same of this stackoverflow thread
I put the entire view code:
#api_view(['GET', 'POST', 'DELETE', 'PUT'])
def movies(request):
if request.method == 'GET':
if request.query_params.get('id'):
try:
id = request.query_params.get('id')
movie = Movie.objects.get(id=id)
serializer = MovieSerializer(movie, many=False)
return Response(serializer.data)
except Movie.DoesNotExist:
return Response(status=status.HTTP_404_NOT_FOUND)
movies = Movie.objects.all().order_by('release_date')
serializer = MovieSerializer(movies , many=True, context={'request':request})
if request.query_params.get('page'):
paginator = LimitOffsetPagination()
result_page = paginator.paginate_queryset(movies, request)
serializer = MovieSerializer(result_page, many=True, context={'request':request})
return Response(serializer.data)
if request.query_params.get('Genre'):
genreparam = request.query_params.get('Genre')
genre = Genre.objects.get(name=genreparam)
queryset = Movie.objects.filter(genre_relation=genre.id).values().order_by('release_date')
return Response(queryset)
return Response(serializer.data)
this is my settings.py
REST_FRAMEWORK = {
'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.PageNumberPagination',
'PAGE_SIZE': 2,
}
this is what i get whatever number i send via request params
[
{
"id": 1,
"title": "Guardians of the galaxy",
"tagline": "this is a tagline",
"overview": "this is an overview, starlord in the begins...",
"release_date": "1971-07-13T03:00:00Z",
"poster_url": "http\"//posterurl",
"backdrop_url": "http\"//backdropurl",
"imdb_id": "idk what is a imdb",
"genre_relation": []
},
{
"id": 2,
"title": "Avengers endgame",
"tagline": "this is a tagline",
"overview": "tony stark dies, theres no more happy days, only days",
"release_date": "2019-07-13T03:00:00Z",
"poster_url": "http//posterurl",
"backdrop_url": "http//backdropurl",
"imdb_id": "idk what is a imdb",
"genre_relation": [
1
]
}
]
You are not using the pagination properly. You need to instantiate the paginator with the request, and then call paginate_queryset. You are merely instantiating a paginator, and then completely ignoring it.
paginator = LimitOffsetPagination()
result_page = paginator.paginate_queryset(movies, request)
You thus should rewrite this to:
paginator = LimitOffsetPagination()
result_page = paginator.paginate_queryset(movies, request, view=self)
Note that we here pass view=self, since the LimitOffsetPagination uses self.request, self.response, etc.
Furthermore you should not construct a new serializer, but reuse the existing one, and pass result_page as the queryset:
serializer = MovieSerializer(result_page, many=True, context={'request': request})
Finally you should return the paginated results with:
return paginator.get_paginated_response(serializer.data)
This will add pagination metadata to the response.
So a full example:
#api_view(['GET', 'POST', 'DELETE', 'PUT'])
def movies(request):
# ...
if request.query_params.get('page'):
paginator = LimitOffsetPagination()
result_page = paginator.paginate_queryset(movies, request, view=self)
serializer = MovieSerializer(result_page, many=True, context={'request':request})
return paginator.get_paginated_response(serializer.data)
# ...
Note that using the #api_view decorator is often discouraged. You might want to consider using the #api_view decorator.

is it possible to extract the value of one of the key value pairs in request to be asserted

peter had provided me a solution to use karate 0.9.3 to apply assertion from examples
Trying to do some assertion from request, which will be present in response
i was wondering if it is possible to assert a value from request instead of full request.
**Background:**
* configure headers = read('classpath:merchantServiceheaders.js')
Given url MservUrl
And path 'XXXXXX'
And request Data
When method POST
Then status 200
And match response != null
And match $ contains {serviceName: 'XXXXX'Service', responseMessage:
'Success' }
And match each $.clauses..responseMessage == 'Success'
And match each $..predicate != null
And match each $..predicate == '#present'
And match each $..predicate == '#regex [^0-9]+[0-9]*$'
And match $..predicate contains Data.clauses.subject
Examples:
|Data! |
|'{"clauses":[{"subject":"XXXX","predicate":"999999"},
{"subject":"XXXXX","predicate":"99999"}]}'|
what i am trying to do is on the And match $..predicate contains Data.clauses.subject
is that possible?
Yes, it is very much possible if Data is defined as a variable. But note that $..predicate will always be a JSON array: https://github.com/intuit/karate#get-plus-index
If you want help, please create a proper simple working example.
Sample Code:
Feature: Validation
Scenario:
* def resp = {predicate : "4325325456545646"}
* def data =
"""
{
"clauses": [
{
"subject": "5432154321543210",
"predicate": "4432154321543210"
},
{
"subject": "4325325456545646",
"predicate": "4325325456545646"
}
]
}
"""
* def sublist = get data.clauses[*].subject
* print sublist
* match sublist contains resp.predicate

How to pass complete response of one feature as a request to another feature

payload.json
{
"channelData": {
"data": "CHANNEL_DATA",
"salesChannel": "WEB",
"createdBy": "WEBSITE",
"accountId": "#(accountId)",
"sessionId": "#(accountname)"
}
}
Request.feature
#ignore
Feature:
Scenario:
* def Request = read('../payload.json')
* def headersData = { "Content-Type" : "application/json"}
Given url BaseUrl + '/account/'+'#(accountId)'
And request Request
And headers headersData
When method post
Then status 200
account.feature
#ignore
Feature:
Scenario:
* print temp
* def headersData = { "Content-Type" : "application/json"}
Given url BaseUrl + '/accountdata/'
And request temp
And headers headersData
When method post
Then status 200
Account-token.feature
Feature:
Scenario: identify the reference account
* def reqRes = karate.call('../Request.feature')
* def temp = karate.pretty(reqRes)
* def account = karate.call('../requests/account.feature',{temp : temp })
I want to pass response of Request.feature as a request payload of account.feature. When I try above case, value for temp is printed in an array. [#response of Request.feature] how to resolve this.
Please study this example carefully, it will answer all the questions you have and you will see where you are going wrong: call-feature.feature
For example, to get the response out of a call result, you have to "unpack" it:
Scenario: create kittens
* def result = call read('create-two-cats.feature')
* def temp = result.response

Karate API, How do I match 2 different responses

I get 2 different responses from an endpoint depending on it's state and either one of them is fine.
first response:
{"available":'#boolean',"collection":'#boolean'}
second response:
{"code": "#string","message": "#string"}
I'm trying the following but it's not working:
def firstSchema = {"available":'#boolean',"collection":'#boolean'}
def secondSchema = {"code": "#string","message": "#string"}
match response contains any (firstSchema, secondSchema)
Any ideas how to best get this working so either response is fine?
Thanks
Try this:
* def first = { available: true, collection: true }
* def second = { code: 'foo', message: 'bar' }
* def response = second
* def expected = response.code ? { code: '#string', 'message': '#string' } : { available: '#boolean', collection: '#boolean' }
* match response == expected
Also refer to the documentation on "Conditional Logic". You can use JsonPath to "check" what shape the response is and then define expected results.
I get 2 different responses from an endpoint and either one of them is fine.
first response:
response1.xml
second response:
response2.xml
I tried below assertion but it's not working:
And match response == read('response1.xml') || response == read('response2.xml')

karate how to parse stringified json response

I got a response like this.
"{\"statusCode\":204,\"output\":\"{\\n \\\"Id\\\" : \\\"884d39b8-4afc-4ee3-807a-9d6dbde8c390\\\",\\n \\\"temp\\\" : \\\"33\\\",\\n \\\"lastUpdateAuthor\\\" : null\\n}\"}"
How can I parse this response and do something like
* def expectedOutput =
"""
{
"Id": "884d39b8-4afc-4ee3-807a-9d6dbde8c390",
"temp": "33",
"lastUpdateAuthor": null
}
Scenario: Testing a PUT endpoint with request body
Given path 'v0'
And request input
When method put
Then match status 200
And match JSON.parse(JSON.parse(response).output) == expectedOutput
The last line of code got skipped by Karate.
Any input?
Figured that out.
* def expectedOutput =
"""
{
"Id": "884d39b8-4afc-4ee3-807a-9d6dbde8c390",
"temp": "33",
"lastUpdateAuthor": null
}
"""
Scenario: Testing a PUT endpoint with request body
Given path 'v0'
And request input
When method put
Then match status 200
And json convertJSON = $
And json convertJSON = convertJSON.output
And match convertJSON.latitude == expectedOutput
It worked.