"""
Tests for permission consistency checking service.
"""

import pytest

from topdownrbac.models import (
    RoleBinding,
    UserPermission,
)
from topdownrbac.services.perm_consistency_check_service import (
    UserPermissionConsistencyService,
)
from topdownrbac.tests.conftest import assert_has_view, assert_no_view


@pytest.mark.django_db
class TestPermissionConsistency:
    """Test the UserPermissionConsistencyService."""

    def test_consistency_check_reports_and_deletes_stale(self, user1, role1, consistency_hierarchy, perm_view):
        """UserPermissionConsistencyService report stale permissions."""
        obj1 = consistency_hierarchy["obj1"]
        rb1 = RoleBinding.objects.create(
            role=role1,
            subject=user1,
            restricted_object=obj1,
            propagate=True,
        )
        UserPermission.objects.create(
            user=user1,
            perm=perm_view,
            restricted_object=obj1,
            source=rb1,
        )
        service = UserPermissionConsistencyService(update=True)
        assert_has_view(user1, obj1)
        summary = service.run()
        assert summary["stale_to_delete"] == 1
        # on the second run there should be no more stale permissions
        summary = service.run()
        assert summary["stale_to_delete"] == 0
        assert_no_view(user1, obj1)

    def test_consistency_check_reports_and_creates_missing(self, user1, role1, consistency_hierarchy, perm_view):
        """UserPermissionConsistencyService report missing UserPermission entries."""
        obj1 = consistency_hierarchy["obj1"]
        all_objects = consistency_hierarchy["all_objects"]
        RoleBinding.objects.create(
            role=role1,
            subject=user1,
            restricted_object=obj1,
            propagate=True,
        )
        role1.permissions.add(perm_view)
        UserPermission.objects.all().delete()
        # 6 permissions should now be missing since there are 6 missing in the hierarchy
        service = UserPermissionConsistencyService(update=True)
        for obj in all_objects:
            assert_no_view(user1, obj)
        summary = service.run()
        assert summary["userpermissions_to_create"] == 6
        # on the second run there should be no more missing permissions
        summary = service.run()
        assert summary["userpermissions_to_create"] == 0
        for obj in all_objects:
            assert_has_view(user1, obj)
