1
0
mirror of https://github.com/matrix-org/matrix-authentication-service.git synced 2025-07-31 09:24:31 +03:00

Stop using Utc::now in templates samples

This commit is contained in:
Quentin Gliech
2022-10-24 09:33:24 +02:00
parent 44d09b68e7
commit f0d95a7613
5 changed files with 74 additions and 69 deletions

View File

@ -15,6 +15,7 @@
use std::path::PathBuf;
use clap::Parser;
use mas_storage::Clock;
use mas_templates::Templates;
#[derive(Parser, Debug)]
@ -57,10 +58,11 @@ impl Options {
}
SC::Check { path, skip_builtin } => {
let clock = Clock::default();
let url_builder = mas_router::UrlBuilder::new("https://example.com/".parse()?);
let templates =
Templates::load(Some(path.into()), !skip_builtin, url_builder).await?;
templates.check_render().await?;
templates.check_render(clock.now()).await?;
Ok(())
}

View File

@ -31,7 +31,7 @@ where
T::UserData: Default,
{
#[must_use]
pub fn samples() -> Vec<Self> {
pub fn samples(_now: chrono::DateTime<Utc>) -> Vec<Self> {
vec![User {
data: Default::default(),
username: "john".to_owned(),
@ -105,13 +105,13 @@ where
T::UserData: Default,
{
#[must_use]
pub fn samples() -> Vec<Self> {
User::<T>::samples()
pub fn samples(now: chrono::DateTime<Utc>) -> Vec<Self> {
User::<T>::samples(now)
.into_iter()
.map(|user| BrowserSession {
data: Default::default(),
user,
created_at: Utc::now(),
created_at: now,
last_authentication: None,
})
.collect()
@ -143,18 +143,18 @@ where
T::UserEmailData: Default,
{
#[must_use]
pub fn samples() -> Vec<Self> {
pub fn samples(now: chrono::DateTime<Utc>) -> Vec<Self> {
vec![
Self {
data: T::UserEmailData::default(),
email: "alice@example.com".to_owned(),
created_at: Utc::now(),
confirmed_at: Some(Utc::now()),
created_at: now,
confirmed_at: Some(now),
},
Self {
data: T::UserEmailData::default(),
email: "bob@example.com".to_owned(),
created_at: Utc::now(),
created_at: now,
confirmed_at: None,
},
]
@ -195,13 +195,13 @@ where
T::UserEmailData: Default + Clone,
{
#[must_use]
pub fn samples() -> Vec<Self> {
pub fn samples(now: chrono::DateTime<Utc>) -> Vec<Self> {
let states = [
UserEmailVerificationState::AlreadyUsed {
when: Utc::now() - Duration::minutes(5),
when: now - Duration::minutes(5),
},
UserEmailVerificationState::Expired {
when: Utc::now() - Duration::hours(5),
when: now - Duration::hours(5),
},
UserEmailVerificationState::Valid,
];
@ -209,11 +209,11 @@ where
states
.into_iter()
.flat_map(|state| {
UserEmail::samples().into_iter().map(move |email| Self {
UserEmail::samples(now).into_iter().map(move |email| Self {
data: Default::default(),
code: "123456".to_owned(),
email,
created_at: Utc::now() - Duration::minutes(10),
created_at: now - Duration::minutes(10),
state: state.clone(),
})
})

View File

@ -77,13 +77,13 @@ pub trait TemplateContext: Serialize {
///
/// This is then used to check for template validity in unit tests and in
/// the CLI (`cargo run -- templates check`)
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized;
}
impl TemplateContext for () {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -101,11 +101,11 @@ pub struct WithCsrf<T> {
}
impl<T: TemplateContext> TemplateContext for WithCsrf<T> {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
T::sample()
T::sample(now)
.into_iter()
.map(|inner| WithCsrf {
csrf_token: "fake_csrf_token".into(),
@ -125,14 +125,14 @@ pub struct WithSession<T> {
}
impl<T: TemplateContext> TemplateContext for WithSession<T> {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
BrowserSession::samples()
BrowserSession::samples(now)
.into_iter()
.flat_map(|session| {
T::sample().into_iter().map(move |inner| WithSession {
T::sample(now).into_iter().map(move |inner| WithSession {
current_session: session.clone(),
inner,
})
@ -151,16 +151,16 @@ pub struct WithOptionalSession<T> {
}
impl<T: TemplateContext> TemplateContext for WithOptionalSession<T> {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
BrowserSession::samples()
BrowserSession::samples(now)
.into_iter()
.map(Some) // Wrap all samples in an Option
.chain(std::iter::once(None)) // Add the "None" option
.flat_map(|session| {
T::sample()
T::sample(now)
.into_iter()
.map(move |inner| WithOptionalSession {
current_session: session.clone(),
@ -188,7 +188,7 @@ impl Serialize for EmptyContext {
}
impl TemplateContext for EmptyContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -212,7 +212,7 @@ impl IndexContext {
}
impl TemplateContext for IndexContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -274,7 +274,7 @@ pub struct LoginContext {
}
impl TemplateContext for LoginContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -348,7 +348,7 @@ pub struct RegisterContext {
}
impl TemplateContext for RegisterContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -392,7 +392,7 @@ pub struct ConsentContext {
}
impl TemplateContext for ConsentContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -423,7 +423,7 @@ pub struct PolicyViolationContext {
}
impl TemplateContext for PolicyViolationContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -471,7 +471,7 @@ pub struct ReauthContext {
}
impl TemplateContext for ReauthContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -510,7 +510,7 @@ pub struct CompatSsoContext {
}
impl TemplateContext for CompatSsoContext {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -519,10 +519,10 @@ impl TemplateContext for CompatSsoContext {
data: (),
redirect_uri: Url::parse("https://app.element.io/").unwrap(),
login_token: "abcdefghijklmnopqrstuvwxyz012345".into(),
created_at: Utc::now(),
created_at: now,
state: CompatSsoLoginState::Pending,
},
action: PostAuthAction::ContinueCompatSsoLogin { data: Ulid::new() },
action: PostAuthAction::ContinueCompatSsoLogin { data: Ulid::nil() },
}]
}
}
@ -563,11 +563,11 @@ impl AccountContext {
}
impl TemplateContext for AccountContext {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
let emails: Vec<UserEmail<()>> = UserEmail::samples();
let emails: Vec<UserEmail<()>> = UserEmail::samples(now);
vec![Self::new(5, emails)]
}
}
@ -588,11 +588,11 @@ impl<T: StorageBackend> AccountEmailsContext<T> {
}
impl<T: StorageBackend> TemplateContext for AccountEmailsContext<T> {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
let emails: Vec<UserEmail<T>> = UserEmail::samples();
let emails: Vec<UserEmail<T>> = UserEmail::samples(now);
vec![Self::new(emails)]
}
}
@ -613,17 +613,17 @@ impl EmailVerificationContext {
}
impl TemplateContext for EmailVerificationContext {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
User::samples()
User::samples(now)
.into_iter()
.map(|user| {
let email = UserEmail {
data: (),
email: "foobar@example.com".to_owned(),
created_at: Utc::now(),
created_at: now,
confirmed_at: None,
};
@ -631,7 +631,7 @@ impl TemplateContext for EmailVerificationContext {
data: (),
code: "123456".to_owned(),
email,
created_at: Utc::now(),
created_at: now,
state: mas_data_model::UserEmailVerificationState::Valid,
};
@ -685,14 +685,14 @@ impl EmailVerificationPageContext {
}
impl TemplateContext for EmailVerificationPageContext {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
let email = UserEmail {
data: (),
email: "foobar@example.com".to_owned(),
created_at: Utc::now(),
created_at: now,
confirmed_at: None,
};
@ -740,7 +740,7 @@ impl EmailAddContext {
}
impl TemplateContext for EmailAddContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
@ -756,11 +756,11 @@ pub struct FormPostContext<T> {
}
impl<T: TemplateContext> TemplateContext for FormPostContext<T> {
fn sample() -> Vec<Self>
fn sample(now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{
let sample_params = T::sample();
let sample_params = T::sample(now);
sample_params
.into_iter()
.map(|params| FormPostContext {
@ -790,7 +790,7 @@ pub struct ErrorContext {
}
impl TemplateContext for ErrorContext {
fn sample() -> Vec<Self>
fn sample(_now: chrono::DateTime<Utc>) -> Vec<Self>
where
Self: Sized,
{

View File

@ -362,24 +362,24 @@ register_templates! {
impl Templates {
/// Render all templates with the generated samples to check if they render
/// properly
pub async fn check_render(&self) -> anyhow::Result<()> {
check::render_login(self).await?;
check::render_register(self).await?;
check::render_consent(self).await?;
check::render_policy_violation(self).await?;
check::render_sso_login(self).await?;
check::render_index(self).await?;
check::render_account_index(self).await?;
check::render_account_password(self).await?;
check::render_account_emails::<()>(self).await?;
check::render_account_add_email(self).await?;
check::render_account_verify_email(self).await?;
check::render_reauth(self).await?;
check::render_form_post::<EmptyContext>(self).await?;
check::render_error(self).await?;
check::render_email_verification_txt(self).await?;
check::render_email_verification_html(self).await?;
check::render_email_verification_subject(self).await?;
pub async fn check_render(&self, now: chrono::DateTime<chrono::Utc>) -> anyhow::Result<()> {
check::render_login(self, now).await?;
check::render_register(self, now).await?;
check::render_consent(self, now).await?;
check::render_policy_violation(self, now).await?;
check::render_sso_login(self, now).await?;
check::render_index(self, now).await?;
check::render_account_index(self, now).await?;
check::render_account_password(self, now).await?;
check::render_account_emails::<()>(self, now).await?;
check::render_account_add_email(self, now).await?;
check::render_account_verify_email(self, now).await?;
check::render_reauth(self, now).await?;
check::render_form_post::<EmptyContext>(self, now).await?;
check::render_error(self, now).await?;
check::render_email_verification_txt(self, now).await?;
check::render_email_verification_html(self, now).await?;
check::render_email_verification_subject(self, now).await?;
Ok(())
}
}
@ -390,8 +390,11 @@ mod tests {
#[tokio::test]
async fn check_builtin_templates() {
#[allow(clippy::disallowed_methods)]
let now = chrono::Utc::now();
let url_builder = UrlBuilder::new("https://example.com/".parse().unwrap());
let templates = Templates::load(None, true, url_builder).await.unwrap();
templates.check_render().await.unwrap();
templates.check_render(now).await.unwrap();
}
}

View File

@ -96,9 +96,9 @@ macro_rules! register_templates {
#[doc = concat!("Render the `", $template, "` template with sample contexts")]
pub async fn $name
$(< $( $lt $( : $clt $(+ $dlt )* + TemplateContext )? ),+ >)?
(templates: &Templates)
(templates: &Templates, now: chrono::DateTime<chrono::Utc>)
-> anyhow::Result<()> {
let samples: Vec< $param > = TemplateContext::sample();
let samples: Vec< $param > = TemplateContext::sample(now);
let name = $template;
for sample in samples {