U
    Â“«ji2  ã                   @   s¬   d Z 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 ddlmZ ddlmZ ddlmZ G dd„ deƒZdS )zi
Tests for L{twisted.mail.scripts.mailmail}, the implementation of the
command line program I{mailmail}.
é    N)ÚStringIO)ÚskipIf)Úversion)ÚDeferred)ÚMemoryReactor)Úsmtp)Úmailmail)ÚparseOptions)ÚFailure)ÚplatformType)ÚTestCasec                   @   sº   e Zd ZdZeƒ 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eedkdƒdd„ ƒZeedkdƒdd„ ƒZd d!„ Zd"d#„ Zd$d%„ Zd&S )'ÚOptionsTestsz¸
    Tests for L{parseOptions} which parses command line arguments and reads
    message text from stdin to produce an L{Options} instance which can be
    used to send a message.
    c                    sf   t ƒ ˆ _ddlm}m} |ˆ jƒ}ˆ  td||d�¡ dˆ _dˆ _dˆ _	‡ fdd„}ˆ  td|¡ dS )	zz
        Override some things in mailmail, so that we capture C{stdout},
        and do not call L{reactor.stop}.
        r   )ÚLoggerÚtextFileLogObserverÚ_log)ZobserverNc                    s.   | ˆ _ |ˆ _|ˆ _tj| |j|j|jˆ jd�S )N)Zreactor)	ÚhostÚoptionsÚidentr   ÚsendmailÚsenderÚtoÚbodyÚmemoryReactor)r   r   r   ©Úself© úC/tmp/pip-unpacked-wheel-59kc99xd/twisted/mail/test/test_mailmail.pyr   3   s    ûz$OptionsTests.setUp.<locals>.sendmailr   )
r   ÚoutZtwisted.loggerr   r   Úpatchr   r   r   r   )r   r   r   ZlogObserverr   r   r   r   ÚsetUp#   s    
zOptionsTests.setUpc                 C   s2   |   tdtdƒ¡ |  ttg ¡}|  |jd¡ dS )zÒ
        If no recipients are given in the argument list and there is no
        recipient header in the message text, L{parseOptions} raises
        L{SystemExit} with a string describing the problem.
        ÚstdinzSubject: foo

Hello, goodbye.
)zNo recipients specified.N)r   Úsysr   ÚassertRaisesÚ
SystemExitr	   ÚassertEqualÚargs©r   Úexcr   r   r   Útest_unspecifiedRecipientsA   s    z'OptionsTests.test_unspecifiedRecipientsc                 C   s"   |   ttdg¡}|  |jd¡ dS )z™
        The I{-bp} option for listing queue information is unsupported and
        if it is passed to L{parseOptions}, L{SystemExit} is raised.
        z-bp©zUnsupported option.N©r"   r#   r	   r$   r%   r&   r   r   r   Útest_listQueueInformationK   s    z&OptionsTests.test_listQueueInformationc                 C   s"   |   ttdg¡}|  |jd¡ dS )z´
        The I{-bs} option for using stdin and stdout as the SMTP transport
        is unsupported and if it is passed to L{parseOptions}, L{SystemExit}
        is raised.
        z-bsr)   Nr*   r&   r   r   r   Útest_stdioTransportS   s    z OptionsTests.test_stdioTransportc                 C   s@   |   ttdg¡}|  |jd¡ |   ttdg¡}|  |jd¡ dS )z»
        The I{-i} and I{-oi} options for ignoring C{"."} by itself on a line
        are unsupported and if either is passed to L{parseOptions},
        L{SystemExit} is raised.
        z-ir)   z-oiNr*   r&   r   r   r   Útest_ignoreFullStop\   s    z OptionsTests.test_ignoreFullStopc                 C   s"   |   ttdg¡}|  |jd¡ dS )z¿
        The I{-om} option for copying the sender if they appear in an alias
        expansion is unsupported and if it is passed to L{parseOptions},
        L{SystemExit} is raised.
        z-omr)   Nr*   r&   r   r   r   Útest_copyAliasedSenderg   s    z#OptionsTests.test_copyAliasedSenderc                 C   sP   t ƒ }|  td|¡ |  ttd¡}|  |jd¡ | ¡ }|  |dt	› d�¡ dS )z~
        The I{--version} option displays the version and raises
        L{SystemExit} with L{None} as the exit code.
        Ústdoutz	--versionNzmailmail version: Ú
)
r   r   r!   r"   r#   r	   r$   ÚcodeÚgetvaluer   )r   r   ZsystemExitCodeÚdatar   r   r   Útest_versionp   s    zOptionsTests.test_versionc                 C   s.   t dƒ}|  td|¡ tdƒ}|  |j¡ dS )zA
        The I{-odb} flag specifies background delivery.
        r0   r    z-odbN)r   r   r!   r	   Ú
assertTrueÚ
background©r   r    Úor   r   r   Útest_backgroundDelivery}   s    z$OptionsTests.test_backgroundDeliveryc                 C   s.   t dƒ}|  td|¡ tdƒ}|  |j¡ dS )zB
        The I{-odf} flags specifies foreground delivery.
        r0   r    z-odfN)r   r   r!   r	   ZassertFalser6   r7   r   r   r   Útest_foregroundDelivery†   s    z$OptionsTests.test_foregroundDeliveryc                 C   s4   t dƒ}|  td|¡ tdƒ}|  t|jƒd¡ dS )zd
        The I{-t} flags specifies that recipients should be obtained
        from headers.
        zTo: Curly <invaliduser2@example.com>
Cc: Larry <invaliduser1@example.com>
Bcc: Moe <invaliduser3@example.com>

Oh, a wise guy?
r    ú-té   N)r   r   r!   r	   r$   Úlenr   r7   r   r   r   Útest_recipientsFromHeaders�   s    ÿz'OptionsTests.test_recipientsFromHeadersc                 C   s6   t dƒ}|  td|¡ tdddgƒ}|  |jd¡ dS )zw
        When a message has no I{From:} header, a I{From:} value can be
        specified with the I{-F} flag.
        z3To: invaliduser2@example.com
Subject: A wise guy?

r    ú-Fz Larry <invaliduser1@example.com>r;   N©r   r   r!   r	   r$   r   r7   r   r   r   Útest_setFromŸ   s    zOptionsTests.test_setFromc                 C   s6   t dƒ}|  td|¡ tdddgƒ}|  |jd¡ dS )z‘
        The I{-F} flag specifies the From: value.  However, I{-F} flag is
        overriden by the value of From: in the e-mail header.
        zLTo: Curly <invaliduser4@example.com>
From: Shemp <invaliduser4@example.com>
r    r?   z"Groucho <invaliduser5@example.com>r;   zinvaliduser4@example.comNr@   r7   r   r   r   Ú!test_overrideFromFlagByFromHeader©   s    ÿz.OptionsTests.test_overrideFromFlagByFromHeaderÚwin32zImailmail.run() does not work on win32 due to lack of support for getuid()c                 C   st   d}t dƒ}|  td|¡ |  td|¡ t ¡  |  | jjt ¡ ¡ |  | jj	dg¡ |  
| jj¡ |  tj¡ dS )z½
        Call L{mailmail.run}, and specify I{-oep} to print errors
        to stderr.  The sender, to, and printErrors options should be
        set and there should be no failure.
        ©ztest_mailmail.pyúinvaliduser2@example.comz-oepr0   Úargvr    rE   N)r   r   r!   r   Úrunr$   r   r   Úgetloginr   r5   ZprintErrorsZassertIsNoneÚfailed)r   rF   r    r   r   r   Útest_runErrorsToStderr¶   s    
z#OptionsTests.test_runErrorsToStderrc              	   C   s¸   t dƒ}|  td|¡ |  ¡ }t ¡ }t ¡ }t|dƒ�}| d 	||¡¡ W 5 Q R X |  t
d|¡ d}|  td|¡ t
 ¡  |  | j ¡ d¡ |  | j ¡ d	¡ |  | j ¡ d
¡ dS )z…
        Error messages for illegal UID value, illegal GID value, and illegal
        identity entry will be sent to stderr.
        r0   r    Úwa  [useraccess]
allow=invaliduser2,invaliduser1
deny=invaliduser3,invaliduser4,{}
order=allow,deny
[groupaccess]
allow=invalidgid1,invalidgid2
deny=invalidgid1,invalidgid2,{}
order=deny,allow
[identity]
localhost=funny
[addresses]
smarthost=localhost
default_domain=example.com
Z	LOCAL_CFGrD   rF   z3Illegal UID in \[useraccess\] section: invaliduser1z3Illegal GID in \[groupaccess\] section: invalidgid1z,Illegal entry in \[identity\] section: funnyN)r   r   r!   ÚmktempÚosÚgetuidÚgetgidÚopenÚwriteÚformatr   rG   ÚassertRegexr   r2   )r   r    ÚfilenameZmyUidZmyGidÚfrF   r   r   r   Útest_readInvalidConfigÌ   s8    	 ôÿþþ ÿz#OptionsTests.test_readInvalidConfigc              	   C   s<   ddl m} |  ¡ }t|dƒ�}| |¡ W 5 Q R X ||ƒS )aª  
        Read a mailmail configuration file.

        The mailmail script checks the twisted.mail.scripts.mailmail.GLOBAL_CFG
        variable and then the twisted.mail.scripts.mailmail.LOCAL_CFG
        variable for the path to its  config file.

        @param config: path to config file
        @type config: L{str}

        @return: A parsed config.
        @rtype: L{twisted.mail.scripts.mailmail.Configuration}
        r   )Ú
loadConfigrK   )Útwisted.mail.scripts.mailmailrW   rL   rP   rQ   )r   ÚconfigrW   rT   rU   r   r   r   ÚgetConfigFromFile  s
    zOptionsTests.getConfigFromFilec                 C   sN  |   d¡}|  |jd¡ |   d¡}|  |jd¡ |   d¡}|  |jd¡ |  |jd¡ |   d¡}|  d|j¡ |  |jd d	d
g¡ |   d¡}|  |jdg¡ |   d¡}|  |jddg¡ |   d¡}|  |jddg¡ |  |jddg¡ |   d¡}|  |jdg¡ |   d¡}|  |j	dg¡ |   d¡}|  |jddg¡ |  |j	ddg¡ dS )zj
        L{twisted.mail.scripts.mailmail.loadConfig}
        parses the config file for mailmail.
        z 
[addresses]
smarthost=localhostÚ	localhostz'
[addresses]
default_domain=example.comzexample.comz;
[addresses]
smarthost=localhost
default_domain=example.comz1
[identity]
host1=invalid
host2=username:passwordZhost1Zhost2ÚusernameÚpasswordz+
[useraccess]
allow=invalid1,35
order=allowé#   z#
[useraccess]
deny=35,36
order=denyé$   z/
[useraccess]
allow=35,36
deny=37,38
order=denyé%   é&   z(
[groupaccess]
allow=gid1,41
order=allowé)   z!
[groupaccess]
deny=41
order=denyz6
[groupaccess]
allow=41,42
deny=43,44
order=allow,denyé*   é+   é,   N)
rZ   r$   Z	smarthostÚdomainZassertNotInZ
identitiesZ	allowUIDsZdenyUIDsZ	allowGIDsZdenyGIDs)r   rY   r   r   r   Útest_loadConfig  sX    ÿÿÿÿÿÿÿÿÿÿzOptionsTests.test_loadConfigc                    sB   ‡ fdd„}ˆ   td|¡ t ¡ }d|_ttƒ ƒ}t ||¡ dS )zš
        L{twisted.mail.scripts.mailmail.senderror} sends mail back to the
        sender if an error occurs while sending mail to the recipient.
        c                    s0   ˆ   |d¡ ˆ  |dg¡ ˆ   | ¡ d¡ tƒ S )Nzpostmaster@Ú
testsenderÚ
ValueError)rS   r$   r2   r   )r   r   Z	recipientr   r   r   r   r   }  s    z-OptionsTests.test_senderror.<locals>.sendmailr   rh   N)r   r   r   ÚOptionsr   r
   ri   Z	senderror)r   r   ÚoptsZfailr   r   r   Útest_senderrorw  s    
zOptionsTests.test_senderrorN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r   r   r(   r+   r,   r-   r.   r4   r9   r:   r>   rA   rB   r   r   rJ   rV   rZ   rg   rl   r   r   r   r   r      s6   
				
þ
þ
6Yr   )rp   rM   r!   Úior   Zunittestr   Ztwisted.copyrightr   Ztwisted.internet.deferr   Ztwisted.internet.testingr   Ztwisted.mailr   Ztwisted.mail.scriptsr   rX   r	   Ztwisted.python.failurer
   Ztwisted.python.runtimer   Ztwisted.trial.unittestr   r   r   r   r   r   Ú<module>   s   