reason: actual value has 1 more key(s) than expected: - cucumber

I am running karate tests.
I am posting a request object and i recieve a response object . however in the response object i have one extra field populated .How will i handle the scenario ?
the following is my test
#NFRSubscription.feature
Feature: NFR Subscription API Tests
Background:
* url __arg.test_service.url
* configure ssl = false
* configure httpVersion = 'http2'
Scenario: Create/Patch/Delete NRF subscription by nfInstanceId subscription condition
* def subscriptionId = ''
* def createSubscriptionByNfInstanceIdRequest = read('subscription/subscriptionCreateRequest.json')
* def patchSubscriptionByNfInstanceIdResponse = read('subscription/subscriptionPatchResponse.json')
* def createSubscriptionByNfInstanceIdResponse = createSubscriptionByNfInstanceIdRequest
# Create the NRF subscription by nfInstanceId
Given path '/nnrf-nfm/v1/subscriptions/'
And header Content-Type = 'application/json; charset=utf-8'
And print createSubscriptionByNfInstanceIdRequest
And request createSubscriptionByNfInstanceIdRequest
When method post
Then status 201
And match response == createSubscriptionByNfInstanceIdResponse
And match response.subscriptionId == '#present'
And print response
the content of subscription/subscriptionCreateRequest.json is as follows.
{
"nfStatusNotificationUri": "http://localhost:8080/ip/test",
"reqNfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76",
"subscrCond": {
"nfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76"
},
"validityTime": "2022-02-18T10:15:15Z",
"reqNotifEvents": [
"NF_REGISTERED"
],
"plmnId": {"mcc": "454", "mnc" : "93" },
"nid": "2465aEB5ff1",
"notifCondition": {
"monitoredAttributes": [
"testattri"
]
},
"reqNfType": "NRF",
"reqNfFqdn": "com.openet.com",
"reqSnssais": [
{ "sst": 10, "sd": "aA82a7" }
],
"reqPlmnList": [
{"mcc": "454", "mnc" : "93" }
],
"reqSnpnList": [
{"mcc": "454", "mnc" : "93" }
],
"servingScope": [
"any string"
],
"nrfSupportedFeatures": "CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d"
}
the content of the file subscription/subscriptionPatchResponse.json is as follows.
{
"nfStatusNotificationUri": "http://localhost:8080/ip/test",
"reqNfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76",
"subscrCond": {
"nfInstanceId": "9c79364e-99e1-42a8-ada1-86c31ad1fa76"
},
"validityTime": "2023-03-07T23:20:50Z",
"reqNotifEvents": [
"NF_REGISTERED"
],
"plmnId": {"mcc": "454", "mnc" : "93" },
"nid": "2465aEB5ff1",
"notifCondition": {
"monitoredAttributes": [
"testattri"
]
},
"reqNfType": "NRF",
"reqNfFqdn": "com.openet.com",
"reqSnssais": [
{ "sst": 10, "sd": "aA82a7" }
],
"reqPlmnList": [
{"mcc": "454", "mnc" : "93" }
],
"reqSnpnList": [
{"mcc": "454", "mnc" : "93" }
],
"servingScope": [
"any string"
],
"nrfSupportedFeatures": "CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d"
}
in the response I would expect a new field called subscriptionId .
my test fails at the moment with the following error .
16:00:57 com.intuit.karate.exception.KarateException: NFRSubscription.feature:24 - path: $, actual: {nfStatusNotificationUri=http://localhost:8080/ip/test, reqNfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76, subscrCond={nfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76}, subscriptionId=608425, validityTime=2022-02-18T10:15:15Z, reqNotifEvents=["NF_REGISTERED"], plmnId={mcc=454, mnc=93}, nid=2465aEB5ff1, notifCondition={monitoredAttributes=["testattri"]}, reqNfType=NRF, reqNfFqdn=com.openet.com, reqSnssais=[{"sst":10,"sd":"aA82a7"}], reqPlmnList=[{"mcc":"454","mnc":"93"}], reqSnpnList=[{"mcc":"454","mnc":"93"}], servingScope=["any string"], nrfSupportedFeatures=CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d}, expected: {nfStatusNotificationUri=http://localhost:8080/ip/test, reqNfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76, subscrCond={nfInstanceId=9c79364e-99e1-42a8-ada1-86c31ad1fa76}, validityTime=2022-02-18T10:15:15Z, reqNotifEvents=["NF_REGISTERED"], plmnId={mcc=454, mnc=93}, nid=2465aEB5ff1, notifCondition={monitoredAttributes=["testattri"]}, reqNfType=NRF, reqNfFqdn=com.openet.com, reqSnssais=[{"sst":10,"sd":"aA82a7"}], reqPlmnList=[{"mcc":"454","mnc":"93"}], reqSnpnList=[{"mcc":"454","mnc":"93"}], servingScope=["any string"], nrfSupportedFeatures=CBAdEd1bef9B118EAd8d5bAfc66B59c1D292fD821d}, reason: actual value has 1 more key(s) than expected: {subscriptionId=608425}
any idea how should i formulate createSubscriptionByNfInstanceIdResponse object to handle an extra dynamically generated field . in other words how can i do the following
add response.subscriptionId into createSubscriptionByNfInstanceIdResponse and then compare response and
createSubscriptionByNfInstanceIdResponse object .
And match response == createSubscriptionByNfInstanceIdResponse

I have changed the test to add the subscriptionId field in the response object and then asserted it .
# Create the NRF subscription by nfInstanceId
Given path '/nnrf-nfm/v1/subscriptions/'
And header Content-Type = 'application/json; charset=utf-8'
And print createSubscriptionByNfInstanceIdRequest
And request createSubscriptionByNfInstanceIdRequest
When method post
Then status 201
And match response.subscriptionId == '#present'
And print response
And set createSubscriptionByNfInstanceIdResponse.subscriptionId = response.subscriptionId
And match response == createSubscriptionByNfInstanceIdResponse

Related

Python: Google Analytics API not retrieving adImpressions and adClicks

I am trying to retrieve some information about my ads in google. I have done the same for campaigns, adgroups and keywords and I haven't got a single issue, however, when it comes to ads and their metrics, I cannot manage to extract something other than adCost.
I have the following code to retrieve the info I need from google ads:
def ad_data(service, view_id, start_date, end_date):
# Initialize request with first page of results
request = {
'reportRequests': [
{
'viewId': view_id,
'dateRanges': [
{
'startDate': start_date,
'endDate': end_date
}
],
'metrics': [
{
'expression': 'ga:adCost'
},
{
'expression': 'ga:adClicks'
},
{
'expression': 'ga:adImpressions'
}
],
'dimensions': [
{
'name': 'ga:date'
},
{
'name': 'ga:campaign'
},
{
'name': 'ga:adContent'
}
],
'pageSize': 1000
}
]
}
all_data = []
while True:
# Make API call and get response
response = service.reports().batchGet(body=request).execute()
report = response.get('reports', [])[0]
rows = report.get('data', {}).get('rows', [])
all_data.extend(rows)
# Check if there are more pages of results
page_token = report.get('nextPageToken', None)
if not page_token:
break
# Update request with next page of results
request['reportRequests'][0]['pageToken'] = page_token
return all_data
The issue that I have is that for some reason I'm not being ale to retrieve metrics other than adCost, hence it shows me the following error:
HttpError: <HttpError 400 when requesting https://analyticsreporting.googleapis.com/v4/reports:batchGet?alt=json returned "Unknown metric(s): ga:adImpressions
For details see https://developers.google.com/analytics/devguides/reporting/core/dimsmets.". Details: "Unknown metric(s): ga:adImpressions
For details see https://developers.google.com/analytics/devguides/reporting/core/dimsmets.">
Could anyone help me out?

Parse JSON Dictionary with Python3

I have a JSON representation that looks like the following:
{
"results": [
{
"vulnerabilities": [
],
}
]
}
I tried to output just the vulnerabilities portion, but the following doesnt work:
for key, value in json_object.items():
print(key, ' : ', value)
This prints out the whole results but not just the vulnerabilities
Assuming multiple dicts in results, each with a vulnerabilities key, you can do:
json_object = {
"results": [
{
"vulnerabilities": [
],
}
]
}
for result in json_object['results']:
for vuln in result['vulnerabilities']:
print(vuln)

Lambda error "TypeError: 'str' object does not support item assignment Traceback"

I am trying out
import json
import uuid
import boto3
def lambda_handler(event, context):
dynamo_client = boto3.resource('dynamodb')
loadeo_carrier_company = dynamo_client.Table('loadeo_carrier_company')
item = {}
item = event['body']
print(item)
item['company_id'] = str(uuid.uuid4())
print (type(item))
try:
loadeo_carrier_company.put_item(
Item=item
)
return {
"statusCode": 200,
"headers" : {
"Access-Control-Allow-Origin" : "*"
},
"message": json.dumps("Record has been inserted"),
"body": item
}
except Exception as e:
return {
"statusCode": 500,
"headers" : {
"Access-Control-Allow-Origin" : "*"
},
"message": "Error: Unable to save record!"
}
This code.
When I test it through Lambda Test event it is working fine.
But when I create an API and try it out with postman showes an internal server error but when I look at the cloud watch logs The below error is shown.
[ERROR] TypeError: 'str' object does not support item assignment
Traceback (most recent call last):
File "/var/task/lambda_function.py", line 19, in lambda_handler
item['company_id'] = str(uuid.uuid4())
NOTE:
The Lambda test event is working fine.
"body": {
"company_name" : "waveaxis pvt ltd",
"mc_number" : "00000",
"email_adderess": "waveaxis#waveaxis.co.in",
"phone_number" : "+91 1234567890",
"company_address" : "Kormangala, Bengaluru"
},
After Trying the answer:
When I test it from lambda test event:
{
"errorMessage": "the JSON object must be str, bytes or bytearray, not dict",
"errorType": "TypeError",
"stackTrace": [
" File \"/var/task/lambda_function.py\", line 17, in lambda_handler\n item = json.loads(event['body'])\n",
" File \"/var/lang/lib/python3.8/json/__init__.py\", line 341, in loads\n raise TypeError(f'the JSON object must be str, bytes or bytearray, '\n"
]
}
and when I call it from postman.
Execution stops before try block with no error
Edit 2: print the json for event
{
"resource":"/",
"path":"/",
"httpMethod":"PUT",
"headers":{
"Accept":"*/*",
"Accept-Encoding":"gzip, deflate, br",
"Authorization":"Bearer eyJraWQiOiJCUUl6ZkxcL1VOdm9QTDVxNExlWGFRNXNxOG1mVmhmXC9rK3ZJUDdYc0p0VjQ9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkYjdkODBmOC1mY2VhLTQwYjItYTZhYi1jMjhhNTZiMTI1NDIiLCJ0b2tlbl91c2UiOiJhY2Nlc3MiLCJzY29wZSI6ImNhcnJpZXJcL3JlYWQgY2FycmllclwvdXBkYXRlIGNhcnJpZXJcL2RlbGV0ZSIsImF1dGhfdGltZSI6MTYwMjA0NDQ5NywiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfWW5nVnJxYUFGIiwiZXhwIjoxNjAyMDQ4MDk3LCJpYXQiOjE2MDIwNDQ0OTcsInZlcnNpb24iOjIsImp0aSI6ImExMzg4ZGUyLTRhZWQtNGI2MC04YjM0LWYzN2I1N2RjM2ZmMiIsImNsaWVudF9pZCI6IjVlZzU1NWhpNzAwZ21lbWc3N3B0NWkzbDIyIiwidXNlcm5hbWUiOiJHb29nbGVfMTEyNjUyMTUzMDI4OTQyNjAzNDM5In0.XMy9GP03o5EYrcLtQFzrMV6KID4IlDI_n0WrHa8osY_7CeeDjaCjH6Dtr766TAommLUzcLoKt-NrBUdq0Zfx-BL919j25rwiZXJbHiZP_4y9n891ddOXfPabO7n8O84-63W6l13QEBozuc21vXi7vuE_dSJ7KAgute46KP3LyoS73WPDhYim_7HZJO8pVedk64hhGNZsYWv6VU5QeQyqPl926spA25ZBo_z5dcoBnMZ_i2n5nz6qxRcINOKfMXL1f4_nDRbtKb5Pd33hKnsKYLkxEI0mrT1JKPJhkJRg9vGqaKcd13oqrigJRFSXYuVQuKNDluc38KbQJcwUoXDjjA",
"Content-Type":"application/json",
"Host":"661ny3iw92.execute-api.us-east-2.amazonaws.com",
"Postman-Token":"654cfdd0-8080-48a5-8758-3aa7e5bcefcc",
"User-Agent":"PostmanRuntime/7.26.5",
"X-Amzn-Trace-Id":"Root=1-5fa13860-63da2718701bf3fc458c78e1",
"X-Forwarded-For":"157.49.141.105",
"X-Forwarded-Port":"443",
"X-Forwarded-Proto":"https"
},
"multiValueHeaders":{
"Accept":[
"*/*"
],
"Accept-Encoding":[
"gzip, deflate, br"
],
"Authorization":[
"Bearer eyJraWQiOiJCUUl6ZkxcL1VOdm9QTDVxNExlWGFRNXNxOG1mVmhmXC9rK3ZJUDdYc0p0VjQ9IiwiYWxnIjoiUlMyNTYifQ.eyJzdWIiOiJkYjdkODBmOC1mY2VhLTQwYjItYTZhYi1jMjhhNTZiMTI1NDIiLCJ0b2tlbl91c2UiOiJhY2Nlc3MiLCJzY29wZSI6ImNhcnJpZXJcL3JlYWQgY2FycmllclwvdXBkYXRlIGNhcnJpZXJcL2RlbGV0ZSIsImF1dGhfdGltZSI6MTYwMjA0NDQ5NywiaXNzIjoiaHR0cHM6XC9cL2NvZ25pdG8taWRwLnVzLWVhc3QtMS5hbWF6b25hd3MuY29tXC91cy1lYXN0LTFfWW5nVnJxYUFGIiwiZXhwIjoxNjAyMDQ4MDk3LCJpYXQiOjE2MDIwNDQ0OTcsInZlcnNpb24iOjIsImp0aSI6ImExMzg4ZGUyLTRhZWQtNGI2MC04YjM0LWYzN2I1N2RjM2ZmMiIsImNsaWVudF9pZCI6IjVlZzU1NWhpNzAwZ21lbWc3N3B0NWkzbDIyIiwidXNlcm5hbWUiOiJHb29nbGVfMTEyNjUyMTUzMDI4OTQyNjAzNDM5In0.XMy9GP03o5EYrcLtQFzrMV6KID4IlDI_n0WrHa8osY_7CeeDjaCjH6Dtr766TAommLUzcLoKt-NrBUdq0Zfx-BL919j25rwiZXJbHiZP_4y9n891ddOXfPabO7n8O84-63W6l13QEBozuc21vXi7vuE_dSJ7KAgute46KP3LyoS73WPDhYim_7HZJO8pVedk64hhGNZsYWv6VU5QeQyqPl926spA25ZBo_z5dcoBnMZ_i2n5nz6qxRcINOKfMXL1f4_nDRbtKb5Pd33hKnsKYLkxEI0mrT1JKPJhkJRg9vGqaKcd13oqrigJRFSXYuVQuKNDluc38KbQJcwUoXDjjA"
],
"Content-Type":[
"application/json"
],
"Host":[
"661ny3iw92.execute-api.us-east-2.amazonaws.com"
],
"Postman-Token":[
"654cfdd0-8080-48a5-8758-3aa7e5bcefcc"
],
"User-Agent":[
"PostmanRuntime/7.26.5"
],
"X-Amzn-Trace-Id":[
"Root=1-5fa13860-63da2718701bf3fc458c78e1"
],
"X-Forwarded-For":[
"157.49.141.105"
],
"X-Forwarded-Port":[
"443"
],
"X-Forwarded-Proto":[
"https"
]
},
"queryStringParameters":"None",
"multiValueQueryStringParameters":"None",
"pathParameters":"None",
"stageVariables":"None",
"requestContext":{
"resourceId":"529nsbfu6a",
"resourcePath":"/",
"httpMethod":"PUT",
"extendedRequestId":"VbW_FFkYCYcF3PQ=",
"requestTime":"03/Nov/2020:11:00:48 +0000",
"path":"/dev",
"accountId":"272075499248",
"protocol":"HTTP/1.1",
"stage":"dev",
"domainPrefix":"661ny3iw92",
"requestTimeEpoch":1604401248435,
"requestId":"970dd9d2-9b35-45c5-b194-806060e27d10",
"identity":{
"cognitoIdentityPoolId":"None",
"accountId":"None",
"cognitoIdentityId":"None",
"caller":"None",
"sourceIp":"157.49.141.105",
"principalOrgId":"None",
"accessKey":"None",
"cognitoAuthenticationType":"None",
"cognitoAuthenticationProvider":"None",
"userArn":"None",
"userAgent":"PostmanRuntime/7.26.5",
"user":"None"
},
"domainName":"661ny3iw92.execute-api.us-east-2.amazonaws.com",
"apiId":"661ny3iw92"
},
"body":"{\r\n \"company_name\": \"waveaxis pvt ltd\",\r\n \"mc_number\": \"00000\",\r\n \"email_adderess\": \"waveaxis#waveaxis.co.in\",\r\n \"phone_number\": \"+91 1234567890\",\r\n \"company_address\": \"Kormangala, Bengaluru\"\r\n}\r\n",
"isBase64Encoded":False
}
Your event['body'] is probably just a json string, not actual json, from what I remember.
Thus, instead of
item = event['body']
you can use
item = json.loads(event['body'])
which should parse json string into json object.
Update
Based on the posted form of the event, you should use ast, not json
import ast
item = ast.literal_eval(event['body'])

Power Query Expression error: A value of type "Record" cannot converted into type "Text"

I have the issue that I'm not able to execute the following code. The syntax seems to be okay, but when I try to execute it, I get the response, that:
Expression.Error: We cannot convert a value of type Record to type "Text".
Details:
Value=[Record]
Type=[Type]
let
body="{
""page"": ""1"",
""pageSize"": ""100"",
""requestParams"": {
""deviceUids"": [
""xxx-yyy-xxx-yyyy-xxxx"",
""yyy-xxx-yyy-xxxx-yyyy"",
""aaa-bbb-aaa-bbbb-aaaa"",
""ccc-ddd-ccc-dddd-cccc""
],
""entityColumns"": [
{
""entityId"": ""144"",
""joinColumnName"": ""device_uid"",
""columnName"": ""device_random_date""
}
],
""columnNames"": [
""ts"",
""device_uid"",
""1"",
""32"",
""55"",
""203"",
""204""
],
""startUnixTsMs"": ""1583413637000"",
""endUnixTsMs"": ""1583413640000"",
""columnFilters"": [
{
""filterType"": ""eq"",
""columnName"": ""55"",
""value"": ""1234""
}
],
""sortOrder"": [
{
""column"": ""ts"",
""order"": ""DESC""
},
{
""column"": ""55"",
""order"": ""ASC""
}
],
""entityFilters"": [
{
""entityId"": ""144"",
""entityEntryIds"": [
""12345-221-232-1231-123456""
]
}
]
}
}",
Parsed_JSON = Json.Document(body),
BuildQueryString = Uri.BuildQueryString(Parsed_JSON),
Quelle = Json.Document(Web.Contents("http://localhost:8101/device-data-reader-api/read-paginated/xxx-xxx-yyyy-yyyy", [Headers=[#"Content-Type"="application/json"], Content = Text.ToBinary(BuildQueryString)]))
in
Quelle
I tried to remove the quotes of the numbers, but this leads to the same issue, as system complains it cannot convert numbers into text.
I need the body which needs to be handed over with the request in order to do a POST request. What I'm doing wrong?
Since you seem to want to send this as application/json, I think you would change this bit in your code:
Content = Text.ToBinary(BuildQueryString)
to:
Content = Text.ToBinary(body)
and then you'd also get rid of the lines below (since you don't need them):
Parsed_JSON = Json.Document(body),
BuildQueryString = Uri.BuildQueryString(Parsed_JSON),
I don't think you would need Uri.BuildQueryString unless you wanted to send as application/x-www-form-urlencoded (i.e. URL encoded key-value pairs).
Unrelated: If it helps, you can build the structure in M and then use JSON.FromValue to turn the structure into bytes which can be put directly into the POST body. Untested example is below.
let
body = [
page = "1",
pageSize = "100",
requestParams = [
deviceUids = {
"xxx-yyy-xxx-yyyy-xxxx",
"yyy-xxx-yyy-xxxx-yyyy",
"aaa-bbb-aaa-bbbb-aaaa",
"ccc-ddd-ccc-dddd-cccc"
},
entityColumns = {
[
entityId = "144",
joinColumnName = "device_uid",
columnName = "device_random_date"
]
},
columnNames = {
"ts",
"device_uid",
"1",
"32",
"55",
"203",
"204"
},
startUnixTsMs = "1583413637000",
endUnixTsMs = "1583413640000",
columnFilters = {
[
filterType = "eq",
columnName = "55",
value = "1234"
]
},
sortOrder = {
[
column = "ts",
order = "DESC"
],
[
column = "55",
order = "ASC"
]
},
entityFilters = {
[
entityId = "144",
entityEntryIds = {
"12345-221-232-1231-123456"
}
]
}
]
],
Quelle = Json.Document(
Web.Contents(
"http://localhost:8101/device-data-reader-api/read-paginated/xxx-xxx-yyyy-yyyy",
[
Headers = [#"Content-Type" = "application/json"],
Content = Json.FromValue(body)
]
)
)
in
Quelle
It might look a little weird (since M uses [] instead of {}, {} instead of [] and = instead of :), but just mentioning in case it helps.

How to match json objects having fields as URL

I am having a GET request which returned response in following format:
"http://wso2.org/claims/role": [
Application/API_ADMIN_SSO",
],
"http://wso2.org/claims/applicationtier": "Unlimited",
"http://wso2.org/claims/keytype": "PRODUCTION",
"http://wso2.org/claims/version": "v1",
"iss": "wso2.org/products/am"
How do I match these fields because if I do
And match response.http://wso2.org/claims/applicationtier == "PRODUCTION"
It throws and error saying path does not exist.
* def response = { "http://wso2.org/claims/applicationtier": "PRODUCTION" }
* match response['http://wso2.org/claims/applicationtier'] == 'PRODUCTION'

Resources