197 lines
8 KiB
Python
197 lines
8 KiB
Python
from django.test import TestCase, Client
|
|
from django.contrib.auth import get_user_model
|
|
from django.utils import timezone
|
|
from django.urls import reverse
|
|
import json
|
|
|
|
from contracts.models import Company, CompanyTeam, CompanyMember, CompanyMemberHistory
|
|
from common.models import UserConfig, Role
|
|
|
|
User = get_user_model()
|
|
|
|
class CompanyMemberTeamsTests(TestCase):
|
|
def setUp(self):
|
|
# Create user and configuration
|
|
self.user = User.objects.create_user(username="testuser", password="password123")
|
|
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
|
|
|
|
# Create company and teams
|
|
self.company = Company.objects.create(name="Test Company")
|
|
self.team1 = CompanyTeam.objects.create(name="Team Alpha", company=self.company)
|
|
self.team2 = CompanyTeam.objects.create(name="Team Beta", company=self.company)
|
|
|
|
# Create member
|
|
self.member = CompanyMember.objects.create(
|
|
name="Jean Dupont",
|
|
user=self.user
|
|
)
|
|
|
|
def test_assign_multiple_teams(self):
|
|
"""Test that a member can be assigned to multiple teams and history tracks it."""
|
|
today = timezone.now().date()
|
|
|
|
# Add to Team 1
|
|
self.member.teams.add(self.team1)
|
|
self.assertEqual(self.member.teams.count(), 1)
|
|
|
|
# Verify history entry created
|
|
histories = CompanyMemberHistory.objects.filter(member=self.member, team=self.team1)
|
|
self.assertEqual(histories.count(), 1)
|
|
self.assertEqual(histories.first().join_date, today)
|
|
self.assertIsNone(histories.first().leave_date)
|
|
|
|
# Add to Team 2
|
|
self.member.teams.add(self.team2)
|
|
self.assertEqual(self.member.teams.count(), 2)
|
|
|
|
# Verify history for Team 2
|
|
histories_team2 = CompanyMemberHistory.objects.filter(member=self.member, team=self.team2)
|
|
self.assertEqual(histories_team2.count(), 1)
|
|
self.assertEqual(histories_team2.first().join_date, today)
|
|
self.assertIsNone(histories_team2.first().leave_date)
|
|
|
|
def test_remove_team(self):
|
|
"""Test that removing a team closes the history period."""
|
|
today = timezone.now().date()
|
|
self.member.teams.add(self.team1)
|
|
|
|
# Remove from Team 1
|
|
self.member.teams.remove(self.team1)
|
|
self.assertEqual(self.member.teams.count(), 0)
|
|
|
|
# Verify history leave_date updated
|
|
history = CompanyMemberHistory.objects.get(member=self.member, team=self.team1)
|
|
self.assertEqual(history.leave_date, today)
|
|
|
|
def test_clear_teams(self):
|
|
"""Test that clearing teams closes all active history periods."""
|
|
today = timezone.now().date()
|
|
self.member.teams.add(self.team1)
|
|
self.member.teams.add(self.team2)
|
|
|
|
# Clear teams
|
|
self.member.teams.clear()
|
|
self.assertEqual(self.member.teams.count(), 0)
|
|
|
|
# Verify history leave_date updated for all
|
|
h1 = CompanyMemberHistory.objects.get(member=self.member, team=self.team1)
|
|
h2 = CompanyMemberHistory.objects.get(member=self.member, team=self.team2)
|
|
self.assertEqual(h1.leave_date, today)
|
|
self.assertEqual(h2.leave_date, today)
|
|
|
|
|
|
class TeamViewsAjaxTests(TestCase):
|
|
def setUp(self):
|
|
self.client = Client()
|
|
self.user = User.objects.create_user(username="adminuser", password="password")
|
|
self.user_config = UserConfig.objects.create(user=self.user, is_intern=True)
|
|
# Give admin role to bypass permission denials
|
|
self.admin_role, _ = Role.objects.get_or_create(name="admin")
|
|
self.user_config.roles.add(self.admin_role)
|
|
|
|
self.client.login(username="adminuser", password="password")
|
|
|
|
self.company = Company.objects.create(name="Test Company")
|
|
self.team_a = CompanyTeam.objects.create(name="Team A", company=self.company)
|
|
self.team_b = CompanyTeam.objects.create(name="Team B", company=self.company)
|
|
|
|
self.member = CompanyMember.objects.create(name="Tech A", user=self.user)
|
|
self.member.teams.add(self.team_a)
|
|
|
|
def test_teams_move_member_transfer(self):
|
|
"""Test moving a member transfers them (removes old, adds new)."""
|
|
url = reverse('contracts:teams_move_member', args=[self.member.id])
|
|
payload = {
|
|
'old_team_id': self.team_a.id,
|
|
'team_id': self.team_b.id
|
|
}
|
|
|
|
response = self.client.post(
|
|
url,
|
|
data=json.dumps(payload),
|
|
content_type='application/json'
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.member.refresh_from_db()
|
|
# Should only belong to Team B now
|
|
self.assertEqual(list(self.member.teams.all()), [self.team_b])
|
|
|
|
# Verify history was updated
|
|
today = timezone.now().date()
|
|
h_old = CompanyMemberHistory.objects.get(member=self.member, team=self.team_a)
|
|
self.assertEqual(h_old.leave_date, today)
|
|
h_new = CompanyMemberHistory.objects.get(member=self.member, team=self.team_b)
|
|
self.assertEqual(h_new.join_date, today)
|
|
self.assertIsNone(h_new.leave_date)
|
|
|
|
def test_teams_update_member_modal(self):
|
|
"""Test updating a member via modal view with transfer."""
|
|
url = reverse('contracts:teams_update_member', args=[self.member.id])
|
|
payload = {
|
|
'name': 'Tech A Modified',
|
|
'old_team_id': self.team_a.id,
|
|
'team_id': self.team_b.id
|
|
}
|
|
|
|
response = self.client.post(
|
|
url,
|
|
data=json.dumps(payload),
|
|
content_type='application/json'
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
self.member.refresh_from_db()
|
|
self.assertEqual(self.member.name, 'Tech A Modified')
|
|
self.assertEqual(list(self.member.teams.all()), [self.team_b])
|
|
|
|
def test_teams_create_member_different_company_allowed_for_team_company(self):
|
|
"""Test that a non-admin user can add a member belonging to the target team's company, even if different from user's company."""
|
|
from django.contrib.auth.models import User
|
|
from common.models import UserConfig, Role
|
|
from contracts.models import Company, CompanyTeam, CompanyMember, UserCompanyTeamAccess
|
|
|
|
# Create user of Company A
|
|
other_user = User.objects.create_user(username="otheruser", password="password")
|
|
company_a = Company.objects.create(name="Company A")
|
|
other_user_config = UserConfig.objects.create(user=other_user, company=company_a)
|
|
|
|
# Create team belonging to Company B
|
|
company_b = Company.objects.create(name="Company B")
|
|
team_b = CompanyTeam.objects.create(name="Team Company B", company=company_b)
|
|
|
|
# Grant user edit permission on team_b
|
|
UserCompanyTeamAccess.objects.create(
|
|
user_config=other_user_config,
|
|
team=team_b,
|
|
can_view=True,
|
|
can_edit=True
|
|
)
|
|
|
|
# Create target user to add, belonging to Company B
|
|
target_user = User.objects.create_user(username="targetuser", password="password")
|
|
UserConfig.objects.create(user=target_user, company=company_b)
|
|
|
|
# Login other_user
|
|
self.client.logout()
|
|
self.client.login(username="otheruser", password="password")
|
|
|
|
# Call teams_create_member
|
|
url = reverse('contracts:teams_create_member')
|
|
payload = {
|
|
'name': 'New Target Member',
|
|
'user_id': target_user.id,
|
|
'team_id': team_b.id
|
|
}
|
|
|
|
response = self.client.post(
|
|
url,
|
|
data=json.dumps(payload),
|
|
content_type='application/json'
|
|
)
|
|
self.assertEqual(response.status_code, 200)
|
|
|
|
# Verify member was created and added to team_b
|
|
member = CompanyMember.objects.get(user=target_user)
|
|
self.assertEqual(member.name, 'New Target Member')
|
|
self.assertIn(team_b, member.teams.all())
|