from types import SimpleNamespace

from django.test import SimpleTestCase

from account.permissions import HasActionPermission, permissions_for_role


class ActionPermissionTests(SimpleTestCase):
    def allowed(self, role, action, required, *, superuser=False, method="POST"):
        user = SimpleNamespace(
            is_authenticated=True,
            is_staff=True,
            is_superuser=superuser,
            system_role=role,
            action_permissions=permissions_for_role(role),
        )
        request = SimpleNamespace(user=user, method=method)
        view = SimpleNamespace(action=action, action_permission_map={action: required})
        return HasActionPermission().has_permission(request, view)

    def test_sales_user_can_post_sales_but_not_purchases(self):
        self.assertTrue(self.allowed("SALES_USER", "post", "sales.post_sale"))
        self.assertFalse(self.allowed("SALES_USER", "post", "purchases.post_purchase"))

    def test_accountant_can_manage_finance_but_not_stock(self):
        self.assertTrue(self.allowed("ACCOUNTANT", "post", "finance.transfer_accounts"))
        self.assertFalse(self.allowed("ACCOUNTANT", "post", "inventory.adjust_stock"))

    def test_branch_manager_and_superuser_have_full_access(self):
        self.assertTrue(self.allowed("BRANCH_MANAGER", "void", "sales.void_sale"))
        self.assertTrue(self.allowed("", "void", "anything", superuser=True))

    def test_legacy_user_remains_allowed_until_role_is_assigned(self):
        self.assertTrue(self.allowed("", "post", "sales.post_sale"))

    def test_accountant_can_post_expenses_but_cashier_cannot(self):
        self.assertTrue(self.allowed("ACCOUNTANT", "post", "expenses.post_expense"))
        self.assertFalse(self.allowed("CASHIER", "post", "expenses.post_expense"))

    def test_api_view_can_enforce_permission_by_http_method(self):
        user = SimpleNamespace(
            is_authenticated=True, is_staff=True, is_superuser=False,
            system_role="WAREHOUSE_USER",
            action_permissions=permissions_for_role("WAREHOUSE_USER"),
        )
        request = SimpleNamespace(user=user, method="POST")
        view = SimpleNamespace(action=None, action_permission_map={"POST": "inventory.adjust_stock"})
        self.assertTrue(HasActionPermission().has_permission(request, view))
        user.system_role = "CASHIER"
        user.action_permissions = permissions_for_role("CASHIER")
        self.assertFalse(HasActionPermission().has_permission(request, view))
