from dataclasses import replace from click.testing import CliRunner from ocado_grocy.grocy import Journal, item_fingerprint from ocado_grocy.history import OrderLink, main, private_json, select_orders from ocado_grocy.order_state import completed_orders, mark_orders from test_grocy import receipt def test_completed_filter_precedes_limit_and_explicit_order_bypasses_it(): links = [OrderLink(str(i),f'2026-09-{i:02d}','url') for i in (1,2,3)] assert [r.order_id for r in select_orders(links,limit=1,completed={'3'})] == ['2'] assert [r.order_id for r in select_orders(links,order_ids=('3',),completed={'3'})] == ['3'] def test_legacy_migration_requires_all_selected_lines_and_never_just_a_cache(tmp_path): state = tmp_path/'imports.sqlite3' order = receipt() item = replace(order.items[0], metadata={'ocado':{'categoryPath':['Food Cupboard']}}) order = replace(order,items=[item,replace(item,name='Second product')]) private_json(tmp_path/'123.json',order.export()) journal = Journal(state) assert completed_orders(state,'server',tmp_path,{}) == set() journal.record('server','123',1,item_fingerprint(order,item),'done',1) assert completed_orders(state,'server',tmp_path,{}) == set() journal.record('server','123',2,item_fingerprint(order,order.items[1]),'pending',2) assert completed_orders(state,'server',tmp_path,{}) == set() journal.record('server','123',2,item_fingerprint(order,order.items[1]),'done',2) assert completed_orders(state,'server',tmp_path,{}) == {'123'} assert completed_orders(state,'other-server',tmp_path,{}) == set() # Enrichment failure must override legacy done stock lines. mark_orders(state,'server',['123'],'processing') assert completed_orders(state,'server',tmp_path,{}) == set() mark_orders(state,'server',['123'],'complete') assert completed_orders(state,'server',tmp_path,{}) == {'123'} journal.db.close() def test_empty_selection_completion_and_read_only_missing_state(tmp_path): state = tmp_path/'imports.sqlite3' assert completed_orders(state,'server',tmp_path,{}) == set() assert not state.exists() mark_orders(state,'server',['123'],'complete') assert completed_orders(state,'server',tmp_path,{}) == {'123'} def test_default_cached_run_skips_receipt_loading_and_all_processing(tmp_path, monkeypatch): from ocado_grocy import history private_json(tmp_path/'orders.json',[{'order_id':'123','purchased_date':'2026-09-08','url':'url'}]) # No receipt file: skipping must happen before trying to load it. mark_orders(tmp_path/'imports.sqlite3','/api',['123'],'complete') def unexpected(*args, **kwargs): raise AssertionError('Completed order was processed again') monkeypatch.setattr(history,'run_import',unexpected) result = CliRunner().invoke(main,['--cached','--archive',str(tmp_path),'--config',str(tmp_path/'config.toml')]) assert result.exit_code == 0, result.output assert 'No new delivered orders' in result.output