mod common;
use timesource::error::Error;
use timesource::store::{CommitOrder, EventStore, EventStoreBuilder};
use uuid::Uuid;
use crate::common::data::{bootstrap_test, TestData, DSN};
use crate::common::order::{OrderCommand, OrderEvent, OrderItem};
#[tokio::test]
async fn repository_should_reconstruct_state_after_appending_all_variants_of_events(
) -> Result<(), Box<dyn std::error::Error>> {
let TestData {
aggregate_id,
repository,
mut root,
..
} = bootstrap_test(false).await;
root.handle(OrderCommand::Create)?;
root.handle(OrderCommand::AddItem {
item: OrderItem {
item_sku: "sku-123".into(),
quantity: 1,
price: 12,
},
})?;
root.handle(OrderCommand::Empty("some reason".into()))?;
repository.commit_orderly(&mut root).await?;
let stored = repository.get(aggregate_id).await?;
let stored_state = stored.state().to_owned().unwrap();
let expected_state = root.state().unwrap();
assert_eq!(
expected_state.items, stored_state.items,
"Stored items are not what's expected"
);
assert_eq!(
expected_state.created_at, stored_state.created_at,
"Order created_at timestamp doesn't match"
);
Ok(())
}
#[tokio::test]
async fn repository_should_err_if_not_found() {
let TestData { repository, .. } = bootstrap_test(false).await;
let output = repository.get(Uuid::new_v4()).await;
match output {
Ok(_) => unreachable!(),
Err(Error::AggregateRootNotFound) => (),
Err(_) => unreachable!(),
}
}
#[tokio::test]
#[should_panic(expected = "Aggregate(AlreadyCreated)")]
async fn should_propagate_aggregate_err() {
let TestData {
aggregate_type_name,
repository,
aggregate_id,
..
} = bootstrap_test(false).await;
let store = EventStoreBuilder::new(DSN)
.build::<OrderEvent>(&aggregate_type_name)
.await
.expect("store to be created");
store
.commit(
aggregate_id,
CommitOrder::None,
&[OrderEvent::Created.into(), OrderEvent::Created.into()],
)
.await
.unwrap();
repository.get(aggregate_id).await.unwrap();
}