657 lines
26 KiB
Python
657 lines
26 KiB
Python
from django.contrib.auth.models import User
|
|
from django.test import TestCase, Client
|
|
from django.urls import reverse
|
|
|
|
from common.models import UserConfig, Thematic, UserThematics, AppView
|
|
|
|
|
|
class SignViewTests(TestCase):
|
|
"""Tests for the sign view functionality."""
|
|
|
|
def setUp(self):
|
|
"""Set up test data."""
|
|
self.client = Client()
|
|
|
|
# Create application views
|
|
self.asset_view = AppView.objects.create(
|
|
code='asset_management',
|
|
name_fr='Gestion des assets',
|
|
name_nl='Asset Management',
|
|
icon='bi-database',
|
|
url_name='home:index',
|
|
is_default=True,
|
|
order=1
|
|
)
|
|
self.sign_view = AppView.objects.create(
|
|
code='sign',
|
|
name_fr='Signalisation',
|
|
name_nl='Signalisatie',
|
|
icon='bi-signpost',
|
|
url_name='sign:index',
|
|
order=2
|
|
)
|
|
|
|
# Create a thematic for sign
|
|
self.sign_thematic = Thematic.objects.create(
|
|
code='sign',
|
|
name_fr='Signalisation',
|
|
name_nl='Signalisatie',
|
|
icon='bi-signpost',
|
|
color='#0022ff'
|
|
)
|
|
|
|
# Create a user with access to sign view
|
|
self.user_with_access = User.objects.create_user(
|
|
username='signuser',
|
|
password='testpass123'
|
|
)
|
|
self.config_with_access = UserConfig.objects.create(
|
|
user=self.user_with_access
|
|
)
|
|
self.config_with_access.accessible_views.add(self.asset_view, self.sign_view)
|
|
|
|
# Give the user access to sign thematic
|
|
UserThematics.objects.create(
|
|
user_config=self.config_with_access,
|
|
thematic=self.sign_thematic,
|
|
can_view_assets=True,
|
|
can_edit_assets=False
|
|
)
|
|
|
|
# Create a user without access to sign view
|
|
self.user_without_access = User.objects.create_user(
|
|
username='notsignuser',
|
|
password='testpass123'
|
|
)
|
|
self.config_without_access = UserConfig.objects.create(
|
|
user=self.user_without_access
|
|
)
|
|
self.config_without_access.accessible_views.add(self.asset_view)
|
|
|
|
# Create a user with only sign access
|
|
self.user_sign_only = User.objects.create_user(
|
|
username='signonly',
|
|
password='testpass123'
|
|
)
|
|
self.config_sign_only = UserConfig.objects.create(
|
|
user=self.user_sign_only
|
|
)
|
|
self.config_sign_only.accessible_views.add(self.sign_view)
|
|
UserThematics.objects.create(
|
|
user_config=self.config_sign_only,
|
|
thematic=self.sign_thematic,
|
|
can_view_assets=True
|
|
)
|
|
|
|
def test_sign_index_access_granted(self):
|
|
"""Test that users with sign access can view the page."""
|
|
self.client.force_login(self.user_with_access)
|
|
response = self.client.get(reverse('sign:index'))
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertTemplateUsed(response, 'sign/index.html')
|
|
|
|
def test_sign_index_access_denied(self):
|
|
"""Test that users without sign access get 403 Forbidden."""
|
|
self.client.force_login(self.user_without_access)
|
|
response = self.client.get(reverse('sign:index'))
|
|
self.assertEqual(response.status_code, 403)
|
|
|
|
def test_sign_requires_authentication(self):
|
|
"""Test that unauthenticated users are redirected to login."""
|
|
response = self.client.get(reverse('sign:index'))
|
|
self.assertRedirects(
|
|
response,
|
|
f"{reverse('login')}?next={reverse('sign:index')}"
|
|
)
|
|
|
|
def test_sign_index_contains_required_elements(self):
|
|
"""Test that the sign page contains required UI elements."""
|
|
self.client.force_login(self.user_with_access)
|
|
response = self.client.get(reverse('sign:index'))
|
|
|
|
# Check for main container
|
|
self.assertContains(response, 'sign-container')
|
|
|
|
# Check for left panel
|
|
self.assertContains(response, 'sign-panel')
|
|
|
|
# Check for map container
|
|
self.assertContains(response, 'sign-map')
|
|
|
|
# Check for tabs
|
|
self.assertContains(response, 'tasks-tab')
|
|
self.assertContains(response, 'filters-tab')
|
|
self.assertContains(response, 'regulations-tab')
|
|
|
|
def test_sign_filter_parameters(self):
|
|
"""Test that filter parameters are passed to context."""
|
|
self.client.force_login(self.user_with_access)
|
|
response = self.client.get(
|
|
reverse('sign:index'),
|
|
{'municipality': ['1', '2'], 'panel': 'filters'}
|
|
)
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertEqual(response.context['active_panel'], 'filters')
|
|
self.assertIn('1', response.context['selected_municipalities'])
|
|
self.assertIn('2', response.context['selected_municipalities'])
|
|
|
|
|
|
class ViewSwitcherTests(TestCase):
|
|
"""Tests for the view switcher functionality in the header."""
|
|
|
|
def setUp(self):
|
|
"""Set up test data."""
|
|
self.client = Client()
|
|
|
|
# Create application views
|
|
self.asset_view = AppView.objects.create(
|
|
code='asset_management',
|
|
name_fr='Gestion des assets',
|
|
name_nl='Asset Management',
|
|
icon='bi-database',
|
|
url_name='home:index',
|
|
is_default=True,
|
|
order=1
|
|
)
|
|
self.sign_view = AppView.objects.create(
|
|
code='sign',
|
|
name_fr='Signalisation',
|
|
name_nl='Signalisatie',
|
|
icon='bi-signpost',
|
|
url_name='sign:index',
|
|
order=2
|
|
)
|
|
|
|
# Create users with different access levels
|
|
self.user_both_views = User.objects.create_user(
|
|
username='bothviews',
|
|
password='testpass123'
|
|
)
|
|
self.config_both = UserConfig.objects.create(
|
|
user=self.user_both_views
|
|
)
|
|
self.config_both.accessible_views.add(self.asset_view, self.sign_view)
|
|
|
|
self.user_asset_only = User.objects.create_user(
|
|
username='assetonly',
|
|
password='testpass123'
|
|
)
|
|
self.config_asset = UserConfig.objects.create(
|
|
user=self.user_asset_only
|
|
)
|
|
self.config_asset.accessible_views.add(self.asset_view)
|
|
|
|
self.user_sign_only = User.objects.create_user(
|
|
username='signonly',
|
|
password='testpass123'
|
|
)
|
|
self.config_sign = UserConfig.objects.create(
|
|
user=self.user_sign_only
|
|
)
|
|
self.config_sign.accessible_views.add(self.sign_view)
|
|
|
|
def test_view_switcher_shown_for_both_views(self):
|
|
"""Test that view switcher is shown for users with access to both views."""
|
|
self.client.force_login(self.user_both_views)
|
|
response = self.client.get(reverse('home:index'))
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertContains(response, 'viewSwitcherDropdown')
|
|
|
|
def test_view_switcher_hidden_for_single_view_asset(self):
|
|
"""Test that view switcher dropdown is not shown for asset-only users."""
|
|
self.client.force_login(self.user_asset_only)
|
|
response = self.client.get(reverse('home:index'))
|
|
|
|
self.assertEqual(response.status_code, 200)
|
|
# The dropdown should not be shown
|
|
self.assertNotContains(response, 'viewSwitcherDropdown')
|
|
|
|
|
|
class UserConfigViewAccessTests(TestCase):
|
|
"""Tests for UserConfig view access with generic AppView model."""
|
|
|
|
def setUp(self):
|
|
"""Set up test data."""
|
|
self.asset_view = AppView.objects.create(
|
|
code='asset_management',
|
|
name_fr='Gestion des assets',
|
|
name_nl='Asset Management',
|
|
icon='bi-database',
|
|
url_name='home:index',
|
|
is_default=True,
|
|
order=1
|
|
)
|
|
self.sign_view = AppView.objects.create(
|
|
code='sign',
|
|
name_fr='Signalisation',
|
|
name_nl='Signalisatie',
|
|
icon='bi-signpost',
|
|
url_name='sign:index',
|
|
order=2
|
|
)
|
|
|
|
def test_can_access_view_method(self):
|
|
"""Test the can_access_view method."""
|
|
user = User.objects.create_user(username='testuser', password='pass')
|
|
config = UserConfig.objects.create(user=user)
|
|
config.accessible_views.add(self.sign_view)
|
|
|
|
self.assertTrue(config.can_access_view('sign'))
|
|
self.assertFalse(config.can_access_view('asset_management'))
|
|
|
|
def test_can_add_multiple_views(self):
|
|
"""Test that multiple views can be added."""
|
|
user = User.objects.create_user(username='testuser', password='pass')
|
|
config = UserConfig.objects.create(user=user)
|
|
config.accessible_views.add(self.asset_view, self.sign_view)
|
|
|
|
self.assertTrue(config.can_access_view('asset_management'))
|
|
self.assertTrue(config.can_access_view('sign'))
|
|
self.assertEqual(config.accessible_views.count(), 2)
|
|
|
|
def test_get_accessible_views_ordered(self):
|
|
"""Test that get_accessible_views returns views in order."""
|
|
user = User.objects.create_user(username='testuser', password='pass')
|
|
config = UserConfig.objects.create(user=user)
|
|
config.accessible_views.add(self.sign_view, self.asset_view)
|
|
|
|
views = list(config.get_accessible_views())
|
|
self.assertEqual(views[0].code, 'asset_management') # order=1
|
|
self.assertEqual(views[1].code, 'sign') # order=2
|
|
|
|
|
|
class AppViewModelTests(TestCase):
|
|
"""Tests for the AppView model."""
|
|
|
|
def test_app_view_creation(self):
|
|
"""Test creating an AppView."""
|
|
view = AppView.objects.create(
|
|
code='test_view',
|
|
name_fr='Vue de test',
|
|
name_nl='Test view',
|
|
icon='bi-test',
|
|
url_name='test:index',
|
|
is_default=False,
|
|
order=10
|
|
)
|
|
|
|
self.assertEqual(view.code, 'test_view')
|
|
self.assertEqual(view.name_fr, 'Vue de test')
|
|
self.assertEqual(view.url_name, 'test:index')
|
|
|
|
def test_app_view_name_property(self):
|
|
"""Test the name property returns the correct language."""
|
|
view = AppView.objects.create(
|
|
code='test_view',
|
|
name_fr='Vue de test',
|
|
name_nl='Test view',
|
|
icon='bi-test',
|
|
url_name='test:index'
|
|
)
|
|
|
|
# Default language should be French
|
|
self.assertEqual(view.name, 'Vue de test')
|
|
|
|
|
|
class ESignPermissionTests(TestCase):
|
|
"""Tests for the refined eSign permissions."""
|
|
|
|
def setUp(self):
|
|
from django.contrib.auth.models import Permission
|
|
from common.models import Role
|
|
|
|
# Create basic roles
|
|
self.admin_role, _ = Role.objects.get_or_create(name='admin')
|
|
self.manager_role, _ = Role.objects.get_or_create(name='manager')
|
|
|
|
# Create superuser
|
|
self.superuser = User.objects.create_superuser(username='super', password='password')
|
|
|
|
# Create normal users
|
|
self.user_none = User.objects.create_user(username='none', password='password')
|
|
self.config_none = UserConfig.objects.create(user=self.user_none)
|
|
|
|
self.user_edit = User.objects.create_user(username='edit', password='password')
|
|
self.config_edit = UserConfig.objects.create(user=self.user_edit, esign_can_edit=True)
|
|
|
|
self.user_manage = User.objects.create_user(username='manage', password='password')
|
|
self.config_manage = UserConfig.objects.create(user=self.user_manage, esign_can_manage_rcp=True)
|
|
|
|
self.user_validate = User.objects.create_user(username='validate', password='password')
|
|
self.config_validate = UserConfig.objects.create(user=self.user_validate, esign_can_validate_rcp=True)
|
|
|
|
# Users with roles
|
|
self.user_admin = User.objects.create_user(username='admin_user', password='password')
|
|
self.config_admin = UserConfig.objects.create(user=self.user_admin)
|
|
self.config_admin.roles.add(self.admin_role)
|
|
|
|
self.user_manager = User.objects.create_user(username='manager_user', password='password')
|
|
self.config_manager = UserConfig.objects.create(user=self.user_manager)
|
|
self.config_manager.roles.add(self.manager_role)
|
|
|
|
# User with Django built-in permission
|
|
self.user_django_perm = User.objects.create_user(username='django_perm', password='password')
|
|
self.config_django_perm = UserConfig.objects.create(user=self.user_django_perm)
|
|
add_perm = Permission.objects.filter(codename='add_signpole', content_type__app_label='sign').first()
|
|
if not add_perm:
|
|
add_perm = Permission.objects.filter(codename='add_signpole').first()
|
|
self.user_django_perm.user_permissions.add(add_perm)
|
|
|
|
def test_user_can_edit_esign_assets(self):
|
|
from sign.permissions import user_can_edit_esign_assets
|
|
|
|
# Superuser should be able to edit
|
|
self.assertTrue(user_can_edit_esign_assets(self.superuser))
|
|
|
|
# Normal user should not be able to edit
|
|
self.assertFalse(user_can_edit_esign_assets(self.user_none))
|
|
|
|
# User with esign_can_edit should be able to edit
|
|
self.assertTrue(user_can_edit_esign_assets(self.user_edit))
|
|
|
|
# User with django perm should be able to edit
|
|
# Refresh user instance to load permissions
|
|
user_django = User.objects.get(pk=self.user_django_perm.pk)
|
|
self.assertTrue(user_can_edit_esign_assets(user_django))
|
|
|
|
def test_user_can_manage_regulations(self):
|
|
from sign.permissions import user_can_manage_regulations
|
|
|
|
# Superuser should be able to manage
|
|
self.assertTrue(user_can_manage_regulations(self.superuser))
|
|
|
|
# Normal user should not be able to manage
|
|
self.assertFalse(user_can_manage_regulations(self.user_none))
|
|
|
|
# User with esign_can_manage_rcp should be able to manage
|
|
self.assertTrue(user_can_manage_regulations(self.user_manage))
|
|
|
|
# Admin and manager roles should be able to manage
|
|
self.assertTrue(user_can_manage_regulations(self.user_admin))
|
|
self.assertTrue(user_can_manage_regulations(self.user_manager))
|
|
|
|
def test_user_can_approve_regulation(self):
|
|
from sign.permissions import user_can_approve_regulation
|
|
|
|
# Superuser should be able to approve
|
|
self.assertTrue(user_can_approve_regulation(self.superuser))
|
|
|
|
# Normal user should not be able to approve
|
|
self.assertFalse(user_can_approve_regulation(self.user_none))
|
|
|
|
# User with esign_can_validate_rcp should be able to approve
|
|
self.assertTrue(user_can_approve_regulation(self.user_validate))
|
|
|
|
# Admin role should be able to approve
|
|
self.assertTrue(user_can_approve_regulation(self.user_admin))
|
|
|
|
# Manager role should NOT be able to approve (requires admin or validate permission)
|
|
self.assertFalse(user_can_approve_regulation(self.user_manager))
|
|
|
|
|
|
class ESignOrganizationRestrictionsTests(TestCase):
|
|
"""Tests for eSign Organization restrictions and validation."""
|
|
|
|
def setUp(self):
|
|
from sign.models import Organization, ComplementaryPoliceRegulation
|
|
self.client = Client()
|
|
|
|
# Create basic app views so we can access 'sign' view
|
|
self.sign_view = AppView.objects.create(
|
|
code='sign',
|
|
name_fr='Signalisation',
|
|
name_nl='Signalisatie',
|
|
icon='bi-signpost',
|
|
url_name='sign:index',
|
|
order=2
|
|
)
|
|
|
|
# Create Organizations
|
|
self.org_a = Organization.objects.create(
|
|
name_fr="Commune A (FR)",
|
|
name_nl="Commune A (NL)",
|
|
code="ORG_A",
|
|
organization_type="municipality"
|
|
)
|
|
self.org_b = Organization.objects.create(
|
|
name_fr="Commune B (FR)",
|
|
name_nl="Commune B (NL)",
|
|
code="ORG_B",
|
|
organization_type="municipality"
|
|
)
|
|
|
|
# Create users
|
|
# 1. Superuser
|
|
self.superuser = User.objects.create_superuser(
|
|
username='super_org',
|
|
password='testpass123'
|
|
)
|
|
self.config_super = UserConfig.objects.create(user=self.superuser)
|
|
self.config_super.accessible_views.add(self.sign_view)
|
|
|
|
# 2. Restricted User for Org A (can manage RCP)
|
|
self.user_a = User.objects.create_user(
|
|
username='user_a',
|
|
password='testpass123'
|
|
)
|
|
self.config_a = UserConfig.objects.create(
|
|
user=self.user_a,
|
|
esign_can_manage_rcp=True
|
|
)
|
|
self.config_a.accessible_views.add(self.sign_view)
|
|
self.config_a.esign_organizations.add(self.org_a)
|
|
|
|
# 3. Restricted User for Org B (can manage RCP)
|
|
self.user_b = User.objects.create_user(
|
|
username='user_b',
|
|
password='testpass123'
|
|
)
|
|
self.config_b = UserConfig.objects.create(
|
|
user=self.user_b,
|
|
esign_can_manage_rcp=True
|
|
)
|
|
self.config_b.accessible_views.add(self.sign_view)
|
|
self.config_b.esign_organizations.add(self.org_b)
|
|
|
|
# 4. User without any allowed organizations (Visitor / read-only)
|
|
self.user_visitor = User.objects.create_user(
|
|
username='user_visitor',
|
|
password='testpass123'
|
|
)
|
|
self.config_visitor = UserConfig.objects.create(
|
|
user=self.user_visitor
|
|
)
|
|
self.config_visitor.accessible_views.add(self.sign_view)
|
|
|
|
# Create some complementary police regulations (RCPs)
|
|
self.reg_a = ComplementaryPoliceRegulation.objects.create(
|
|
title="Regulation Org A",
|
|
reference="REF-A-001",
|
|
description="Test A",
|
|
organization=self.org_a,
|
|
status="in_preparation",
|
|
uploaded_by=self.user_a
|
|
)
|
|
self.reg_b = ComplementaryPoliceRegulation.objects.create(
|
|
title="Regulation Org B",
|
|
reference="REF-B-001",
|
|
description="Test B",
|
|
organization=self.org_b,
|
|
status="in_preparation",
|
|
uploaded_by=self.user_b
|
|
)
|
|
|
|
def test_asset_forms_organization_required(self):
|
|
"""Test that SignPoleForm and SignPanelForm require an organization."""
|
|
import json
|
|
from sign.forms import SignPoleForm, SignPanelForm
|
|
|
|
# 1. SignPoleForm validation
|
|
pole_data_no_org = {
|
|
'orientation': 90,
|
|
'lat': 50.85,
|
|
'lon': 4.35
|
|
}
|
|
form_pole = SignPoleForm(data=pole_data_no_org)
|
|
self.assertFalse(form_pole.is_valid())
|
|
self.assertIn('organization', form_pole.errors)
|
|
|
|
pole_data_with_org = pole_data_no_org.copy()
|
|
pole_data_with_org['organization'] = self.org_a.id
|
|
form_pole_ok = SignPoleForm(data=pole_data_with_org)
|
|
self.assertTrue(form_pole_ok.is_valid())
|
|
|
|
# 2. SignPanelForm validation
|
|
panel_data_no_org = {
|
|
'orientation': 180,
|
|
'support_type': 'pole',
|
|
'is_temporary': False,
|
|
'lat': 50.85,
|
|
'lon': 4.35
|
|
}
|
|
form_panel = SignPanelForm(data=panel_data_no_org)
|
|
self.assertFalse(form_panel.is_valid())
|
|
self.assertIn('organization', form_panel.errors)
|
|
|
|
panel_data_with_org = panel_data_no_org.copy()
|
|
panel_data_with_org['organization'] = self.org_a.id
|
|
form_panel_ok = SignPanelForm(data=panel_data_with_org)
|
|
self.assertTrue(form_panel_ok.is_valid())
|
|
|
|
def test_universal_asset_visibility(self):
|
|
"""Test that any logged-in user can view assets without being blocked by organization permissions."""
|
|
import json
|
|
self.client.force_login(self.user_visitor)
|
|
response = self.client.get(reverse('sign:index'))
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
response_poles = self.client.post(
|
|
reverse('sign:sign_poles_overview_geojson'),
|
|
data=json.dumps({}),
|
|
content_type='application/json'
|
|
)
|
|
self.assertEqual(response_poles.status_code, 200)
|
|
|
|
def test_superuser_bypass_restrictions(self):
|
|
"""Test that superusers can see and modify any regulation across all organizations."""
|
|
import json
|
|
self.client.force_login(self.superuser)
|
|
|
|
# 1. Superuser should see both regulations in list
|
|
response = self.client.get(reverse('sign:regulations_list'))
|
|
self.assertEqual(response.status_code, 200)
|
|
self.assertContains(response, self.reg_a.title)
|
|
self.assertContains(response, self.reg_b.title)
|
|
|
|
# 2. Superuser should see both regulations in search
|
|
response_search = self.client.get(reverse('sign:regulations_search'), {'q': ''})
|
|
self.assertEqual(response_search.status_code, 200)
|
|
results = response_search.json().get('results', [])
|
|
self.assertEqual(len(results), 2)
|
|
|
|
# 3. Superuser can access detail of both
|
|
response_detail_a = self.client.get(reverse('sign:regulation_detail', kwargs={'regulation_id': self.reg_a.id}))
|
|
self.assertEqual(response_detail_a.status_code, 200)
|
|
response_detail_b = self.client.get(reverse('sign:regulation_detail', kwargs={'regulation_id': self.reg_b.id}))
|
|
self.assertEqual(response_detail_b.status_code, 200)
|
|
|
|
def test_restricted_user_visibility_and_access(self):
|
|
"""Test that a restricted user can only see and access regulations of their organization."""
|
|
import json
|
|
self.client.force_login(self.user_a)
|
|
|
|
# 1. List only contains reg_a
|
|
response_list = self.client.get(reverse('sign:regulations_list'))
|
|
self.assertEqual(response_list.status_code, 200)
|
|
self.assertContains(response_list, self.reg_a.title)
|
|
self.assertNotContains(response_list, self.reg_b.title)
|
|
|
|
# 2. Search only returns reg_a
|
|
response_search = self.client.get(reverse('sign:regulations_search'), {'q': ''})
|
|
self.assertEqual(response_search.status_code, 200)
|
|
results = response_search.json().get('results', [])
|
|
self.assertEqual(len(results), 1)
|
|
self.assertEqual(results[0]['id'], self.reg_a.id)
|
|
|
|
# 3. Detail view for reg_a works, but reg_b raises PermissionDenied (403)
|
|
response_detail_a = self.client.get(reverse('sign:regulation_detail', kwargs={'regulation_id': self.reg_a.id}))
|
|
self.assertEqual(response_detail_a.status_code, 200)
|
|
|
|
response_detail_b = self.client.get(reverse('sign:regulation_detail', kwargs={'regulation_id': self.reg_b.id}))
|
|
self.assertEqual(response_detail_b.status_code, 403)
|
|
|
|
# 4. Docx generation for reg_a works (or handles it, but not 403), but reg_b raises 403
|
|
response_docx_b = self.client.get(reverse('sign:regulation_generate_docx', kwargs={'regulation_id': self.reg_b.id}))
|
|
self.assertEqual(response_docx_b.status_code, 403)
|
|
|
|
def test_regulation_creation_organization_check(self):
|
|
"""Test that creating a regulation is limited to the user's allowed organizations."""
|
|
self.client.force_login(self.user_a)
|
|
|
|
# 1. Try creating a regulation for org_b (not allowed)
|
|
response_create_forbidden = self.client.post(
|
|
reverse('sign:regulation_create'),
|
|
{
|
|
'title': 'New Reg Forbidden',
|
|
'reference': 'REF-F-001',
|
|
'description': 'Description',
|
|
'organization': self.org_b.id
|
|
}
|
|
)
|
|
self.assertEqual(response_create_forbidden.status_code, 403)
|
|
|
|
# 2. Try creating a regulation for org_a (allowed)
|
|
response_create_ok = self.client.post(
|
|
reverse('sign:regulation_create'),
|
|
{
|
|
'title': 'New Reg Allowed',
|
|
'reference': 'REF-OK-001',
|
|
'description': 'Description',
|
|
'organization': self.org_a.id
|
|
}
|
|
)
|
|
self.assertEqual(response_create_ok.status_code, 200)
|
|
self.assertTrue(response_create_ok.json().get('success'))
|
|
|
|
def test_regulation_editing_organization_check(self):
|
|
"""Test that editing a regulation and updating its organization checks user permissions."""
|
|
self.client.force_login(self.user_a)
|
|
|
|
# 1. Edit reg_a: change title, keep org_a -> OK
|
|
response_edit_ok = self.client.post(
|
|
reverse('sign:regulation_edit', kwargs={'regulation_id': self.reg_a.id}),
|
|
{
|
|
'title': 'Updated Title',
|
|
'reference': self.reg_a.reference,
|
|
'description': self.reg_a.description,
|
|
'organization': self.org_a.id
|
|
}
|
|
)
|
|
self.assertEqual(response_edit_ok.status_code, 200)
|
|
self.assertTrue(response_edit_ok.json().get('success'))
|
|
|
|
# 2. Edit reg_a: try to change organization to org_b -> Forbidden
|
|
response_edit_forbidden = self.client.post(
|
|
reverse('sign:regulation_edit', kwargs={'regulation_id': self.reg_a.id}),
|
|
{
|
|
'title': 'Updated Title',
|
|
'reference': self.reg_a.reference,
|
|
'description': self.reg_a.description,
|
|
'organization': self.org_b.id
|
|
}
|
|
)
|
|
self.assertEqual(response_edit_forbidden.status_code, 403)
|
|
|
|
# 3. Try to edit reg_b (which belongs to org_b) -> Forbidden (user_can_edit_regulation checks organization)
|
|
response_edit_other_rcp = self.client.post(
|
|
reverse('sign:regulation_edit', kwargs={'regulation_id': self.reg_b.id}),
|
|
{
|
|
'title': 'Updated Title Other',
|
|
'reference': self.reg_b.reference,
|
|
'description': self.reg_b.description,
|
|
'organization': self.org_b.id
|
|
}
|
|
)
|
|
self.assertEqual(response_edit_other_rcp.status_code, 403)
|