Files
sales-trainer/backend/tests/test_group_repositories.py

115 lines
3.9 KiB
Python

"""Contract tests for the S4.3 group/persona repository packet."""
from __future__ import annotations
from pathlib import Path
import pytest
from sqlalchemy.orm import Session
from app.db import Base, create_db_engine
from app.repositories import (
EntityNotFoundError,
InvalidRepositoryField,
SqlAlchemyGroupRepository,
SqlAlchemyOrganizationRepository,
SqlAlchemyUserRepository,
)
@pytest.fixture
def repository_session(tmp_path: Path):
engine = create_db_engine(f"sqlite:///{tmp_path / 'groups.db'}")
Base.metadata.create_all(engine)
with Session(engine) as session:
yield session
def test_group_repository_scopes_groups_and_personas_to_org(repository_session: Session):
organizations = SqlAlchemyOrganizationRepository(repository_session)
users = SqlAlchemyUserRepository(repository_session)
groups = SqlAlchemyGroupRepository(repository_session)
organizations.create(organization_id="org-a", name="Alpha")
organizations.create(organization_id="org-b", name="Beta")
users.create(
user_id="user-a",
org_id="org-a",
username="alice",
password_hash="hash-a",
name="Alice",
role="user",
)
repository_session.flush()
group_a = groups.create(
group_id="group-a",
org_id="org-a",
name="Alpha Group",
creator_user_id="user-a",
input_json={"product": "A"},
)
groups.create(group_id="group-b", org_id="org-b", name="Beta Group")
repository_session.flush()
persona_a = groups.create_persona(
persona_id="persona-a",
group_id="group-a",
tier="base",
public_json={"name": "Customer A"},
latent_json={"objection": "price"},
org_id="org-a",
)
repository_session.commit()
assert groups.get("group-a", org_id="org-a") is group_a
assert groups.get("group-b", org_id="org-a") is None
assert [item.id for item in groups.list_for_org("org-a")] == ["group-a"]
assert groups.get_persona("group-a", "persona-a", org_id="org-a") is persona_a
assert [item.id for item in groups.list_personas("group-a", org_id="org-a")] == ["persona-a"]
assert groups.get_persona("group-a", "persona-a", org_id="org-b") is None
def test_group_repository_updates_only_allowed_fields(repository_session: Session):
organizations = SqlAlchemyOrganizationRepository(repository_session)
groups = SqlAlchemyGroupRepository(repository_session)
organizations.create(organization_id="org-a", name="Alpha")
groups.create(group_id="group-a", org_id="org-a", name="Before")
repository_session.commit()
updated = groups.update(
"group-a",
org_id="org-a",
name="After",
status="ready",
report_text="Report",
)
repository_session.commit()
assert updated.name == "After"
assert updated.status == "ready"
assert updated.report_text == "Report"
with pytest.raises(EntityNotFoundError):
groups.update("group-a", org_id="org-b", name="cross-tenant mutation")
with pytest.raises(EntityNotFoundError):
groups.update("missing", org_id="org-a", name="nope")
with pytest.raises(InvalidRepositoryField):
groups.update("group-a", org_id="org-a", creator_user_id="cannot-change")
def test_group_repository_rejects_cross_org_persona_creation(repository_session: Session):
organizations = SqlAlchemyOrganizationRepository(repository_session)
groups = SqlAlchemyGroupRepository(repository_session)
organizations.create(organization_id="org-a", name="Alpha")
organizations.create(organization_id="org-b", name="Beta")
groups.create(group_id="group-a", org_id="org-a", name="Alpha Group")
repository_session.commit()
with pytest.raises(EntityNotFoundError):
groups.create_persona(
persona_id="persona-invalid",
group_id="group-a",
tier="base",
public_json={},
org_id="org-b",
)