#[path = "../common/mod.rs"]
mod common;
use brain_db_sdk::new_id;
use brain_db_sdk::wire::types::{
EntityCreateRequest, EntityGetRequest, EntityMergeRequest, EntityRenameRequest,
EntityTombstoneRequest, EntityUnmergeRequest, EntityUpdateRequest,
};
fn create(name: &str) -> EntityCreateRequest {
EntityCreateRequest {
act_as: None,
entity_type_id: 1,
canonical_name: name.to_string(),
aliases: vec![],
attributes_blob: vec![],
session_id: 0,
request_id: new_id(),
}
}
#[tokio::test]
async fn update_then_rename_then_tombstone() {
let Some(it) = common::It::from_env() else {
return common::skip("update_then_rename_then_tombstone");
};
let (client, _agent) = it.connect_fresh().await;
let id = client
.create_entity(&create("Ada"))
.await
.expect("create")
.entity_id;
let updated = client
.update_entity(&EntityUpdateRequest {
entity_id: id,
canonical_name: "Ada Lovelace".to_string(),
aliases: vec!["Ada".to_string()],
attributes_blob: b"role=mathematician".to_vec(),
request_id: new_id(),
})
.await
.expect("update");
assert_eq!(updated.entity.canonical_name, "Ada Lovelace");
let renamed = client
.rename_entity(&EntityRenameRequest {
entity_id: id,
new_canonical_name: "Countess Lovelace".to_string(),
move_to_alias: true,
request_id: new_id(),
})
.await
.expect("rename");
assert_eq!(renamed.entity.canonical_name, "Countess Lovelace");
assert!(
renamed.entity.aliases.iter().any(|a| a == "Ada Lovelace"),
"the prior canonical name is retained as an alias"
);
let fetched = client
.get_entity(&EntityGetRequest {
entity_id: id,
act_as: None,
})
.await
.expect("get after rename")
.entity;
assert_eq!(
fetched.canonical_name, "Countess Lovelace",
"rename persisted"
);
assert!(
fetched.aliases.iter().any(|a| a == "Ada Lovelace"),
"alias persisted"
);
let ts = client
.tombstone_entity(&EntityTombstoneRequest {
entity_id: id,
reason: "test cleanup".to_string(),
request_id: new_id(),
})
.await
.expect("tombstone");
assert!(ts.tombstoned_at_unix_nanos > 0, "tombstone records a time");
let after = client
.get_entity(&EntityGetRequest {
entity_id: id,
act_as: None,
})
.await
.expect("tombstoned entity is still fetchable by id (soft)")
.entity;
assert_eq!(after.entity_id, id, "get-by-id survives a soft tombstone");
client.close().await.expect("close");
}
#[tokio::test]
async fn merge_then_unmerge() {
let Some(it) = common::It::from_env() else {
return common::skip("merge_then_unmerge");
};
let (client, _agent) = it.connect_fresh().await;
let survivor = client
.create_entity(&create("NYC"))
.await
.expect("create a")
.entity_id;
let merged = client
.create_entity(&create("New York City"))
.await
.expect("create b")
.entity_id;
let m = client
.merge_entities(&EntityMergeRequest {
survivor,
merged,
confidence: 0.95,
reason: "same city".to_string(),
request_id: new_id(),
})
.await
.expect("merge");
assert!(
m.grace_period_seconds > 0,
"merge is reversible for a window"
);
let u = client
.unmerge_entity(&EntityUnmergeRequest {
merged_entity: merged,
request_id: new_id(),
})
.await
.expect("unmerge");
assert_eq!(
u.restored_entity_id, merged,
"the folded entity is restored"
);
client.close().await.expect("close");
}