from sqlalchemy import select from sqlalchemy.orm import Session from src.models.category import Category, CategoryDb, upsert_category def test_upsert_category_returns_orm_object(db_session: Session): result = upsert_category( db_session, Category.from_str("dummy_parent_1:dummy_parent_2:dummy"), do_commit=False, ) assert result assert isinstance(result, CategoryDb) assert str(result.name) == "dummy" assert str(result.parent.name) == "dummy_parent_2" assert str(result.parent.parent.name) == "dummy_parent_1" def test_upsert_category_writes_new_to_db(db_session: Session): upsert_category( db_session, Category.from_str("grand_father:father:new_category"), do_commit=True, ) result = db_session.execute( select(CategoryDb).filter_by(name="new_category") ).scalar_one() assert result assert str(result.name) == "new_category" assert str(result.parent.name) == "father" assert str(result.parent.parent.name) == "grand_father" def test_upsert_category_skips_existing(db_session: Session): for _ in range(3): upsert_category( db_session, Category.from_str("grand_father:father:try_again_and_again"), do_commit=True, ) result = db_session.execute( select(CategoryDb).filter_by(name="try_again_and_again") ).all() assert len(result) == 1 def test_category_hash_id_computed_field(): """Test hash_id computed field is present and deterministic.""" c1 = Category.from_str("single") c2 = Category.from_str("single") assert hasattr(c1, "hash_id") assert c1.hash_id == c2.hash_id def test_category_hash_id_different_inputs(): """Test that different category hierarchies have different hash_ids.""" c1 = Category.from_str("A:B") c2 = Category.from_str("A:C") # Different last level -> different hash_id assert c1.hash_id != c2.hash_id def test_category_to_str_single_level(): """Test to_str() for single-level category.""" c = Category.from_str("single") assert c.to_str() == "single" def test_category_to_str_nested(): """Test to_str() for nested category.""" c = Category.from_str("parent:child:grandchild") assert c.to_str() == "parent:child:grandchild" def test_category_str_delegates_to_to_str(): """Test that __str__ delegates to to_str().""" c = Category.from_str("A:B:C") assert str(c) == c.to_str() == "A:B:C" def test_category_repr_simple(): """Test repr() for single-level category.""" c = Category.from_str("single") expected = 'Category.from_str("single")' assert repr(c) == expected def test_category_repr_nested(): """Test repr() for nested category.""" c = Category.from_str("parent:child") expected = 'Category.from_str("parent:child")' assert repr(c) == expected