2026-09-14 12:47:12 +02:00
|
|
|
from data_layer.food_visibility import (
|
|
|
|
|
attach_visibility,
|
2026-09-14 13:01:41 +02:00
|
|
|
can_edit_food,
|
2026-09-14 12:47:12 +02:00
|
|
|
is_global_mapping_target,
|
|
|
|
|
is_visible_to,
|
|
|
|
|
require_mapping_target,
|
2026-09-14 12:55:09 +02:00
|
|
|
same_id,
|
2026-09-14 12:47:12 +02:00
|
|
|
visibility_of,
|
|
|
|
|
visibility_rank,
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2026-09-14 13:01:41 +02:00
|
|
|
def test_can_edit_central_only_as_admin():
|
|
|
|
|
central = {"catalog_kind": "manual_admin", "owner_profile_id": None, "is_active": True}
|
|
|
|
|
personal = {"catalog_kind": "manual_user", "owner_profile_id": "alice", "is_active": True}
|
|
|
|
|
bls = {"catalog_kind": "official_bls", "owner_profile_id": None, "is_active": True}
|
|
|
|
|
assert can_edit_food(central, "alice", is_admin=False) is False
|
|
|
|
|
assert can_edit_food(central, "alice", is_admin=True) is True
|
|
|
|
|
assert can_edit_food(personal, "alice", is_admin=False) is True
|
|
|
|
|
assert can_edit_food(personal, "bob", is_admin=False) is False
|
|
|
|
|
assert can_edit_food(personal, "bob", is_admin=True) is True
|
|
|
|
|
assert can_edit_food(bls, "alice", is_admin=True) is False
|
|
|
|
|
|
|
|
|
|
|
2026-09-14 12:55:09 +02:00
|
|
|
def test_same_id_ignores_dashes_and_case():
|
|
|
|
|
assert same_id("AaBbCcDd-0000-0000-0000-000000000001", "aabbccdd000000000000000000000001")
|
|
|
|
|
|
|
|
|
|
|
2026-09-14 12:47:12 +02:00
|
|
|
def test_visibility_scopes():
|
|
|
|
|
assert visibility_of({"catalog_kind": "official_bls"}) == "bls"
|
|
|
|
|
assert visibility_of({"catalog_kind": "manual_admin", "owner_profile_id": None}) == "global"
|
|
|
|
|
assert visibility_of({"catalog_kind": "manual_user", "owner_profile_id": "u1"}) == "personal"
|
|
|
|
|
assert visibility_rank({"catalog_kind": "manual_user"}) < visibility_rank({"catalog_kind": "manual_admin"})
|
|
|
|
|
assert visibility_rank({"catalog_kind": "manual_admin"}) < visibility_rank({"catalog_kind": "official_bls"})
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_personal_food_not_visible_to_others():
|
|
|
|
|
food = {"catalog_kind": "manual_user", "owner_profile_id": "alice", "is_active": True}
|
|
|
|
|
assert is_visible_to(food, "alice") is True
|
|
|
|
|
assert is_visible_to(food, "bob") is False
|
|
|
|
|
assert is_global_mapping_target(food) is False
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_admin_and_bls_visible_to_everyone():
|
|
|
|
|
admin = {"catalog_kind": "manual_admin", "owner_profile_id": None, "is_active": True}
|
|
|
|
|
bls = {"catalog_kind": "official_bls", "owner_profile_id": None, "is_active": True}
|
|
|
|
|
assert is_visible_to(admin, "bob") is True
|
|
|
|
|
assert is_visible_to(bls, None) is True
|
|
|
|
|
assert is_global_mapping_target(admin) is True
|
|
|
|
|
assert is_global_mapping_target(bls) is True
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_attach_visibility():
|
|
|
|
|
row = attach_visibility({"catalog_kind": "manual_admin"})
|
|
|
|
|
assert row["visibility"] == "global"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_require_global_mapping_rejects_personal():
|
|
|
|
|
class _Cur:
|
|
|
|
|
def execute(self, sql, params=None):
|
|
|
|
|
self._row = {
|
|
|
|
|
"id": params[0],
|
|
|
|
|
"name_de": "Öl",
|
|
|
|
|
"catalog_kind": "manual_user",
|
|
|
|
|
"owner_profile_id": "alice",
|
|
|
|
|
"is_active": True,
|
|
|
|
|
"bls_code": None,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
def fetchone(self):
|
|
|
|
|
return self._row
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
require_mapping_target(_Cur(), "fid", None)
|
|
|
|
|
assert False, "expected PermissionError"
|
|
|
|
|
except PermissionError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def test_require_user_mapping_allows_own_and_global():
|
|
|
|
|
class _Cur:
|
|
|
|
|
def __init__(self, food):
|
|
|
|
|
self.food = food
|
|
|
|
|
|
|
|
|
|
def execute(self, sql, params=None):
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def fetchone(self):
|
|
|
|
|
return self.food
|
|
|
|
|
|
|
|
|
|
own = require_mapping_target(
|
|
|
|
|
_Cur({
|
|
|
|
|
"id": "1", "name_de": "X", "catalog_kind": "manual_user",
|
|
|
|
|
"owner_profile_id": "alice", "is_active": True, "bls_code": None,
|
|
|
|
|
}),
|
|
|
|
|
"1",
|
|
|
|
|
"alice",
|
|
|
|
|
)
|
|
|
|
|
assert own["catalog_kind"] == "manual_user"
|
|
|
|
|
shared = require_mapping_target(
|
|
|
|
|
_Cur({
|
|
|
|
|
"id": "2", "name_de": "Y", "catalog_kind": "manual_admin",
|
|
|
|
|
"owner_profile_id": None, "is_active": True, "bls_code": None,
|
|
|
|
|
}),
|
|
|
|
|
"2",
|
|
|
|
|
"alice",
|
|
|
|
|
)
|
|
|
|
|
assert shared["catalog_kind"] == "manual_admin"
|