How can I use a variable as a json key in karate? - json

* def myvariable = 1
* def schema =
"""
{
myvariable : '#number',
2: '#number',
3: '#number',
4: '#number',
5: '#number',
6: '#number',
}
"""
I need to use 'myvariable' as a key. How can I do this?

Here you go:
* def schema = {}
* schema.myvariable = 1
* match schema == { myvariable: 1 }
# dynamic key name
* def name = 'myvariable'
* def schema = {}
* schema[name] = 1
* match schema == { myvariable: 1 }

Related

Karate - Iterate through array and call rest api for each value

Scenario:
* def Test_assignment_type = 'ALL'
* def TEST_NODE_ID = '123455667'
* def list = [ '123', '1234', '12345' ]
* def gId_list = karate.mapWithKey(list, 'HOOK_TEST_LOCATION_GID')
* callonce read('classpath:hook/delete-assignments-hook.feature') {HOOK_TEST_LOCATION_ID: "#(TEST_NODE_ID)", HOOK_TEST_ASSIGNMENT_TYPE: "#(Test_assignment_type)"}
delete-assignments-hook.feature:
Scenario:
* Given path '/nodes/'+HOOK_TEST_LOCATION_ID+'/locations/'+HOOK_TEST_LOCATION_GID+'/assignments'
* And param assignmentType = HOOK_TEST_ASSIGNMENT_TYPE
* When method delete
* Then assert responseStatus == 204 || responseStatus == 404
how to pass gId_list in my delete-assignments-hook.feature, so that delete api runs for each value in the list.
Just start with a simple example and study it. This below will make 3 calls with a parameter called id. And also read the documentation: https://github.com/karatelabs/karate#data-driven-features
Feature:
Scenario:
* def array = [1, 2, 3]
* def data = karate.mapWithKey(array, 'id')
* call read('#called') data
#ignore #called
Scenario:
* url 'https://httpbin.org/anything'
* param id = id
* method get

How to delete empty lists and dictionaries in json row and count them?

How to delete empty lists and dictionaries in json row and count them, for example:
[ [ { }, [ ], " ", { {"1":{}, "2":[ ] }, [ [ { } ] , " " ] ] ]
This uses an object to handle the recognition & counting of empty things:
class Counts:
d = 0
l = 0
def count(self,x):
if x==[]:
self.l += 1
return True
elif x=={}:
self.d += 1
return True
return False
def __repr__(self):
return "<d=%d, l=%d>" % (self.d,self.l)
def tr(x):
c = Counts()
new_x = tr2(x,c)
c.count(new_x) # Count final result
return new_x,c.d,c.l
def tr2(x,c):
if isinstance(x,dict):
new_x = {}
for k,v in x.items():
if not c.count(v):
new_v = tr2(v,c)
if not c.count(new_v):
new_x[k] = new_v
return new_x
elif isinstance(x,list):
new_x = []
for v in x:
if not c.count(v):
new_v = tr2(v,c)
if not c.count(new_v):
new_x.append( new_v )
return new_x
return x

dictionary value is dict but printing as string in json dump

I have a script that is working fine except for this tiny issue. My script is looping over list items and appending a json string over a loop and then doing json dump to file.
My json string:
main_json = {"customer": {"main_address": "","billing_address": "","invoice_reference": "","product": []}}
main loop:
for row in result:
account_id = ACCOUNTID_DATA_CACHE.get(row['customer.main_address.customer_id'])
if account_id is None or account_id != row['customer.main_address.customer_id']:
if main_json:
results.append(main_json)
main_json = {"customer": {"main_address": "","billing_address": "","invoice_reference": "","product": []}}
main_address = {}
billing_address = {}
for key,value in row.items():
if key.startswith('customer.main_address'):
main_address[key.split(".")[2]] = value
if key.startswith('customer.billing_address'):
billing_address[key.split(".")[2]] = value
billing_address_copy = billing_address.copy()
for mkey,mvalue in main_address.items():
for bkey,bvalue in billing_address_copy.items():
if str(bvalue) == str(mvalue):
bvalue = ''
billing_address_copy[bkey] = bvalue
if all(value == '' for value in billing_address_copy.values()) is True:
main_json['customer']['billing_address'] = ''
else:
main_json['customer']['billing_address'] = billing_address
main_json['customer']['main_address'] = main_address
product = parse_products(row)
main_json['customer']['product'].append(product)
...
def parse_products(row):
product = {}
x = {}
for key,value in row.items():
if key.startswith('customer.product'):
product[key.split(".")[2]] = value
if key.startswith('customer.product.custom_attributes'):
x['domain'] = value
print(x)
product[key.split(".")[2]] = x
if key == 'start_date' or 'renewal_date':
value = str(value)
product[key] = value
return product
In this part below, how do make sure that the value is not a string when dumped?
if key.startswith('customer.product.custom_attributes'):
x['domain'] = value
print(x)
product[key.split(".")[2]] = x
Because in the output I'm getting:
{
"custom_attributes": "{'domain': 'somedomain.com'}",
"description": "some_description",
"discount": "0.00"}
When what I really want is:
{
"custom_attributes": {"domain": "somedomain.com"},
"description": "some_description",
"discount": "0.00"}
EDIT: how i'm dumping:
with open('out.json', 'w') as jsonout:
json.dump(main_json, jsonout, sort_keys=True, indent=4)
Well, this IF is flawed and always TRUE:
if key == 'start_date' or 'renewal_date':
So you are converting everything to str()

How do I insert field having default value in Slick

Given mapping having NOT NULL field str with a default value:
case class Tst(id: Option[Int] = None, ii: Int, str: String)
class Tsts(tag: Tag) extends Table[Tst](tag, "tsts") {
def id = column[Option[Int]]("id", O.PrimaryKey, O.AutoInc)
def ii = column[Int]("ii")
def str = column[String]("str", O.Default("ddd"))
def * = (id, ii, str) <> (Tst.tupled, Tst.unapply)
}
How do I insert object specifying the field value if I have it:
Tst(ii = 1, str = "aaa")
and skipping it if I don't:
Tst(ii = 1)
Yes, I know the last statement will not compile.
I tried using Option[String] and other things. It ends up with either inserting null or failing with can't be null error
The compiler depends on you putting default values at the end, like:
scala> case class TST(ii: Int, str: String = "aaa", id: Option[Int] = None)
defined class TST
scala> new TST(3)
res0: TST = TST(3,aaa,None)
Edit: Just realized I didn't answer completely:
scala> new TST(3, id = Some(1))
res1: TST = TST(3,aaa,Some(1))
scala> new TST(3, str = "bbb")
res2: TST = TST(3,bbb,None)

HttpResponseException Message null Caused by Not Found

This is my controller
package course_management_collection
import groovyx.net.http.HTTPBuilder
class CourseController {
def equellaService
def search() {
if (params.courseCodeQuery) {
def clientId = '2191fc19-2084-46f0-ab8e-aef7a912ff54'
def clientSecret = '24f83161-09df-47a2-aa70-7929d96cd4a9'
def http = new HTTPBuilder('https://eqtst.uow.edu.au/uow/')
def accessToken = equellaService.getAccessToken(http, clientId, clientSecret)
def itemInfo = equellaService.getItemInfo(http, accessToken, params.courseCodeQuery, "81895979-822f-41b6-9a61-4629216f727d" )
// def itemInfo = equellaService.getItemInfo(http, accessToken, "a05bc842-8226-4773-a64a-f92d20bd9834", 1)
// def course= equellaService.getCourse(http, accessToken, "81895979-822f-41b6-9a61-4629216f727d")
return [courseCodeQuery: params.courseCodeQuery, itemInfo: itemInfo]
// return [courseCodeQuery: params.courseCodeQuery, course: course]
}
}
}
I have edited the EquellaService.groovy as follows:
package course_management_collection
import grails.transaction.Transactional
import static groovyx.net.http.Method.GET
import static groovyx.net.http.ContentType.JSON
#Transactional
class EquellaService {
def getAccessToken(http, clientId, clientSecret) {
def accessToken
http.request(GET, JSON) {
uri.path = 'oauth/access_token'
uri.query = [grant_type: 'client_credentials', client_id: clientId, client_secret: clientSecret, redirect_uri: 'default']
response.success = { resp, json ->
accessToken = json.access_token
}
}
return accessToken
}
def getItemInfo(http, accessToken, params.courseCodeQuery, collection) {
def itemInfo
http.request(GET, JSON) {
uri.path = "api/search/${params.courseCodeQuery}/${collection}"
uri.query = [info: 'all']
headers.'X-Authorization' = "access_token=${accessToken}"
response.success = { resp, json ->
itemInfo = json
}
}
return itemInfo
}
}
the response:
URI
/
Class
groovyx.net.http.HttpResponseException
Message
null
Caused by
Not Found
Around line 30 of grails-app\services\course_management_collection\EquellaService.groovy
27:def getItemInfo(http, accessToken, params.courseCodeQuery, collection) {
28:def itemInfo
29:
30:http.request(GET, JSON) {
31:uri.path = "api/search/${params.courseCodeQuery}/${collection}"
32: uri.query = [info: 'all']
33: headers.'X-Authorization' = "access_token=${accessToken}"
Around line 18 of grails-app\controllers\course_management_collection\CourseController.groovy
15: def http = new HTTPBuilder('https://eqtst.uow.edu.au/uow/')
16: def accessToken = equellaService.getAccessToken(http, clientId, clientSecret)
17:
18: def itemInfo = equellaService.getItemInfo(http, accessToken, params.courseCodeQuery, "81895979-822f-41b6-9a61-4629216f727d" )
19: // def itemInfo = equellaService.getItemInfo(http, accessToken, "a05bc842-8226-4773-a64a-f92d20bd9834", 1)
20: //def course= equellaService.getCourse(http, accessToken, "81895979-822f-41b6-9a61-4629216f727d")
21: return [courseCodeQuery: params.courseCodeQuery, itemInfo: itemInfo]
Trace
Line | Method
->> 1110 | runWorker in java.util.concurrent.ThreadPoolExecutor
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
| 603 | run in java.util.concurrent.ThreadPoolExecutor$Worker
^ 722 | run . . . in java.lang.Thread
Caused by HttpResponseException: Not Found
Your line
def itemInfo = equellaService.getItemInfo(http, accessToken, courseCodeQuery, "81895979-822f-41b6-9a61-4629216f727d" )
Should be
def itemInfo = equellaService.getItemInfo(http, accessToken, params.courseCodeQuery, "81895979-822f-41b6-9a61-4629216f727d" )
Note the params.
Because you don't have a variable named 'courseCodeQuery,' you have 'params.courseCodeQuery'?