from django.test import TestCase from django.utils import timezone from django.conf import settings from django.contrib.auth.models import User from unittest.mock import Mock from finance.rules import is_creator, not_submitted, leads_excursion from finance.models import Statement, Ledger from members.models import Member, Group, Freizeit, GEMEINSCHAFTS_TOUR, MUSKELKRAFT_ANREISE, MALE, FEMALE class FinanceRulesTestCase(TestCase): def setUp(self): self.group = Group.objects.create(name="Test Group") self.ledger = Ledger.objects.create(name="Test Ledger") self.user1 = User.objects.create_user(username="alice", password="test123") self.member1 = Member.objects.create( prename="Alice", lastname="Smith", birth_date=timezone.now().date(), email=settings.TEST_MAIL, gender=FEMALE, user=self.user1 ) self.member1.group.add(self.group) self.user2 = User.objects.create_user(username="bob", password="test123") self.member2 = Member.objects.create( prename="Bob", lastname="Jones", birth_date=timezone.now().date(), email=settings.TEST_MAIL, gender=MALE, user=self.user2 ) self.member2.group.add(self.group) self.freizeit = Freizeit.objects.create( name="Test Excursion", kilometers_traveled=100, tour_type=GEMEINSCHAFTS_TOUR, tour_approach=MUSKELKRAFT_ANREISE, difficulty=2 ) self.freizeit.jugendleiter.add(self.member1) self.statement = Statement.objects.create( short_description="Test Statement", explanation="Test explanation", night_cost=27, created_by=self.member1, excursion=self.freizeit ) self.statement.allowance_to.add(self.member1) def test_is_creator_true(self): """Test is_creator predicate returns True when user created the statement""" self.assertTrue(is_creator(self.user1, self.statement)) self.assertFalse(is_creator(self.user2, self.statement)) def test_not_submitted_statement(self): """Test not_submitted predicate returns True when statement is not submitted""" self.statement.submitted = False self.assertTrue(not_submitted(self.user1, self.statement)) self.statement.submitted = True self.assertFalse(not_submitted(self.user1, self.statement)) def test_not_submitted_freizeit_with_statement(self): """Test not_submitted predicate with Freizeit having unsubmitted statement""" self.freizeit.statement = self.statement self.statement.submitted = False self.assertTrue(not_submitted(self.user1, self.freizeit)) def test_not_submitted_freizeit_without_statement(self): """Test not_submitted predicate with Freizeit having no statement attribute""" # Create a mock Freizeit that truly doesn't have the statement attribute mock_freizeit = Mock(spec=Freizeit) # Remove the statement attribute entirely if hasattr(mock_freizeit, 'statement'): delattr(mock_freizeit, 'statement') self.assertTrue(not_submitted(self.user1, mock_freizeit)) def test_leads_excursion_freizeit_user_is_leader(self): """Test leads_excursion predicate returns True when user leads the Freizeit""" self.assertTrue(leads_excursion(self.user1, self.freizeit)) self.assertFalse(leads_excursion(self.user2, self.freizeit)) def test_leads_excursion_statement_with_excursion(self): """Test leads_excursion predicate with statement having excursion led by user""" result = leads_excursion(self.user1, self.statement) self.assertTrue(result) def test_leads_excursion_statement_no_excursion_attribute(self): """Test leads_excursion predicate with statement having no excursion attribute""" mock_statement = Mock() del mock_statement.excursion result = leads_excursion(self.user1, mock_statement) self.assertFalse(result) def test_leads_excursion_statement_excursion_is_none(self): """Test leads_excursion predicate with statement having None excursion""" statement_no_excursion = Statement.objects.create( short_description="Test Statement No Excursion", explanation="Test explanation", night_cost=27, created_by=self.member1, excursion=None ) result = leads_excursion(self.user1, statement_no_excursion) self.assertFalse(result)