mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-09-05 13:38:00 +00:00
Raise test coverage: utils.py, elastic.py, and opensearch.py to 100% (#816)
* Raise test coverage: utils, elastic, and opensearch to 100%
Coverage of the shipped library rises from 88% to 90%, with
parsedmarc/utils.py 86% -> 100% and elastic.py / opensearch.py
99% -> 100%. All new tests assert on observable behaviour and mock
only at SDK boundaries (dnspython Resolver.resolve, requests.get,
subprocess.check_call, elasticsearch_dsl/opensearchpy Document.save).
New tests cover: query_dns transient-error retries, the load_ip_db
download/cache/bundled fallback chain, the IPinfo API token probe and
per-request MMDB fallbacks, _normalize_ip_record schema handling,
reverse-DNS-map invalid-CSV fallback, caller-provided reverse DNS
maps, Outlook MSG conversion (missing msgconvert and success paths),
parse_email Cc/Bcc/attachment-hash branches, aggregate-XML edge cases
(bytes input, repeated policy_published, unknown RFC 9990 override
types, missing org_name, attribute-only <email>), extract_report on
non-seekable streams, and the _AggregateReportDoc.save() override
that derives passed_dmarc.
Bugs found by the new tests, fixed in the same PR per the testing
standards:
- parse_email() crashed with KeyError: 'Headers' on messages whose
From header is present but unparseable (e.g. a bare "From:" line):
the fallback read parsed_email["Headers"], but the parsed headers
are stored under lowercase "headers" (assigned a few lines up in
the same function), so the key never exists. At the CLI surface
this made any failure report whose embedded sample had an empty
From: header fail to parse ("Missing value: 'Headers'").
- configure_ipinfo_api(probe=True) logged "IPinfo API configured"
when the probe could not reach the API, contradicting its own
docstring ("other errors are logged and the token is still
accepted"): _ipinfo_api_lookup() returns None on network errors
instead of raising, so the probe's exception handler was
unreachable. The probe now checks the lookup result and warns on
failure; 401/403 still raises InvalidIPinfoAPIKey.
Dead code deleted rather than padded with tests:
- _SMTPTLSReportDoc.add_policy() in elastic.py and opensearch.py
(the save paths construct _SMTPTLSPolicyDoc directly).
- The no-op "for failure_index in failure_indexes: pass" loop in
both migrate_indexes() implementations (parameter still accepted).
- The importlib.resources ImportError fallback in utils.py, which
re-imported the same module and is unreachable on Python >= 3.10.
- The "Invalid report content" guard in extract_report(): every
input branch assigns file_object or raises first (confirmed by
pyright narrowing with the guard removed).
Also widens parse_aggregate_report_xml's annotation to str | bytes
to match its existing runtime behaviour (bytes are decoded with
errors ignored).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* Use assertGreater for the reverse-DNS-map fallback size check
Addresses the github-code-quality bot finding on PR #816: assertTrue
with a comparison inside can't show the operands on failure, while
assertGreater reports both values and the failed relation. No change
to test behavior.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
parent
a1da7b3420
commit
746da77de5
@@ -579,6 +579,32 @@ class TestSaveAggregateReport(unittest.TestCase):
|
||||
self.assertIn("cust_dmarc_aggregate_tenant_a*", search_index)
|
||||
|
||||
|
||||
class TestAggregateDocPassedDmarc(unittest.TestCase):
|
||||
"""The _AggregateReportDoc.save() override derives passed_dmarc — the
|
||||
field dashboards filter on for DMARC pass/fail — from SPF/DKIM
|
||||
alignment. The SDK parent (elasticsearch_dsl.Document.save) is mocked so
|
||||
no cluster is needed."""
|
||||
|
||||
def test_passed_dmarc_derived_from_alignment(self):
|
||||
cases = [
|
||||
(True, False, True),
|
||||
(False, True, True),
|
||||
(True, True, True),
|
||||
(False, False, False),
|
||||
]
|
||||
for spf_aligned, dkim_aligned, expected in cases:
|
||||
with self.subTest(spf=spf_aligned, dkim=dkim_aligned):
|
||||
with patch.object(
|
||||
elastic_module.Document, "save", return_value=None
|
||||
) as mock_super_save:
|
||||
doc = elastic_module._AggregateReportDoc(
|
||||
spf_aligned=spf_aligned, dkim_aligned=dkim_aligned
|
||||
)
|
||||
doc.save()
|
||||
mock_super_save.assert_called_once()
|
||||
self.assertEqual(bool(doc.passed_dmarc), expected)
|
||||
|
||||
|
||||
# ---------------------------------------------------------------------------
|
||||
# save_failure_report_to_elasticsearch
|
||||
# ---------------------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user