test: 添加规则服务与电子表格变更记录的测试用例
- AgentAssetService 测试覆盖版本创建、送审、审核通过等流程 - 新增电子表格变更记录的前端测试
This commit is contained in:
@@ -25,10 +25,12 @@ from app.schemas.agent_asset import (
|
|||||||
AgentAssetReviewCreate,
|
AgentAssetReviewCreate,
|
||||||
AgentAssetVersionCreate,
|
AgentAssetVersionCreate,
|
||||||
)
|
)
|
||||||
|
from app.api.deps import CurrentUserContext
|
||||||
from app.services.agent_assets import AgentAssetService
|
from app.services.agent_assets import AgentAssetService
|
||||||
from app.services.agent_runs import AgentRunService
|
from app.services.agent_runs import AgentRunService
|
||||||
from app.services.audit import AuditLogService
|
from app.services.audit import AuditLogService
|
||||||
from app.services.expense_rule_runtime import ExpenseRuleRuntimeService
|
from app.services.expense_rule_runtime import ExpenseRuleRuntimeService
|
||||||
|
from app.services.settings import OnlyOfficeRuntimeConfig
|
||||||
|
|
||||||
|
|
||||||
def build_session() -> Session:
|
def build_session() -> Session:
|
||||||
@@ -173,6 +175,36 @@ def test_rule_working_version_does_not_replace_published_version_until_activatio
|
|||||||
assert detail.latest_review is None
|
assert detail.latest_review is None
|
||||||
|
|
||||||
|
|
||||||
|
def test_pending_review_can_name_new_working_version_before_submission() -> None:
|
||||||
|
with build_session() as db:
|
||||||
|
service = AgentAssetService(db)
|
||||||
|
rule = next(
|
||||||
|
item
|
||||||
|
for item in service.list_assets(asset_type=AgentAssetType.RULE.value)
|
||||||
|
if item.code == "rule.expense.travel_risk_control_standard"
|
||||||
|
)
|
||||||
|
|
||||||
|
review = service.create_review(
|
||||||
|
rule.id,
|
||||||
|
AgentAssetReviewCreate(
|
||||||
|
version="v1.2.0",
|
||||||
|
reviewer="manager_user",
|
||||||
|
review_status=AgentReviewStatus.PENDING,
|
||||||
|
review_note="请审核",
|
||||||
|
),
|
||||||
|
actor="finance_user",
|
||||||
|
)
|
||||||
|
detail = service.get_asset(rule.id)
|
||||||
|
|
||||||
|
assert review.version == "v1.2.0"
|
||||||
|
assert detail is not None
|
||||||
|
assert detail.current_version == "v1.2.0"
|
||||||
|
assert detail.working_version == "v1.2.0"
|
||||||
|
assert detail.published_version == "v1.1.0"
|
||||||
|
assert detail.latest_review is not None
|
||||||
|
assert detail.latest_review.reviewer == "manager_user"
|
||||||
|
|
||||||
|
|
||||||
def test_expense_rule_runtime_uses_published_version_instead_of_working_version() -> None:
|
def test_expense_rule_runtime_uses_published_version_instead_of_working_version() -> None:
|
||||||
with build_session() as db:
|
with build_session() as db:
|
||||||
service = AgentAssetService(db)
|
service = AgentAssetService(db)
|
||||||
@@ -296,6 +328,78 @@ def test_working_spreadsheet_version_reads_immutable_snapshot_instead_of_live_co
|
|||||||
live_path.write_bytes(original_live_bytes)
|
live_path.write_bytes(original_live_bytes)
|
||||||
|
|
||||||
|
|
||||||
|
def test_spreadsheet_change_records_return_recent_edit_details() -> None:
|
||||||
|
with build_session() as db:
|
||||||
|
service = AgentAssetService(db)
|
||||||
|
rule = next(
|
||||||
|
item
|
||||||
|
for item in service.list_assets(asset_type=AgentAssetType.RULE.value)
|
||||||
|
if item.code == "rule.expense.company_travel_expense_reimbursement"
|
||||||
|
)
|
||||||
|
service.audit_service.log_action(
|
||||||
|
actor="manager_user",
|
||||||
|
action="edit_rule_spreadsheet",
|
||||||
|
resource_type=rule.asset_type,
|
||||||
|
resource_id=rule.id,
|
||||||
|
after_json={
|
||||||
|
"summary": "在线编辑:共 1 处改动。",
|
||||||
|
"changed_sheet_count": 1,
|
||||||
|
"changed_cell_count": 1,
|
||||||
|
"sheet_changes": [],
|
||||||
|
"cell_changes": [
|
||||||
|
{
|
||||||
|
"sheet_name": "规则表",
|
||||||
|
"cell": "B2",
|
||||||
|
"change_type": "modified",
|
||||||
|
"before_value": 500,
|
||||||
|
"after_value": 550,
|
||||||
|
}
|
||||||
|
],
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
records = service.list_spreadsheet_change_records(rule.id)
|
||||||
|
|
||||||
|
assert len(records) == 1
|
||||||
|
assert records[0].actor == "manager_user"
|
||||||
|
assert records[0].changed_cell_count == 1
|
||||||
|
assert records[0].cell_changes[0].cell == "B2"
|
||||||
|
|
||||||
|
|
||||||
|
def test_editable_spreadsheet_onlyoffice_config_enables_forcesave(monkeypatch) -> None:
|
||||||
|
with build_session() as db:
|
||||||
|
monkeypatch.setattr(
|
||||||
|
"app.services.agent_assets.resolve_onlyoffice_settings",
|
||||||
|
lambda: OnlyOfficeRuntimeConfig(
|
||||||
|
enabled=True,
|
||||||
|
public_url="http://onlyoffice.example.com",
|
||||||
|
backend_url="http://backend.example.com",
|
||||||
|
jwt_secret="secret",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
service = AgentAssetService(db)
|
||||||
|
rule = next(
|
||||||
|
item
|
||||||
|
for item in service.list_assets(asset_type=AgentAssetType.RULE.value)
|
||||||
|
if item.code == "rule.expense.company_travel_expense_reimbursement"
|
||||||
|
)
|
||||||
|
|
||||||
|
config = service.build_rule_spreadsheet_onlyoffice_config(
|
||||||
|
rule.id,
|
||||||
|
CurrentUserContext(
|
||||||
|
username="finance_user",
|
||||||
|
name="财务人员",
|
||||||
|
role_codes=["finance"],
|
||||||
|
is_admin=False,
|
||||||
|
),
|
||||||
|
)
|
||||||
|
|
||||||
|
customization = config.config["editorConfig"]["customization"]
|
||||||
|
assert config.config["editorConfig"]["mode"] == "edit"
|
||||||
|
assert customization["forcesave"] is True
|
||||||
|
|
||||||
|
|
||||||
def test_version_timeline_contains_created_review_and_publish_events() -> None:
|
def test_version_timeline_contains_created_review_and_publish_events() -> None:
|
||||||
with build_session() as db:
|
with build_session() as db:
|
||||||
service = AgentAssetService(db)
|
service = AgentAssetService(db)
|
||||||
|
|||||||
92
web/tests/spreadsheet-change-records.test.mjs
Normal file
92
web/tests/spreadsheet-change-records.test.mjs
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
import assert from 'node:assert/strict'
|
||||||
|
|
||||||
|
import {
|
||||||
|
buildSpreadsheetChangeRecords,
|
||||||
|
resolveSpreadsheetOperationLabel
|
||||||
|
} from '../src/views/scripts/spreadsheetChangeRecords.js'
|
||||||
|
|
||||||
|
function testResolveSpreadsheetOperationLabelFromHistorySource() {
|
||||||
|
assert.equal(
|
||||||
|
resolveSpreadsheetOperationLabel({
|
||||||
|
spreadsheetMeta: { source: 'onlyoffice' },
|
||||||
|
note: 'ONLYOFFICE 编辑保存规则表。'
|
||||||
|
}),
|
||||||
|
'在线编辑保存'
|
||||||
|
)
|
||||||
|
|
||||||
|
assert.equal(
|
||||||
|
resolveSpreadsheetOperationLabel({
|
||||||
|
spreadsheetMeta: { source: 'content-import' }
|
||||||
|
}),
|
||||||
|
'导入表格'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBuildSpreadsheetChangeRecordsPrefersUnpublishedHistory() {
|
||||||
|
const records = buildSpreadsheetChangeRecords({
|
||||||
|
publishedVersion: 'v1.0.0',
|
||||||
|
history: [
|
||||||
|
{
|
||||||
|
version: 'v1.0.1',
|
||||||
|
note: 'ONLYOFFICE 编辑保存规则表。',
|
||||||
|
createdBy: '张三',
|
||||||
|
createdAt: '2026-05-18T10:00:00Z',
|
||||||
|
isWorking: true,
|
||||||
|
spreadsheetMeta: { source: 'onlyoffice' }
|
||||||
|
},
|
||||||
|
{
|
||||||
|
version: 'v1.0.0',
|
||||||
|
note: '首个上线版本',
|
||||||
|
createdBy: '系统',
|
||||||
|
createdAt: '2026-05-18T09:00:00Z',
|
||||||
|
isWorking: false,
|
||||||
|
spreadsheetMeta: { source: 'upload' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
records.map((item) => [item.version, item.operationLabel]),
|
||||||
|
[['v1.0.1', '在线编辑保存']]
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
function testBuildSpreadsheetChangeRecordsKeepsPendingLocalEditFirst() {
|
||||||
|
const records = buildSpreadsheetChangeRecords({
|
||||||
|
publishedVersion: 'v1.0.0',
|
||||||
|
localRecords: [
|
||||||
|
{
|
||||||
|
version: 'v1.0.1',
|
||||||
|
operationLabel: '编辑中',
|
||||||
|
operationActor: '李四',
|
||||||
|
note: '检测到未保存的表格改动,保存后会生成新版本并可查看差异。',
|
||||||
|
time: '2026-05-18T10:30:00Z',
|
||||||
|
isPendingLocalEdit: true,
|
||||||
|
disabledReason: '当前是本地未保存修改,保存后才会生成可对比的版本。'
|
||||||
|
}
|
||||||
|
],
|
||||||
|
history: [
|
||||||
|
{
|
||||||
|
version: 'v1.0.1',
|
||||||
|
note: 'ONLYOFFICE 编辑保存规则表。',
|
||||||
|
createdBy: '李四',
|
||||||
|
createdAt: '2026-05-18T10:00:00Z',
|
||||||
|
isWorking: true,
|
||||||
|
spreadsheetMeta: { source: 'onlyoffice' }
|
||||||
|
}
|
||||||
|
]
|
||||||
|
})
|
||||||
|
|
||||||
|
assert.equal(records[0].operationLabel, '编辑中')
|
||||||
|
assert.equal(records[0].isPendingLocalEdit, true)
|
||||||
|
assert.equal(records[1].operationLabel, '在线编辑保存')
|
||||||
|
}
|
||||||
|
|
||||||
|
function run() {
|
||||||
|
testResolveSpreadsheetOperationLabelFromHistorySource()
|
||||||
|
testBuildSpreadsheetChangeRecordsPrefersUnpublishedHistory()
|
||||||
|
testBuildSpreadsheetChangeRecordsKeepsPendingLocalEditFirst()
|
||||||
|
console.log('spreadsheet change record tests passed')
|
||||||
|
}
|
||||||
|
|
||||||
|
run()
|
||||||
Reference in New Issue
Block a user