o
    ÌÄ.jK  ã                   @   s„   d Z ddlZddlmZ ddlmZ ddlmZmZ ddlm	Z	 d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 )z@Tests for issue #844: timezone placement in calendar components.é    N)Údatetime)ÚZoneInfo)ÚCalendarÚEvent)ÚTimezonec                  C   s¨   t ƒ } |  dd¡ |  dd¡ tƒ }| dtt ¡ ƒ¡ tdddd	d
tdƒd|_| dd¡ |  	|¡ |  
¡  dd„ | jD ƒ}|ddgksHJ ‚| jd jdksRJ ‚dS )zVTest that single timezone is placed before event when using `add_missing_timezones()`.ÚVERSIONú2.0ÚPRODIDútest calendarÚUIDéê  é   é   é   é   úEurope/London©ÚtzinfoÚSUMMARYú
Test Eventc                 S   ó   g | ]}|j ‘qS © ©Úname©Ú.0Úcompr   r   úf/home/thesage/.local/lib/python3.10/site-packages/icalendar/tests/test_issue_844_timezone_placement.pyÚ
<listcomp>   ó    z<test_single_timezone_placed_before_event.<locals>.<listcomp>Ú	VTIMEZONEÚVEVENTr   N)r   Úaddr   ÚstrÚuuidÚuuid4r   r   ÚstartÚadd_componentÚadd_missing_timezonesÚsubcomponentsÚ	timezonesÚtz_name)ÚcalendarÚeventÚ
componentsr   r   r   Ú(test_single_timezone_placed_before_event   s   
r/   c                  C   s  t ƒ } |  dd¡ |  dd¡ tƒ }| dtt ¡ ƒ¡ tdddd	d
tdƒd|_| dd¡ |  	|¡ tƒ }| dtt ¡ ƒ¡ tddddd
tdƒd|_| dd¡ |  	|¡ |  
¡  dd„ | jD ƒ}|dd… ddgksqJ ‚|dd… ddgks}J ‚dd„ | jD ƒ}|ddhksJ ‚dS )z6Test that multiple timezones are placed before events.r   r   r	   r
   r   r   r   r   r   r   r   r   r   zLondon Eventé   úAmerica/New_YorkúNew York Eventc                 S   r   r   r   r   r   r   r   r   4   r   z@test_multiple_timezones_placed_before_events.<locals>.<listcomp>Né   r    r!   c                 S   ó   h | ]}|j ’qS r   ©r+   ©r   Útzr   r   r   Ú	<setcomp>9   r   z?test_multiple_timezones_placed_before_events.<locals>.<setcomp>)r   r"   r   r#   r$   r%   r   r   r&   r'   r(   r)   r*   )r,   Úevent1Úevent2r.   Útimezone_namesr   r   r   Ú,test_multiple_timezones_placed_before_events    s&   

r<   c                  C   s2  t ƒ } |  dd¡ |  dd¡ t d¡}|  |¡ tƒ }| dtt ¡ ƒ¡ t	ddd	d
dt
dƒd|_| dd¡ |  |¡ tƒ }| dtt ¡ ƒ¡ t	ddd	ddt
dƒd|_| dd¡ |  |¡ |  ¡  dd„ | jD ƒ}|dd… ddgks{J ‚|dd… ddgks‡J ‚dd„ | jD ƒ}|ddhks—J ‚dS )zRTest that existing timezones are preserved and new ones added in correct position.r   r   r	   r
   zEurope/Berlinr   r   r   r   r   r   r   r   zBerlin Eventr0   r1   r2   c                 S   r   r   r   r   r   r   r   r   U   r   zMtest_existing_timezone_preserved_new_ones_added_correctly.<locals>.<listcomp>Nr3   r    r!   c                 S   r4   r   r5   r6   r   r   r   r8   Z   r   zLtest_existing_timezone_preserved_new_ones_added_correctly.<locals>.<setcomp>)r   r"   r   Ú	from_tzidr'   r   r#   r$   r%   r   r   r&   r(   r)   r*   )r,   Úexisting_tzr9   r:   r.   r;   r   r   r   Ú9test_existing_timezone_preserved_new_ones_added_correctly=   s*   



r?   c                  C   sª   t ƒ } |  dd¡ |  dd¡ tƒ }| dtt ¡ ƒ¡ tdddd	d
ƒ|_| dd¡ |  |¡ dd„ | j	D ƒ}|  
¡  dd„ | j	D ƒ}||  krPdgksSJ ‚ J ‚dS )zDTest that method handles case with no missing timezones. Gracefully.r   r   r	   r
   r   r   r   r   r   r   r   zNo Timezone Eventc                 S   r   r   r   r   r   r   r   r   j   r   z8test_no_missing_timezones_no_changes.<locals>.<listcomp>c                 S   r   r   r   r   r   r   r   r   l   r   r!   N)r   r"   r   r#   r$   r%   r   r&   r'   r)   r(   )r,   r-   Úoriginal_componentsÚnew_componentsr   r   r   Ú$test_no_missing_timezones_no_changes^   s   
"rB   c                  C   sF   t ƒ } |  dd¡ |  dd¡ |  ¡  dd„ | jD ƒ}|g ks!J ‚dS )zETest that `add_missing_timezones()` handles empty calendar correctly.r   r   r	   r
   c                 S   r   r   r   r   r   r   r   r   y   r   z=test_empty_calendar_add_missing_timezones.<locals>.<listcomp>N)r   r"   r(   r)   )r,   r.   r   r   r   Ú)test_empty_calendar_add_missing_timezonesq   s   rC   c                  C   sê   t ƒ } |  dd¡ |  dd¡ tƒ }| dtt ¡ ƒ¡ tdddd	d
tdƒd|_| dd¡ |  	|¡ |  
¡  |  ¡  ¡ }| d¡}d}d}t|ƒD ]\}}| ¡ dkrX|}qK| ¡ dkr`|}qK|dusgJ ‚|dusmJ ‚||k ssJ ‚dS )zHTest that timezones appear before events in serialized iCalendar output.r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   Ú
NzBEGIN:VTIMEZONEzBEGIN:VEVENT)r   r"   r   r#   r$   r%   r   r   r&   r'   r(   Úto_icalÚdecodeÚsplitÚ	enumerateÚstrip)r,   r-   Úical_contentÚlinesÚvtimezone_lineÚvevent_lineÚiÚliner   r   r   Ú,test_timezone_placement_in_serialized_output}   s,   

€rP   c                  C   sJ   d} t  | ¡}t|jƒdksJ ‚t|jƒdksJ ‚|jd jdks#J ‚dS )z:Test that our fix doesn't break forward reference parsing.a.  BEGIN:VCALENDAR
VERSION:2.0
PRODID:test
BEGIN:VEVENT
UID:test-event
DTSTART;TZID=Europe/London:20260319T123000
SUMMARY:Test Event
END:VEVENT
BEGIN:VTIMEZONE
TZID:Europe/London
BEGIN:STANDARD
DTSTART:20001029T020000
TZOFFSETFROM:+0100
TZOFFSETTO:+0000
TZNAME:GMT
END:STANDARD
END:VTIMEZONE
END:VCALENDARé   r   r   N)r   Ú	from_icalÚlenÚeventsr*   r+   )rJ   r,   r   r   r   Ú$test_forward_reference_compatibility   s
   
rU   c               
   C   s,  ddl } | j d¡}G dd„ dƒ}|ƒ | jd< zntƒ }| dd¡ | dd	¡ tƒ }| d
tt ¡ ƒ¡ t	dddddt
dƒd|_| dd¡ | |¡ | ¡  dd„ |jD ƒ}|ddgks`J ‚t|jƒdksiJ ‚|jd jdkssJ ‚W |r}|| jd< dS | j dd¡ dS |rŽ|| jd< w | j dd¡ w )z=Test timezone placement. Works even if pytz is not available.r   NÚpytzc                   @   s   e Zd Zdd„ ZdS )z6test_timezone_placement_without_pytz.<locals>.MockPytzc                 S   s   t dƒ‚)NzNo module named 'pytz')ÚImportError)Úselfr   r   r   r   Ú__getattr__Â   s   zBtest_timezone_placement_without_pytz.<locals>.MockPytz.__getattr__N)Ú__name__Ú
__module__Ú__qualname__rY   r   r   r   r   ÚMockPytzÁ   s    r]   r   r   r	   r
   r   r   r   r   r   r   r   r   r   r   c                 S   r   r   r   r   r   r   r   r   Ô   r   z8test_timezone_placement_without_pytz.<locals>.<listcomp>r    r!   rQ   )ÚsysÚmodulesÚgetr   r"   r   r#   r$   r%   r   r   r&   r'   r(   r)   rS   r*   r+   Úpop)r^   Úoriginal_pytzr]   r,   r-   r.   r   r   r   Ú$test_timezone_placement_without_pytzº   s0   
ýrc   )Ú__doc__r$   r   Úzoneinfor   Ú	icalendarr   r   Úicalendar.cal.timezoner   r/   r<   r?   rB   rC   rP   rU   rc   r   r   r   r   Ú<module>   s    ! 