Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Assertion JSON shouldcontainjsonkeyvalue should support filter results as value #3980

Closed
anthraxn8b opened this issue Apr 25, 2024 · 7 comments

Comments

@anthraxn8b
Copy link

anthraxn8b commented Apr 25, 2024

If using the "shouldcontainjsonkeyvalue" (https://kotest.io/docs/assertions/json/content-json-matchers.html#shouldcontainjsonkeyvalue
) function with a path containing a filter, the returned value of the json path is always a list.
It seems as if "shouldcontainjsonkeyvalue" does not expect this behavior.

Example:
DATA:
[ {"name":"name_I_am_looking_for", "status":"HEALTHY"}, {"name":"name_I_am_NOT_looking_for", "status":"UNHEALTHY"} ]
PATH:
$[?(@.name=='name_I_am_looking_for')].status
VALUE:
["HEALTHY"]

This value seems not to be expected and cannot be handled by the assertion.

Interesting question: How can I handle the resulting array / define an array that will match? (sorting,...)

If this functionality is already present, please tell me how :-)

UPDATE 1:

Kotest version: 5.8.1

Code used:

val eventuallyConfig = eventuallyConfig {
    initialDelay = 60.seconds
    duration = 30.seconds
    interval = 1.seconds
}

test("Healthchecks successful") {
    testApplication {
        environment {
            config = ApplicationConfig("application.conf")
        }
        eventually(eventuallyConfig) {
            var response = client.get("/liveness")
            var responseBodyAsText = response.bodyAsText()
            responseBodyAsText.shouldContainJsonKeyValue(
                "\$[?(@.name=='some_name_i_look_for')].status",
                "Healthy"
            )
        }
    }
}

(I tried with values like "Healthy" and "["Healthy"]"...)

@mirageoasis
Copy link
Contributor

mirageoasis commented Apr 26, 2024

can you tell me the version of kotest you are using?
and code you are using in this example

I assume you want to code like this

what you want

val data = """
    [ {"name":"name_I_am_looking_for", "status":"HEALTHY"}, {"name":"name_I_am_NOT_looking_for", "status":"UNHEALTHY"} ]
""".trimIndent()
val path = """
    ${'$'}[?(@.name=='name_I_am_looking_for')].status
""".trimIndent()

data.shouldContainJsonKeyValue("$[?(@.name=='name_I_am_looking_for')].status", "HEALTHY")

instead of

val data = """
    [ {"name":"name_I_am_looking_for", "status":"HEALTHY"}, {"name":"name_I_am_NOT_looking_for", "status":"UNHEALTHY"} ]
""".trimIndent()
val path = """
    ${'$'}[?(@.name=='name_I_am_looking_for')].status
""".trimIndent()

data.shouldContainJsonKeyValue("$[?(@.name=='name_I_am_looking_for')].status", listOf("HEALTHY"))

@anthraxn8b
Copy link
Author

anthraxn8b commented Apr 26, 2024

@mirageoasis, should I use "listOf("Healthy")? I'll try it! Give me a second...

A second later...
Well! This seems indeed to work! THX!!!
Maybe it would not be a bad idea to add such an example in the documentation - just for kotest-noobs like me... ;-)

@mirageoasis
Copy link
Contributor

@mirageoasis, should I use "listOf("Healthy")? I'll try it! Give me a second...

A second later... Well! This seems indeed to work! THX!!! Maybe it would not be a bad idea to add such an example in the documentation - just for kotest-noobs like me... ;-)

seems like your point makes sense maybe I can improve code to support single element

@mirageoasis
Copy link
Contributor

@anthraxn8b
well while I was looking around the kotest code

implementation code was like

      val passed = value != null && try {
         JsonPath.parse(value).read(path, T::class.java) == t
      } catch (e: PathNotFoundException) {
         false
      } catch (e: InvalidPathException) {
         throw AssertionError("$path is not a valid JSON path")
      }

and this JsonPath.read only returns Java Array

I think it would be helpful to raise Error if type other then collection comes in to prevent confusion like your case

and also fix the docs

@anthraxn8b
Copy link
Author

@mirageoasis, do not overcomplicate it! ;-)
I just did not understand / know the right way to go.
Therefor maybe it makes sense to improve the docs.

@mirageoasis
Copy link
Contributor

think fixing is unnecessary
look here
link

jsonData.shouldContainJsonKeyValue("\$[0].status", "HEALTHY")

when I wrote code like this it passed the test

which means problem lies in JsonPath query not this shouldContainJsonKeyValue.

@anthraxn8b
Copy link
Author

@mirageoasis, jpath does it absolutely right. It is defined that in case a filter is used, a list of elements is returned.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants