@@ -29,7 +29,7 @@ async def test_fetch_auto_approve_transactions_filters_expected_rows(db):
2929 found = await fetch_auto_approve_transactions (con )
3030
3131 assert {plan_id : [txn .id for txn in txns ] for plan_id , txns in found .items ()} == {
32- "plan-1" : ["pair-a-1" ],
32+ "plan-1" : ["pair-a-1" , "unmatched" ],
3333 "plan-2" : ["pair-b-1" ],
3434 }
3535
@@ -69,6 +69,28 @@ def test_build_updates_groups_by_plan_and_updates_both_ids():
6969 assert all (txn .approved is True for txns in updates .values () for txn in txns )
7070
7171
72+ def test_build_updates_approves_unmatched_scheduled_transactions ():
73+ txns_by_plan = {
74+ "plan-1" : [
75+ Transaction (
76+ id = "txn-1" ,
77+ matched_transaction_id = None ,
78+ plan_id = "plan-1" ,
79+ account_name = "Checking" ,
80+ payee_name = "Apple" ,
81+ amount_formatted = "-$21.76" ,
82+ date = "2026-04-20" ,
83+ )
84+ ]
85+ }
86+
87+ updates = build_updates (txns_by_plan )
88+
89+ assert {plan_id : [txn .id for txn in txns ] for plan_id , txns in updates .items ()} == {
90+ "plan-1" : ["txn-1" ],
91+ }
92+
93+
7294@patch .dict ("os.environ" , {_ENV_TOKEN : "" })
7395@pytest .mark .asyncio
7496async def test_run_requires_token (db ):
@@ -105,6 +127,15 @@ def _expected_auto_approve_result(updated_count: int) -> AutoApproveResult:
105127 amount_formatted = "-$4.50" ,
106128 date = "2026-04-20" ,
107129 ),
130+ Transaction (
131+ id = "unmatched" ,
132+ matched_transaction_id = None ,
133+ plan_id = "plan-1" ,
134+ account_name = "Checking" ,
135+ payee_name = "Solo" ,
136+ amount_formatted = "-$7.00" ,
137+ date = "2026-04-21" ,
138+ ),
108139 Transaction (
109140 id = "pair-b-1" ,
110141 matched_transaction_id = "pair-b-2" ,
@@ -177,9 +208,13 @@ async def test_auto_approve_for_real_returns_updated_count(
177208 ynab_api_client .assert_called_once_with (ynab_configuration .return_value )
178209 sync .assert_called_once_with ("token" , db , False , quiet = True )
179210 assert [plan_id for plan_id , _ in updates ] == ["plan-1" , "plan-2" ]
180- assert [txn .id for txn in updates [0 ][1 ].transactions ] == ["pair-a-1" , "pair-a-2" ]
211+ assert [txn .id for txn in updates [0 ][1 ].transactions ] == [
212+ "pair-a-1" ,
213+ "pair-a-2" ,
214+ "unmatched" ,
215+ ]
181216 assert [txn .id for txn in updates [1 ][1 ].transactions ] == ["pair-b-1" , "pair-b-2" ]
182- assert result == _expected_auto_approve_result (2 )
217+ assert result == _expected_auto_approve_result (3 )
183218
184219
185220@patch .dict ("os.environ" , {_ENV_TOKEN : "token" })
@@ -194,7 +229,7 @@ async def test_run_dry_run_does_not_update_transactions(sync, db, capsys):
194229 sync .assert_called_once_with ("token" , db , False , quiet = False )
195230 assert "** Refreshing SQLite DB **" in out
196231 assert "** Done **" in out
197- assert "Found 2 matched transaction(s) to approve." in out
232+ assert "Found 3 transaction(s) to approve." in out
198233 assert "Use --for-real to actually approve transactions." in out
199234
200235
@@ -217,7 +252,7 @@ async def test_run_quiet_suppresses_all_output(sync, db, capsys):
217252async def test_run_no_matching_transactions (sync , db , capsys ):
218253 with sqlite3 .connect (db ) as con :
219254 con .execute (
220- "UPDATE transactions SET approved = 1 WHERE matched_transaction_id IS NOT NULL"
255+ "UPDATE transactions SET approved = 1 WHERE matched_transaction_id IS NOT NULL OR id = 'unmatched' "
221256 )
222257
223258 ret = await run (("--sqlite-export-for-ynab-db" , str (db )))
@@ -227,7 +262,7 @@ async def test_run_no_matching_transactions(sync, db, capsys):
227262 sync .assert_called_once_with ("token" , db , False , quiet = False )
228263 assert "** Refreshing SQLite DB **" in out
229264 assert "** Done **" in out
230- assert "Found 0 matched transaction(s) to approve." in out
265+ assert "Found 0 transaction(s) to approve." in out
231266
232267
233268@patch .dict ("os.environ" , {_ENV_TOKEN : "token" })
@@ -248,5 +283,9 @@ async def test_run_for_real_updates_transactions_grouped_by_plan(
248283 ynab_api_client .assert_called_once_with (ynab_configuration .return_value )
249284 sync .assert_called_once_with ("token" , db , False , quiet = False )
250285 assert [plan_id for plan_id , _ in updates ] == ["plan-1" , "plan-2" ]
251- assert [txn .id for txn in updates [0 ][1 ].transactions ] == ["pair-a-1" , "pair-a-2" ]
286+ assert [txn .id for txn in updates [0 ][1 ].transactions ] == [
287+ "pair-a-1" ,
288+ "pair-a-2" ,
289+ "unmatched" ,
290+ ]
252291 assert [txn .id for txn in updates [1 ][1 ].transactions ] == ["pair-b-1" , "pair-b-2" ]
0 commit comments