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> { let TestData { aggregate_id, repository, mut root, .. } = bootstrap_test(false).await; // append unit, tuple and struct enum variants 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::(&aggregate_type_name) .await .expect("store to be created"); // Order aggregate should fail with invalid events store .commit( aggregate_id, CommitOrder::None, &[OrderEvent::Created.into(), OrderEvent::Created.into()], ) .await .unwrap(); repository.get(aggregate_id).await.unwrap(); }