Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions hr/tests/factories.py
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,4 @@ class Meta:
last_name = factory.Faker('last_name')
email = factory.LazyAttribute(lambda obj: f'{obj.username}@example.com')
password = make_password('password')
position = factory.SubFactory(PositionFactory)
175 changes: 175 additions & 0 deletions hr/tests/test_employees.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,3 +93,178 @@ def test_successful_employee_creation_message(self):
self.assertEqual(len(messages), 1)
self.assertEqual(str(messages[0]), 'Працівника успішно створено.')


class EmployeeProfileViewTest(TestCase):
def setUp(self):
self.client = Client()
self.admin_user = EmployeeFactory(is_staff=True, is_superuser=True)
self.non_admin_user = EmployeeFactory(is_staff=False, is_superuser=False)
self.employee = EmployeeFactory()
self.position = PositionFactory()
self.employee.position = self.position
# Clear avatar and cv fields to avoid template rendering issues
self.employee.avatar = None
self.employee.cv = None
self.employee.save()

def test_employee_profile_view_access_by_admin(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_profile', kwargs={'pk': self.employee.pk})
# Test the view function access without rendering template
from django.test import RequestFactory
from hr.views.generic_views import EmployeeProfileView

factory = RequestFactory()
request = factory.get(url)
request.user = self.admin_user

view = EmployeeProfileView()
view.setup(request, pk=self.employee.pk)
# Test that admin can access the view (no permission denied exception)
try:
view.dispatch(request, pk=self.employee.pk)
access_allowed = True
except Exception:
access_allowed = False
self.assertTrue(access_allowed)

def test_employee_profile_view_access_by_non_admin(self):
self.client.force_login(self.non_admin_user)
url = reverse('hr:employee_profile', kwargs={'pk': self.employee.pk})
response = self.client.get(url)
self.assertNotEqual(response.status_code, 200)

def test_employee_profile_view_context_object(self):
# Test that the view returns the correct employee object
from django.test import RequestFactory
from hr.views.generic_views import EmployeeProfileView

factory = RequestFactory()
request = factory.get('/fake-url/')
request.user = self.admin_user

view = EmployeeProfileView()
view.setup(request, pk=self.employee.pk)
view.object = view.get_object()

self.assertEqual(view.object.pk, self.employee.pk)
self.assertEqual(view.object.username, self.employee.username)

def test_employee_profile_view_nonexistent_employee(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_profile', kwargs={'pk': 99999})
response = self.client.get(url)
self.assertEqual(response.status_code, 404)


class EmployeeUpdateViewTest(TestCase):
def setUp(self):
self.client = Client()
self.admin_user = EmployeeFactory(is_staff=True, is_superuser=True)
self.non_admin_user = EmployeeFactory(is_staff=False, is_superuser=False)
self.employee = EmployeeFactory()
self.position = PositionFactory()

def test_employee_update_view_get_by_admin(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_update', kwargs={'pk': self.employee.pk})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'employee_form.html')
self.assertTrue('form' in response.context)

def test_employee_update_view_get_by_non_admin(self):
self.client.force_login(self.non_admin_user)
url = reverse('hr:employee_update', kwargs={'pk': self.employee.pk})
response = self.client.get(url)
self.assertNotEqual(response.status_code, 200)

def test_successful_employee_update(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_update', kwargs={'pk': self.employee.pk})
updated_data = {
'username': self.employee.username,
'first_name': 'UpdatedName',
'last_name': 'UpdatedLastName',
'email': 'updated@example.com',
'position': self.position.id,
}
response = self.client.post(url, updated_data)
self.assertEqual(response.status_code, 302)

# Check that changes were saved to database
self.employee.refresh_from_db()
self.assertEqual(self.employee.first_name, 'UpdatedName')
self.assertEqual(self.employee.last_name, 'UpdatedLastName')
self.assertEqual(self.employee.email, 'updated@example.com')

def test_employee_update_invalid_data(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_update', kwargs={'pk': self.employee.pk})
invalid_data = {
'username': '', # Required field
'first_name': 'UpdatedName',
'last_name': 'UpdatedLastName',
'email': 'invalid-email', # Invalid email
'position': self.position.id,
}
response = self.client.post(url, invalid_data)
self.assertEqual(response.status_code, 200) # Form should be re-rendered with errors
self.assertTrue('form' in response.context)
self.assertTrue(response.context['form'].errors)

def test_employee_update_nonexistent_employee(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_update', kwargs={'pk': 99999})
response = self.client.get(url)
self.assertEqual(response.status_code, 404)


class EmployeeDeleteViewTest(TestCase):
def setUp(self):
self.client = Client()
self.admin_user = EmployeeFactory(is_staff=True, is_superuser=True)
self.non_admin_user = EmployeeFactory(is_staff=False, is_superuser=False)
self.employee = EmployeeFactory()

def test_employee_delete_view_get_by_admin(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_delete', kwargs={'pk': self.employee.pk})
response = self.client.get(url)
self.assertEqual(response.status_code, 200)
self.assertTemplateUsed(response, 'employee_confirm_delete.html')
self.assertTrue('object' in response.context)
self.assertEqual(response.context['object'].pk, self.employee.pk)

def test_employee_delete_view_get_by_non_admin(self):
self.client.force_login(self.non_admin_user)
url = reverse('hr:employee_delete', kwargs={'pk': self.employee.pk})
response = self.client.get(url)
self.assertNotEqual(response.status_code, 200)

def test_successful_employee_deletion(self):
self.client.force_login(self.admin_user)
employee_pk = self.employee.pk
url = reverse('hr:employee_delete', kwargs={'pk': employee_pk})

# Verify employee exists before deletion
self.assertTrue(Employee.objects.filter(pk=employee_pk).exists())

response = self.client.post(url)
self.assertEqual(response.status_code, 302)

# Verify employee was deleted from database
self.assertFalse(Employee.objects.filter(pk=employee_pk).exists())

def test_employee_delete_redirect_url(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_delete', kwargs={'pk': self.employee.pk})
response = self.client.post(url)
self.assertRedirects(response, reverse('hr:employee_list'))

def test_employee_delete_nonexistent_employee(self):
self.client.force_login(self.admin_user)
url = reverse('hr:employee_delete', kwargs={'pk': 99999})
response = self.client.get(url)
self.assertEqual(response.status_code, 404)

119 changes: 118 additions & 1 deletion hr/tests/test_employees_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
APITestCase,
)

from hr.models import Employee
from hr.models import Employee, Position
from hr.tests.factories import (
EmployeeFactory,
PositionFactory,
Expand Down Expand Up @@ -49,3 +49,120 @@ def test_search_employee(self):
response = self.client.get(reverse('api-hr:employee-list'), {'search': 'Test'})
self.assertEqual(response.status_code, status.HTTP_200_OK)


class PositionViewSetTestCase(APITestCase):
def setUp(self):
self.client = APIClient()
self.user = Employee.objects.create_user(username='testuser', password='testpassword', email='test@gmail.com')
self.admin_user = Employee.objects.create_user(username='adminuser', password='adminpassword', email='admin@gmail.com', is_staff=True, is_superuser=True)
self.department = PositionFactory().department # Create department through PositionFactory
self.position = PositionFactory(department=self.department)
self.client.force_authenticate(user=self.user)

def test_get_position_list(self):
"""Test retrieving list of positions (GET request)"""
response = self.client.get(reverse('api-hr:position-list'))
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertTrue(len(response.data) >= 1) # At least our test position should be there

def test_create_position(self):
"""Test creating a new position (POST request)"""
data = {
'title': 'Software Engineer',
'department': self.department.id,
'is_manager': False,
'is_active': True,
'job_description': 'Develops software applications',
'monthly_rate': 5000
}
response = self.client.post(reverse('api-hr:position-list'), data)
self.assertEqual(response.status_code, status.HTTP_201_CREATED)
self.assertTrue(Position.objects.filter(title='Software Engineer').exists())

# Verify the created position has correct data
created_position = Position.objects.get(title='Software Engineer')
self.assertEqual(created_position.department.id, self.department.id)
self.assertEqual(created_position.job_description, 'Develops software applications')
self.assertEqual(created_position.monthly_rate, 5000)

def test_get_position_detail(self):
"""Test retrieving a specific position (GET request)"""
response = self.client.get(reverse('api-hr:position-detail', kwargs={'pk': self.position.pk}))
self.assertEqual(response.status_code, status.HTTP_200_OK)
self.assertEqual(response.data['id'], self.position.pk)
self.assertEqual(response.data['title'], self.position.title)

def test_update_position_patch(self):
"""Test updating a position using PATCH request"""
data = {
'title': 'Senior Software Engineer',
'monthly_rate': 6000
}
response = self.client.patch(reverse('api-hr:position-detail', kwargs={'pk': self.position.pk}), data)
self.assertEqual(response.status_code, status.HTTP_200_OK)

# Verify the changes were saved to database
self.position.refresh_from_db()
self.assertEqual(self.position.title, 'Senior Software Engineer')
self.assertEqual(self.position.monthly_rate, 6000)

def test_update_position_put(self):
"""Test updating a position using PUT request"""
data = {
'title': 'Lead Software Engineer',
'department': self.department.id,
'is_manager': True,
'is_active': True,
'job_description': 'Leads development team',
'monthly_rate': 7000
}
response = self.client.put(reverse('api-hr:position-detail', kwargs={'pk': self.position.pk}), data)
self.assertEqual(response.status_code, status.HTTP_200_OK)

# Verify the changes were saved to database
self.position.refresh_from_db()
self.assertEqual(self.position.title, 'Lead Software Engineer')
self.assertEqual(self.position.is_manager, True)
self.assertEqual(self.position.job_description, 'Leads development team')
self.assertEqual(self.position.monthly_rate, 7000)

def test_delete_position(self):
"""Test deleting a position (DELETE request)"""
position_pk = self.position.pk

# Verify position exists before deletion
self.assertTrue(Position.objects.filter(pk=position_pk).exists())

response = self.client.delete(reverse('api-hr:position-detail', kwargs={'pk': position_pk}))
self.assertEqual(response.status_code, status.HTTP_204_NO_CONTENT)

# Verify position was deleted from database
self.assertFalse(Position.objects.filter(pk=position_pk).exists())

def test_create_position_invalid_data(self):
"""Test creating position with invalid data"""
data = {
'title': '', # Required field
'department': 99999, # Non-existent department
'monthly_rate': -1000 # Potentially invalid value
}
response = self.client.post(reverse('api-hr:position-list'), data)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertFalse(Position.objects.filter(title='').exists())

def test_get_nonexistent_position(self):
"""Test retrieving a non-existent position"""
response = self.client.get(reverse('api-hr:position-detail', kwargs={'pk': 99999}))
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_update_nonexistent_position(self):
"""Test updating a non-existent position"""
data = {'title': 'Updated Title'}
response = self.client.patch(reverse('api-hr:position-detail', kwargs={'pk': 99999}), data)
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

def test_delete_nonexistent_position(self):
"""Test deleting a non-existent position"""
response = self.client.delete(reverse('api-hr:position-detail', kwargs={'pk': 99999}))
self.assertEqual(response.status_code, status.HTTP_404_NOT_FOUND)

Loading