imbo / behat-api-extension

API extension for Behat, used to ease testing of JSON-based APIs
MIT License
107 stars 42 forks source link

The response body contains object is not working as expected #133

Open josep11 opened 1 year ago

josep11 commented 1 year ago

Hi all,

I found an issue when asserting the response body for a LIST endpoint. Discovered it because the endpoint is working as expected but the behat test were not passing.

Essentially the problem is that when using the step definition "And the response body contains JSON" in conjunction with an assertion for object "@variableType(object)" it's not working because the method ApiContext::assertResponseBodyContainsJson converts everything into an associative array.

Response returned by the API:

[
    {
        "id": "evt-05820f88852740a4852ad04a49a47997",
        "calendar_id": "16881371283040",
        "custom_data": {}
    }
]

Behat test:

Scenario Outline: Event LIST: Response Structure

        When I get the event list
        Then the response code is 200
        And the response body contains JSON:
"""
    [
      {
        "id": "@variableType(string)",
        "calendar_id": "@variableType(string)",
        "custom_data": "@variableType(object)"
      }
    ]
"""

More background

Essentially the issue is with this line: https://github.com/imbo/behat-api-extension/blob/099d66bf84e17ab6713de00941dbe738376aaae9/src/Context/ApiContext.php#L1198 As it parses both "[]" and "{}" values into an associative array, therefore, making the assertion for variable type object not working.

christeredvartsen commented 1 year ago

Thanks for raising this issue. I have created a test locally that recreates the issue, and I will see if I can come up with a proper solution for it.

josep11 commented 1 year ago

@christeredvartsen I believe for the solution we will need to pass along an alternative haystack variable (decoded body as a non-associative array) into the method ArrayContainsComparator::compare and then in the foreach of that method check the $value to see if it equal to "@variableType(object)". If that happens, then pick the alternative haystack. I think that will work.