use crate::node::{
Canister, Def, Entity, FieldList, PrimaryKey, PrimaryKeySource, Schema, SchemaNode, Store, Type,
};
use super::*;
fn insert_canister_store(
schema: &mut Schema,
module_path: &'static str,
canister_ident: &'static str,
canister_path: &'static str,
store_ident: &'static str,
store_path: &'static str,
) {
schema.insert_node(SchemaNode::Canister(Canister::new(
Def::new(module_path, canister_ident),
"test_db",
None,
)));
schema.insert_node(SchemaNode::Store(Store::new_journaled(
Def::new(module_path, store_ident),
canister_path,
StoreJournaledMemoryConfig::new("main"),
)));
let inserted_store_path = format!("{module_path}::{store_ident}");
assert_eq!(
inserted_store_path, store_path,
"test helper requires literal store-path to match Def path",
);
}
fn insert_entity(
schema: &mut Schema,
module_path: &'static str,
entity_ident: &'static str,
store_path: &'static str,
) {
schema.insert_node(SchemaNode::Entity(Entity::new(
Def::new(module_path, entity_ident),
store_path,
1,
PrimaryKey::new(&["id"], PrimaryKeySource::Internal),
&[],
&[],
&[],
FieldList::new(&[]),
Type::new(&[], &[], &[]),
)));
}
#[test]
fn validate_entity_naming_rejects_case_insensitive_duplicates_per_canister() {
let mut schema = Schema::new();
insert_canister_store(
&mut schema,
"schema_case_conflict",
"Canister",
"schema_case_conflict::Canister",
"Store",
"schema_case_conflict::Store",
);
insert_entity(
&mut schema,
"schema_case_conflict",
"Struct",
"schema_case_conflict::Store",
);
insert_entity(
&mut schema,
"schema_case_conflict",
"struct",
"schema_case_conflict::Store",
);
let mut errs = ErrorTree::new();
validate_entity_naming(&schema, &mut errs);
let err = errs
.result()
.expect_err("case-insensitive duplicate entity names must fail");
let rendered = err.to_string();
assert!(
rendered.contains("duplicate entity name"),
"expected duplicate entity-name error, got: {rendered}",
);
assert!(
rendered.contains("case-insensitive conflict"),
"expected case-insensitive conflict detail, got: {rendered}",
);
assert!(
rendered.contains("schema_case_conflict::Struct")
&& rendered.contains("schema_case_conflict::struct"),
"expected both conflicting entity paths in error detail, got: {rendered}",
);
}
#[test]
fn validate_entity_naming_allows_same_name_when_canister_differs() {
let mut schema = Schema::new();
insert_canister_store(
&mut schema,
"schema_case_allowed_a",
"CanisterA",
"schema_case_allowed_a::CanisterA",
"StoreA",
"schema_case_allowed_a::StoreA",
);
insert_canister_store(
&mut schema,
"schema_case_allowed_b",
"CanisterB",
"schema_case_allowed_b::CanisterB",
"StoreB",
"schema_case_allowed_b::StoreB",
);
insert_entity(
&mut schema,
"schema_case_allowed_a",
"Struct",
"schema_case_allowed_a::StoreA",
);
insert_entity(
&mut schema,
"schema_case_allowed_b",
"struct",
"schema_case_allowed_b::StoreB",
);
let mut errs = ErrorTree::new();
validate_entity_naming(&schema, &mut errs);
errs.result()
.expect("case variants across different canisters should pass");
}