pub struct TestClient<'a> { /* private fields */ }Expand description
Sends requests carrying cookies and tenant.
Implementations§
Source§impl<'a> TestClient<'a>
impl<'a> TestClient<'a>
pub fn new(router: &'a Router) -> Self
Sourcepub fn panel(&self, panel: &PanelHandle) -> Self
pub fn panel(&self, panel: &PanelHandle) -> Self
Resolves resource’s URLs in panel, the handle the router’s builder
gives through panel_handle.
let builder = Router::builder().discover().with(db).panel(panel)?;
let admin = builder.panel_handle("admin").expect("mounted above");
let router = builder.build();
let client = tablo_test::TestClient::new(&router).panel(&admin);Sourcepub fn resource<R: Resource>(&self) -> ResourceClient<'_, 'a, R>
pub fn resource<R: Resource>(&self) -> ResourceClient<'_, 'a, R>
Attaches a cookie to every request; a later value for the same name replaces the earlier one.
Attaches every (name, value) pair, replacing earlier values for the
same name.
Sourcepub fn language(&self, languages: &str) -> Self
pub fn language(&self, languages: &str) -> Self
Sends Accept-Language: {languages} with every request, as a browser preferring them does:
"fr-CA, en;q=0.5".
Sourcepub fn csrf(&self, token: &str) -> Self
pub fn csrf(&self, token: &str) -> Self
Attach the CSRF cookie the form’s csrf_token field must match.
Sourcepub async fn sign_in(&self, db: &Db, panel: &str, user: &impl PanelUser) -> Self
pub async fn sign_in(&self, db: &Db, panel: &str, user: &impl PanelUser) -> Self
Signs user in to the panel Panel::new(panel) mounts, as a successful login does, and
attaches the session cookie; no password is hashed or checked.
The session row goes into db, the router’s database, keyed to PanelUser::user_id:
each request loads the user back through the panel’s Authenticator::find_by_id, so a
custom authenticator works as the shipped one does.
let admin = tablo_core::auth::create_admin(&mut db, "admin@example.com", "secret", "Admin")
.await
.expect("seed the admin");
let client = TestClient::new(router).sign_in(&db, "admin", &admin).await;§Panics
When the session row cannot be written, e.g. the database does not register
AuthSession.
Sourcepub async fn log_in(
&self,
panel: &str,
email: &str,
password: &str,
next: &str,
) -> (Self, Response<Body>)
pub async fn log_in( &self, panel: &str, email: &str, password: &str, next: &str, ) -> (Self, Response<Body>)
Signs in through the login form of the panel Panel::new(panel) mounts, as a browser
does: loads the page, posts email and password with the page’s CSRF token, and keeps
the cookies both responses set. Returns the client and the login response, which
redirects on success and re-renders the form on a refusal.
next is the page to land on after signing in, "" for the panel’s home. Prefer
sign_in unless the test is about the login itself.
§Panics
When the login page renders no csrf_token input: the panel’s authentication is off.
Sourcepub fn tenant(&self, tenant: TenantId) -> Self
pub fn tenant(&self, tenant: TenantId) -> Self
Acts for tenant, as a browser that switched to it from the tenant menu: a signed-in user
who is not one of its members acts for their own tenant instead, so a cross-tenant test
reaches only what a browser would. With nobody signed in, such as on a panel with auth
disabled, the request acts for tenant.
pub async fn get(&self, uri: &str) -> Response<Body>
pub async fn head(&self, uri: &str) -> Response<Body>
pub async fn post_form(&self, uri: &str, body: String) -> Response<Body>
Sourcepub async fn submit(&self, uri: &str, body: &str) -> Response<Body>
pub async fn submit(&self, uri: &str, body: &str) -> Response<Body>
Posts the urlencoded body as a panel form does: with the CSRF token in both the cookie
and the csrf_token field, the one csrf attached, else a fresh one.
Sourcepub async fn submit_multipart(
&self,
uri: &str,
parts: &[(&str, Option<&str>, &str)],
) -> Response<Body>
pub async fn submit_multipart( &self, uri: &str, parts: &[(&str, Option<&str>, &str)], ) -> Response<Body>
Posts multipart_body’s parts as a panel form with a file input does: with the CSRF
token in both the cookie and a csrf_token part, as submit picks it.
pub async fn post_multipart( &self, uri: &str, boundary: &str, body: String, ) -> Response<Body>
Sourcepub async fn call_procedure(&self, path: &str, args: &str) -> Response<Body>
pub async fn call_procedure(&self, path: &str, args: &str) -> Response<Body>
Calls the runtime procedure served at path with args, the JSON array of its
arguments, as the browser’s runtime does: a JSON POST that answers with the JSON of its
result.
let response = client
.call_procedure(
"/_topcoat/runtime/procedures/tablo-notifications/mark",
&format!(r#"["{id}", true]"#),
)
.await;
assert_eq!(response.status(), 200);