use crate::helpers::{
NormalizeString,
UpdateItem,
UpdateItemQuery,
UpdateItemUpdate,
WriteModelSkipItem,
WriteModelSkipItemQuery,
WriteModelSkipItemUpdate,
};
use sqlxo::blocks::{
BuildableFilter,
Expression,
};
use sqlxo::{
Buildable,
QueryBuilder,
Updatable,
};
use uuid::Uuid;
#[test]
fn test_update_struct_generated() {
let update = UpdateItemUpdate {
name: Some("new name".into()),
description: Some("new desc".into()),
price: Some(99.99),
};
assert!(update.name.is_some());
assert!(update.description.is_some());
assert!(update.price.is_some());
}
#[test]
fn test_update_default() {
let update = UpdateItemUpdate::default();
assert!(update.name.is_none());
assert!(update.description.is_none());
assert!(update.price.is_none());
}
#[test]
fn test_update_derives_updatable() {
assert_eq!(UpdateItem::UPDATE_MARKER_FIELD, Some("updated_at"));
}
#[test]
fn test_update_partial_fields() {
let update = UpdateItemUpdate {
name: Some("only name".into()),
description: None,
price: None,
};
assert!(update.name.is_some());
assert!(update.description.is_none());
assert!(update.price.is_none());
}
#[cfg(any(test, feature = "test-utils"))]
#[test]
fn test_update_sql_exact_match_single_field() {
let test_id = Uuid::new_v4();
let update = UpdateItemUpdate {
name: Some("test".into()),
..Default::default()
};
let plan = QueryBuilder::<UpdateItem>::update()
.model(update)
.r#where(Expression::Leaf(UpdateItemQuery::IdEq(test_id)))
.build();
assert_eq!(
plan.sql().normalize(),
"UPDATE update_item SET updated_at = NOW(), name = COALESCE($1, \
name), description = COALESCE($2, description), price = COALESCE($3, \
price) WHERE \"update_item\".\"id\" = $4"
);
}
#[cfg(any(test, feature = "test-utils"))]
#[test]
fn test_update_sql_exact_match_multiple_fields() {
let test_id = Uuid::new_v4();
let update = UpdateItemUpdate {
name: Some("test".into()),
description: Some("desc".into()),
price: Some(99.99),
};
let plan = QueryBuilder::<UpdateItem>::update()
.model(update)
.r#where(Expression::Leaf(UpdateItemQuery::IdEq(test_id)))
.build();
assert_eq!(
plan.sql().normalize(),
"UPDATE update_item SET updated_at = NOW(), name = COALESCE($1, \
name), description = COALESCE($2, description), price = COALESCE($3, \
price) WHERE \"update_item\".\"id\" = $4"
);
}
#[cfg(any(test, feature = "test-utils"))]
#[test]
fn test_update_sql_no_marker_just_fields() {
let test_id = Uuid::new_v4();
let update = UpdateItemUpdate {
name: Some("test".into()),
description: Some("desc".into()),
price: None,
};
let plan = QueryBuilder::<UpdateItem>::update()
.model(update)
.r#where(Expression::Leaf(UpdateItemQuery::IdEq(test_id)))
.build();
assert_eq!(
plan.sql().normalize(),
"UPDATE update_item SET updated_at = NOW(), name = COALESCE($1, \
name), description = COALESCE($2, description), price = COALESCE($3, \
price) WHERE \"update_item\".\"id\" = $4"
);
}
#[cfg(any(test, feature = "test-utils"))]
#[test]
fn test_update_ignores_joinvalue_and_sqlx_skip_fields() {
let test_id = Uuid::new_v4();
let material_id = Uuid::new_v4();
let update = WriteModelSkipItemUpdate {
name: Some("updated".into()),
material_id: Some(Some(material_id)),
..Default::default()
};
let plan = QueryBuilder::<WriteModelSkipItem>::update()
.model(update)
.r#where(Expression::Leaf(WriteModelSkipItemQuery::IdEq(test_id)))
.build();
assert_eq!(
plan.sql().normalize(),
"UPDATE write_model_skip_item SET updated_at = NOW(), name = \
COALESCE($1, name), price = COALESCE($2, price), material_id = CASE \
WHEN $3 THEN $4 ELSE material_id END WHERE \
\"write_model_skip_item\".\"id\" = $5"
);
}