diff --git a/tests/fixtures/invest_engine/html_partial_match.eml b/tests/fixtures/invest_engine/html_partial_match.eml new file mode 100644 index 0000000..fc41aa1 --- /dev/null +++ b/tests/fixtures/invest_engine/html_partial_match.eml @@ -0,0 +1,40 @@ +From: InvestEngine +To: viktorbarzin@example.com +Subject: Your portfolio has been updated +Date: Wed, 15 Apr 2026 11:00:00 +0000 +MIME-Version: 1.0 +Content-Type: multipart/alternative; boundary="----=_Part_PM" + +------=_Part_PM +Content-Type: text/plain; charset=UTF-8 + +(HTML-only view — your client does not render HTML emails.) + +------=_Part_PM +Content-Type: text/html; charset=UTF-8 + + +
Logo
+ + + + + + + + +
Date: 15 April 2026
+ + + + +
Vanguard S&P 500: VUAG
Bought 3.0 @ £61.25 per share
Total: £183.75
+
+ + + +
Some broken order with no ticker and no bought line
(Malformed — IE dropped a row mid-render)
+
+ + +------=_Part_PM-- diff --git a/tests/fixtures/invest_engine/unparseable.eml b/tests/fixtures/invest_engine/unparseable.eml new file mode 100644 index 0000000..933f99a --- /dev/null +++ b/tests/fixtures/invest_engine/unparseable.eml @@ -0,0 +1,15 @@ +From: InvestEngine +To: viktorbarzin@example.com +Subject: InvestEngine newsletter +Date: Thu, 10 Apr 2025 12:00:00 +0000 +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 + +Hi Viktor, + +This is a newsletter, not a trade confirmation. There is no structured +order data here — just marketing copy and a promo for a new feature we +are rolling out. Thanks for being a customer. + +Cheers, +The InvestEngine team diff --git a/tests/providers/parsers/test_invest_engine.py b/tests/providers/parsers/test_invest_engine.py index 8ef81d3..9c30889 100644 --- a/tests/providers/parsers/test_invest_engine.py +++ b/tests/providers/parsers/test_invest_engine.py @@ -89,3 +89,20 @@ def test_csv_attachment_parses_all_rows() -> None: assert a.account_type is AccountType.ISA assert a.notes is not None assert "csv" in a.notes + + +# -- graceful failure modes -- + + +def test_unparseable_email_returns_empty_list() -> None: + assert parse_invest_engine_email(_load("unparseable.eml")) == [] + + +def test_html_partial_match_returns_only_parseable_orders() -> None: + activities = parse_invest_engine_email(_load("html_partial_match.eml")) + assert len(activities) == 1 + a = activities[0] + assert a.symbol == "VUAG" + assert a.quantity == Decimal("3.0") + assert a.unit_price == Decimal("61.25") + assert a.date == datetime(2026, 4, 15)