279 lines
9.1 KiB
Python
279 lines
9.1 KiB
Python
#!/usr/bin/env python
|
|
"""
|
|
Test script to verify agency user isolation and all fixes are working properly.
|
|
This tests:
|
|
1. Agency login functionality (AttributeError fix)
|
|
2. Agency portal template isolation (agency_base.html usage)
|
|
3. Agency user access restrictions
|
|
4. JavaScript fixes in submit candidate form
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import django
|
|
from django.test import TestCase, Client
|
|
from django.urls import reverse
|
|
from django.contrib.auth.models import User
|
|
from unittest.mock import patch, MagicMock
|
|
|
|
# Setup Django
|
|
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'NorahUniversity.settings')
|
|
django.setup()
|
|
|
|
from recruitment.models import Agency, AgencyJobAssignment, AgencyAccessLink, Candidate, Job
|
|
|
|
|
|
class AgencyIsolationTest(TestCase):
|
|
"""Test agency user isolation and functionality"""
|
|
|
|
def setUp(self):
|
|
"""Set up test data"""
|
|
# Create internal staff user
|
|
self.staff_user = User.objects.create_user(
|
|
username='staff_user',
|
|
email='staff@example.com',
|
|
password='testpass123',
|
|
is_staff=True
|
|
)
|
|
|
|
# Create agency user
|
|
self.agency_user = User.objects.create_user(
|
|
username='agency_user',
|
|
email='agency@example.com',
|
|
password='testpass123',
|
|
is_staff=False
|
|
)
|
|
|
|
# Create agency
|
|
self.agency = Agency.objects.create(
|
|
name='Test Agency',
|
|
contact_email='agency@example.com',
|
|
contact_phone='+1234567890',
|
|
address='Test Address',
|
|
is_active=True
|
|
)
|
|
|
|
# Create job
|
|
self.job = Job.objects.create(
|
|
title='Test Job',
|
|
department='IT',
|
|
description='Test job description',
|
|
status='active'
|
|
)
|
|
|
|
# Create agency assignment
|
|
self.assignment = AgencyJobAssignment.objects.create(
|
|
agency=self.agency,
|
|
job=self.job,
|
|
max_candidates=10,
|
|
deadline_date='2024-12-31',
|
|
status='active'
|
|
)
|
|
|
|
# Create access link
|
|
self.access_link = AgencyAccessLink.objects.create(
|
|
assignment=self.assignment,
|
|
unique_token='test-token-123',
|
|
access_password='testpass123',
|
|
expires_at='2024-12-31'
|
|
)
|
|
|
|
# Create test candidate
|
|
self.candidate = Candidate.objects.create(
|
|
first_name='Test',
|
|
last_name='Candidate',
|
|
email='candidate@example.com',
|
|
phone='+1234567890',
|
|
job=self.job,
|
|
source='agency',
|
|
hiring_agency=self.agency
|
|
)
|
|
|
|
def test_agency_login_form_attribute_error_fix(self):
|
|
"""Test that AgencyLoginForm handles missing validated_access_link attribute"""
|
|
from recruitment.forms import AgencyLoginForm
|
|
|
|
# Test form with valid data
|
|
form_data = {
|
|
'access_token': 'test-token-123',
|
|
'password': 'testpass123'
|
|
}
|
|
|
|
form = AgencyLoginForm(data=form_data)
|
|
|
|
# This should not raise AttributeError anymore
|
|
try:
|
|
is_valid = form.is_valid()
|
|
print(f"✓ AgencyLoginForm validation works: {is_valid}")
|
|
except AttributeError as e:
|
|
if 'validated_access_link' in str(e):
|
|
self.fail("AttributeError 'validated_access_link' not fixed!")
|
|
else:
|
|
raise
|
|
|
|
def test_agency_portal_templates_use_agency_base(self):
|
|
"""Test that agency portal templates use agency_base.html"""
|
|
agency_portal_templates = [
|
|
'recruitment/agency_portal_login.html',
|
|
'recruitment/agency_portal_dashboard.html',
|
|
'recruitment/agency_portal_submit_candidate.html',
|
|
'recruitment/agency_portal_messages.html',
|
|
'recruitment/agency_access_link_detail.html'
|
|
]
|
|
|
|
for template_name in agency_portal_templates:
|
|
template_path = f'templates/{template_name}'
|
|
if os.path.exists(template_path):
|
|
with open(template_path, 'r') as f:
|
|
content = f.read()
|
|
self.assertIn("{% extends 'agency_base.html' %}", content,
|
|
f"{template_name} should use agency_base.html")
|
|
print(f"✓ {template_name} uses agency_base.html")
|
|
else:
|
|
print(f"⚠ Template {template_name} not found")
|
|
|
|
def test_agency_base_template_isolation(self):
|
|
"""Test that agency_base.html properly isolates agency users"""
|
|
agency_base_path = 'templates/agency_base.html'
|
|
|
|
if os.path.exists(agency_base_path):
|
|
with open(agency_base_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
# Check that it extends base.html
|
|
self.assertIn("{% extends 'base.html' %}", content)
|
|
|
|
# Check that it has agency-specific navigation
|
|
self.assertIn('agency_portal_dashboard', content)
|
|
self.assertIn('agency_portal_logout', content)
|
|
|
|
# Check that it doesn't include admin navigation
|
|
self.assertNotIn('admin:', content)
|
|
|
|
print("✓ agency_base.html properly configured")
|
|
else:
|
|
self.fail("agency_base.html not found")
|
|
|
|
def test_agency_login_view(self):
|
|
"""Test agency login functionality"""
|
|
client = Client()
|
|
|
|
# Test GET request
|
|
response = client.get(reverse('agency_portal_login'))
|
|
self.assertEqual(response.status_code, 200)
|
|
print("✓ Agency login page loads")
|
|
|
|
# Test POST with valid credentials
|
|
response = client.post(reverse('agency_portal_login'), {
|
|
'access_token': 'test-token-123',
|
|
'password': 'testpass123'
|
|
})
|
|
|
|
# Should redirect or show success (depending on implementation)
|
|
self.assertIn(response.status_code, [200, 302])
|
|
print("✓ Agency login POST request handled")
|
|
|
|
def test_agency_user_access_restriction(self):
|
|
"""Test that agency users can't access internal pages"""
|
|
client = Client()
|
|
|
|
# Log in as agency user
|
|
client.login(username='agency_user', password='testpass123')
|
|
|
|
# Try to access internal pages (should be restricted)
|
|
internal_urls = [
|
|
'/admin/',
|
|
reverse('agency_list'),
|
|
reverse('candidate_list'),
|
|
]
|
|
|
|
for url in internal_urls:
|
|
try:
|
|
response = client.get(url)
|
|
# Agency users should get redirected or forbidden
|
|
self.assertIn(response.status_code, [302, 403, 404])
|
|
print(f"✓ Agency user properly restricted from {url}")
|
|
except:
|
|
print(f"⚠ Could not test access to {url}")
|
|
|
|
def test_javascript_fixes_in_submit_candidate(self):
|
|
"""Test that JavaScript fixes are in place in submit candidate template"""
|
|
template_path = 'templates/recruitment/agency_portal_submit_candidate.html'
|
|
|
|
if os.path.exists(template_path):
|
|
with open(template_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
# Check for safe element access patterns
|
|
self.assertIn('getElementValue', content)
|
|
self.assertIn('if (element)', content)
|
|
|
|
# Check for error handling
|
|
self.assertIn('console.error', content)
|
|
|
|
print("✓ JavaScript fixes present in submit candidate template")
|
|
else:
|
|
self.fail("agency_portal_submit_candidate.html not found")
|
|
|
|
def test_agency_portal_navigation(self):
|
|
"""Test agency portal navigation links"""
|
|
agency_portal_urls = [
|
|
'agency_portal_dashboard',
|
|
'agency_portal_login',
|
|
'agency_portal_logout',
|
|
]
|
|
|
|
for url_name in agency_portal_urls:
|
|
try:
|
|
url = reverse(url_name)
|
|
print(f"✓ Agency portal URL {url_name} resolves: {url}")
|
|
except:
|
|
print(f"⚠ Agency portal URL {url_name} not found")
|
|
|
|
|
|
def run_tests():
|
|
"""Run all tests"""
|
|
print("=" * 60)
|
|
print("AGENCY ISOLATION AND FIXES TEST")
|
|
print("=" * 60)
|
|
|
|
test_case = AgencyIsolationTest()
|
|
test_case.setUp()
|
|
|
|
tests = [
|
|
test_case.test_agency_login_form_attribute_error_fix,
|
|
test_case.test_agency_portal_templates_use_agency_base,
|
|
test_case.test_agency_base_template_isolation,
|
|
test_case.test_agency_login_view,
|
|
test_case.test_agency_user_access_restriction,
|
|
test_case.test_javascript_fixes_in_submit_candidate,
|
|
test_case.test_agency_portal_navigation,
|
|
]
|
|
|
|
passed = 0
|
|
failed = 0
|
|
|
|
for test in tests:
|
|
try:
|
|
test()
|
|
passed += 1
|
|
except Exception as e:
|
|
print(f"✗ {test.__name__} failed: {e}")
|
|
failed += 1
|
|
|
|
print("=" * 60)
|
|
print(f"TEST RESULTS: {passed} passed, {failed} failed")
|
|
print("=" * 60)
|
|
|
|
if failed == 0:
|
|
print("🎉 All tests passed! Agency isolation is working properly.")
|
|
else:
|
|
print("⚠️ Some tests failed. Please review the issues above.")
|
|
|
|
return failed == 0
|
|
|
|
|
|
if __name__ == '__main__':
|
|
success = run_tests()
|
|
sys.exit(0 if success else 1)
|