dodil/erp-brick-purchasing

DODIL ERP brick: purchasing

tests/test_composition.py

"""The brick composes: `erp-compose check` finds no table or tool collision, no version drift, and a process view — with the real
business-partner brick when it is installed."""
import pathlib

import pytest
from erp_platform import compose

HERE = pathlib.Path(__file__).parent

from brick_purchasing.application import base as _base  # noqa: E402

_FORWARD = _base.repository        # captured at collection, before conftest swaps base.repository for SQLite


def test_the_composition_checks():
    pytest.importorskip("brick_bp", reason="brick-business-partner is not installed")
    report = compose.check(compose.load(HERE / "tier1.compose.yaml"))
    assert report["problems"] == []


def test_every_machine_permission_is_declared_and_no_person_role_holds_one():
    import yaml

    from brick_purchasing.application.base import MACHINE
    roles = yaml.safe_load((HERE.parent / "src" / "brick_purchasing" / "roles.yaml").read_text())
    holders = {p: [r for r, perms in roles["roles"].items() if p in perms] for p in MACHINE}
    persons = {r for r in roles["roles"] if r not in roles["service_clients"]}
    for p, held in holders.items():
        assert not (set(held) & persons), (p, held)
        assert held, f"{p} is held by no service client"


def test_the_controls_are_held_by_the_owner_alone():
    import yaml
    roles = yaml.safe_load((pathlib.Path(__file__).parent.parent / "src" / "brick_purchasing" / "roles.yaml").read_text())["roles"]
    assert [r for r, perms in roles.items() if "purchasing:settings:controls" in perms] == ["owner"]


def test_the_composition_swaps_use_cases_repository_and_every_module_sees_it(monkeypatch):
    """erp-platform's in-process composition (init's composition test, tier-1 serve, `--local`) swaps
    use_cases.repository; base.repository — what every module reads — must follow it (it used to keep its own)."""
    from contextlib import contextmanager

    from brick_purchasing.application import base, master, use_cases
    seen = []

    @contextmanager
    def swapped():
        seen.append(1)
        yield "the composition's repository"
    monkeypatch.setattr(base, "repository", _FORWARD)        # undo conftest's swap: this test IS the composition's
    monkeypatch.setattr(use_cases, "repository", swapped)
    with base.repo_() as r:
        assert r == "the composition's repository"
    with master.repository() as r:
        assert r == "the composition's repository"
    assert len(seen) == 2