test: strengthen Task 4 absence-exclusion tests (parity + behavioral POST guard)
This commit is contained in:
parent
5fa3efcf64
commit
86b0cb9dd6
@ -3542,4 +3542,47 @@ class ManagerSalariedAbsenceExclusionTests(TestCase):
|
|||||||
def test_absenceedit_supervisor_excludes_fixed(self):
|
def test_absenceedit_supervisor_excludes_fixed(self):
|
||||||
from core.forms import AbsenceEditForm
|
from core.forms import AbsenceEditForm
|
||||||
qs = AbsenceEditForm(user=self.sup).fields['worker'].queryset
|
qs = AbsenceEditForm(user=self.sup).fields['worker'].queryset
|
||||||
|
self.assertIn(self.daily, qs)
|
||||||
self.assertNotIn(self.mgr, qs)
|
self.assertNotIn(self.mgr, qs)
|
||||||
|
|
||||||
|
def test_absence_log_post_rejects_manager_id(self):
|
||||||
|
"""Behavioral guard (matches Task 3's POST-level rigor): the
|
||||||
|
ModelMultipleChoiceField re-validates submitted worker ids against
|
||||||
|
its excluded-fixed queryset. POSTing a manager's id must be rejected
|
||||||
|
with a `workers` form error and create ZERO Absence rows for the
|
||||||
|
manager — which also prevents the underlying bug this feature exists
|
||||||
|
to stop: a paid manager-absence auto-creating a Bonus
|
||||||
|
PayrollAdjustment at daily_rate. A daily worker POSTed with the SAME
|
||||||
|
payload succeeds, proving the rejection is specific to the manager
|
||||||
|
(pay_type='fixed') and not a broken payload."""
|
||||||
|
self.client.force_login(self.admin)
|
||||||
|
|
||||||
|
# --- Manager id is rejected ---
|
||||||
|
resp = self.client.post(reverse('absence_log'), data={
|
||||||
|
'date': '2026-05-14',
|
||||||
|
'reason': 'sick',
|
||||||
|
'workers': [self.mgr.id],
|
||||||
|
'notes': 'should be rejected',
|
||||||
|
})
|
||||||
|
# Form re-rendered (not a redirect to success/confirm flow).
|
||||||
|
self.assertEqual(resp.status_code, 200)
|
||||||
|
self.assertIn('form', resp.context)
|
||||||
|
self.assertIn('workers', resp.context['form'].errors)
|
||||||
|
# No Absence row created for the manager — and therefore no
|
||||||
|
# auto-created Bonus PayrollAdjustment leaking at daily_rate.
|
||||||
|
self.assertEqual(Absence.objects.filter(worker=self.mgr).count(), 0)
|
||||||
|
self.assertEqual(
|
||||||
|
PayrollAdjustment.objects.filter(worker=self.mgr).count(), 0)
|
||||||
|
|
||||||
|
# --- Positive control: daily worker, identical payload, succeeds ---
|
||||||
|
resp2 = self.client.post(reverse('absence_log'), data={
|
||||||
|
'date': '2026-05-14',
|
||||||
|
'reason': 'sick',
|
||||||
|
'workers': [self.daily.id],
|
||||||
|
'notes': 'legit daily absence',
|
||||||
|
})
|
||||||
|
# No conflicts → immediate create + redirect to the absence list.
|
||||||
|
self.assertRedirects(
|
||||||
|
resp2, reverse('absence_list'), fetch_redirect_response=False)
|
||||||
|
self.assertEqual(Absence.objects.filter(worker=self.daily).count(), 1)
|
||||||
|
self.assertEqual(Absence.objects.filter(worker=self.mgr).count(), 0)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user