0

I am getting 90 cent success with my approach but when the response has got multiple entries in one of the child key then the logic gets failed and I am not able to put one common logic in place which would run for all the cases.

The response sample is

{
  "items": [
             {
              "id":1,
              "name": "John",
              "sections": [
                          { 
                           "id":1,
                           "description": "John smith" 
                          }
                      ]
           }
         ]
}

Now my use case says you search for John text and then items array would contains many objects whose items.name or items.sections.description should contains the "John" keyword

The matching logic which I have put is working fine because I am iterating through items[].name and items.sections[].description

The main challenge comes when the sections[*].description contains the multiple sections like below

{
  "items": [
             {
              "id":1,
              "name": "John",
              "sections": [
                          { 
                           "id":1,
                           "description": "John smith" 
                          },
                          { 
                           "id":1,
                           "description": "remain smith of the first object" 
                          }
                      ]
           }
         ]
}

The logic should now work on items[].name or items.sections[].description (multiple entries of sections[*].description)

Problem I am facing is when I am iterating items[].name & items[].sections[*].description

It gives me all the names and all the sections.description in separate arrays what I want is that it should give me one by one.

For example first result set should give me below

[
"John"
]

and 

[
"John smith"
"remain smith of the first object" 
]

So that I can run my existing logic to check whether John is available or not. Currently my logic runs on first entry of the description and it does not check the next entry or section.description that is the reason below matching object is failing because "john" is present in the second entry of the description

{
  "items": [
             {
              "id":11,
              "name": "SMITH",
              "sections": [
                          { 
                           "id":11,
                           "description": "SMITH" 
                          },
                          { 
                           "id":11,
                           "description": "JOHN Carter" 
                          }
                      ]
           }
         ]
}

The matching logic which I am currently using is -

* def matchText = 
"""
function (nameArr, sectionArr, matchingWord)
{
for(var i = 0; i < nameArr.length; i++)
var regEx = new RegExp(matchingWord, 'gi')
var nameMatch = nameArr[i].match(regEx)
var secMatch = sectionArr[i].match(regEx)
if (nameMatch ==null && secMatch == null) {
return false;
}
}
return true;
}
"""
* def getName = get response.items[*].name
* def getDescription = get response.items[*].sections[*].description
* assert matchText(getName,getDescription,'john')

So this logic works when you have same length in name & sections.description but when sections.description has got multiple arrays then it does not iterate correctly. That was the only reason I wanted to treat the name as one object and sections.description as another even when there will be multiple child ids in it.

vdrulerz
  • 264
  • 3
  • 13

1 Answers1

1

Sample Code:

Feature: Validation

    Scenario:
        * def resp =
            """
            {
                "items": [
                    {
                        "id": 11,
                        "name": "JOHN",
                        "sections": [
                            {
                                "id": 11,
                                "description": "SMITH"
                            },
                            {
                                "id": 11,
                                "description": "JOHN Carter"
                            }
                        ]
                    }
                ]
            }
            """
    * def names = []
    * def fun =
        """
        function(x){ 
            var json  = x.sections; 
            var temp = x.name
            for(var i = 0; i < json.length; i++) {
                var obj = json[i];
                temp = temp + "," + obj.description
            }                
             karate.appendTo(names, temp);
            }
        """
    * def items = get resp.items[*]
    * karate.forEach(items, fun)
    * match each names == '#regex .*JOHN.*'
Neodawn
  • 1,086
  • 1
  • 6
  • 9
  • No buddy.....looks like you dint understand my requirement fully. You can't rely on the items.name always because there will be possibilities that "John" would not even be there in the name and just present in one of the child in the sections.description. Please go through my query again. – vdrulerz Nov 07 '19 at 08:48
  • If you had shared your code snippet it would have been helpful to understand. Anyways another try (not sure if this is what you are looking for): ` * def arr = get resp.items[0].sections[*].description * string str = arr+ "," + resp.items[0].name * match str == '#regex .*JOHN.*' ` – Neodawn Nov 07 '19 at 11:34
  • Hi @Neodawn....I have updated the question with the sample automation code. The query should be crystal to you now. – vdrulerz Nov 08 '19 at 12:14