|
| 1 | +import dns.resolver |
| 2 | +import pytest |
| 3 | +import re |
| 4 | + |
| 5 | +from email_validator import EmailUndeliverableError, \ |
| 6 | + validate_email |
| 7 | +from email_validator.deliverability import caching_resolver, validate_email_deliverability |
| 8 | + |
| 9 | + |
| 10 | +def test_deliverability_found(): |
| 11 | + response = validate_email_deliverability('gmail.com', 'gmail.com') |
| 12 | + assert response.keys() == {'mx', 'mx_fallback_type'} |
| 13 | + assert response['mx_fallback_type'] is None |
| 14 | + assert len(response['mx']) > 1 |
| 15 | + assert len(response['mx'][0]) == 2 |
| 16 | + assert isinstance(response['mx'][0][0], int) |
| 17 | + assert response['mx'][0][1].endswith('.com') |
| 18 | + |
| 19 | + |
| 20 | +def test_deliverability_fails(): |
| 21 | + # No MX record. |
| 22 | + domain = 'xkxufoekjvjfjeodlfmdfjcu.com' |
| 23 | + with pytest.raises(EmailUndeliverableError, match='The domain name {} does not exist'.format(domain)): |
| 24 | + validate_email_deliverability(domain, domain) |
| 25 | + |
| 26 | + # Null MX record. |
| 27 | + domain = 'example.com' |
| 28 | + with pytest.raises(EmailUndeliverableError, match='The domain name {} does not accept email'.format(domain)): |
| 29 | + validate_email_deliverability(domain, domain) |
| 30 | + |
| 31 | + |
| 32 | +@pytest.mark.parametrize( |
| 33 | + 'email_input', |
| 34 | + [ |
| 35 | + ('me@mail.example'), |
| 36 | + ('me@example.com'), |
| 37 | + ('me@mail.example.com'), |
| 38 | + ], |
| 39 | +) |
| 40 | +def test_email_example_reserved_domain(email_input): |
| 41 | + # Since these all fail deliverabiltiy from a static list, |
| 42 | + # DNS deliverability checks do not arise. |
| 43 | + with pytest.raises(EmailUndeliverableError) as exc_info: |
| 44 | + validate_email(email_input) |
| 45 | + # print(f'({email_input!r}, {str(exc_info.value)!r}),') |
| 46 | + assert re.match(r"The domain name [a-z\.]+ does not (accept email|exist)\.", str(exc_info.value)) is not None |
| 47 | + |
| 48 | + |
| 49 | +def test_deliverability_dns_timeout(): |
| 50 | + validate_email_deliverability.TEST_CHECK_TIMEOUT = True |
| 51 | + response = validate_email_deliverability('gmail.com', 'gmail.com') |
| 52 | + assert "mx" not in response |
| 53 | + assert response.get("unknown-deliverability") == "timeout" |
| 54 | + validate_email('test@gmail.com') |
| 55 | + del validate_email_deliverability.TEST_CHECK_TIMEOUT |
| 56 | + |
| 57 | + |
| 58 | +def test_validate_email__with_caching_resolver(): |
| 59 | + # unittest.mock.patch("dns.resolver.LRUCache.get") doesn't |
| 60 | + # work --- it causes get to always return an empty list. |
| 61 | + # So we'll mock our own way. |
| 62 | + class MockedCache: |
| 63 | + get_called = False |
| 64 | + put_called = False |
| 65 | + |
| 66 | + def get(self, key): |
| 67 | + self.get_called = True |
| 68 | + return None |
| 69 | + |
| 70 | + def put(self, key, value): |
| 71 | + self.put_called = True |
| 72 | + |
| 73 | + # Test with caching_resolver helper method. |
| 74 | + mocked_cache = MockedCache() |
| 75 | + dns_resolver = caching_resolver(cache=mocked_cache) |
| 76 | + validate_email("test@gmail.com", dns_resolver=dns_resolver) |
| 77 | + assert mocked_cache.put_called |
| 78 | + validate_email("test@gmail.com", dns_resolver=dns_resolver) |
| 79 | + assert mocked_cache.get_called |
| 80 | + |
| 81 | + # Test with dns.resolver.Resolver instance. |
| 82 | + dns_resolver = dns.resolver.Resolver() |
| 83 | + dns_resolver.lifetime = 10 |
| 84 | + dns_resolver.cache = MockedCache() |
| 85 | + validate_email("test@gmail.com", dns_resolver=dns_resolver) |
| 86 | + assert mocked_cache.put_called |
| 87 | + validate_email("test@gmail.com", dns_resolver=dns_resolver) |
| 88 | + assert mocked_cache.get_called |
0 commit comments