loko/streetup/contracts/tests.py
2026-07-22 14:48:40 +02:00

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())