mirror of
https://github.com/domainaware/parsedmarc.git
synced 2026-08-02 21:52:18 +00:00
Normalize aggregate result words to lowercase (#835)
* fix: normalize aggregate result words Normalize policy-evaluated and authentication result values so mixed-case reporter output does not create duplicate categories. Add a regression covering the existing uppercase sample. * Move changelog entry to the Unreleased section The entry landed in the released 10.2.4 section because the branch was cut before the Unreleased heading existed on master; merged master and moved it under Unreleased -> Bug fixes, matching the house entry style. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> * Apply review feedback: normalize disposition, share a guarded helper - policy_evaluated disposition gets the same lowercase normalization as dkim/spf and the auth result words; the RFC 7489 Appendix C / RFC 9990 disposition enum is lowercase (none/quarantine/reject), and mixed-case values split the Message Disposition categories in every dashboard the same way Pass/pass did. - All four normalization sites now share _normalize_result_word(), which guards with isinstance(str): xmltodict returns a dict for attribute-bearing elements, so the previously unguarded .lower() calls on auth results could raise AttributeError on malformed input that used to pass through. - The #520 fixture's disposition is now mixed-case (None) and the test asserts it parses as "none"; verified the assertion fails against the pre-fix parser. Test docstring cites the RFC authority per the project's testing standards. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> --------- Co-authored-by: Sean Whalen <44679+seanthegeek@users.noreply.github.com> Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Fable 5
Sean Whalen
parent
6acacd01d1
commit
e98e12acb0
@@ -166,6 +166,25 @@ class Test(unittest.TestCase):
|
||||
)
|
||||
print("Passed!")
|
||||
|
||||
def testAggregateResultWordsAreLowercase(self):
|
||||
"""Reporter-supplied result words are lowercased at ingest; RFC 7489
|
||||
Appendix C and RFC 9990 define the result and disposition types as
|
||||
lowercase enum tokens (issue #288).
|
||||
"""
|
||||
result = parsedmarc.parse_report_file(
|
||||
"samples/aggregate_invalid/report_with_upper_cased_pass.xml",
|
||||
offline=True,
|
||||
)
|
||||
assert result["report_type"] == "aggregate"
|
||||
report = cast(AggregateReport, result["report"])
|
||||
record = report["records"][0]
|
||||
|
||||
self.assertEqual(record["policy_evaluated"]["dkim"], "pass")
|
||||
self.assertEqual(record["policy_evaluated"]["spf"], "pass")
|
||||
self.assertEqual(record["auth_results"]["dkim"][0]["result"], "pass")
|
||||
self.assertEqual(record["auth_results"]["spf"][0]["result"], "pass")
|
||||
self.assertEqual(record["policy_evaluated"]["disposition"], "none")
|
||||
|
||||
def testEmptySample(self):
|
||||
"""Test empty/unparasable report"""
|
||||
with self.assertRaises(parsedmarc.ParserError):
|
||||
|
||||
Reference in New Issue
Block a user