Getting testing error " Test data contained a dictionary value for key 'category'" - testing

Writing test for a little API. Test for GET method working, but for create an error is being called. What could be the problem? i may guess the wrong data format is using.
class CoursesTest(APITestCase):
def setUp(self):
self.course_url = reverse('course-group')
User.objects.create(username='test111', password='123456')
def test_courses_post(self):
data = {
"name": "Blasssbla",
"description": "blabla",
"logo": "img",
"category": {
"name": "Baling",
"imgpath": "img"
},
"contacts": [
{
"status": 1
}
],
"branches": [
{
"latitude": "2131ssss2321",
"longitude": "12321321",
"address": "Osssssh"
}
]
}
self.response = self.client.post(self.course_url, data)
self.assertEqual(self.response.status_code, status.HTTP_201_CREATED)
Error:
AssertionError: Test data contained a dictionary value for key 'category', but multipart uploads do not support nested data. You may want to consider using format='json' in this test case.

If your test data is JSON, you should add format="json" to self.client.post.
class CoursesTest(APITestCase):
def setUp(self):
self.course_url = reverse('course-group')
User.objects.create(username='test111', password='123456')
def test_courses_post(self):
data = {
"name": "Blasssbla",
"description": "blabla",
"logo": "img",
"category": {
"name": "Baling",
"imgpath": "img"
},
"contacts": [
{
"status": 1
}
],
"branches": [
{
"latitude": "2131ssss2321",
"longitude": "12321321",
"address": "Osssssh"
}
]
}
self.response = self.client.post(self.course_url, data, format="json")
self.assertEqual(self.response.status_code, status.HTTP_201_CREATED)

Related

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.

JSON element extraction from response based on scenario outline examples or external file

This is my api response. Want to extract the value of the Id based on the displayNumber. This display number is a given in the list of values in examples/csv file.
{
"Acc": [
{
"Id": "2b765368696b3441673633325",
"code": "SGD",
"val": 406030.83,
"displayNumber": "8957",
"curval": 406030.83
},
{
"Id": "4e676269685a73787472355776764b50717a4",
"code": "GBP",
"val": 22.68,
"displayNumber": "1881",
"curval": 22.68
},
{
"Id": "526e666d65366e67626244626e6266467",
"code": "SGD",
"val": 38404.44,
"displayNumber": "1004",
"curval": 38404.44
},
],
"combinations": [
{
"displayNumber": "3444",
"Code": "SGD",
"Ids": [
{
"Id": "2b765368696b34416736333254462"
},
{
"Id": "4e676269685a7378747235577"
},
{
"Id": "526e666d65366e6762624d"
}
],
"destId": "3678434b643530456962435272d",
"curval": 3.85
},
{
"displayNumber": "8957",
"code": "SGD",
"Ids": [
{
"Id": "3678434b6435304569624357"
},
{
"Id": "4e676269685a73787472355776764b50717a4"
},
{
"Id": "526e666d65366e67626244626e62664679"
}
],
"destId": "2b765368696b344167363332544",
"curval": 406030.83
},
{
"displayNumber": "1881",
"code": "GBP",
"Ids": [
{
"Id": "3678434b643530456962435275"
},
{
"Id": "2b765368696b3441673"
},
{
"Id": "526e666d65366e67626244626e626"
}
],
"destId": "4e676269685a7378747d",
"curval": 22.68
},
]
}
Examples
|displayNumber|
|8957|
|3498|
|4943|
Below expression works if i give the value
* def tempid = response
* def fromAccount = get[0] tempid.Acc[?(#.displayNumber==8957].Id
I'm not sure how to make this comparison value (i.e. 1881) as a variable which can be read from examples (scenario outline) or a csv file. Went through the documentation, which recommends, karate filters or maps. However, not able to follow how to implement.
You almost got it :-). This is the way you want to solve this
Scenario Outline: Testing SO question for Navneeth
* def tempid = response
* def fromAccount = get[0] tempid.Acc[?(#.displayNumber == <displayNumber>)]
* print fromAccount
Examples:
|displayNumber|
|8957|
|1881|
|3444|
You need to pass the placeholder in examples as -
'<displayNumber>'

I want to extract array from json file

i have json file with this data
[
{
“rolename”: “Number one”,
“roledescription”: “Number one”,
“rolepermission”: [“manage_users”,“view_user_logs”],
“roletype”: “client”
}
]
i want to extract data from “rolepermission” and put it in body request
this api accept data like this
{
"role": {
"name": "Test",
"description": "Test",
"permissions": [
"manage_users",
"manage_role",
"managing_custom_page"
],
"userType":"admin"
}
}
and i convert it to this to extract data from my json file
{
"role": {
"name": "{{rolename}}",
"description": "{{roledescription}}",
"permissions": [
"{{rolepermission}}"
],
"userType": "{{roletype}}"
}
}
but he send request like this
“permissions”: [
“manage_users,view_user_logs”
],
instead it should send it like this
“permissions”: [
“manage_users”,
“view_user_logs”
],
what should i do
To save array data, you need stringify first which is mentioned here https://learning.postman.com/docs/sending-requests/variables/#understanding-variables
const res = pm.response.json();
const rolepermission = res.data[0].rolepermission;
pm.environment.set("rolepermission", JSON.stringify(rolepermission));
Use this variable in request body:
{
"role": {
"name": "{{rolename}}",
"description": "{{roledescription}}",
"permissions": {{rolepermission}},
"userType": "{{roletype}}"
}
}

Karate API json response - How to validate the presence of a key which sometimes come and sometimes not in the API response

I need help in validating the presence of one key in the response. The response of the API looks like -
"persons": [
{
"id": "27",
"source": {
"personId": 281,
"emailAddress": "abc#abc.com",
"firstName": "Steve"
}
},
{
"id": "28",
"source": {
"personId": 353,
"emailAddress": "abcd#abc.com",
"firstName": "John"
"LastName" : "Cena"
}
}
]
}
I want to assert if the source.LastName appears or not and if it does then it should always hold a string value.
The solution should be generic and it should work for 30 or 40 persons object also down the time, currently I am using karate version 0.9.4 and need a resolution for handling such scenarios.
Thanks in advance !
In the schema "##string" validates that the field can be null or a string.
Sample Code:
Feature: Schema validation
Scenario:
* def resp =
"""
{
"persons": [
{
"id": "27",
"source": {
"personId": 281,
"emailAddress": "abc#abc.com",
"firstName": "Steve"
}
},
{
"id": "28",
"source": {
"personId": 353,
"emailAddress": "abcd#abc.com",
"firstName": "John",
"LastName" : "Cena"
}
}
]
}
"""
* def schema =
"""
{
"id": "#string",
"source": {
"personId": "#number",
"emailAddress": "#string",
"firstName": "#string",
"LastName": "##string"
}
}
"""
* match each resp.persons == schema

How to update existing Knowledgebase using QnA Maker API v4.0?

I've successfully created my Knowledgebase using API.
But I forgot to add some alternative questions and metadata for one of the pairs.
I've noticed PATH method in the API to update the Knowledebase, so updating kb is supported.
I've created a payload which looked like this:
{
"add": {
},
"delete": {
},
"update": {
"qnaList": [
{
"id": 1,
"answer": "Answer",
"source": "link_to_source",
"questions": [
"Question 1?",
"Question 2?"
],
"metadata": [
{
"name": "oldMetadata",
"value": "oldMetadata"
},
{
"name": "newlyAddedMetaData",
"value": "newlyAddedMetaData"
}
]
}]}
}
I get back the following response HTTP 202 Accepted:
{
"operationState": "NotStarted",
"createdTimestamp": "2018-05-21T07:46:52Z",
"lastActionTimestamp": "2018-05-21T07:46:52Z",
"userId": "user_uuid",
"operationId": "operation_uuid"
}
So, looks like it worked. But in reality, this request doesn't take any affect.
When I check operation details, it returns me the following:
{
"operationState": "Succeeded",
"createdTimestamp": "2018-05-21T07:46:52Z",
"lastActionTimestamp": "2018-05-21T07:46:54Z",
"resourceLocation": "/knowledgebases/kb_uuid",
"userId": "user_uuid",
"operationId": "operation_uuid"
}
What am I doing wrong? And how should I update my kb via API properly?
Please help
I had the same problem, I discovered that it was necessary to have all the data of the json even if they were not used.
In your case you need "name" and "urls" in the "update" section and "Delete" in "update/qnaList/questions" section:
{
"add": {},
"delete": {},
"update": {
"name": "nameofKbBase", //this
"qnaList": [
{
"id": 2370,
"answer": "DemoAnswerEdit",
"source": "CustomSource",
"questions": {
"add": [
"DemoQuestionEdit"
],
"delete": [] //this
},
"metadata": { }
}
],
"urls": [] //this
}
}