pub struct TestApp { /* private fields */ }Expand description
The app under test, with a browser-like client.
Implementations§
Source§impl TestApp
impl TestApp
Sourcepub async fn new(app: App) -> Self
pub async fn new(app: App) -> Self
Boots app with the test configuration and runs its migrations.
Sourcepub async fn with_config(app: App, configure: impl FnOnce(&mut Config)) -> Self
pub async fn with_config(app: App, configure: impl FnOnce(&mut Config)) -> Self
Like new, after configure adjusts the test configuration.
Sourcepub fn mailer(&self) -> &Mailer
pub fn mailer(&self) -> &Mailer
The app’s mailer (the memory driver unless the config changes it).
Sourcepub fn fake_http(&self) -> FakeHttp
pub fn fake_http(&self) -> FakeHttp
Answers state.http requests with fakes and records them, instead
of reaching the network; see crate::http::FakeHttp.
Sourcepub async fn run_scheduled(&self, name: &str) -> Result
pub async fn run_scheduled(&self, name: &str) -> Result
Runs the scheduled task name now (as schedule:run does), at the
time TestApp::travel moved the clock to.
app.travel(Duration::from_secs(31 * 24 * 60 * 60)); // a month later
app.run_scheduled("monthly-report").await?;Sourcepub fn travel(&self, by: Duration) -> &Self
pub fn travel(&self, by: Duration) -> &Self
Moves the clock forward by by for what this TestApp does next:
requests, run_jobs, run_scheduled, and code run in TestApp::at_travelled_time
(renox::db::now(), sessions, signed URLs, the queue, the cache).
Adds up; TestApp::travel_back returns to the present.
// The app guards `/settings/billing` with `.require_password_confirmed()`.
app.acting_as(&user).confirm_password();
app.travel(Duration::from_secs(3 * 60 * 60)); // past the password confirmation
app.get("/settings/billing").await.assert_redirect("/confirm-password");Sourcepub fn travel_back(&self) -> &Self
pub fn travel_back(&self) -> &Self
Returns the clock to the present.
Sourcepub async fn at_travelled_time<F: Future>(&self, fut: F) -> F::Output
pub async fn at_travelled_time<F: Future>(&self, fut: F) -> F::Output
Runs fut with the clock where TestApp::travel moved it, e.g.
to call a model or a job’s code directly.
Sourcepub fn fake_events(&self) -> &Self
pub fn fake_events(&self) -> &Self
Records events instead of running their listeners, from now on; read
them with TestApp::emitted or TestApp::assert_emitted.
Sourcepub fn emitted<E: Event>(&self) -> Vec<E>
pub fn emitted<E: Event>(&self) -> Vec<E>
The events of type E emitted since fake_events, oldest first.
Sourcepub fn assert_emitted<E: Event>(&self, check: impl Fn(&E) -> bool) -> &Self
pub fn assert_emitted<E: Event>(&self, check: impl Fn(&E) -> bool) -> &Self
Panics unless an E matching check was emitted.
Sourcepub fn assert_not_emitted<E: Event>(&self) -> &Self
pub fn assert_not_emitted<E: Event>(&self) -> &Self
Panics unless no E was emitted since fake_events.
Sourcepub fn fake_notifications(&self) -> &Self
pub fn fake_notifications(&self) -> &Self
Records notifications instead of sending them (mail, database, channels), from now on.
Sourcepub fn notifications(&self) -> Vec<SentNotification>
pub fn notifications(&self) -> Vec<SentNotification>
The notifications recorded since fake_notifications, oldest first.
Sourcepub fn assert_notified(&self, user: &User, kind: &str) -> &Self
pub fn assert_notified(&self, user: &User, kind: &str) -> &Self
Panics unless user was sent a notification of kind.
Sourcepub fn assert_notified_to(&self, address: &str, kind: &str) -> &Self
pub fn assert_notified_to(&self, address: &str, kind: &str) -> &Self
Panics unless someone with address (on any channel, or a user’s
email) was sent a notification of kind.
Sourcepub fn fake_broadcasts(&self) -> &Self
pub fn fake_broadcasts(&self) -> &Self
Records what state.broadcast(…) and broadcast_to(…) send from
now on, instead of sending it to the open pages.
Sourcepub fn broadcasts(&self) -> Vec<SentBroadcast>
pub fn broadcasts(&self) -> Vec<SentBroadcast>
The broadcasts recorded since fake_broadcasts, oldest first.
Sourcepub fn assert_broadcast(
&self,
event: &str,
check: impl Fn(&SentBroadcast) -> bool,
) -> &Self
pub fn assert_broadcast( &self, event: &str, check: impl Fn(&SentBroadcast) -> bool, ) -> &Self
Panics unless an event whose data passes check was broadcast
(to anyone) since fake_broadcasts.
Sourcepub fn assert_nothing_notified(&self) -> &Self
pub fn assert_nothing_notified(&self) -> &Self
Panics unless no notification was recorded since fake_notifications.
Sourcepub fn session_get<T: DeserializeOwned>(&self, key: &str) -> Option<T>
pub fn session_get<T: DeserializeOwned>(&self, key: &str) -> Option<T>
A value in the session as the next request will see it.
Sourcepub fn assert_session_has(&self, key: &str) -> &Self
pub fn assert_session_has(&self, key: &str) -> &Self
Panics unless the session holds key.
Sourcepub fn assert_session_missing(&self, key: &str) -> &Self
pub fn assert_session_missing(&self, key: &str) -> &Self
Panics if the session holds key.
Sourcepub fn assert_authenticated(&self, user: Option<&User>) -> &Self
pub fn assert_authenticated(&self, user: Option<&User>) -> &Self
Panics unless the session is logged in (as user, when given).
Sourcepub fn assert_guest(&self) -> &Self
pub fn assert_guest(&self) -> &Self
Panics unless the session is a guest’s (no one logged in).
Sourcepub async fn serve(&self) -> String
pub async fn serve(&self) -> String
Serves the app on a free local port and returns its base URL
(http://127.0.0.1:…), e.g. for a browser test (docs/testing.md).
The server runs until the test’s runtime ends.
Sourcepub async fn run_all_jobs(&self) -> usize
pub async fn run_all_jobs(&self) -> usize
Runs every queued job, including those waiting for a delay or a
retry’s backoff, until none is left (at most 1,000 rounds); returns
how many attempts ran. For tests of retries and failed hooks.
Sourcepub async fn queued_jobs(&self) -> Vec<String>
pub async fn queued_jobs(&self) -> Vec<String>
Names of the jobs waiting in the queue, oldest first.
Sourcepub fn confirm_password(&self) -> &Self
pub fn confirm_password(&self) -> &Self
Marks the password as just typed, so routes behind
require_password_confirmed let the user through.
The session cookie as the browser holds it (name=value), e.g. to
play a second device: save one, log in again, switch back with
TestApp::use_session_cookie.
Sends this session cookie from now on (see TestApp::session_cookie).
Sourcepub fn csrf_token(&self) -> String
pub fn csrf_token(&self) -> String
The CSRF token of the current session, creating the session if needed.
Sourcepub fn request(&self) -> TestRequest<'_>
pub fn request(&self) -> TestRequest<'_>
A request with extra headers, e.g. app.request().htmx().post(..).
Sourcepub fn htmx(&self) -> TestRequest<'_>
pub fn htmx(&self) -> TestRequest<'_>
Shorthand for request().htmx().
Sourcepub async fn get(&self, uri: &str) -> TestResponse
pub async fn get(&self, uri: &str) -> TestResponse
A GET request.
Sourcepub async fn post(&self, uri: &str, form: &[(&str, &str)]) -> TestResponse
pub async fn post(&self, uri: &str, form: &[(&str, &str)]) -> TestResponse
A form post (urlencoded), with the CSRF token.
Sourcepub async fn put(&self, uri: &str, form: &[(&str, &str)]) -> TestResponse
pub async fn put(&self, uri: &str, form: &[(&str, &str)]) -> TestResponse
A form PUT (urlencoded), with the CSRF token.
Sourcepub async fn patch(&self, uri: &str, form: &[(&str, &str)]) -> TestResponse
pub async fn patch(&self, uri: &str, form: &[(&str, &str)]) -> TestResponse
A form PATCH (urlencoded), with the CSRF token.
Sourcepub async fn delete(&self, uri: &str) -> TestResponse
pub async fn delete(&self, uri: &str) -> TestResponse
A DELETE request, with the CSRF token.
Sourcepub async fn post_json(&self, uri: &str, body: &impl Serialize) -> TestResponse
pub async fn post_json(&self, uri: &str, body: &impl Serialize) -> TestResponse
A JSON post, with the CSRF token.
Sourcepub async fn post_multipart(
&self,
uri: &str,
fields: &[(&str, &str)],
files: &[(&str, &str, &[u8])],
) -> TestResponse
pub async fn post_multipart( &self, uri: &str, fields: &[(&str, &str)], files: &[(&str, &str, &[u8])], ) -> TestResponse
A multipart form with files; see TestRequest::post_multipart.
Sourcepub async fn post_body(
&self,
uri: &str,
content_type: &str,
body: impl Into<Vec<u8>>,
) -> TestResponse
pub async fn post_body( &self, uri: &str, content_type: &str, body: impl Into<Vec<u8>>, ) -> TestResponse
A POST with exactly these bytes (e.g. a signed webhook); no CSRF token.
Sourcepub async fn assert_database_has(
&self,
table: &str,
values: &[(&str, &(dyn ToDbValue + Sync))],
)
pub async fn assert_database_has( &self, table: &str, values: &[(&str, &(dyn ToDbValue + Sync))], )
Fails unless a row of table has all these column values.
Sourcepub async fn assert_database_missing(
&self,
table: &str,
values: &[(&str, &(dyn ToDbValue + Sync))],
)
pub async fn assert_database_missing( &self, table: &str, values: &[(&str, &(dyn ToDbValue + Sync))], )
Fails if a row of table has all these column values.
Sourcepub async fn assert_database_count(&self, table: &str, expected: i64)
pub async fn assert_database_count(&self, table: &str, expected: i64)
Fails unless table has exactly expected rows.
Sourcepub fn assert_mail_sent(&self, to: &str, subject: &str)
pub fn assert_mail_sent(&self, to: &str, subject: &str)
Fails unless a mail went to to with subject in its subject.
Auto Trait Implementations§
impl !Freeze for TestApp
impl !RefUnwindSafe for TestApp
impl !UnwindSafe for TestApp
impl Send for TestApp
impl Sync for TestApp
impl Unpin for TestApp
impl UnsafeUnpin for TestApp
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
impl<A, B, T> HttpServerConnExec<A, B> for Twhere
B: Body,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more