Client configuration
Grillon can be configured in different ways. We use Hyper as the default HTTP client and provide you with a default configuration. By using Hyper, we can leverage on the low-level API to inspect HTTP requests and responses and provide interesting features to Grillon.
Default client implementation
The default client implementation should provide you with the most common features. All you need to do is configure the base API URL when you create an instance of Grillon.
let grillon = Grillon::new("https://jsonplaceholder.typicode.com")?;
This way you don't have to rewrite the base URL each time you want to send a request and perform
assertions on the response. You can reuse the existing client and create a new request. In the
following example we send a POST
request to https://jsonplaceholder.typicode.com/posts
:
let request = grillon
.post("posts")
.payload(json!({
"title": "foo",
"body": "bar",
"userId": 1
}))
.assert()
.await;
The assert
function consumes the
grillon::Request
and prevents
further changes to the structure of the request when users want to run assertions on the response.
Refer to the Requests chapter for more information about how to configure your requests. Note that at the moment Grillon only supports HTTP(s), but later we will extend the use for different protocols and frameworks such as gRPC or SSL.
Session and authentication
Store cookies
You can update your client to enable or disable the cookie store with store_cookies
:
// If an http response contains `Set-Cookie` headers, then cookies will be saved for
// subsequent http requests.
let grillon = Grillon::new("https://server.com/")?.store_cookies(true)?;
grillon.post("auth").assert().await.headers(contains(vec![(
SET_COOKIE,
HeaderValue::from_static("SESSIONID=123; HttpOnly"),
)]));
grillon
.get("authenticated/endpoint") // An endpoint where the session cookie `SESSIONID=123` is required.
.assert()
.await
.status(is_success());
The cookie store is disabled by default.
Basic Auth
You can easily configure your headers with the basic_auth
function to set a per-request authentication:
Grillon::new("https://server.com/")?
.get("auth/basic/endpoint")
.basic_auth("isaac", Some("rayne"))
.assert()
.await
.status(is_success());
Note that the header is considered as sensitive and will not be logged.
Bearer token
You can also use the bearer_auth
function to set your Bearer
header per-request:
Grillon::new("https://server.com/")?
.get("auth/bearer/endpoint")
.bearer_auth("token-123")
.assert()
.await
.status(is_success());
This header is also considered as sensitive and will not be logged.
Use a different client
When you want to use a different client to send your requests and handle the responses, you should
use the internal http response representation to assert. For that you need to use the
Assert
structure.
For example, suppose you want to use reqwest
to perform an http GET
request and you want to
assert that the response time
is less than
400ms. First you need to create your own structure
that will handle a reqwest::Response
.
struct MyResponse {
pub response: reqwest::Response,
}
Next, you need to implement the
grillon::Response
trait to describe
how you handle the various pieces of information that Grillon needs to perform assertions:
#[async_trait(?Send)]
impl Response for MyResponse {
fn status(&self) -> StatusCode {
self.response.status()
}
async fn json(self) -> Option<Value> {
self.response.json::<Value>().await.ok()
}
fn headers(&self) -> HeaderMap {
self.response.headers().clone()
}
}
The next step is to create a new Assert
instance which requires:
- An implementation of a
grillon::Response
, - the response time in milliseconds,
- and the
LogSettings
for the assertion results.
Let's first run the request and get the execution time:
let now = Instant::now();
let response = reqwest::get(mock_server.server.url("/users/1"))
.await
.expect("Failed to send the http request");
let response_time = now.elapsed().as_millis() as u64;
Now let's pass the response to your own response structure:
let my_response = MyResponse { response };
You are now ready to assert against a reqwest::Response
wrapped by your own implementation of a
grillon::Response
:
Assert::new(my_response, response_time, LogSettings::default())
.await
.response_time(is_less_than(400));