コード例 #1
0
def test_attachment_relative(tmpdir):
    """Attachment with a relative file path is relative to template dir."""
    # Simple attachment
    attachment_path = Path(tmpdir/"attachment.txt")
    attachment_path.write_text(u"Hello world\n")

    # Simple template
    template_path = Path(tmpdir/"template.txt")
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: attachment.txt

        Hello world
    """))

    # Render
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})

    # Verify directory used to render is different from template directory
    assert os.getcwd() != tmpdir

    # Verify attachment
    attachments = extract_attachments(message)
    filename, content = attachments[0]
    assert filename == "attachment.txt"
    assert content == b"Hello world\n"
コード例 #2
0
def test_emoji_markdown(tmp_path):
    """Verify emoji are encoded in Markdown formatted messages."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(
        textwrap.dedent(u"""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]
        CONTENT-TYPE: text/markdown

        ```
        emoji_string = 😀
        ```
            """))  # grinning face emoji
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})

    # Message should contain an unrendered Markdown plaintext part and a
    # rendered Markdown HTML part
    plaintext_part, html_part = message.get_payload()

    # Verify encodings
    assert str(plaintext_part.get_charset()) == "utf-8"
    assert str(html_part.get_charset()) == "utf-8"
    assert plaintext_part["Content-Transfer-Encoding"] == "base64"
    assert html_part["Content-Transfer-Encoding"] == "base64"

    # Verify content, which is base64 encoded grinning face emoji
    plaintext = plaintext_part.get_payload(decode=True).decode("utf-8")
    htmltext = html_part.get_payload(decode=True).decode("utf-8")
    assert plaintext == u'```\nemoji_string = \U0001f600\n```'
    assert htmltext == (u"<html><body><p><code>"
                        u"emoji_string = \U0001f600"
                        u"</code></p></body></html>")
コード例 #3
0
def test_utf8_database(tmp_path):
    """Verify UTF8 support when template is rendered with UTF-8 value."""
    # Simple template
    template_path = tmp_path / "template.txt"
    template_path.write_text(
        textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]

        Hi {{name}}
    """))

    # Render template with context containing unicode characters
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render({
        "name": u"Laȝamon",
    })

    # Verify sender and recipients
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]

    # Verify message encoding.  The template was ASCII, but when the template
    # is rendered with UTF-8 data, the result is UTF-8 encoding.
    assert message.get_content_maintype() == "text"
    assert message.get_content_subtype() == "plain"
    assert message.get_content_charset() == "utf-8"

    # Verify content
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == u"Hi Laȝamon"
コード例 #4
0
def test_emoji_database(tmp_path):
    """Verify emoji are encoded when they are substituted via template db.

    The template is ASCII encoded, but after rendering the template, an emoji
    character will substituted into the template.  The result should be a utf-8
    encoded message.
    """
    template_path = tmp_path / "template.txt"
    template_path.write_text(
        textwrap.dedent(u"""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]

        Hi {{emoji}}
    """))
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({
        "emoji": u"😀"  # grinning face
    })

    # Verify encoding
    assert message.get_charset() == "utf-8"
    assert message["Content-Transfer-Encoding"] == "base64"

    # Verify content
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == u"Hi 😀"
コード例 #5
0
def test_attachment_simple(tmpdir):
    """Verify a simple attachment."""
    # Simple attachment
    attachment_path = Path(tmpdir/"attachment.txt")
    attachment_path.write_text(u"Hello world\n")

    # Simple template
    template_path = Path(tmpdir/"template.txt")
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: attachment.txt

        Hello world
    """))

    # Render in tmpdir
    with tmpdir.as_cwd():
        template_message = TemplateMessage(template_path)
        sender, recipients, message = template_message.render({})

    # Verify sender and recipients
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]

    # Verify message is multipart and contains attachment
    assert message.is_multipart()
    attachments = extract_attachments(message)
    assert len(attachments) == 1

    # Verify attachment
    filename, content = attachments[0]
    assert filename == "attachment.txt"
    assert content == b"Hello world\n"
コード例 #6
0
def test_content_id_header_for_attachments(tmpdir):
    """All attachments should get a content-id header."""
    attachment_path = Path(tmpdir / "attachment.txt")
    attachment_path.write_text("Hello world\n", encoding="utf8")

    # Simple template
    template_path = Path(tmpdir / "template.txt")
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: attachment.txt

        Hello world
    """),
                             encoding="utf8")

    # Render in tmpdir
    with tmpdir.as_cwd():
        template_message = TemplateMessage(template_path)
        _, _, message = template_message.render({})

    # Verify message is multipart and contains attachment
    assert message.is_multipart()
    attachments = extract_attachments(message)
    assert len(attachments) == 1

    # Verify attachment
    filename, content, cid_header = attachments[0]
    assert filename == "attachment.txt"
    assert content == b"Hello world\n"
    assert re.match(r'<[\d\w]+(\.[\d\w]+)*@mailmerge\.invalid>', cid_header)
コード例 #7
0
def test_attachment_template(tmpdir):
    """Attachment with template as part of file path."""
    # Simple attachment lives in sub directory
    attachments_dir = tmpdir.mkdir("attachments")
    attachment_path = Path(attachments_dir/"attachment.txt")
    attachment_path.write_text(u"Hello world\n")

    # Simple template
    template_path = Path(tmpdir/"template.txt")
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: {{filename}}

        Hello world
    """))

    # Render in tmpdir
    with tmpdir.as_cwd():
        template_message = TemplateMessage(template_path)
        _, _, message = template_message.render({
            "filename": str(attachment_path),
        })

    # Verify attachment
    attachments = extract_attachments(message)
    filename, content = attachments[0]
    assert filename == "attachment.txt"
    assert content == b"Hello world\n"
コード例 #8
0
def test_attachment_absolute(tmpdir):
    """Attachment with absolute file path."""
    # Simple attachment lives in sub directory
    attachments_dir = tmpdir.mkdir("attachments")
    attachment_path = Path(attachments_dir / "attachment.txt")
    attachment_path.write_text("Hello world\n", encoding="utf8")

    # Simple template
    template_path = Path(tmpdir / "template.txt")
    template_path.write_text(textwrap.dedent(f"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: {attachment_path}

        Hello world
    """),
                             encoding="utf8")

    # Render in tmpdir
    with tmpdir.as_cwd():
        template_message = TemplateMessage(template_path)
        _, _, message = template_message.render({})

    # Verify attachment
    attachments = extract_attachments(message)
    filename, content, _ = attachments[0]
    assert filename == "attachment.txt"
    assert content == b"Hello world\n"
コード例 #9
0
def test_encoding_multipart_mismatch(tmp_path):
    """Render a utf-8 template with multipart encoding and wrong headers.

    Content-Type headers say "us-ascii", but the message contains utf-8.
    """
    template_path = tmp_path / "template.txt"
    template_path.write_text(
        textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        MIME-Version: 1.0
        Content-Type: multipart/alternative; boundary="boundary"

        This is a MIME-encoded message. If you are seeing this, your mail
        reader is old.

        --boundary
        Content-Type: text/plain; charset=us-ascii

        Hello Laȝamon

        --boundary
        Content-Type: text/html; charset=us-ascii

        <html>
          <body>
            <p>Hello Laȝamon</p>
          </body>
        </html>
    """))
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render({})

    # Verify sender and recipients
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]

    # Should be multipart: plaintext and HTML
    assert message.is_multipart()
    parts = message.get_payload()
    assert len(parts) == 2
    plaintext_part, html_part = parts

    # Verify plaintext part
    assert plaintext_part.get_charset() == "utf-8"
    assert plaintext_part.get_content_charset() == "utf-8"
    assert plaintext_part.get_content_type() == "text/plain"
    plaintext = plaintext_part.get_payload(decode=True).decode("utf-8")
    plaintext = plaintext.strip()
    assert plaintext == u"Hello Laȝamon"

    # Verify html part
    assert html_part.get_charset() == "utf-8"
    assert html_part.get_content_charset() == "utf-8"
    assert html_part.get_content_type() == "text/html"
    htmltext = html_part.get_payload(decode=True).decode("utf-8")
    htmltext = re.sub(r"\s+", "", htmltext)  # Strip whitespace
    assert htmltext == u"<html><body><p>HelloLaȝamon</p></body></html>"
コード例 #10
0
def test_html_plaintext(tmp_path):
    """Verify HTML and plaintest multipart template."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]
        MIME-Version: 1.0
        Content-Type: multipart/alternative; boundary="boundary"

        This is a MIME-encoded message. If you are seeing this, your mail
        reader is old.

        --boundary
        Content-Type: text/plain; charset=us-ascii

        {{message}}

        --boundary
        Content-Type: text/html; charset=us-ascii

        <html>
          <body>
            <p>{{message}}</p>
          </body>
        </html>
    """))
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render({
        "message": "Hello world"
    })

    # Verify sender and recipients
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]

    # Should be multipart: plaintext and HTML
    assert message.is_multipart()
    parts = message.get_payload()
    assert len(parts) == 2
    plaintext_part, html_part = parts

    # Verify plaintext part
    assert plaintext_part.get_charset() == "us-ascii"
    assert plaintext_part.get_content_charset() == "us-ascii"
    assert plaintext_part.get_content_type() == "text/plain"
    plaintext = plaintext_part.get_payload()
    plaintext = plaintext.strip()
    assert plaintext == "Hello world"

    # Verify html part
    assert html_part.get_charset() == "us-ascii"
    assert html_part.get_content_charset() == "us-ascii"
    assert html_part.get_content_type() == "text/html"
    htmltext = html_part.get_payload()
    htmltext = re.sub(r"\s+", "", htmltext)  # Strip whitespace
    assert htmltext == "<html><body><p>Helloworld</p></body></html>"
コード例 #11
0
def test_attachment_image_in_markdown(tmp_path):
    """Images sent as attachments should get linked correctly in images."""
    shutil.copy(str(utils.TESTDATA / "attachment_3.jpg"), str(tmp_path))

    # Create template .txt file
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: {{email}}
        SUBJECT: Testing mailmerge
        FROM: My Self <*****@*****.**>
        ATTACHMENT: attachment_3.jpg
        CONTENT-TYPE: text/markdown

        ![](./attachment_3.jpg)
    """),
                             encoding="utf8")
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render(
        {"email": "*****@*****.**"})

    # Verify sender and recipients
    assert sender == "My Self <*****@*****.**>"
    assert recipients == ["*****@*****.**"]

    # Verify message is multipart
    assert message.is_multipart()

    # Make sure there is a message body and the attachment
    payload = message.get_payload()
    assert len(payload) == 2

    # Markdown: Make sure there is a plaintext part and an HTML part
    message_payload = payload[0].get_payload()
    assert len(message_payload) == 2

    plaintext = extract_text_from_markdown_payload(message_payload[0],
                                                   'text/plain')
    htmltext = extract_text_from_markdown_payload(message_payload[1],
                                                  'text/html')

    assert plaintext.strip() == "![](./attachment_3.jpg)"

    attachments = extract_attachments(message)
    assert len(attachments) == 1
    filename, content, cid = attachments[0]
    cid = cid[1:-1]
    assert filename == "attachment_3.jpg"
    assert len(content) == 697

    expected = html5lib.parse(
        textwrap.dedent(f"""\
        <html><head />
        <body><p><img src="cid:{cid}" alt="" /></p></body>
        </html>
    """))
    assert html_docs_equal(html5lib.parse(htmltext), expected)
コード例 #12
0
def test_utf8_template(tmp_path):
    """Verify UTF8 support in email template."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(
        textwrap.dedent(u"""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]

        From the Tagelied of Wolfram von Eschenbach (Middle High German):

        Sîne klâwen durh die wolken sint geslagen,
        er stîget ûf mit grôzer kraft,
        ich sih in grâwen tägelîch als er wil tagen,
        den tac, der im geselleschaft
        erwenden wil, dem werden man,
        den ich mit sorgen în verliez.
        ich bringe in hinnen, ob ich kan.
        sîn vil manegiu tugent michz leisten hiez.

        http://www.columbia.edu/~fdc/utf8/
    """))
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render({
        "email":
        "*****@*****.**",
    })

    # Verify encoding
    assert message.get_content_maintype() == "text"
    assert message.get_content_subtype() == "plain"
    assert message.get_content_charset() == "utf-8"

    # Verify sender and recipients
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]

    # Verify content
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == textwrap.dedent(u"""\
        From the Tagelied of Wolfram von Eschenbach (Middle High German):

        Sîne klâwen durh die wolken sint geslagen,
        er stîget ûf mit grôzer kraft,
        ich sih in grâwen tägelîch als er wil tagen,
        den tac, der im geselleschaft
        erwenden wil, dem werden man,
        den ich mit sorgen în verliez.
        ich bringe in hinnen, ob ich kan.
        sîn vil manegiu tugent michz leisten hiez.

        http://www.columbia.edu/~fdc/utf8/""")
コード例 #13
0
def test_encoding_us_ascii(tmp_path):
    """Render a simple template with us-ascii encoding."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: [email protected]

        Hello world
    """))
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})
    assert message.get_charset() == "us-ascii"
    assert message.get_content_charset() == "us-ascii"
    assert message.get_payload() == "Hello world"
コード例 #14
0
def test_encoding_utf8(tmp_path):
    """Render a simple template with UTF-8 encoding."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: [email protected]

        Hello Laȝamon
    """))
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})
    assert message.get_charset() == "utf-8"
    assert message.get_content_charset() == "utf-8"
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == "Hello Laȝamon"
コード例 #15
0
def test_attachment_blank(tmpdir):
    """Attachment header without a filename is an error."""
    template_path = Path(tmpdir/"template.txt")
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT:

        Hello world
    """))
    template_message = TemplateMessage(template_path)
    with pytest.raises(MailmergeError) as err:
        with tmpdir.as_cwd():
            template_message.render({})
    assert "Empty attachment header" in str(err)
コード例 #16
0
def test_no_substitutions(tmp_path):
    """Render a template with an empty context."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]

        Hello world!
    """))
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render({})
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]
    plaintext = message.get_payload()
    assert "Hello world!" in plaintext
コード例 #17
0
def test_utf8_subject(tmp_path):
    """Verify UTF8 support in SUBJECT field."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: [email protected]
        SUBJECT: Laȝamon

        {{message}}
    """))
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({
        "message": "hello",
    })

    # Verify subject
    assert message["subject"] == "Laȝamon"
コード例 #18
0
def test_utf8_to(tmp_path):
    """Verify UTF8 support in TO field."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: Laȝamon <*****@*****.**>
        FROM: [email protected]

        {{message}}
    """))
    template_message = TemplateMessage(template_path)
    _, recipients, message = template_message.render({
        "message": "hello",
    })

    # Verify recipient name and email
    assert recipients == ["*****@*****.**"]
    assert message["to"] == "Laȝamon <*****@*****.**>"
コード例 #19
0
def test_utf8_from(tmp_path):
    """Verify UTF8 support in FROM field."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: Laȝamon <*****@*****.**>

        {{message}}
    """))
    template_message = TemplateMessage(template_path)
    sender, _, message = template_message.render({
        "message": "hello",
    })

    # Verify sender name and email
    assert sender == "Laȝamon <*****@*****.**>"
    assert message["from"] == "Laȝamon <*****@*****.**>"
コード例 #20
0
def test_attachment_not_found(tmpdir):
    """Attachment file not found."""
    # Template specifying an attachment that doesn't exist
    template_path = Path(tmpdir/"template.txt")
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: attachment.txt

        Hello world
    """))

    # Render in tmpdir, which lacks attachment.txt
    template_message = TemplateMessage(template_path)
    with pytest.raises(MailmergeError):
        with tmpdir.as_cwd():
            template_message.render({})
コード例 #21
0
def test_attachment_tilde_path(tmpdir):
    """Attachment with home directory tilde notation file path."""
    template_path = Path(tmpdir/"template.txt")
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        FROM: [email protected]
        ATTACHMENT: ~/attachment.txt

        Hello world
    """))

    # Render will throw an error because we didn't create a file in the
    # user's home directory.  We'll just check the filename.
    template_message = TemplateMessage(template_path)
    with pytest.raises(MailmergeError) as err:
        template_message.render({})
    correct_path = Path.home() / "attachment.txt"
    assert str(correct_path) in str(err)
コード例 #22
0
def test_encoding_is8859_1(tmp_path):
    """Render a simple template with IS8859-1 encoding.

    Mailmerge will coerce the encoding to UTF-8.
    """
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: [email protected]

        Hello L'Haÿ-les-Roses
    """))
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})
    assert message.get_charset() == "utf-8"
    assert message.get_content_charset() == "utf-8"
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == "Hello L'Haÿ-les-Roses"
コード例 #23
0
def test_simple(tmp_path):
    """Render a simple template."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent(u"""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]

        Hello {{name}}!
    """))
    template_message = TemplateMessage(template_path)
    sender, recipients, message = template_message.render({
        "name": "world",
    })
    assert sender == "*****@*****.**"
    assert recipients == ["*****@*****.**"]
    plaintext = message.get_payload()
    assert "Hello world!" in plaintext
コード例 #24
0
def test_encoding_mismatch(tmp_path):
    """Render a simple template that lies about its encoding.

    Header says us-ascii, but it contains utf-8.
    """
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        FROM: [email protected]
        Content-Type: text/plain; charset="us-ascii"

        Hello Laȝamon
    """))
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})
    assert message.get_charset() == "utf-8"
    assert message.get_content_charset() == "utf-8"
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == "Hello Laȝamon"
コード例 #25
0
def test_emoji(tmp_path):
    """Verify emoji are encoded."""
    template_path = tmp_path / "template.txt"
    template_path.write_text(textwrap.dedent("""\
        TO: [email protected]
        SUBJECT: Testing mailmerge
        FROM: [email protected]

        Hi 😀
    """))  # grinning face emoji
    template_message = TemplateMessage(template_path)
    _, _, message = template_message.render({})

    # Verify encoding
    assert message.get_charset() == "utf-8"
    assert message["Content-Transfer-Encoding"] == "base64"

    # Verify content
    plaintext = message.get_payload(decode=True).decode("utf-8")
    assert plaintext == "Hi 😀"