From 07f252225120c1d42b8c5448d9e4dcdd42fc7900 Mon Sep 17 00:00:00 2001 From: Daniel Date: Sat, 25 Oct 2025 17:28:49 -0400 Subject: [PATCH] Added a few more tests to improve code coverage --- tests/mocked-dns-answers.json | 26 +++++++++++++++++++++++++- tests/test_deliverability.py | 6 ++++++ tests/test_main.py | 27 +++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 1 deletion(-) diff --git a/tests/mocked-dns-answers.json b/tests/mocked-dns-answers.json index 12d3885..8da7db6 100644 --- a/tests/mocked-dns-answers.json +++ b/tests/mocked-dns-answers.json @@ -129,7 +129,7 @@ "type": "A", "class": "IN" }, - "answer": [] + "answer": ["127.0.0.1"] }, { "query": { @@ -139,6 +139,30 @@ }, "answer": [] }, + { + "query": { + "name": "ipv6only.joshdata.me", + "type": "MX", + "class": "IN" + }, + "answer": [] + }, + { + "query": { + "name": "ipv6only.joshdata.me", + "type": "A", + "class": "IN" + }, + "answer": [] + }, + { + "query": { + "name": "ipv6only.joshdata.me", + "type": "AAAA", + "class": "IN" + }, + "answer": ["::1"] + }, { "query": { "name": "mail.example", diff --git a/tests/test_deliverability.py b/tests/test_deliverability.py index 1754e52..e1307c2 100644 --- a/tests/test_deliverability.py +++ b/tests/test_deliverability.py @@ -35,6 +35,7 @@ def test_deliverability_found(domain: str, expected_response: str) -> None: # No MX or A/AAAA records, but some other DNS records must # exist such that the response is NOANSWER instead of NXDOMAIN. ('justtxt.joshdata.me', 'The domain name {domain} does not accept email'), + ('ipv6only.joshdata.me', 'The domain name {domain} does not accept email'), ], ) def test_deliverability_fails(domain: str, error: str) -> None: @@ -65,6 +66,11 @@ def test_deliverability_dns_timeout() -> None: assert response.get("unknown-deliverability") == "timeout" +def test_timeout_and_resolver() -> None: + with pytest.raises(ValueError, match="It's not valid to pass both timeout and dns_resolver."): + validate_email_deliverability('timeout.com', 'timeout.com', timeout=1, dns_resolver=RESOLVER) + + @pytest.mark.network def test_caching_dns_resolver() -> None: class TestCache: diff --git a/tests/test_main.py b/tests/test_main.py index ab8eecd..f11087b 100644 --- a/tests/test_main.py +++ b/tests/test_main.py @@ -1,3 +1,4 @@ +import typing import pytest from email_validator import validate_email, EmailSyntaxError @@ -16,6 +17,14 @@ def test_dict_accessor() -> None: assert valid_email.as_dict()["original"] == input_email +def test_dict_accessor_with_domain_address() -> None: + input_email = "me@[127.0.0.1]" + valid_email = validate_email(input_email, check_deliverability=False, allow_domain_literal=True) + assert valid_email.domain == "[127.0.0.1]" + assert isinstance(valid_email.as_dict(), dict) + assert valid_email.as_dict()["domain_address"] == '"IPv4Address(\'127.0.0.1\')"' + + def test_main_single_good_input(monkeypatch: pytest.MonkeyPatch, capsys: pytest.CaptureFixture[str]) -> None: import json test_email = "google@google.com" @@ -65,3 +74,21 @@ def test_deprecation() -> None: valid_email = validate_email(input_email, check_deliverability=False) with pytest.deprecated_call(): assert valid_email.email is not None + + +@pytest.mark.parametrize('invalid_email', [ + None, + 12345, + [], + {}, + lambda x: x, +]) +def test_invalid_type(invalid_email: typing.Any) -> None: + with pytest.raises(TypeError, match="email must be str or bytes"): + validate_email(invalid_email, check_deliverability=False) + + +def test_invalid_ascii() -> None: + invalid_email = b'\xd0\xba\xd0\xb2\xd1\x96\xd1\x82\xd0\xbe\xd1\x87\xd0\xba\xd0\xb0@\xd0\xbf\xd0\xbe\xd1\x88\xd1\x82\xd0\xb0.test' + with pytest.raises(EmailSyntaxError, match="The email address is not valid ASCII."): + validate_email(invalid_email, check_deliverability=False)