a
    Cg+                     @   s   d dl Z d dlZd dlmZ d dlmZ d dlmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ erd dlmZ d dlmZ G dd deeZG dd deeZG dd deeZdS )    N)Path)TYPE_CHECKING)settings)widgets)Context)SimpleTestCase)
SafeString)	ComponentMediaContainer)MediaAssertionMixin)Optional)RenderContextc                   @   sd   e Zd ZdZddddZddddZdddd	Zddd
dZddddZddddZ	dS )TestComponentz"Directly test the Component class.Nreturnc                 C   s   t  | _d S N)r	   	componentself r   Z/var/www/lab.imftr.de/x/nb_venv/lib/python3.9/site-packages/laces/tests/test_components.pysetUp   s    zTestComponent.setUpc                 C   s8   |  t | j  W d   n1 s*0    Y  dS )zTest the `render_html` method.N)assertRaisesAttributeErrorr   render_htmlr   r   r   r   test_render_html   s    zTestComponent.test_render_htmlc                 C   s,   | j jt d}| |t | |i  dS )z
        Test the default `get_context_data`.

        The parent context should not matter, but we use it as it is used in
        `render_html` (which passes a `Context` object).
        parent_contextN)r   get_context_datar   assertIsInstancedictassertEqualr   resultr   r   r   7test_get_context_data_with_parent_context_empty_context%   s    zETestComponent.test_get_context_data_with_parent_context_empty_contextc                 C   s*   | j jdd}| |t | |i  dS )zHTest the default `get_context_data` when received `parent_context=None`.Nr   r   r   r   r    r!   r"   r   r   r   .test_get_context_data_with_parent_context_none1   s    z<TestComponent.test_get_context_data_with_parent_context_nonec                 C   s&   | j  }| |t | |i  dS )zGTest the default `get_context_data` when not passing  `parent_context`.Nr%   r"   r   r   r   5test_get_context_data_without_parent_context_argument8   s    
zCTestComponent.test_get_context_data_without_parent_context_argumentc                 C   s.   t  }| | jjt j | | jj| dS )z
        Test the `media` property.

        The `media` property is added through the `metaclass=MediaDefiningClass`
        definition.

        N)r   Mediar   r   mediaassertMediaEqual)r   Zempty_mediar   r   r   
test_media?   s    zTestComponent.test_media)
__name__
__module____qualname____doc__r   r   r$   r&   r'   r+   r   r   r   r   r      s   r   c                   @   s   e Zd ZdZeedddZeedddZdddd	Zedd
ddZ	ddddZ
ddddZddddZddddZddddZdS )TestComponentSubclassesaG  
    Test the Component class through subclasses.

    Most functionality of the Component class is only unlocked through subclassing and
    definition of certain attributes (like `template_name`) or overriding of the
    existing methods. This test class tests the functionality that is unlocked through
    subclassing.
    r   c                 C   s   dt dd dS )Nzexample-i  i'  z.html)randomrandint)clsr   r   r   make_example_template_nameV   s    z2TestComponentSubclasses.make_example_template_namec                 C   s"   |   }tj|r|   }q|S r   )r4   ospathexists)r3   example_template_namer   r   r   get_example_template_nameZ   s    
z1TestComponentSubclasses.get_example_template_nameNc                 C   s.   |   | _ttjd | j | _| d d S )NZ	templates )r9   r8   r   r   ZPROJECT_DIRexample_templateset_example_template_contentr   r   r   r   r   a   s    
zTestComponentSubclasses.setUp)contentr   c                 C   s:   t | jd}|| W d    n1 s,0    Y  d S )Nw)openr;   write)r   r=   fr   r   r   r<   i   s    z4TestComponentSubclasses.set_example_template_contentc                    sP   G  fdddt } d |  } |t  |t  |d dS )zQ
        Test `render_html` method with a set `template_name` attribute.
        c                       s   e Zd Z jZdS )zYTestComponentSubclasses.test_render_html_with_template_name_set.<locals>.ExampleComponentN)r,   r-   r.   r8   template_namer   r   r   r   ExampleComponents   s   rC   ZTestN)r	   r<   r   r   strr   r!   r   rC   r#   r   r   r   'test_render_html_with_template_name_setm   s    

z?TestComponentSubclasses.test_render_html_with_template_name_setc                    s8   G  fdddt } d |  } |d dS )zk
        Test `render_html` method with `get_context_data` providing data for the
        context.
        c                       s$   e Zd Z jZddddddZdS )zxTestComponentSubclasses.test_render_html_with_template_name_set_and_data_from_get_context_data.<locals>.ExampleComponentNOptional[RenderContext]r   r   r   c                 S   s   ddiS )z)Return a context dict with fixed content.nameZWorldr   r   r   r   r   r   r      s    zTestComponentSubclasses.test_render_html_with_template_name_set_and_data_from_get_context_data.<locals>.ExampleComponent.get_context_data)Nr,   r-   r.   r8   rB   r   r   r   r   r   rC      s    rC   zHello {{ name }}zHello WorldNr	   r<   r   r!   rE   r   r   r   Ftest_render_html_with_template_name_set_and_data_from_get_context_data   s    	

z^TestComponentSubclasses.test_render_html_with_template_name_set_and_data_from_get_context_datac                    s8   G  fdddt } d |  } |d dS )a%  
        Test `render_html` method when `get_context_data` returns `None`.

        Originally, the `render_html` method explicitly raised a `TypeError` when
        `None` was returned from `get_context_method`.

        I was not able to find out why this check was put in place. The usage of
        components in Wagtail does not reveal any issues when the raising of the
        exception is removed. Also, the following template rendering (with
        `django.template.base.Template.render`) works just fine with the context being
        `None`.

        It seems therefore safe to assume that this was a left-over without much current
        need.

        This test is in place to prove that a component can behave as expected when the
        `get_context_data` method returns `None`.
        c                       s$   e Zd Z jZddddddZdS )zeTestComponentSubclasses.test_render_html_when_get_context_data_returns_none.<locals>.ExampleComponentNrG   rH   c                 S   s   dS )z"Return `None` as the context data.Nr   rJ   r   r   r   r      s    zvTestComponentSubclasses.test_render_html_when_get_context_data_returns_none.<locals>.ExampleComponent.get_context_data)NrK   r   r   r   r   rC      s    rC   ZHelloNrL   rE   r   r   r   3test_render_html_when_get_context_data_returns_none   s    

zKTestComponentSubclasses.test_render_html_when_get_context_data_returns_nonec                 C   sH   G dd dt }| j}| |tj | |tjddgidgd dS )a  
        Test the `media` property when defined through a nested class.

        The `media` property is added through the `metaclass=MediaDefiningClass`
        definition. This test ensures that the `media` property is available when
        configured through a nested class.
        c                   @   s   e Zd ZG dd dZdS )zYTestComponentSubclasses.test_media_defined_through_nested_class.<locals>.ExampleComponentc                   @   s   e Zd ZddgiZdgZdS )z_TestComponentSubclasses.test_media_defined_through_nested_class.<locals>.ExampleComponent.Mediaallexample.css
example.jsN)r,   r-   r.   cssjsr   r   r   r   r(      s   
r(   N)r,   r-   r.   r(   r   r   r   r   rC      s   rC   rO   rP   rQ   rR   rS   N)r	   r)   r   r   r(   r*   rE   r   r   r   'test_media_defined_through_nested_class   s    
z?TestComponentSubclasses.test_media_defined_through_nested_classc                 C   s   t j| jd d S )N)r6   )r5   remover;   r   r   r   r   tearDown   s    z TestComponentSubclasses.tearDown)r,   r-   r.   r/   classmethodrD   r4   r9   r   r<   rF   rM   rN   rU   rW   r   r   r   r   r0   L   s   	&r0   c                   @   sV   e Zd ZdZddddZddddZdddd	Zddd
dZddddZdS )TestMediaContainera  
    Test the MediaContainer class.

    The `MediaContainer` functionality depends on the `django.forms.widgets.Media`
    class. The `Media` class provides the logic to combine the media definitions of
    multiple objects through its `__add__` method. The `MediaContainer` relies on this
    functionality to provide a `media` property that combines the media definitions of
    its members.

    See also:
    https://docs.djangoproject.com/en/4.2/topics/forms/media
    Nr   c                 C   s   t  | _d S r   )r
   media_containerr   r   r   r   r      s    zTestMediaContainer.setUpc                 C   s*   | j j}| |tj | |t  d S r   )rZ   r)   r   r   r(   r*   r"   r   r   r   
test_empty   s    zTestMediaContainer.test_emptyc                 C   sb   G dd d}| }| j | | j j}| |tj | ||j | |tjddgid d S )Nc                   @   s   e Zd ZejddgidZdS )z;TestMediaContainer.test_single_member.<locals>.ExampleClassrO   rP   rR   Nr,   r-   r.   r   r(   r)   r   r   r   r   ExampleClass   s   r^   rO   rP   r\   rZ   appendr)   r   r   r(   r*   )r   r^   exampler#   r   r   r   test_single_member   s    z%TestMediaContainer.test_single_memberc                 C   sj   G dd d}| }| }| j | | j | | j j}| |tj | |tjddgidgd d S )Nc                   @   s"   e Zd ZejddgidgdZdS )zGTestMediaContainer.test_two_members_of_same_class.<locals>.ExampleClassrO   rP   rQ   rT   Nr]   r   r   r   r   r^     s   r^   rO   rP   rQ   rT   r_   )r   r^   Z	example_1Z	example_2r#   r   r   r   test_two_members_of_same_class  s    z1TestMediaContainer.test_two_members_of_same_classc                 C   s   G dd d}G dd d}| }| j | | }| j | | j j}| |tj | |tjddgdgdd	d
gd d S )Nc                   @   s"   e Zd ZejddgidgdZdS )zNTestMediaContainer.test_two_members_of_different_classes.<locals>.ExampleClassrO   
shared.cssrQ   rT   Nr]   r   r   r   r   r^     s   r^   c                   @   s(   e Zd ZejddgdgddgdZdS )zSTestMediaContainer.test_two_members_of_different_classes.<locals>.OtherExampleClass	other.cssrd   	print.cssrO   printother.jsrT   Nr]   r   r   r   r   OtherExampleClass  s   rj   re   rd   rf   rg   rQ   ri   rT   r_   )r   r^   rj   ra   otherr#   r   r   r   %test_two_members_of_different_classes  s"    
z8TestMediaContainer.test_two_members_of_different_classes)	r,   r-   r.   r/   r   r[   rb   rc   rl   r   r   r   r   rY      s   rY   )r5   r1   pathlibr   typingr   Zdjango.confr   Zdjango.formsr   Zdjango.templater   Zdjango.testr   Zdjango.utils.safestringr   Zlaces.componentsr	   r
   Zlaces.tests.utilsr   r   Zlaces.typingr   r   r0   rY   r   r   r   r   <module>   s"   5 