from datetime import datetime, timezone import pytest from app import crud def _now(): return datetime.now(timezone.utc) def test_create_item_sets_defaults(db_session): item, created = crud.create_item( db_session, modality="bh_email", raw_content="Hi, I have books to donate", captured_at=_now(), discord_message_id="msg-1", ) assert created is True assert item.id is not None assert item.stage == "new" assert item.type is None def test_create_item_is_idempotent_by_discord_message_id(db_session): first, first_created = crud.create_item( db_session, modality="bh_email", raw_content="a", captured_at=_now(), discord_message_id="dup-1", ) second, second_created = crud.create_item( db_session, modality="bh_email", raw_content="b (should be ignored)", captured_at=_now(), discord_message_id="dup-1", ) assert first_created is True assert second_created is False assert second.id == first.id assert second.raw_content == "a" def test_list_items_excludes_done_by_default(db_session): crud.create_item(db_session, modality="voice", raw_content="x", captured_at=_now(), discord_message_id="m1") done_item, _ = crud.create_item(db_session, modality="voice", raw_content="y", captured_at=_now(), discord_message_id="m2") crud.update_item(db_session, done_item.id, type="other", stage="new") crud.update_item(db_session, done_item.id, stage="done") results = crud.list_items(db_session) assert done_item.id not in [i.id for i in results] results_with_done = crud.list_items(db_session, include_done=True) assert done_item.id in [i.id for i in results_with_done] def test_update_item_rejects_invalid_stage_for_type(db_session): item, _ = crud.create_item(db_session, modality="voice", raw_content="x", captured_at=_now(), discord_message_id="m3") crud.update_item(db_session, item.id, type="other") with pytest.raises(ValueError): crud.update_item(db_session, item.id, stage="pickup_scheduled") def test_update_item_returns_none_for_missing_id(db_session): assert crud.update_item(db_session, 9999, notes="x") is None