feat: enable safe community auto publishing
This commit is contained in:
@@ -9,7 +9,7 @@ from sqlalchemy.orm import Session
|
||||
|
||||
from app.community_importer import CommunityImportError, stage_observations
|
||||
from app.database import Base
|
||||
from app.models import DataSource, ExternalObservation
|
||||
from app.models import CatchReport, DataSource, ExternalEntityAlias, ExternalObservation, Fish, Waterbody
|
||||
from rf4_research.community_sources import parse_rf4db_catches, parse_rf4map_point, parse_rf4posts_spot
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ def test_staging_is_idempotent_and_preserves_first_seen(db: Session) -> None:
|
||||
assert item.last_seen_at.replace(tzinfo=timezone.utc) == second
|
||||
assert db.scalar(select(func.count()).select_from(ExternalObservation)) == 1
|
||||
source = db.get(DataSource, "rf4db")
|
||||
assert source is not None and source.enabled is False
|
||||
assert source is not None and source.enabled is True
|
||||
|
||||
|
||||
def test_external_ids_are_isolated_by_source(db: Session) -> None:
|
||||
@@ -73,12 +73,60 @@ def test_external_ids_are_isolated_by_source(db: Session) -> None:
|
||||
assert (created, updated) == (2, 0)
|
||||
|
||||
|
||||
def test_research_sources_can_enter_disabled_staging(db: Session) -> None:
|
||||
def test_research_sources_enter_enabled_staging(db: Session) -> None:
|
||||
created, updated = stage_observations(db, [record("rf4map"), record("rf4posts-spot")])
|
||||
|
||||
assert (created, updated) == (2, 0)
|
||||
assert db.get(DataSource, "rf4map").enabled is False
|
||||
assert db.get(DataSource, "rf4posts-spot").enabled is False
|
||||
assert db.get(DataSource, "rf4map").enabled is True
|
||||
assert db.get(DataSource, "rf4posts-spot").enabled is True
|
||||
|
||||
|
||||
def test_complete_observation_with_reviewed_aliases_is_published(db: Session) -> None:
|
||||
source = DataSource(key="rf4db", name="RF4DB", base_url="https://rf4db.com", default_confidence=70, enabled=True)
|
||||
fish = Fish(slug="pike", name_ru="Щука")
|
||||
waterbody = Waterbody(slug="test-lake", name_ru="Тестовое озеро")
|
||||
db.add_all([source, fish, waterbody])
|
||||
db.flush()
|
||||
now = datetime.now(timezone.utc)
|
||||
db.add_all([
|
||||
ExternalEntityAlias(source_system="rf4db", entity_type="fish", external_id="pike", external_name="Щука", fish=fish, updated_at=now),
|
||||
ExternalEntityAlias(source_system="rf4db", entity_type="waterbody", external_id="test-lake", external_name="Тестовое озеро", waterbody=waterbody, updated_at=now),
|
||||
])
|
||||
db.commit()
|
||||
|
||||
assert stage_observations(db, [record() | {"weight_g": 5_000}]) == (1, 0)
|
||||
|
||||
item = db.scalar(select(ExternalObservation))
|
||||
assert item is not None
|
||||
assert item.status == "published"
|
||||
assert item.catch_report is not None
|
||||
assert item.catch_report.fish_id == fish.id
|
||||
assert item.catch_report.waterbody_id == waterbody.id
|
||||
assert db.scalar(select(func.count()).select_from(CatchReport)) == 1
|
||||
|
||||
assert stage_observations(db, [record() | {"weight_g": 5_000}]) == (0, 1)
|
||||
db.refresh(item)
|
||||
assert item.status == "published"
|
||||
assert db.scalar(select(func.count()).select_from(CatchReport)) == 1
|
||||
|
||||
|
||||
def test_auto_publication_requires_enabled_source(db: Session) -> None:
|
||||
source = DataSource(key="rf4db", name="RF4DB", base_url="https://rf4db.com", default_confidence=70, enabled=False)
|
||||
fish = Fish(slug="pike", name_ru="Щука")
|
||||
waterbody = Waterbody(slug="test-lake", name_ru="Тестовое озеро")
|
||||
db.add_all([source, fish, waterbody])
|
||||
db.flush()
|
||||
now = datetime.now(timezone.utc)
|
||||
db.add_all([
|
||||
ExternalEntityAlias(source_system="rf4db", entity_type="fish", external_id="pike", external_name="Щука", fish=fish, updated_at=now),
|
||||
ExternalEntityAlias(source_system="rf4db", entity_type="waterbody", external_id="test-lake", external_name="Тестовое озеро", waterbody=waterbody, updated_at=now),
|
||||
])
|
||||
db.commit()
|
||||
|
||||
stage_observations(db, [record() | {"weight_g": 5_000}])
|
||||
|
||||
item = db.scalar(select(ExternalObservation))
|
||||
assert item is not None and item.status == "staged" and item.catch_report is None
|
||||
|
||||
|
||||
def test_parser_json_can_be_staged_without_losing_provenance(db: Session) -> None:
|
||||
|
||||
Reference in New Issue
Block a user