|
| 1 | +import pytest |
| 2 | +from django.test.utils import override_settings |
| 3 | + |
| 4 | +from ansible_base.lib.utils.response import get_relative_url |
| 5 | +from ansible_base.rbac.models import DABContentType, DABPermission |
| 6 | +from ansible_base.rbac.remote import get_local_resource_prefix |
| 7 | + |
| 8 | + |
| 9 | +@pytest.mark.django_db |
| 10 | +@override_settings(ANSIBLE_BASE_ROLES_REQUIRE_VIEW=True) |
| 11 | +def test_create_remote_role_missing_view_returns_400_with_clear_message(admin_api_client): |
| 12 | + """Reproduces AAP-50803: remote stand-in cls lacks verbose_name, causing 500. |
| 13 | +
|
| 14 | + Ensure creating a role for a remote content type with change-only permission |
| 15 | + returns HTTP 400 and a readable message that mentions view permission is required. |
| 16 | + """ |
| 17 | + # Ensure a remote content type exists (service not shared/local) |
| 18 | + local_service = get_local_resource_prefix() |
| 19 | + remote_ct = DABContentType.objects.exclude(service__in=("shared", local_service)).first() |
| 20 | + if remote_ct is None: |
| 21 | + # Create a representative remote content type (e.g., awx.inventory) |
| 22 | + remote_ct, _ = DABContentType.objects.get_or_create( |
| 23 | + service="awx", |
| 24 | + app_label="awx", |
| 25 | + model="inventory", |
| 26 | + defaults={"pk_field_type": "integer"}, |
| 27 | + ) |
| 28 | + |
| 29 | + # Ensure both view and change permissions exist so the validator enforces the view requirement |
| 30 | + view_perm, _ = DABPermission.objects.get_or_create( |
| 31 | + content_type=remote_ct, |
| 32 | + codename="view_inventory", |
| 33 | + defaults={"name": "Can view inventory"}, |
| 34 | + ) |
| 35 | + change_perm, _ = DABPermission.objects.get_or_create( |
| 36 | + content_type=remote_ct, |
| 37 | + codename="change_inventory", |
| 38 | + defaults={"name": "Can change inventory"}, |
| 39 | + ) |
| 40 | + |
| 41 | + url = get_relative_url('roledefinition-list') |
| 42 | + response = admin_api_client.post( |
| 43 | + url, |
| 44 | + data={ |
| 45 | + 'name': 'remote-change-no-view', |
| 46 | + 'description': '', |
| 47 | + 'content_type': remote_ct.api_slug, |
| 48 | + 'permissions': [change_perm.api_slug], |
| 49 | + }, |
| 50 | + ) |
| 51 | + |
| 52 | + # Expected: 400 with message indicating view is required |
| 53 | + assert response.status_code == 400, response.data |
| 54 | + msg = str(response.data).lower() |
| 55 | + assert 'view' in msg and ('needs to include view' in msg or 'required' in msg) |
0 commit comments