o
    .j<                     @   s   d Z ddlmZmZmZ ddlZddlmZmZ ddlm	Z	m
Z
 G dd dZG dd	 d	ZG d
d dZG dd dZG dd dZG dd dZdS )aR  Tests for issue #860: Improved setters for start/duration/end.

This test suite defines the desired behavior for the improved setter implementations
as described in https://github.com/collective/icalendar/issues/860

The tests ensure RFC 5545 compliance, proper property locking mechanisms,
and backward compatibility with existing code.
    )datedatetime	timedeltaN)EventTodo)IncompleteComponentInvalidCalendarc                   @   s0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )TestDurationSetterz+Test the new duration setter functionality.c                 C      t  }|dd tddddd|_tddddd|_tdd	|_|jtdddddks.J |jtdddd
dks;J |jtdd	ksEJ d|v sKJ d|vsQJ dS )z;Test setting duration with start locked (default behavior).UIDztest-duration-setter        r         hours   DURATIONDTENDNr   addr   startendr   durationselfevent r   d/home/thesage/.local/lib/python3.10/site-packages/icalendar/tests/test_issue_860_improved_setters.py,test_event_duration_setter_with_start_locked      z?TestDurationSetter.test_event_duration_setter_with_start_lockedc                 C   s   t  }|dd tddddd|_tddddd|_d|v s!J d	|vs'J tdd
|_d	|v s3J d|vs9J |jtdd
ksCJ dS )zGTest that setting duration creates DURATION property and removes DTEND.r   ztest-duration-propertyr   r   r   r   r   r   r   r   Nr   r   r   r   r   4test_event_duration_setter_creates_duration_property%   s   zGTestDurationSetter.test_event_duration_setter_creates_duration_propertyc                 C   r
   )z1Test setting duration for Todo with start locked.r   ztest-todo-durationr   r   r   r   r      r      r   DUEN)r   r   r   r   r   r   r   r   todor   r   r   +test_todo_duration_setter_with_start_locked7   r!   z>TestDurationSetter.test_todo_duration_setter_with_start_lockedc                 C   sN   t  }|dd tt tdd|_W d   dS 1 s w   Y  dS )zBTest that setting duration without start raises appropriate error.r   ztest-no-start   r   N)r   r   pytestraisesr   r   r   r   r   r   r   /test_duration_setter_without_start_raises_errorG   s
   "zBTestDurationSetter.test_duration_setter_without_start_raises_errorN)__name__
__module____qualname____doc__r    r"   r(   r,   r   r   r   r   r	      s    r	   c                   @   H   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d Zdd Z	dd Z
dS )TestExplicitLockingMethodszITest the explicit locking methods set_start(), set_end(), set_duration().c                 C   s   t  }|dd tddddd|_tddddd|_|tdd	 |jtdddddks0J |jtdddd
dks=J |jtdd	ksGJ dS )z0Test set_duration() with start locked (default).r   ztest-set-durationr   r   r   r   r   r   r   r   Nr   r   r   r   r   set_durationr   r   r   r   r   r   #test_set_duration_with_start_lockedS   s   z>TestExplicitLockingMethods.test_set_duration_with_start_lockedc                 C   s   t  }|dd tddddd|_tddddd|_|jtdd	d
d |jtdddddks2J |jtdddddks?J |jtdd	ksIJ dS )z$Test set_duration() with end locked.r   ztest-set-duration-end-lockedr   r   r   r   r   r   r   r   locked   Nr3   r   r   r   r   !test_set_duration_with_end_lockeda   s   z<TestExplicitLockingMethods.test_set_duration_with_end_lockedc                 C   sp   t  }|dd tddddd|_tddddd|_|d d	|v s&J d
|vs,J |jtddks6J dS )z>Test set_duration() with None to convert to DURATION property.r   ztest-convert-durationr   r   r   r   r   Nr   r   r)   r   )r   r   r   r   r   r4   r   r   r   r   r   r   .test_set_duration_convert_to_duration_propertyo   s   
zITestExplicitLockingMethods.test_set_duration_convert_to_duration_propertyc                 C   s   t  }|dd tddddd|_|dtdd	 |tdddd
d |jtdddd
dks3J |jtdddddks@J |jtdd	ksJJ dS )z&Test set_start() with duration locked.r   ztest-set-startr   r   r   r   r   r)   r   
   N)r   r   r   r   r   	set_startr   r   r   r   r   r   #test_set_start_with_duration_locked}      z>TestExplicitLockingMethods.test_set_start_with_duration_lockedc                 C   s   t  }|dd tddddd|_tddddd|_|jtdddddd	d
 |jtdddddks5J |jtdddddksBJ |jtddksLJ dS )z!Test set_start() with end locked.r   ztest-set-start-end-lockedr   r   r   r   r   r;   r   r6   r#   r   N)r   r   r   r   r   r<   r   r   r   r   r   r   test_set_start_with_end_locked      z9TestExplicitLockingMethods.test_set_start_with_end_lockedc                 C   s   t  }|dd tddddd|_tddddd|_|tddddd |jtdddddks3J |jtdddddks@J |jtd	d
ksJJ dS )z+Test set_end() with start locked (default).r   ztest-set-endr   r   r   r   r   r$   r#   r   N)r   r   r   r   r   set_endr   r   r   r   r   r   test_set_end_with_start_locked   r>   z9TestExplicitLockingMethods.test_set_end_with_start_lockedc                 C   s   t  }|dd tddddd|_|dtdd	 |jtdddd
ddd |jtdddddks5J |jtdddd
dksBJ |jtdd	ksLJ dS )z$Test set_end() with duration locked.r   ztest-set-end-duration-lockedr   r   r   r   r   r)   r   r$   r   r6   r   N)r   r   r   r   r   rA   r   r   r   r   r   r   !test_set_end_with_duration_locked   r@   z<TestExplicitLockingMethods.test_set_end_with_duration_lockedN)r-   r.   r/   r0   r5   r9   r:   r=   r?   rB   rC   r   r   r   r   r2   P   s    r2   c                   @   (   e Zd ZdZdd Zdd Zdd ZdS )	TestImprovedPropertySettersz7Test the improved property setters with smart defaults.c                 C   s   t  }|dd tddddd|_|dtdd	 tdddd
d|_|jtdddd
dks1J |jtdddddks>J |jtdd	ksHJ dS )zGTest start setter when DURATION property exists (should lock duration).r   ztest-start-durationr   r   r   r   r   r)   r   r;   Nr   r   r   r   r   r   r   r   r   r   r   (test_start_setter_with_duration_property      zDTestImprovedPropertySetters.test_start_setter_with_duration_propertyc                 C   s   t  }|dd tddddd|_tddddd|_tddddd|_|jtdddddks1J |jtdddddks>J |jtd	d
ksHJ dS )z?Test start setter when DTEND property exists (should lock end).r   ztest-start-dtendr   r   r   r   r   r;   r#   r   Nr   r   r   r   r   r   r   r   r   r   r   %test_start_setter_with_dtend_property   rH   zATestImprovedPropertySetters.test_start_setter_with_dtend_propertyc                 C   s   t  }|dd tddddd|_|dtdd	 tdddd
d|_|jtdddddks1J |jtdddd
dks>J |jtdd	ksHJ d|v sNJ d|vsTJ dS )zGTest end setter when DURATION property exists (should remove DURATION).r   ztest-end-durationr   r   r   r   r   r)   r   r$   r#   r   NrF   r   r   r   r   &test_end_setter_with_duration_property   s   zBTestImprovedPropertySetters.test_end_setter_with_duration_propertyN)r-   r.   r/   r0   rG   rJ   rK   r   r   r   r   rE      s
    rE   c                   @   rD   )	TestRFCCompliancez<Test that the improved setters maintain RFC 5545 compliance.c                 C   s   t  }|dd tddddd|_tddddd|_tdd	|_d
|v s'J d|vs-J tddddd|_d|v s<J d
|vsBJ dS )z4Test that DTEND and DURATION are mutually exclusive.r   ztest-mutual-exclusionr   r   r   r   r   r   r   r   r   r$   Nr   r   r   r   r   (test_dtend_and_duration_mutual_exclusion   s   z:TestRFCCompliance.test_dtend_and_duration_mutual_exclusionc                 C   sz   t  }|dd tddd|_tt tdd|_W d   n1 s&w   Y  tdd|_|jtddks;J dS )	z=Test that date DTSTART with time-based DURATION raises error.r   ztest-date-durationr   r   r)   r   N)days)	r   r   r   r   r*   r+   r   r   r   r   r   r   r   test_date_duration_validation   s   z/TestRFCCompliance.test_date_duration_validationc                 C   sh   t  }|dd tddddd|_tddd|_tt |j}W d   dS 1 s-w   Y  dS )z0Test that DTSTART and DTEND must have same type.r   ztest-type-consistencyr   r   r   r   N)	r   r   r   r   r   r   r*   r+   r   )r   r   _r   r   r   test_datetime_type_consistency  s   "z0TestRFCCompliance.test_datetime_type_consistencyN)r-   r.   r/   r0   rM   rO   rQ   r   r   r   r   rL      s
    rL   c                   @   s    e Zd ZdZdd Zdd ZdS )TestBackwardCompatibilityz?Test that the improved setters maintain backward compatibility.c                 C   s   t  }|dd tddddd|_tddddd|_|jtdddddks(J |jtdddddks5J |jtdd	ks?J d
S )z4Test that existing simple usage patterns still work.r   ztest-backward-compatr   r   r   r   r   r)   r   NrI   r   r   r   r   &test_existing_simple_usage_still_works  s   z@TestBackwardCompatibility.test_existing_simple_usage_still_worksc                 C   s   t  }|dd tddddd|_|dtdd	 |jd
us"J |jd
us)J |jd
u s0J |jtdddddks=J |jtdddddksJJ |j	tdd	ksTJ d
S )z-Test that property access remains compatible.r   ztest-property-accessr   r   r   r   r   r)   r   Nr   )
r   r   r   r   r   DTSTARTr   r   r   r   r   r   r   r   "test_property_access_compatibility$  s   z<TestBackwardCompatibility.test_property_access_compatibilityN)r-   r.   r/   r0   rS   rU   r   r   r   r   rR     s    rR   c                   @   r1   )TestErrorConditionsz;Test error conditions and edge cases for improved coverage.c                 C   sl   t  }|dd tddddd|_tjtdd |jtd	d
dd W d   dS 1 s/w   Y  dS )9Test that invalid locked values raise appropriate errors.r   test-invalid-lockedr   r   r   r   .locked must be 'start' or 'end', not 'invalid'matchr)   r   invalidr6   N)	r   r   r   r   r*   r+   
ValueErrorr4   r   r   r   r   r   &test_set_duration_invalid_locked_value9  s   "z:TestErrorConditions.test_set_duration_invalid_locked_valuec                 C   r   t  }|dd tddddd|_tjtdd |jtdddd	dd
d W d   dS 1 s2w   Y  dS )rW   r   rX   r   r   r   r   8locked must be 'duration', 'end', or None, not 'invalid'rZ   r   r\   r6   N)r   r   r   r   r*   r+   r]   r<   r   r   r   r   #test_set_start_invalid_locked_valueD     "z7TestErrorConditions.test_set_start_invalid_locked_valuec                 C   r_   )rW   r   rX   r   r   r   r   3locked must be 'start' or 'duration', not 'invalid'rZ   r   r\   r6   N)r   r   r   r   r*   r+   r]   rA   r   r   r   r   !test_set_end_invalid_locked_valueO  rb   z5TestErrorConditions.test_set_end_invalid_locked_valuec                 C   s^   t  }|dd tddddd|_tjtdd d	|_W d
   d
S 1 s(w   Y  d
S )z0Test that duration setter rejects invalid types.r   test-invalid-typer   r   r   r   zUse timedelta, not strrZ   z2 hoursN)r   r   r   r   r*   r+   	TypeErrorr   r   r   r   r   !test_duration_setter_invalid_typeZ  s   "z5TestErrorConditions.test_duration_setter_invalid_typec                 C   sf   t  }|dd tddddd|_tjtdd |jd	d
d W d   dS 1 s,w   Y  dS )z-Test that set_duration rejects invalid types.r   re   r   r   r   r   zUse timedelta, not intrZ   i   r   r6   N)r   r   r   r   r*   r+   rf   r4   r   r   r   r   test_set_duration_invalid_typec  s   "z2TestErrorConditions.test_set_duration_invalid_typec                 C   s   t  }|dd tddddd|_tjtdd |jtd	d
dd W d   n1 s.w   Y  tjtdd |j	tddddddd W d   n1 sRw   Y  tjtdd |j
tddddddd W d   dS 1 sww   Y  dS )z%Test error conditions for Todo class.r   ztest-todo-errorsr   r   r   r   rY   rZ   r)   r   r\   r6   Nr`   r   rc   )r   r   r   r   r*   r+   r]   r4   r   r<   rA   r&   r   r   r   test_todo_error_conditionsl  s$   "z.TestErrorConditions.test_todo_error_conditionsc                 C   s\   t  }|dd |jtddddddd |jtdddddks#J tdddd	d|_dS )
z6Test auto-detection when no existing properties exist.r   ztest-auto-detectr   r   r   r   Nr6   r   )r   r   r<   r   r   r   r   r   r   r   1test_set_start_auto_detect_no_existing_properties  s
   zETestErrorConditions.test_set_start_auto_detect_no_existing_propertiesN)r-   r.   r/   r0   r^   ra   rd   rg   rh   ri   rj   r   r   r   r   rV   6  s    		rV   )r0   r   r   r   r*   	icalendarr   r   icalendar.errorr   r   r	   r2   rE   rL   rR   rV   r   r   r   r   <module>   s    	>f0."