feat(platform): close AI expense value loop
Add tenant-safe value, telemetry, connector, commercial, and production-readiness foundations.
This commit is contained in:
@@ -32,7 +32,7 @@ def build_session() -> Session:
|
||||
|
||||
def test_employee_directory_seeds_rich_employee_data() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
|
||||
employees = service.list_employees()
|
||||
meta = service.get_employee_meta()
|
||||
@@ -59,7 +59,7 @@ def test_employee_directory_seeds_rich_employee_data() -> None:
|
||||
|
||||
def test_employee_detail_contains_department_and_roles() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
detail = service.get_employee(employee.id)
|
||||
|
||||
@@ -72,7 +72,7 @@ def test_employee_detail_contains_department_and_roles() -> None:
|
||||
|
||||
def test_update_employee_persists_changes_and_hashes_password() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
|
||||
updated = service.update_employee(
|
||||
@@ -115,7 +115,7 @@ def test_update_employee_persists_changes_and_hashes_password() -> None:
|
||||
|
||||
def test_disable_employee_marks_status_and_logs_change() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = next(item for item in service.list_employees() if item.status != "停用")
|
||||
|
||||
updated = service.disable_employee(employee.id)
|
||||
@@ -131,7 +131,7 @@ def test_disable_employee_marks_status_and_logs_change() -> None:
|
||||
|
||||
def test_enable_employee_restores_status_and_logs_change() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = next(item for item in service.list_employees() if item.status != "停用")
|
||||
service.disable_employee(employee.id)
|
||||
|
||||
@@ -148,7 +148,7 @@ def test_enable_employee_restores_status_and_logs_change() -> None:
|
||||
|
||||
def test_profile_repairs_do_not_run_on_every_list() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
|
||||
updated = service.update_employee(
|
||||
@@ -163,7 +163,7 @@ def test_profile_repairs_do_not_run_on_every_list() -> None:
|
||||
|
||||
def test_role_update_appends_recent_history() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
current_codes = list(employee.roleCodes)
|
||||
next_codes = ["finance", "user"] if "finance" not in current_codes else ["user"]
|
||||
@@ -175,7 +175,7 @@ def test_role_update_appends_recent_history() -> None:
|
||||
|
||||
def test_employee_change_logs_keep_only_latest_five() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
persisted = db.get(Employee, employee.id)
|
||||
assert persisted is not None
|
||||
@@ -198,7 +198,7 @@ def test_employee_change_logs_keep_only_latest_five() -> None:
|
||||
|
||||
def test_employee_meta_includes_organization_options() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
meta = service.get_employee_meta()
|
||||
|
||||
assert meta.organizationOptions
|
||||
@@ -215,7 +215,7 @@ def test_employee_meta_includes_organization_options() -> None:
|
||||
|
||||
def test_employee_directory_normalizes_legacy_departments() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
service.list_employees()
|
||||
|
||||
legacy_department = OrganizationUnit(
|
||||
@@ -239,11 +239,17 @@ def test_employee_directory_normalizes_legacy_departments() -> None:
|
||||
assert refreshed.organization is not None
|
||||
assert refreshed.organization.code == "TECH-DEPT"
|
||||
assert "RND-CENTER" not in {item.code for item in meta.organizationOptions}
|
||||
persisted = db.execute(
|
||||
select(Employee).where(Employee.employee_no == "E11745")
|
||||
).scalar_one()
|
||||
assert persisted.tenant_id == "default"
|
||||
assert persisted.organization_unit is not None
|
||||
assert persisted.organization_unit.unit_code == "TECH-DEPT"
|
||||
|
||||
|
||||
def test_update_employee_changes_organization() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
organizations = service.repository.list_organization_units()
|
||||
current_code = employee.organization.code if employee.organization else None
|
||||
@@ -266,7 +272,7 @@ def test_update_employee_changes_organization() -> None:
|
||||
|
||||
def test_update_employee_rejects_unknown_organization() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
|
||||
with pytest.raises(ValueError, match="部门编码"):
|
||||
@@ -278,7 +284,7 @@ def test_update_employee_rejects_unknown_organization() -> None:
|
||||
|
||||
def test_update_employee_changes_manager() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employees = service.list_employees()
|
||||
employee = employees[0]
|
||||
manager = next(item for item in employees if item.id != employee.id)
|
||||
@@ -302,7 +308,7 @@ def test_format_history_datetime_uses_local_timezone_without_seconds() -> None:
|
||||
|
||||
def test_update_employee_rejects_invalid_date_format() -> None:
|
||||
with build_session() as db:
|
||||
service = EmployeeService(db)
|
||||
service = EmployeeService(db, tenant_id="default")
|
||||
employee = service.list_employees()[0]
|
||||
|
||||
with pytest.raises(ValueError, match="出生日期格式必须为 YYYY-MM-DD。"):
|
||||
|
||||
Reference in New Issue
Block a user