Files
shanxia2.0/backend/tests/test_refresh_dispatch_calendar_site.py
T

120 lines
4.6 KiB
Python

"""历史派车补派脚本:预览只读、差量、幂等及事务。"""
from datetime import date
import pytest
from sqlalchemy import create_engine
from sqlalchemy.orm import Session
from app.models.pl_dispatch_calendar import PlDispatchCalendar as Record
from scripts.refresh_dispatch_calendar_site import refresh
@pytest.fixture
def db():
engine = create_engine('sqlite://')
Record.__table__.create(engine)
with Session(engine, autoflush=False, expire_on_commit=False) as session:
yield session
engine.dispose()
def source(db, id='s1', **values):
data = dict(id=id, tenant_no='t1', calendar_kind='acid', dispatch_date=date(2026, 10, 28),
vehicle_id='v1', license_plate='鄂E12345', product_id='p1', product_name='盐酸',
origin='山峡', destination='武汉', create_by='u1', create_dept_id='d1',
site_sync_enabled=0)
data.update(values)
row = Record(**data)
db.add(row)
db.commit()
return row
def run(db, apply=False):
return refresh(db, tenant='t1', start=date(2026, 10, 28), end=date(2026, 10, 30),
operator='calendar-site-refresh', apply=apply)
@pytest.mark.parametrize('kind', ['acid', 'alkali', 'other'])
def test_preview_backfill_and_repeat_preserve_identity(db, kind):
row = source(db, calendar_kind=kind)
assert run(db)['counts']['created'] == 1
assert db.query(Record).count() == 1 and row.site_sync_enabled == 0
assert run(db, True)['counts']['created'] == 1
target = db.query(Record).filter(Record.source_record_id == row.id).one()
identity = (target.id, target.create_time, target.create_by, target.update_time)
assert row.site_sync_enabled == 1 and target.document_type == '出库计划'
assert run(db, True)['counts']['unchanged'] == 1
assert (target.id, target.create_time, target.create_by, target.update_time) == identity
assert db.query(Record).count() == 2
def test_scope_and_matching(db):
source(db, 'before', dispatch_date=date(2026, 10, 27))
source(db, 'after', dispatch_date=date(2026, 10, 31))
source(db, 'foreign', tenant_no='t2')
source(db, 'manual', calendar_kind='site')
source(db, 'deleted', del_flag=1)
source(db, 'nomatch', origin='武汉', destination='合肥')
source(db, 'inbound', destination='云栋', origin='合肥', dispatch_date=date(2026, 10, 29))
source(db, 'both', destination='云栋', dispatch_date=date(2026, 10, 30))
result = run(db, True)
targets = db.query(Record).filter(Record.source_record_id.isnot(None)).all()
assert {r.source_record_id: r.document_type for r in targets} == {'inbound': '入库计划', 'both': '出入库计划'}
assert result['counts']['created'] == 2
assert db.get(Record, 'nomatch').site_sync_enabled == 0
assert db.get(Record, 'manual').origin == '山峡'
def test_update_soft_delete_restore_and_enable_history_with_existing_target(db):
row = source(db)
run(db, True)
target = db.query(Record).filter(Record.source_record_id == row.id).one()
identity = (target.id, target.create_time)
row.destination = '云栋'
row.quantity = '32.50'
db.commit()
assert run(db, True)['counts']['updated'] == 1
assert target.document_type == '出入库计划' and target.quantity == '32.50'
row.del_flag = 1
db.commit()
assert run(db, True)['counts']['removed'] == 1
assert target.del_flag == 1
row.del_flag = 0
row.site_sync_enabled = 0
db.commit()
assert run(db, True)['counts']['restored'] == 1
assert row.site_sync_enabled == 1 and target.del_flag == 0
assert (target.id, target.create_time) == identity
def test_failure_rolls_back_all_changes(db, monkeypatch):
import scripts.refresh_dispatch_calendar_site as script
row = source(db)
original = script.svc._sync_site_record
def fail(*args):
original(*args)
args[0].flush()
raise RuntimeError('forced failure')
monkeypatch.setattr(script.svc, '_sync_site_record', fail)
with pytest.raises(RuntimeError):
run(db, True)
assert db.query(Record).count() == 1
assert db.get(Record, row.id).site_sync_enabled == 0
def test_reversed_date_range_is_rejected(db):
with pytest.raises(ValueError):
refresh(db, tenant='t1', start=date(2026, 10, 30), end=date(2026, 10, 28),
operator='calendar-site-refresh', apply=True)
def test_preview_rejects_disabled_source_with_stale_automatic_target(db):
row = source(db)
run(db, True)
row.site_sync_enabled = 0
row.origin = '武汉'
db.commit()
with pytest.raises(ValueError, match='未启用同步'):
run(db)