mod entities;
mod helpers;
use entities::order::*;
use es_entity::*;
use sqlx::PgPool;
#[derive(EsRepo, Debug)]
#[es_repo(entity = "Order")]
pub struct Orders {
pool: PgPool,
#[es_repo(nested)]
items: OrderItems,
}
impl Orders {
pub fn new(pool: PgPool) -> Self {
Self {
pool: pool.clone(),
items: OrderItems::new(pool),
}
}
}
#[derive(EsRepo, Debug)]
#[es_repo(
entity = "OrderItem",
columns(order_id(ty = "OrderId", update(persist = false), parent))
)]
pub struct OrderItems {
pool: PgPool,
}
impl OrderItems {
pub fn new(pool: PgPool) -> Self {
Self { pool }
}
}
#[tokio::test]
async fn create_order_and_add_items() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let orders = Orders::new(pool);
let order_id = OrderId::new();
let new_order = NewOrderBuilder::default().id(order_id).build().unwrap();
let mut order = orders.create(new_order).await?;
for item in [
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id)
.product_name("Laptop")
.quantity(1)
.price(999.99)
.build()
.unwrap(),
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id)
.product_name("Mouse")
.quantity(2)
.price(29.99)
.build()
.unwrap(),
] {
order.add_item(item);
}
orders.update(&mut order).await?;
let loaded_order = orders.find_by_id(order_id).await?;
assert_eq!(loaded_order.n_items(), 2);
assert!(loaded_order.find_item_with_name("Laptop").is_some());
assert!(loaded_order.find_item_with_name("Mouse").is_some());
Ok(())
}
#[tokio::test]
async fn update_item() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let orders = Orders::new(pool);
let order_id = OrderId::new();
let new_order = NewOrderBuilder::default().id(order_id).build().unwrap();
let mut order = orders.create(new_order).await?;
order.add_item(
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id)
.product_name("Keyboard")
.quantity(1)
.price(79.99)
.build()
.unwrap(),
);
orders.update(&mut order).await?;
let mut loaded_order = orders.find_by_id(order_id).await?;
let keyboard = loaded_order.find_item_with_name("Keyboard").unwrap();
assert_eq!(keyboard.quantity, 1);
loaded_order.update_item_quantity("Keyboard", 3).unwrap();
let keyboard = loaded_order.find_item_with_name("Keyboard").unwrap();
assert_eq!(keyboard.quantity, 3);
orders.update(&mut loaded_order).await?;
let final_order = orders.find_by_id(order_id).await?;
let keyboard = final_order.find_item_with_name("Keyboard").unwrap();
assert_eq!(keyboard.quantity, 3);
Ok(())
}
#[tokio::test]
async fn find_all_with_nested_entities() -> anyhow::Result<()> {
let pool = helpers::init_pool().await?;
let orders = Orders::new(pool);
let order_id_1 = OrderId::new();
let order_id_2 = OrderId::new();
let order_id_3 = OrderId::new();
let mut order1 = orders
.create(NewOrderBuilder::default().id(order_id_1).build().unwrap())
.await?;
order1.add_item(
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id_1)
.product_name("Laptop")
.quantity(1)
.price(999.99)
.build()
.unwrap(),
);
order1.add_item(
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id_1)
.product_name("Mouse")
.quantity(2)
.price(29.99)
.build()
.unwrap(),
);
orders.update(&mut order1).await?;
let mut order2 = orders
.create(NewOrderBuilder::default().id(order_id_2).build().unwrap())
.await?;
order2.add_item(
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id_2)
.product_name("Keyboard")
.quantity(1)
.price(79.99)
.build()
.unwrap(),
);
orders.update(&mut order2).await?;
let mut order3 = orders
.create(NewOrderBuilder::default().id(order_id_3).build().unwrap())
.await?;
order3.add_item(
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id_3)
.product_name("Monitor")
.quantity(1)
.price(299.99)
.build()
.unwrap(),
);
order3.add_item(
NewOrderItemBuilder::default()
.id(OrderItemId::new())
.order_id(order_id_3)
.product_name("Webcam")
.quantity(1)
.price(89.99)
.build()
.unwrap(),
);
orders.update(&mut order3).await?;
let all_order_ids = vec![order_id_1, order_id_2, order_id_3];
let loaded_orders = orders.find_all::<Order>(&all_order_ids).await?;
assert_eq!(loaded_orders.len(), 3);
let loaded_order_1 = loaded_orders.get(&order_id_1).unwrap();
assert_eq!(loaded_order_1.n_items(), 2);
assert!(loaded_order_1.find_item_with_name("Laptop").is_some());
assert!(loaded_order_1.find_item_with_name("Mouse").is_some());
let loaded_order_2 = loaded_orders.get(&order_id_2).unwrap();
assert_eq!(loaded_order_2.n_items(), 1);
assert!(loaded_order_2.find_item_with_name("Keyboard").is_some());
let loaded_order_3 = loaded_orders.get(&order_id_3).unwrap();
assert_eq!(loaded_order_3.n_items(), 2);
assert!(loaded_order_3.find_item_with_name("Monitor").is_some());
assert!(loaded_order_3.find_item_with_name("Webcam").is_some());
let laptop = loaded_order_1.find_item_with_name("Laptop").unwrap();
assert_eq!(laptop.quantity, 1);
assert_eq!(laptop.price, 999.99);
let keyboard = loaded_order_2.find_item_with_name("Keyboard").unwrap();
assert_eq!(keyboard.quantity, 1);
assert_eq!(keyboard.price, 79.99);
let monitor = loaded_order_3.find_item_with_name("Monitor").unwrap();
assert_eq!(monitor.quantity, 1);
assert_eq!(monitor.price, 299.99);
let webcam = loaded_order_3.find_item_with_name("Webcam").unwrap();
assert_eq!(webcam.quantity, 1);
assert_eq!(webcam.price, 89.99);
Ok(())
}