The response_data
helper will dig through a graphql response, through
the outer hash, into the response data for an operation, and through any
and all layers of hash and array.
response_data *[dig_pattern]
Data returned via this helper will assume a "data" =>
key at the root of
the response
object. This root does not need to be specified in the list
of attributes for the dig_pattern
.
*[dig_pattern]
- an array of attributes (:symbol
,"string"
, orkey: :value
pair) that describes the data structure to dig through, and the final data set to retrieve from the graphql response.
Each attribute added to the dig_pattern
represents an attribute at the given level of the
data structure, in numeric order from left to right. The first attribute provides will dig into
that attribute at the first level of data (just below the "data" =>
key). The second attribute
will dig through data just below that first level, etc. etc. etc.
For example, with a data structure as shown below, in "Basic Use", you could specifiy these attributes for the dig pattern:
- :characters
- :name
Like this:
response_data :characters, :name
This dig pattern will find the "characters"
key just below "data"
, then iterate through
the array of characters and retrieve the "name"
of each character.
For more details and options for the dig pattern, see the examples below.
A response
data structure may look something like the following.
{
"data" => {
"characters" => [
{ "id" => "1", "name" => "Jam" },
{ "id" => "2", "name" => "Redemption" },
{ "id" => "3", "name" => "Pet" }
]
}
}
The response_data
helper will dig through to give you simplified
results that are easier to verify.
For example, if only the names of the characters need to be checked:
response_data :characters, :name
# => ["Jam", "Redemption", "Pet"]
Or perhaps only the name for 2nd character is needed:
response_data {characters: [1]}, :name
# => "Redemption"
Many responses from a graphql call will include an array of data somewhere in the data structure. If you need to return all of the items in an array, you only need to specify that array's key:
it "has characters" do
characters = response_data(:characters)
expect(character).to include(
{ id: 1, name: "Jam" },
# ...
)
end
When validation only needs to occur on a specific field for items found in an array, there are two options.
- Specify a list of fields as already shown
- change the array's key to a hash and provide a
:symbol
wrapped in an array as the value
The first option was already shown in the Basic Use section above.
response_data :characters, :name
# => ["Jam", "Redemption", "Pet"]
For the second option, the code would look like this:
response_data characters: [:name]
# => ["Jam", "Redemption", "Pet"]
Both of these options are functionaly the same. The primary difference will be how you wish to express the data structure in your code. Changing the list of attributes to a hash with an array wrapping the value will provide a better indication that an array is expected at that point in the data structure.
There may be times when only a single piece of a returned array needs to be validated. To handle this, switch the key of the array to a hash, as in the previous example. Rather than specifying a child node's key in the value, though, specify the index of the item you wish to extract.
response_data characters: [1]
This will return the character at index 1, from the array of characters.
If there is no data the key supplied, the helper will return nil
response_data(:something_that_does_not_exist) #=> nil