mod entities;
mod helpers;
use entities::user::*;
use es_entity::{clock::*, *};
use sqlx::PgPool;
#[derive(EsRepo, Debug)]
#[es_repo(entity = "User", columns(name(ty = "String", list_for)))]
pub struct Users {
pool: PgPool,
}
impl Users {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
}
mod users_with_clock {
use es_entity::{EsEntity, EsEvent, EsRepo, clock::ClockHandle};
use sqlx::PgPool;
use crate::entities::user::*;
#[derive(EsRepo, Debug)]
#[es_repo(entity = "User", columns(name(ty = "String", list_for)))]
pub struct UsersWithClock {
pool: PgPool,
clock: Option<ClockHandle>,
}
impl UsersWithClock {
pub fn new(pool: PgPool) -> Self {
Self { pool, clock: None }
}
pub fn with_clock(pool: PgPool, clock: ClockHandle) -> Self {
Self {
pool,
clock: Some(clock),
}
}
}
}
use users_with_clock::UsersWithClock;
mod users_with_required_clock {
use es_entity::{EsEntity, EsEvent, EsRepo, clock::ClockHandle};
use sqlx::PgPool;
use crate::entities::user::*;
#[derive(EsRepo, Debug)]
#[es_repo(entity = "User", columns(name(ty = "String", list_for)))]
pub struct UsersWithRequiredClock {
pool: PgPool,
clock: ClockHandle,
}
impl UsersWithRequiredClock {
pub fn new(pool: PgPool, clock: ClockHandle) -> Self {
Self { pool, clock }
}
}
}
use users_with_required_clock::UsersWithRequiredClock;
#[tokio::test]
async fn create_with_manual_clock() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let users = Users::new(pool);
let fixed_time = {
let t = chrono::Utc::now() - chrono::Duration::days(30);
chrono::DateTime::from_timestamp_millis(t.timestamp_millis()).unwrap()
};
let (clock, _ctrl) = ClockHandle::manual_at(fixed_time);
let mut op = users.begin_op_with_clock(&clock).await?;
let new_user = NewUser::builder()
.id(UserId::new())
.name("TimeTest")
.build()
.unwrap();
let user = users.create_in_op(&mut op, new_user).await?;
let user_id = user.id;
op.commit().await?;
let loaded_user = users.find_by_id(user_id).await?;
let recorded_at = loaded_user
.events()
.entity_first_persisted_at()
.expect("should have recorded_at");
assert_eq!(recorded_at, fixed_time);
Ok(())
}
#[tokio::test]
async fn create_with_repo_clock_field() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let fixed_time = {
let t = chrono::Utc::now() - chrono::Duration::days(60);
chrono::DateTime::from_timestamp_millis(t.timestamp_millis()).unwrap()
};
let (clock, _ctrl) = ClockHandle::manual_at(fixed_time);
let users = UsersWithClock::with_clock(pool, clock);
let new_user = NewUser::builder()
.id(UserId::new())
.name("ClockFieldTest")
.build()
.unwrap();
let user = users.create(new_user).await?;
let user_id = user.id;
let loaded_user = users.find_by_id(user_id).await?;
let recorded_at = loaded_user
.events()
.entity_first_persisted_at()
.expect("should have recorded_at");
assert_eq!(recorded_at, fixed_time);
Ok(())
}
#[tokio::test]
async fn create_with_repo_clock_field_none() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let users = UsersWithClock::new(pool);
let new_user = NewUser::builder()
.id(UserId::new())
.name("NoClockFieldTest")
.build()
.unwrap();
let user = users.create(new_user).await?;
let user_id = user.id;
let loaded_user = users.find_by_id(user_id).await?;
let recorded_at = loaded_user
.events()
.entity_first_persisted_at()
.expect("should have recorded_at");
let now = chrono::Utc::now();
let diff = now.signed_duration_since(recorded_at);
assert!(
diff.num_seconds().abs() < 10,
"recorded_at should be close to now"
);
Ok(())
}
#[tokio::test]
async fn create_with_required_clock_field() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let fixed_time = {
let t = chrono::Utc::now() - chrono::Duration::days(90);
chrono::DateTime::from_timestamp_millis(t.timestamp_millis()).unwrap()
};
let (clock, _ctrl) = ClockHandle::manual_at(fixed_time);
let users = UsersWithRequiredClock::new(pool, clock);
let new_user = NewUser::builder()
.id(UserId::new())
.name("RequiredClockTest")
.build()
.unwrap();
let user = users.create(new_user).await?;
let user_id = user.id;
let loaded_user = users.find_by_id(user_id).await?;
let recorded_at = loaded_user
.events()
.entity_first_persisted_at()
.expect("should have recorded_at");
assert_eq!(recorded_at, fixed_time);
Ok(())
}