title: REST Assured: How to find element using nested property in JSON and validate other properties
body: <p>I have limited experience with rest assured. We have a number of tests that I can usually find examples within, or failing that google, but I am stuck when trying to match on a nested property for an element in an anonymous array, and verify properties up across and down (cousins?).</p>
  
  <p>Example JSON:</p>
  
  <pre><code>[  
     {  
        "id":1,
        "type":{  
           "typeId":3,
           "name":"LPM"
        },
        "status":{  
           "id":1,
           "price":1.20,
           "source":172,
           "valid":0
        }
     },
     {  
        "id":2,
        "type":{  
           "typeId":2,
           "name":"ST"
        },
        "status":{  
           "id":10,
           "price":1.20,
           "source":172,
           "valid":0
        }
     }
  ]
  </code></pre>
  
  <p>I'm using rest assured, and I want to find the element in the list that has <code>type.name</code> equal to LPM, and then validate <code>status.price</code>, <code>status.source</code>, and <code>status.id</code> of only that element.</p>
  
  <p>When I initially started validating the responses, it was only possible for one item to be in the array, so I was using:</p>
  
  <pre><code>response.then()
          .assertThat()
          .body("size", greaterThan(0))
          .body("[0].type.name", equalToIgnoringCase("LPM"))
          .body("[0].status.id", equalTo(statusId))
          .body("[0].status.source", equalTo(sourceId))
          .body("[0].status.price", equalTo(price));
  </code></pre>
  
  <p>However this is no longer assured to work, as there may be more than one element in the array, and the order is not guaranteed.</p>
  
  <p>I have modified my body checks to be:</p>
  
  <pre><code>response.then()
          .assertThat()
          .body("size", greaterThan(0))
          .body("type.name", hasItem("LPM"))
          .body("status.id", hasItem(statusId))
          .body("status.source", hasItem(sourceId))
          .body("status.price", hasItem(price));
  </code></pre>
  
  <p>This is enough to get the test to pass, but this introduces the risk that the <code>status.id</code>, <code>status.source</code>, and <code>status.price</code> of the element with <code>type.name</code> LPM could be incorrect, but this would not be detected as they would be matched against the element with <code>type.name</code> ST.</p>
  
  <p>So I want to be able to find the element which has LPM as it's <code>type.name</code>, of which I can guarantee there to be only one, and then for <code>status.id</code>, <code>status.source</code>, and <code>status.price</code>, check that element only, i.e. <strong>NOT</strong> the ST element.</p>
  
  <p>I tried to modify my body matcher to find the elements with the <code>type.name</code> that I need, but I can't get this to work, as I can't figure out how to go back up the tree, across and down, to check other attributes in the same element:</p>
  
  <pre><code>response.then()
          .assertThat()
          .body("size", greaterThan(0))
          .body("$.findAll (it.type.name = LPM}.status.id ", hasItem(statusId))
          .body("$.findAll (it.type.name = LPM}.status.source", hasItem(sourceId))
          .body("$.findAll (it.type.name = LPM}.status.price", hasItem(price));
  </code></pre>
  
  <p>Also even if this worked, it would search the tree 3 times when really once would have done.</p>
  
  <p>My middle matches have this test passing for now but I want to get this right. I'm aware I could get the elements into a <code>List</code> and work it out from there, but for consistency with the rest of our examples I'd rather not, though I currently can't see another option.</p>
  
  <p>I have tried to find examples of what I'm trying to do in documentation, multiple rest assured tutorials and examples but I haven't, so there is always the possibility that this isn't actually possible. If not I'm happy to educate don the theory behind it.</p>
  
  <p>Any help appreciated.</p>