import json from unittest.mock import MagicMock, patch from coulomb_social.apps.identity import flex_auth def test_local_shell_view_allow(): d = flex_auth.check("shell:view", resource="shell", subject="s1") assert d.allow is True assert d.effect == "allow" def test_local_member_self_read(): ok = flex_auth.check( "member:self:read", resource="member", resource_id="sub-1", subject="sub-1" ) assert ok.allow is True bad = flex_auth.check( "member:self:read", resource="member", resource_id="sub-1", subject="other" ) assert bad.allow is False def test_local_unknown_deny(): d = flex_auth.check("member:admin", resource="member", subject="s1") assert d.allow is False def test_http_allow(settings): settings.FLEX_AUTH_BASE_URL = "http://flex.example" settings.FLEX_AUTH_PROTECTED_SYSTEM_ID = "coulomb-social" settings.DEFAULT_TENANT_ID = "tenant:coulomb" settings.USER_ENGINE_APPLICATION_ID = "coulomb-social" body = json.dumps({"id": "dec-1", "effect": "allow", "reason": "policy"}).encode() mock_resp = MagicMock() mock_resp.__enter__.return_value = mock_resp mock_resp.__exit__.return_value = False mock_resp.read.return_value = body # json.load on response import coulomb_social.apps.identity.flex_auth as mod with patch.object(mod, "urlopen", return_value=mock_resp): with patch.object(mod, "json") as j: j.load.return_value = {"id": "dec-1", "effect": "allow", "reason": "policy"} j.dumps = json.dumps d = flex_auth.check("shell:view", subject="s1", tenant="tenant:coulomb") assert d.allow is True assert d.decision_id == "dec-1" def test_http_fail_closed(settings): settings.FLEX_AUTH_BASE_URL = "http://flex.example" from urllib.error import URLError import coulomb_social.apps.identity.flex_auth as mod with patch.object(mod, "urlopen", side_effect=URLError("down")): d = flex_auth.check("shell:view", subject="s1") assert d.allow is False assert "fail-closed" in d.reason