use crate::prelude::*;
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn create_initializes_version(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let item = toasty::create!(Item { name: "hello" })
.exec(&mut db)
.await?;
assert_eq!(item.version, 1);
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn update_increments_version(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let mut item = toasty::create!(Item { name: "hello" })
.exec(&mut db)
.await?;
assert_eq!(item.version, 1);
item.update().name("world").exec(&mut db).await?;
assert_eq!(item.version, 2);
item.update().name("again").exec(&mut db).await?;
assert_eq!(item.version, 3);
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn stale_update_fails(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let mut item = toasty::create!(Item { name: "hello" })
.exec(&mut db)
.await?;
assert_eq!(item.version, 1);
let mut stale = Item::filter_by_id(item.id).get(&mut db).await?;
assert_eq!(stale.version, 1);
item.update().name("updated").exec(&mut db).await?;
assert_eq!(item.version, 2);
let result: Result<()> = stale.update().name("should fail").exec(&mut db).await;
assert!(
result.is_err(),
"expected stale update to fail, but it succeeded"
);
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn duplicate_create_fails(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let item = toasty::create!(Item { name: "original" })
.exec(&mut db)
.await?;
let result = toasty::create!(Item {
id: item.id,
name: "duplicate"
})
.exec(&mut db)
.await;
assert!(
result.is_err(),
"expected duplicate create to fail, but it succeeded"
);
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn batch_insert_checks_version(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let items = toasty::create!(Item::[
{ name: "first" },
{ name: "second" },
])
.exec(&mut db)
.await?;
assert_eq!(items.len(), 2);
assert!(items.iter().all(|i| i.version == 1));
let existing_id = items[0].id;
let result = toasty::create!(Item::[
{ id: existing_id, name: "duplicate" },
{ name: "new" },
])
.exec(&mut db)
.await;
assert!(
result.is_err(),
"expected batch create with duplicate to fail"
);
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::tagged_item))]
pub async fn query_update_multi_key_works(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let items = toasty::create!(Item::[
{ tag: "batch", status: "active", name: "alpha" },
{ tag: "batch", status: "active", name: "beta" },
])
.exec(&mut db)
.await?;
Item::filter_by_tag("batch")
.update()
.name("updated")
.exec(&mut db)
.await?;
let a2 = Item::filter_by_id(items[0].id).get(&mut db).await?;
let b2 = Item::filter_by_id(items[1].id).get(&mut db).await?;
assert_eq!(a2.name, "updated");
assert_eq!(b2.name, "updated");
Ok(())
}
#[driver_test(
requires(not(sql)),
scenario(crate::scenarios::versioned_user_unique_email)
)]
pub async fn unique_index_update_increments_version(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let mut user = toasty::create!(User {
email: "alice@example.com"
})
.exec(&mut db)
.await?;
assert_eq!(user.version, 1);
user.update()
.email("alice2@example.com")
.exec(&mut db)
.await?;
assert_eq!(user.version, 2);
user.update()
.email("alice3@example.com")
.exec(&mut db)
.await?;
assert_eq!(user.version, 3);
Ok(())
}
#[driver_test(
requires(not(sql)),
scenario(crate::scenarios::versioned_user_unique_email)
)]
pub async fn unique_index_stale_update_fails(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let mut user = toasty::create!(User {
email: "bob@example.com"
})
.exec(&mut db)
.await?;
assert_eq!(user.version, 1);
let mut stale = User::filter_by_email("bob@example.com")
.get(&mut db)
.await?;
assert_eq!(stale.version, 1);
user.update()
.email("bob2@example.com")
.exec(&mut db)
.await?;
assert_eq!(user.version, 2);
let result: Result<()> = stale.update().email("bob3@example.com").exec(&mut db).await;
assert!(
result.is_err(),
"expected stale unique-index update to fail"
);
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn delete_checks_version(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let item = toasty::create!(Item { name: "hello" })
.exec(&mut db)
.await?;
assert_eq!(item.version, 1);
let id = item.id;
item.delete().exec(&mut db).await?;
let after_delete = Item::filter_by_id(id).get(&mut db).await;
assert!(after_delete.is_err(), "item should have been deleted");
Ok(())
}
#[driver_test(requires(not(sql)), scenario(crate::scenarios::versioned_item))]
pub async fn stale_delete_fails(test: &mut Test) -> Result<()> {
let mut db = setup(test).await;
let mut item = toasty::create!(Item { name: "hello" })
.exec(&mut db)
.await?;
assert_eq!(item.version, 1);
let stale = Item::filter_by_id(item.id).get(&mut db).await?;
item.update().name("updated").exec(&mut db).await?;
assert_eq!(item.version, 2);
let result: Result<()> = stale.delete().exec(&mut db).await;
assert!(result.is_err(), "expected stale delete to fail");
let _ = Item::filter_by_id(item.id)
.get(&mut db)
.await
.expect("item should still exist");
Ok(())
}