"""计划配置的指纹与逐证人工条件,不涉及业务数据库。""" import pytest from fastapi import HTTPException from types import SimpleNamespace def test_condition_confirmation_is_per_certificate_and_current_revision(): from app.services.pl_quota_planning import validate_conditions from app.schemas.pl.quota_planning import PlanQuotaConfiguration fingerprint='a'*64 cert=SimpleNamespace(revision=2) config=PlanQuotaConfiguration(purchaseCertIds=['g'],transportCertIds=['y']) certs={('purchase','g'):cert,('transport','y'):cert} with pytest.raises(HTTPException): validate_conditions(config,certs,fingerprint) conditions=[{'certType':kind,'certId':cid,'certRevision':2,'sourceFingerprint':fingerprint, 'partiesConfirmed':True,'routeConfirmed':kind=='transport','note':'核对实际参与方与证面范围'} for kind,cid in certs] config=PlanQuotaConfiguration(**{**config.model_dump(by_alias=True),'conditions':conditions}) validate_conditions(config,certs,fingerprint) with pytest.raises(HTTPException): validate_conditions(config,certs,'b'*64) cert.revision=3 with pytest.raises(HTTPException): validate_conditions(config,certs,fingerprint) def test_transport_route_confirmation_cannot_be_replaced_by_parties_confirmation(): from app.services.pl_quota_planning import validate_conditions from app.schemas.pl.quota_planning import PlanQuotaConfiguration config=PlanQuotaConfiguration(transportCertIds=['y'],conditions=[{ 'certType':'transport','certId':'y','certRevision':1,'sourceFingerprint':'a'*64, 'partiesConfirmed':True,'routeConfirmed':False,'note':'只确认参与方'}]) with pytest.raises(HTTPException) as error: validate_conditions(config,{('transport','y'):SimpleNamespace(revision=1)},'a'*64) assert error.value.status_code==409 def test_supplement_is_explicit_and_archive_public_schema_preserves_intent(): from app.schemas.pl.plan import PlanArchiveBody from app.schemas.pl.quota_planning import PlanQuotaOperation assert PlanArchiveBody().quota_allow_supplement is False assert PlanArchiveBody(quotaAllowSupplement=True).quota_allow_supplement is True assert PlanQuotaOperation(operationId='op', allowSupplement=True).allow_supplement is True