Add dark theme, richer Markdown and readable plugin results. Improve Android input evidence, response integrity and diagnostics. Unify lifecycle, guidance receipts and evidence sources across clients. Keep direct action dispatch without an added AI quota approval layer. Align version metadata at 2.2.0 and bundle Helper 1.2.2. Validation: 3063 backend tests before the version bump; 44 after. Frontend: 317 tests and production build passed.
106 lines
3.4 KiB
Python
106 lines
3.4 KiB
Python
from copy import deepcopy
|
|
|
|
from artemis.data_engine.evidence_sources import recorded_sources
|
|
|
|
|
|
def record(kind, target, **extra):
|
|
return {
|
|
"plugin_id": "adapter",
|
|
"source": {"kind": kind, "target_id": target, "label": "安卓业务后台"},
|
|
**extra,
|
|
}
|
|
|
|
|
|
def test_business_backend_name_does_not_become_an_execution_platform_or_assertion():
|
|
steps = [
|
|
{
|
|
"step_id": "step-real-id",
|
|
"step_number": 7,
|
|
"last_execution_result": {
|
|
"execution": [record("api", "backend", call_id="call-real-id", read_only=True)]
|
|
},
|
|
}
|
|
]
|
|
before = deepcopy(steps)
|
|
value = recorded_sources(steps)
|
|
source = value["sources"][0]
|
|
assert source["kind"] == "api"
|
|
assert source["category"] == "auxiliary"
|
|
assert source["references"] == [
|
|
{"step_id": "step-real-id", "step_number": 7, "call_id": "call-real-id", "read_only": True}
|
|
]
|
|
assert not any(key in source for key in ("passed", "verified", "verdict"))
|
|
assert steps == before
|
|
|
|
|
|
def test_sources_remain_separate_and_references_use_host_ids():
|
|
steps = [
|
|
{
|
|
"step_id": "s1",
|
|
"step_number": 1,
|
|
"action_taken": record("computer", "window", call_id="c1"),
|
|
},
|
|
{
|
|
"step_id": "s2",
|
|
"step_number": 2,
|
|
"action_taken": record("computer", "window", call_id="c2"),
|
|
},
|
|
{
|
|
"step_id": "s3",
|
|
"step_number": 3,
|
|
"action_taken": record("android", "phone", call_id="c3"),
|
|
},
|
|
]
|
|
value = recorded_sources(steps)
|
|
assert value["total_sources"] == 2
|
|
assert value["sources"][0]["reference_count"] == 2
|
|
assert [r["call_id"] for r in value["sources"][0]["references"]] == ["c1", "c2"]
|
|
assert value["sources"][0]["id"] == recorded_sources(steps[:1])["sources"][0]["id"]
|
|
assert value["sources"][1]["category"] == "interface"
|
|
|
|
|
|
def test_model_arguments_and_unsourced_images_do_not_fabricate_source_metadata():
|
|
value = recorded_sources(
|
|
[
|
|
{
|
|
"step_id": "s",
|
|
"step_number": 3,
|
|
"pre_image_name": "hash",
|
|
"action_taken": {"args": {"source": {"kind": "computer", "target_id": "claim"}}},
|
|
}
|
|
]
|
|
)
|
|
assert value["sources"] == []
|
|
assert value["unattributed_references"] == [{"step_id": "s", "step_number": 3}]
|
|
|
|
|
|
def test_summary_is_bounded_and_reports_omissions_explicitly():
|
|
steps = [{"step_id": str(i), "action_taken": record("file", str(i))} for i in range(10)]
|
|
value = recorded_sources(steps, limit=2)
|
|
assert len(value["sources"]) == 2
|
|
assert value["total_sources"] == 10
|
|
assert value["sources_omitted"] == 8
|
|
repeated = recorded_sources(
|
|
[{"step_id": str(i), "action_taken": record("api", "one")} for i in range(20)]
|
|
)
|
|
assert len(repeated["sources"][0]["references"]) == 8
|
|
assert repeated["sources"][0]["reference_count"] == 20
|
|
|
|
|
|
def test_partial_source_metadata_does_not_hide_unknown_actions_in_the_same_step():
|
|
value = recorded_sources(
|
|
[
|
|
{
|
|
"step_id": "mixed",
|
|
"last_execution_result": {
|
|
"execution": [
|
|
record("api", "service"),
|
|
{"action": "tap"},
|
|
]
|
|
},
|
|
}
|
|
]
|
|
)
|
|
assert value["total_sources"] == 1
|
|
assert value["unattributed_step_count"] == 1
|