o
    h3                    @   s   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mZ d dlmZ dd	d
ZG dd deZG dd deZdS )    N)patch)TestCase)DOM)HTML)ContentstateConverterpersist_key_for_block)EmbedFc                    s   t | t kr
dS t| tr+t|  t krdS t fdd|  D S t| trHt| tkr:dS t fddt	| D S | kS )zaTest whether two contentState structures are equal, ignoring 'key' properties if match_keys=FalseFc                 3   s4    | ]\}}|d kr  pt ||  dV  qdS )key
match_keysNcontent_state_equal).0kvr   v2 e/var/www/html/ndineBlogger/venv/lib/python3.10/site-packages/wagtail/admin/tests/test_contentstate.py	<genexpr>   s    
z&content_state_equal.<locals>.<genexpr>c                 3   s"    | ]\}}t || d V  qdS )r
   Nr   )r   abr
   r   r   r      s    
)
type
isinstancedictsetkeysallitemslistlenzip)v1r   r   r   r   r   r      s   

r   c                   @   s\  e Zd ZdgZdSdd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d 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'd( Zd)d* Zd+d, Zd-d. Zd/d0 Zed1d2d3 Zed1d4d5 Zd6d7 Zd8d9 Zd:d; Z d<d= Z!d>d? Z"d@dA Z#dBdC Z$dDdE Z%dFdG Z&dHdI Z'dJdK Z(dLdM Z)dNdO Z*dPdQ Z+dRS )TTestHtmlToContentStatez	test.jsonFc              	   C   s6   |  t|||ddtj|ddtj|ddf  dS )zcAssert that two contentState structures are equal, ignoring 'key' properties if match_keys is Falser
   z%s does not match %s   )indentN)
assertTruer   jsondumps)selfr"   r   r   r   r   r   assertContentStateEqual)   s   z.TestHtmlToContentState.assertContentStateEqualc                 C   sT   t g d}t|d}| j|i g ddddg dg dddd	g dgd
dd d S )Nfeatures}
            <p data-block-key='00000'>Hello world!</p>
            <p data-block-key='00001'>Goodbye world!</p>
            Hello world!r   unstyled00000inlineStyleRangestextdepthr   r	   entityRangesGoodbye world!00001	entityMapblocksTr
   r   r'   loadsfrom_database_formatr*   r)   	converterresultr   r   r   test_paragraphs1   s6   
	
z&TestHtmlToContentState.test_paragraphsc                 C   s`   t g d}t|d}| |i g ddddg dg ddddg dg d	dddg dgd
 d S )Nr+   z~
            <foo>Hello world!</foo>
            <foo>I said hello world!</foo>
            <p>Goodbye world!</p>
            r.   r   r/   r0   r1   zI said hello world!r6   r8   r;   r>   r   r   r   $test_unknown_block_becomes_paragraphU   sB   
			z;TestHtmlToContentState.test_unknown_block_becomes_paragraphc                 C   s   t g d}t|d}| |i g ddddg dg ddddg dg d	dddg dg ddddg dg d
dddg dgd d S )Nr+   z
            before
            <p>paragraph</p>
            between
            <p>paragraph</p>
            after
            beforer   r/   r0   r1   	paragraphbetweenafterr8   r;   r>   r   r   r    test_bare_text_becomes_paragraph   s^   
				z7TestHtmlToContentState.test_bare_text_becomes_paragraphc                 C   @   t g d}t|d}| |i g ddddg dgd d S )	Nr+   zB
            <p>Hello <foo>frabjuous</foo> world!</p>
            zHello frabjuous world!r   r/   r0   r1   r8   r;   r>   r   r   r   'test_ignore_unrecognised_tags_in_blocks   &   
z>TestHtmlToContentState.test_ignore_unrecognised_tags_in_blocksc                 C   X   t ddgd}t|d}| |i ddddd	d
ddgddddg dgd d S )Nbolditalicr+   R
            <p>You <b>do <em>not</em> talk</b> about Fight Club.</p>
            r$      BOLDoffsetlengthstyle      ITALIC!You do not talk about Fight Club.r   r/   r0   r1   r8   r;   r>   r   r   r   test_inline_styles   *   

z)TestHtmlToContentState.test_inline_stylesc                 C   rK   )NrL   rM   r+   zK
            You <b>do <em>not</em> talk</b> about Fight Club.
            r$   rO   rP   rQ   rU   rV   rW   rX   r   r/   r0   r1   r8   r;   r>   r   r   r   test_inline_styles_at_top_level   rZ   z6TestHtmlToContentState.test_inline_styles_at_top_levelc                 C   sX   t ddgd}t|d}| |i ddddd	d
ddgddddg dgd d S )NrL   rM   r+   z?<b>Seriously</b>, stop talking about <i>Fight Club</i> already.r   	   rP   rQ      
   rW   z1Seriously, stop talking about Fight Club already.r/   r0   r1   r8   r;   r>   r   r   r   )test_inline_styles_at_start_of_bare_block  s*   

z@TestHtmlToContentState.test_inline_styles_at_start_of_bare_blockc                 C   sN   t ddgd}t|d}| |i ddddgd	d
ddg dgd d S )NrM   zjust-made-it-upr+   rN   rU   rV   rW   rQ   rX   r   r/   r0   r1   r8   r;   r>   r   r   r   %test_inline_styles_depend_on_features.  s(   
z<TestHtmlToContentState.test_inline_styles_depend_on_featuresc                 C   s|   t g dd}t|d}| j|i g ddddg dg d	dd
dg dddddddddgd	dd
dg dgddd d S )Nh1olrL   rM   r+   a(  
            <h1 data-block-key='00000'>The rules of Fight Club</h1>
            <ol>
                <li data-block-key='00001'>You do not talk about Fight Club.</li>
                <li data-block-key='00002'>You <b>do <em>not</em> talk</b> about Fight Club.</li>
            </ol>
            The rules of Fight Clubr   
header-oner0   r1   rX   ordered-list-itemr7   r$   rO   rP   rQ   rU   rV   rW   00002r8   Tr
   r;   r>   r   r   r   test_ordered_listJ  sH   	


 
z(TestHtmlToContentState.test_ordered_listc                 C   s   t ddgd}t|d}| j|i g ddddg d	g d
dddg d	g ddddg d	g ddddg d	g ddddg d	g ddddg d	gddd d S )Nrb   ulr+   a  
            <h1 data-block-key='00000'>Shopping list</h1>
            <ul>
                <li data-block-key='00001'>Milk</li>
                <li data-block-key='00002'>
                    Flour
                    <ul>
                        <li data-block-key='00003'>Plain</li>
                        <li data-block-key='00004'>Self-raising</li>
                    </ul>
                </li>
                <li data-block-key='00005'>Eggs</li>
            </ul>
            zShopping listr   re   r0   r1   Milkunordered-list-itemr7   Flourrg   Plain   00003zSelf-raising00004Eggs00005r8   Tr
   r;   r>   r   r   r   test_nested_list|  sn   					5
z'TestHtmlToContentState.test_nested_listc                 C   \   t dgd}t|d}| |dddddid	ig d
dddddddgdgd d S )Nlinkr+   zR
            <p>an <a href="http://wagtail.org">external</a> link</p>
            0MUTABLELINKurlhttp://wagtail.org
mutabilityr   dataan external linkr   r/   r0   rV      rR   rS   r	   r1   r8   r;   r>   r   r   r   test_external_link  0   	z)TestHtmlToContentState.test_external_linkc                 C   rt   )Nru   r+   z1an <a href="http://wagtail.org">external</a> linkrv   rw   rx   ry   rz   r{   r~   r   r/   r0   rV   r   r   r1   r8   r;   r>   r   r   r   test_link_in_bare_text  s0   	z-TestHtmlToContentState.test_link_in_bare_textc                 C   st   t dgd}t|d}| |ddddiddddd	idd
g ddddddddddddgdgd d S )Nru   r+   z_<a href="http://wagtail.org">an external link</a> and <a href="http://torchbox.com">another</a>rw   rx   ry   rz   r{   zhttp://torchbox.comrv   1zan external link and anotherr   r/   r0      r      rU   rn   r1   r8   r;   r>   r   r   r   test_link_at_start_of_bare_text  s:   

z6TestHtmlToContentState.test_link_at_start_of_bare_textc                 C   s`   t dgd}t|d}| |dddddd	d
dig ddddddddgdgd d S )Nru   r+   zO
            <p>an <a linktype="page" id="3">internal</a> link</p>
            rv   rw   rx   rV   z/events/   idry   parentIdr{   an internal linkr   r/   r0   r   r   r1   r8   r;   r>   r   r   r   test_page_link.  0   
	z%TestHtmlToContentState.test_page_linkc                 C   `   t dgd}t|d}| |ddddd d dd	ig d
dddddddgdgd d S )Nru   r+   zR
            <p>an <a linktype="page" id="9999">internal</a> link</p>
            rv   rw   rx   '  r   r{   r   r   r/   r0   rV   r   r   r1   r8   r;   r>   r   r   r   test_broken_page_linkN  6   z,TestHtmlToContentState.test_broken_page_linkc                 C   r   )Nru   r+   zO
            <p>an <a linktype="page" id="1">internal</a> link</p>
            rv   rw   rx   rn   r   r{   r   r   r/   r0   rV   r   r   r1   r8   r;   r>   r   r   r   test_link_to_root_pager  r   z-TestHtmlToContentState.test_link_to_root_pagec                 C   s`   t dgd}t|d}| |dddddd	d
dig ddddddddgdgd d S )Ndocument-linkr+   zR
            <p>a <a linktype="document" id="1">document</a> link</p>
            rv   rw   DOCUMENTrn   z/documents/1/test.pdfztest.pdf)r   ry   filenamer{   a document linkr   r/   r0   r   r   r   r1   r8   r;   r>   r   r   r   test_document_link  r   z)TestHtmlToContentState.test_document_linkc                 C   rt   )Nr   r+   zU
            <p>a <a linktype="document" id="9999">document</a> link</p>
            rv   rw   r   r   r   r{   r   r   r/   r0   r   r   r   r1   r8   r;   r>   r   r   r   test_broken_document_link  r   z0TestHtmlToContentState.test_broken_document_linkc                 C   sX   t dgd}t|d}| |dddi dig dd	d
dddd	dgdgd d S )Nr   r+   zK
            <p>a <a linktype="document">document</a> link</p>
            rv   rw   r   r{   r   r   r/   r0   r   r   r   r1   r8   r;   r>   r   r   r   "test_document_link_with_missing_id  s(   z9TestHtmlToContentState.test_document_link_with_missing_idc                 C      t dgd}t|d}| |dg g dddddg ddd	d
gdddddg g ddddgdddddddddid d S )Nimager+   z
            <p>before</p>
            <embed embedtype="image" alt="an image" id="1" format="left" />
            <p>after</p>
            r0   r   rC   r/   r	   r2   r5   r4   r3   r   rn   r	   rR   rS    atomicrF   rv   leftan imager   /media/not-foundformataltr   src	IMMUTABLEIMAGEr}   r|   r   r:   r9   r;   r>   r   r   r   test_image_embed  sT   			z'TestHtmlToContentState.test_image_embedc                 C   s   t dgd}t|d}| |dg g dddddg ddd	d
gdddddg g dddddg d	dd	d
gdddddg g ddddgdddddddddddddddddd d S )Nr   r+   z
            <embed embedtype="image" alt="an image" id="1" format="left" />
            <embed embedtype="image" alt="an image" id="1" format="left" />
            r0   r    r/   r   rn   r   r   r   r   r   r   r   r   r   r   r   r   r   r;   r>   r   r   r   .test_add_spacer_paragraph_between_image_embeds)  s~   				-zETestHtmlToContentState.test_add_spacer_paragraph_between_image_embedsc                 C   s   t ddgd}t|d}| |ddddd	d
dddig ddddg dg ddddg ddg ddddgddddg ddddg dg ddddg dgd dS )zZ
        There should be no spacer paragraph inserted between a list and an image
        ri   r   r+   a!  
            <ul>
                <li>Milk</li>
                <li>Eggs</li>
            </ul>
            <embed embedtype="image" alt="an image" id="1" format="left" />
            <ul>
                <li>More milk</li>
                <li>More eggs</li>
            </ul>
            rv   r   r   r   r   r   r   r   r   rj   r   rk   r0   r1   rq   rn   r   r   r   r   z	More milkz	More eggsr8   Nr;   r>   r   r   r   test_image_after_listy  sp   				z,TestHtmlToContentState.test_image_after_listzwagtail.embeds.embeds.get_embedc                 C   s   t dd ddddddddd	
|_td
gd}t|d}| |dg g dddddg ddddgdddddg g ddddgdddddddddddid d S )N+https://www.youtube.com/watch?v=Kh0Y2hVe_bwvideo	test htmlwhat are birdslook around youYouTubehttp://test/thumbnail.url  
ry   	max_widthr   htmltitleauthor_nameprovider_namethumbnail_urlwidthheightembedr+   z
            <p>before</p>
            <embed embedtype="media" url="https://www.youtube.com/watch?v=Kh0Y2hVe_bw" />
            <p>after</p>
            r0   r   rC   r/   r   rn   r   r   r   rF   rv   	thumbnail	embedTypeproviderNamer   
authorNamery   r   EMBEDr   r   r   return_valuer   r'   r<   r=   r*   r)   	get_embedr?   r@   r   r   r   test_media_embed  sp   			z'TestHtmlToContentState.test_media_embedc                 C   s   t dd ddddddddd	
|_td
gd}t|d}| |dg g dddddg ddddgdddddg g dddddg ddddgdddddg g ddddgdddddddddddddddddddddd d S )Nr   r   r   r   r   r   r   r   r   r   r+   z
            <embed embedtype="media" url="https://www.youtube.com/watch?v=Kh0Y2hVe_bw" />
            <embed embedtype="media" url="https://www.youtube.com/watch?v=Kh0Y2hVe_bw" />
            r0   r   r   r/   r   rn   r   r   r   r   r   r   r   r   r   r   r   r   r   r   *test_add_spacer_paras_between_media_embeds  s   				-zATestHtmlToContentState.test_add_spacer_paras_between_media_embedsc                 C   x   t dgd}t|d}| |dg g dddddg ddd	d
gdddddg g ddddgdi dddid d S )Nhrr+   zS
            <p>before</p>
            <hr />
            <p>after</p>
            r0   r   rC   r/   r   rn   r   r   r   rF   rv   r   HORIZONTAL_RULEr   r   r;   r>   r   r   r   test_hrr  sL   			zTestHtmlToContentState.test_hrc                 C   s   t dgd}t|d}| |dg g dddddg ddd	d
gdddddg g dddddg d	dd	d
gdddddg g ddddgi dddi ddddd d S )Nr   r+   z3
            <hr />
            <hr />
            r0   r   r   r/   r   rn   r   r   r   r   r   r   r   r   r;   r>   r   r   r   %test_add_spacer_paragraph_between_hrs  sn   				,z<TestHtmlToContentState.test_add_spacer_paragraph_between_hrsc                 C   r   )Nr   r+   z2
            <p>before<hr />after</p>
            r0   r   rC   r/   r   rn   r   r   r   rF   rv   r   r   r   r   r;   r>   r   r   r   test_block_element_in_paragraph  sL   		z6TestHtmlToContentState.test_block_element_in_paragraphc                 C   s@   t g d}t|d}| |i dg g ddddgd d S )	Nr+   z1
            <p>before<br/>after</p>
            r0   r   zbefore
afterr/   r   r8   r;   r>   r   r   r   test_br_element_in_paragraph  rJ   z3TestHtmlToContentState.test_br_element_in_paragraphc                 C   sP   t g d}t|d}| |i dg g dddddg g ddddgd	 d S )
Nr+   zS
            <p>before</p>
            <br />
            <p>after</p>
            r0   r   rC   r/   r   rF   r8   r;   r>   r   r   r   "test_br_element_between_paragraphs4  s4   
		z9TestHtmlToContentState.test_br_element_between_paragraphsc                 C   sx   t dgd}t|d}| |dg g dddddg ddd	d
gdddddg g ddddgdi dddid d S )Nr   r+   z'
            <p><hr /></p>
            r0   r   r   r/   r   rn   r   r   r   rv   r   r   r   r   r;   r>   r   r   r   %test_block_element_in_empty_paragraphX  sL   
		z<TestHtmlToContentState.test_block_element_in_empty_paragraphc                 C   rH   )	Nr+   zf
            <p>Arthur &quot;two sheds&quot; Jackson &lt;the third&gt; &amp; his wife</p>
            z1Arthur "two sheds" Jackson <the third> & his wifer   r/   r0   r1   r8   r;   r>   r   r   r   test_html_entities  rJ   z)TestHtmlToContentState.test_html_entitiesc                 C   sP   t g d}t|d}| |i g ddddg dg ddddg dgd	 d S )
Nr+   u   
            <p>Multiple whitespaces:     should  be reduced</p>
            <p>Multiple non-breaking whitespace characters:       should be preserved</p>
            z'Multiple whitespaces: should be reducedr   r/   r0   r1   uG   Multiple non-breaking whitespace characters:     should be preservedr8   r;   r>   r   r   r   ,test_collapse_targeted_whitespace_characters  s4   
	zCTestHtmlToContentState.test_collapse_targeted_whitespace_charactersc                 C   rH   )	Nr+   z8
            </p>
            <p>Before</p>
            Beforer   r/   r0   r1   r8   r;   r>   r   r   r   test_extra_end_tag_before  &   

z0TestHtmlToContentState.test_extra_end_tag_beforec                 C   rH   )	Nr+   z7
            <p>After</p>
            </p>
            Afterr   r/   r0   r1   r8   r;   r>   r   r   r   test_extra_end_tag_after  r   z/TestHtmlToContentState.test_extra_end_tag_afterc                 C   sR   t dgd}t|d}| |dg g dddddg g dd	d
dgi d d S )Nintror+   zN
            <p class="intro">before</p>
            <p>after</p>
            r0   r   rC   zintro-paragraphr   rF   r/   r   r;   r>   r   r   r   test_p_with_class  s4   	z(TestHtmlToContentState.test_p_with_classc                 C   r   )Nr   r+   zm
            <p>before <embed embedtype="image" alt="an image" id="1" format="left" /> after</p>
            r0   r   rC   r/   r   rn   r   r   r   rF   rv   r   r   r   r   r   r   r   r   r   r;   r>   r   r   r   test_image_inside_paragraph*  sT   		z2TestHtmlToContentState.test_image_inside_paragraphc                 C   s   t ddgd}t|d}| |ddddd	gg dd
dddg ddddgddddddddd	gg ddddddddd	gg dddddg ddddgddddddddd	gg ddddgdddddddddddddddddd d S )Nr   rM   r+   z
            <p><i>before <embed embedtype="image" alt="an image" id="1" format="left" /> after</i></p>
            <p><i><embed embedtype="image" alt="an image" id="1" format="left" /></i></p>
            r0   r      rW   rQ   rC   r/   r   rn   r   r   r      rF   r   r   r   r   r   r   r   r   r   r   r   r;   r>   r   r   r   test_image_inside_stylea  s   
	

	
=z.TestHtmlToContentState.test_image_inside_stylec                 C   s  t ddgd}t|d}| |dg ddddgdd	d
ddg ddddgdddddg ddddgddd
ddg ddddgddd
ddg ddddgdddddg ddddgddd
dgddddiddddddddd ddddiddddddddd d!d" d S )#Nr   ru   r+   a  
            <p><a href="https://wagtail.org">before <embed embedtype="image" alt="an image" id="1" format="left" /> after</a></p>
            <p><a href="https://wagtail.org"><embed embedtype="image" alt="an image" id="1" format="left" /></a></p>
            r0   r   r   r   rC   r/   r   rn   r   r   r   rF   r   r   rV   rw   rx   ry   zhttps://wagtail.orgr{   r   r   r   r   r   r   r   r   )rv   r   23r   r;   r>   r   r   r   test_image_inside_link  s   					4z-TestHtmlToContentState.test_image_inside_linkNF),__name__
__module____qualname__fixturesr*   rA   rB   rG   rI   rY   r[   r_   r`   rh   rs   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r#   &   sV    
$,>2N & $ $ 7PP
F
a2F0$3%&7cr#   c                   @   sD   e 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 )TestContentStateToHtmlc                 C   `   t dgd}tdddddidig d	d
ddddd
dgdgd}||}| |d d S )Nru   r+   rv   rw   rx   ry   rz   r{   r~   r   r/   r0   rV   r   r   r1   r8   zO<p data-block-key="00000">an <a href="http://wagtail.org">external</a> link</p>r   r'   r(   to_database_formatassertEqualr)   r?   contentstate_jsonr@   r   r   r   r   +  .   	
z)TestContentStateToHtml.test_external_linkc                 C   r   )Nru   r+   rv   rw   rx   ry   z/some/local/path/r{   r~   r   r/   r0   rV   r   r   r1   r8   zN<p data-block-key="00000">an <a href="/some/local/path/">external</a> link</p>r   r   r   r   r   test_local_linkI  r   z&TestContentStateToHtml.test_local_linkc                 C   r   )Nru   r+   rv   rw   rx   ry   zjavascript:alert('oh no')r{   r~   r   r/   r0   rV   r   r   r1   r8   z5<p data-block-key="00000">an <a>external</a> link</p>r   r   r   r   r   test_reject_javascript_linkg  s,   	
z2TestContentStateToHtml.test_reject_javascript_linkc                 C   sT   t g d}ti g ddddg dg ddddg dgd	}||}| |d
 d S )Nr+   r.   r   r/   r0   r1   r6   r7   r8   r-   )r   r'   r(   r   assertHTMLEqual)r)   r?   contentStater@   r   r   r   test_paragraphs_retain_keys  s2   
	
z2TestContentStateToHtml.test_paragraphs_retain_keysc                 C   sd   t g dd}|ti g ddddg dg ddd	d
g dg ddd	dg dgd}| |d d S )Nra   r+   rd   r   re   r0   r1   rX   rf   r7   rg   r8   a  
            <h1 data-block-key='00000'>The rules of Fight Club</h1>
            <ol>
                <li data-block-key='00001'>You do not talk about Fight Club.</li>
                <li data-block-key='00002'>You do not talk about Fight Club.</li>
            </ol>
        )r   r   r'   r(   r   r>   r   r   r   test_wrapped_block_retains_key  sB   		!z5TestContentStateToHtml.test_wrapped_block_retains_keyc              	   C   sf   dt dd ii i g tjd}i g ddddg dg d	ddd
g dgd}t||}| |d d S )Nr/   c                 S   s   t di | d S )Npchildren)r   create_element)propsr   r   r   <lambda>  s    zATestContentStateToHtml.test_wrap_block_function.<locals>.<lambda>)	block_map	style_mapentity_decoratorscomposite_decoratorsenginer.   r   r0   r1   r6   r7   r8   r-   )r   r   STRINGHTMLExporterrenderr   )r)   exporter_configr   r@   r   r   r   test_wrap_block_function  s>   	z/TestContentStateToHtml.test_wrap_block_functionc                 C   s   t g d}| jdd }|ti ddddgddd	d
g dgd}W d    n1 s.w   Y  | |d | d|jd  d S )Nr+   WARNING)levelr      	UNDERLINErQ   r.   r/   r0   r1   r8   z^
            <p data-block-key="00000">
                Hello world!
            </p>
        z/Missing config for "UNDERLINE". Deleting style.)r   
assertLogsr   r'   r(   r   assertInoutput)r)   r?   
log_outputr@   r   r   r   test_style_fallback  s2   


z*TestContentStateToHtml.test_style_fallbackN)
r   r   r   r   r   r   r   r   r	  r  r   r   r   r   r   *  s    "/-r   r   )r'   unittest.mockr   django.testr   draftjs_exporter.domr   draftjs_exporter.htmlr   r  /wagtail.admin.rich_text.converters.contentstater   r   wagtail.embeds.modelsr   r   r#   r   r   r   r   r   <module>   s0    
              