| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384 |
- """mineVehicles:车辆人员归属过滤与写校验。"""
- from __future__ import annotations
- from datetime import date, datetime
- from types import SimpleNamespace
- import pytest
- from sqlalchemy import create_engine
- from sqlalchemy.orm import sessionmaker
- from app.models.models import SysRole, SysUserRole
- from app.models.pl_models import (
- PlPersonnel,
- PlVehicle,
- PlVehiclePersonnel,
- PlVehicleRechargeApply,
- )
- def _make_session():
- engine = create_engine("sqlite://")
- for table in (
- PlVehicle.__table__,
- PlPersonnel.__table__,
- PlVehiclePersonnel.__table__,
- PlVehicleRechargeApply.__table__,
- SysRole.__table__,
- SysUserRole.__table__,
- ):
- table.create(engine)
- return sessionmaker(bind=engine)()
- def _user(uid: str = "u-driver") -> SimpleNamespace:
- return SimpleNamespace(id=uid, name="司机甲", dept_id="d1", role="driver", tenant_no="t1")
- def _seed_person_vehicle(db, *, user_id="u-driver", plate="鄂A11111", vehicle_id="veh-a"):
- db.add(
- PlVehicle(
- id=vehicle_id,
- vehicle_type="self",
- license_plate=plate,
- tenant_no="t1",
- create_dept_id="d1",
- del_flag=0,
- )
- )
- db.add(
- PlPersonnel(
- id="p-1",
- personnel_name="司机甲",
- personnel_type="driver",
- personnel_affiliation="self",
- status="1",
- sys_user_id=user_id,
- tenant_no="t1",
- create_dept_id="d1",
- del_flag=0,
- )
- )
- db.add(
- PlVehiclePersonnel(
- id="vp-1",
- vehicle_id=vehicle_id,
- personnel_id="p-1",
- role="driver",
- is_default=1,
- tenant_no="t1",
- create_dept_id="d1",
- del_flag=0,
- )
- )
- def _seed_admin_role(db, *, user_id="u-admin", role_name="管理员", role_id="role-admin"):
- db.add(
- SysRole(
- id=role_id,
- role_name=role_name,
- status="1",
- tenant_no="t1",
- create_dept_id="d1",
- create_time=datetime.now(),
- update_time=datetime.now(),
- del_flag=0,
- )
- )
- db.add(
- SysUserRole(
- id=f"ur-{role_id}",
- user_id=user_id,
- role_id=role_id,
- tenant_no="t1",
- create_dept_id="d1",
- create_time=datetime.now(),
- update_time=datetime.now(),
- del_flag=0,
- )
- )
- def test_license_plates_for_user_personnel():
- from app.services.pl_vehicle_mine_vehicles import license_plates_for_user_personnel
- db = _make_session()
- _seed_person_vehicle(db)
- db.add(
- PlVehicle(
- id="veh-b",
- vehicle_type="self",
- license_plate="鄂A22222",
- tenant_no="t1",
- create_dept_id="d1",
- del_flag=0,
- )
- )
- db.commit()
- plates = license_plates_for_user_personnel(db, "t1", "u-driver")
- assert plates == {"鄂A11111"}
- def test_license_plates_empty_when_no_personnel():
- from app.services.pl_vehicle_mine_vehicles import license_plates_for_user_personnel
- db = _make_session()
- db.commit()
- assert license_plates_for_user_personnel(db, "t1", "u-nobody") == set()
- def test_user_is_pl_recharge_admin_by_role_name():
- from app.services.pl_vehicle_mine_vehicles import (
- should_restrict_mine_vehicles,
- user_is_pl_recharge_admin,
- )
- db = _make_session()
- _seed_admin_role(db, user_id="u-admin", role_name="管理员")
- _seed_admin_role(
- db, user_id="u-super", role_name="超级管理员", role_id="role-super"
- )
- db.commit()
- assert user_is_pl_recharge_admin(db, "t1", "u-admin") is True
- assert user_is_pl_recharge_admin(db, "t1", "u-super") is True
- assert user_is_pl_recharge_admin(db, "t1", "u-driver") is False
- assert (
- should_restrict_mine_vehicles(db, "t1", "u-admin", mine_vehicles=True) is False
- )
- assert (
- should_restrict_mine_vehicles(db, "t1", "u-driver", mine_vehicles=True) is True
- )
- assert (
- should_restrict_mine_vehicles(db, "t1", "u-admin", mine_vehicles=False) is False
- )
- def _seed_apply(db, *, apply_id, plate, applicant_id, status="draft"):
- db.add(
- PlVehicleRechargeApply(
- id=apply_id,
- apply_no=f"SXSQ{apply_id}",
- license_plate=plate,
- recharge_type="etc",
- apply_date=date.today(),
- applicant_id=applicant_id,
- status=status,
- tenant_no="t1",
- create_by=applicant_id,
- create_dept_id="d1",
- create_time=datetime.now(),
- update_time=datetime.now(),
- del_flag=0,
- )
- )
- def test_list_applies_mine_vehicles_includes_others_on_my_plate(monkeypatch):
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_person_vehicle(db)
- _seed_apply(db, apply_id="a1", plate="鄂A11111", applicant_id="u-office")
- _seed_apply(db, apply_id="a2", plate="鄂A99999", applicant_id="u-office")
- db.commit()
- monkeypatch.setattr(svc, "apply_pl_scope", lambda query, *_a, **_k: query)
- monkeypatch.setattr(svc, "assert_pl_row_in_scope", lambda *_a, **_k: None)
- monkeypatch.setattr(svc, "_resolve_user_name", lambda *_a, **_k: "X")
- monkeypatch.setattr(
- svc,
- "apply_to_read",
- lambda row, db, **kw: SimpleNamespace(
- id=row.id, licensePlate=row.license_plate, applicantId=row.applicant_id
- ),
- )
- items, total = svc.list_applies(
- db, "t1", _user(), mine_vehicles=True, page=1, page_size=20
- )
- assert total == 1
- assert items[0].id == "a1"
- def test_list_applies_mine_vehicles_admin_sees_all_plates(monkeypatch):
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_admin_role(db, user_id="u-admin")
- _seed_apply(db, apply_id="a1", plate="鄂A11111", applicant_id="u-office")
- _seed_apply(db, apply_id="a2", plate="鄂A99999", applicant_id="u-office")
- db.commit()
- monkeypatch.setattr(svc, "apply_pl_scope", lambda query, *_a, **_k: query)
- monkeypatch.setattr(
- svc,
- "apply_to_read",
- lambda row, db, **kw: SimpleNamespace(id=row.id),
- )
- items, total = svc.list_applies(
- db, "t1", _user("u-admin"), mine_vehicles=True, page=1, page_size=20
- )
- assert total == 2
- assert {i.id for i in items} == {"a1", "a2"}
- def test_get_apply_mine_vehicles_allows_others_on_my_plate(monkeypatch):
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_person_vehicle(db)
- _seed_apply(db, apply_id="a1", plate="鄂A11111", applicant_id="u-office")
- db.commit()
- monkeypatch.setattr(
- svc,
- "assert_pl_row_in_scope",
- lambda *_a, **_k: (_ for _ in ()).throw(
- AssertionError("should not use data scope when mine_vehicles")
- ),
- )
- monkeypatch.setattr(svc, "_resolve_user_name", lambda *_a, **_k: "X")
- monkeypatch.setattr(
- svc,
- "apply_to_read",
- lambda row, db, **kw: SimpleNamespace(id=row.id),
- )
- result = svc.get_apply(db, "t1", _user(), "a1", mine_vehicles=True)
- assert result.id == "a1" or getattr(result, "id", None) == "a1"
- def test_get_apply_mine_vehicles_rejects_foreign_plate(monkeypatch):
- from fastapi import HTTPException
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_person_vehicle(db)
- _seed_apply(db, apply_id="a2", plate="鄂A99999", applicant_id="u-office")
- db.commit()
- monkeypatch.setattr(svc, "_resolve_user_name", lambda *_a, **_k: "X")
- with pytest.raises(HTTPException) as exc:
- svc.get_apply(db, "t1", _user(), "a2", mine_vehicles=True)
- assert exc.value.status_code == 403
- assert "无权" in exc.value.detail
- def test_get_apply_mine_vehicles_admin_allows_foreign_plate(monkeypatch):
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_admin_role(db, user_id="u-admin")
- _seed_apply(db, apply_id="a2", plate="鄂A99999", applicant_id="u-office")
- db.commit()
- monkeypatch.setattr(
- svc,
- "assert_pl_row_in_scope",
- lambda *_a, **_k: (_ for _ in ()).throw(
- AssertionError("admin mineVehicles should skip data scope")
- ),
- )
- monkeypatch.setattr(
- svc,
- "apply_to_read",
- lambda row, db, **kw: SimpleNamespace(id=row.id),
- )
- result = svc.get_apply(db, "t1", _user("u-admin"), "a2", mine_vehicles=True)
- assert result.id == "a2"
- def test_create_apply_mine_vehicles_rejects_foreign_plate(monkeypatch):
- from fastapi import HTTPException
- from app.schemas.pl.vehicle_recharge import VehicleRechargeApplyCreate
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_person_vehicle(db)
- db.commit()
- monkeypatch.setattr(svc, "apply_pl_scope", lambda query, *_a, **_k: query)
- monkeypatch.setattr(svc, "assert_pl_row_in_scope", lambda *_a, **_k: None)
- monkeypatch.setattr(svc, "_resolve_user_name", lambda *_a, **_k: "X")
- monkeypatch.setattr(svc, "_resolve_applicant_id", lambda *_a, **_k: "u-driver")
- monkeypatch.setattr(svc, "_assert_vehicle_exists", lambda *_a, **_k: None)
- monkeypatch.setattr(svc, "generate_apply_no", lambda *_a, **_k: "SXSQTEST1")
- payload = VehicleRechargeApplyCreate(
- licensePlate="鄂A99999",
- rechargeType="etc",
- applyDate=date.today(),
- odometerKm=1000,
- attachmentUrls="http://example.com/a.jpg",
- )
- with pytest.raises(HTTPException) as ei:
- svc.create_apply(db, "t1", _user(), payload, mine_vehicles=True)
- assert ei.value.status_code in (400, 403)
- def test_create_apply_mine_vehicles_admin_allows_foreign_plate(monkeypatch):
- from app.schemas.pl.vehicle_recharge import VehicleRechargeApplyCreate
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_admin_role(db, user_id="u-admin")
- db.commit()
- monkeypatch.setattr(svc, "_assert_vehicle_exists", lambda *_a, **_k: None)
- monkeypatch.setattr(svc, "generate_apply_no", lambda *_a, **_k: "SXSQADMIN1")
- monkeypatch.setattr(
- svc,
- "apply_to_read",
- lambda row, db, **kw: SimpleNamespace(
- id=row.id, licensePlate=row.license_plate, applicantId=row.applicant_id
- ),
- )
- payload = VehicleRechargeApplyCreate(
- licensePlate="鄂A99999",
- rechargeType="etc",
- applyDate=date.today(),
- odometerKm=1000,
- attachmentUrls="http://example.com/a.jpg",
- )
- result = svc.create_apply(
- db, "t1", _user("u-admin"), payload, mine_vehicles=True
- )
- assert result.licensePlate == "鄂A99999"
- assert result.applicantId == "u-admin"
- def test_update_cancel_submit_require_own_applicant(monkeypatch):
- from fastapi import HTTPException
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_person_vehicle(db)
- _seed_apply(
- db, apply_id="a1", plate="鄂A11111", applicant_id="u-office", status="draft"
- )
- db.commit()
- monkeypatch.setattr(svc, "assert_pl_row_in_scope", lambda *_a, **_k: None)
- monkeypatch.setattr(svc, "_resolve_user_name", lambda *_a, **_k: "X")
- with pytest.raises(HTTPException) as ei:
- svc.cancel_apply(db, "t1", _user(), "a1", mine_vehicles=True)
- assert ei.value.status_code == 403
- def test_admin_cancel_still_requires_own_applicant(monkeypatch):
- from fastapi import HTTPException
- from app.services import pl_vehicle_recharge_service as svc
- db = _make_session()
- _seed_admin_role(db, user_id="u-admin")
- _seed_apply(
- db, apply_id="a1", plate="鄂A99999", applicant_id="u-office", status="draft"
- )
- db.commit()
- monkeypatch.setattr(svc, "_resolve_user_name", lambda *_a, **_k: "X")
- with pytest.raises(HTTPException) as ei:
- svc.cancel_apply(db, "t1", _user("u-admin"), "a1", mine_vehicles=True)
- assert ei.value.status_code == 403
|