# -*- coding: utf-8 -*- from odoo.tests import TransactionCase from odoo.exceptions import ValidationError class TestSignInSignOutConstraints(TransactionCase): """Test cases for sign in/out time constraints in resource.calendar""" def setUp(self): """Setup test data - calendar for time validation""" super(TestSignInSignOutConstraints, self).setUp() self.calendar = self.env['resource.calendar'].create({ 'name': 'Time Constraints Test Calendar', 'noke': False, }) def test_full_day_max_sign_in_less_than_min_raises_error(self): # Arrange & Act & Assert with self.assertRaises(ValidationError) as context: self.calendar.write({ 'is_full_day': True, 'full_min_sign_in': 9.0, 'full_min_sign_out': 8.0, 'full_max_sign_in': 8.0, # Before min 'full_max_sign_out': 18.0, }) self.assertIn('Max sign in should be greater than or equal min sign in', str(context.exception)) def test_full_day_min_sign_out_before_min_sign_in_raises_error(self): """ Arrange: Set min sign out before min sign in for full day Act: Try to write invalid data Assert: ValidationError raised automatically by @api.constrains """ # Act & Assert - wrap the write() call with self.assertRaises(ValidationError) as context: self.calendar.write({ 'is_full_day': True, 'full_min_sign_in': 10.0, 'full_max_sign_in': 11.0, 'full_min_sign_out': 9.0, # Invalid: before min sign in 'full_max_sign_out': 18.0, 'working_hours': 8.0, # Add this to avoid other constraints }) # Optional: verify error message self.assertIn('min sign out should be greater than or equal min sign in', str(context.exception)) def test_shift_one_max_sign_in_less_than_min_raises_error(self): """ Arrange: Set invalid shift one times (max < min) Act: Try to write Assert: ValidationError raised """ with self.assertRaises(ValidationError) as context: self.calendar.write({ 'is_full_day': False, 'shift_one_min_sign_in': 10.0, # min = 10 'shift_one_max_sign_in': 9.0, # max = 9 (INVALID!) 'shift_one_min_sign_out': 16.0, 'shift_one_max_sign_out': 17.0, 'shift_one_working_hours': 6.0, # Add working hours }) self.assertIn('Max sign in should be greater than or equal min sign in', str(context.exception)) def test_shift_two_min_sign_out_before_min_sign_in_raises_error(self): """ Arrange: Set invalid shift two times Act: Try to write Assert: ValidationError raised """ with self.assertRaises(ValidationError) as context: self.calendar.write({ 'is_full_day': False, 'shift_two_min_sign_in': 16.0, 'shift_two_max_sign_in': 17.0, 'shift_two_min_sign_out': 15.0, # Invalid: before min sign in 'shift_two_max_sign_out': 24.0, 'shift_two_working_hours': 8.0, # Add working hours }) self.assertIn('shift two', str(context.exception).lower()) def test_full_day_max_sign_out_less_than_min_sign_out_raises_error(self): # This test is CORRECT - error is expected and happening! with self.assertRaises(ValidationError) as context: self.calendar.write({ 'is_full_day': True, 'full_min_sign_in': 8.0, 'full_max_sign_in': 9.0, 'full_min_sign_out': 17.0, 'full_max_sign_out': 16.0, # Before min - ERROR EXPECTED }) self.assertIn('Max sign out should be greater', str(context.exception)) def test_full_day_valid_times_do_not_raise_error(self): """ Arrange: Set valid full day times Act: Save calendar Assert: No validation error should be raised """ # Arrange self.calendar.write({ 'is_full_day': True, 'full_min_sign_in': 8.0, 'full_max_sign_in': 9.0, 'full_min_sign_out': 17.0, 'full_max_sign_out': 18.0, }) # Act & Assert try: self.calendar.full_time_constrains() except ValidationError: self.fail("Valid full day times should not raise ValidationError") def test_noke_mode_bypasses_time_constraints(self): """ Arrange: Enable noke mode with invalid times Act: Save calendar Assert: No validation error (noke mode disables checks) """ # Arrange self.calendar.write({ 'is_full_day': True, 'noke': True, 'full_min_sign_in': 10.0, 'full_max_sign_in': 8.0, # Invalid, but noke=True 'full_min_sign_out': 17.0, 'full_max_sign_out': 16.0, }) # Act & Assert try: self.calendar.full_time_constrains() except ValidationError: self.fail("Noke mode should bypass time constraints validation")