实现侧: - 上下文:任务范围拆分为 范围校验/范围授权;索引按可发现口径重建、索引新鲜度改对称差;依赖校验统一快照漂移说明。 - 知识方法:方法与材料读取口径统一;超限方法材料按可选省略,核对路径不再二次计费;删除无合同的读时重算。 - 任务运行:新增 context.usage/tool.denied 事件类型;连接池常驻并在装配生命周期内开关;调用结算与核对分列。 - 效果评测/审校修订/交付连载/作者经验/作品规划:凭据冻结、标定消费、导出补证、事实引文核对等收尾修复。 - 资源加载:能力正文不再夹带索引用的导航注记(该注记此前进入角色与技能的模型提示)。 - 元数据:受保护骨架与代码保护属性对齐;字段校验与内置结构口径同步。 - 基础设施:环境预检进入装配生命周期;数据库连接运行期字段不参与相等比较;索引指纹归一化 jsonb 浮点。 - 删除被替代实现:7 份旧提示词模板与空壳 资料来源 读取器。 用例侧: - 用例身份与导航元信息迁移;夹具补生命周期、同库暴露与模板封存; - 本轮定向修复:方法材料省略、事实引文、迁移回执、额度与暂停用例、慢用例超时预算等。
138 lines
5.1 KiB
Python
138 lines
5.1 KiB
Python
"""当前用途与历史内容独立;重导入不会复活撤权。"""
|
|
|
|
from dataclasses import replace
|
|
from types import SimpleNamespace
|
|
|
|
import pytest
|
|
|
|
from muse.资料研究 import 来源导入, 来源授权
|
|
from muse.资料研究.接口 import 资料服务
|
|
from muse.资料研究.来源授权 import 授权写入, 来源用途变更
|
|
from muse.资料研究.模型 import 导入请求, 资料错误
|
|
|
|
源ID = "12345678-1234-1234-1234-123456789abc"
|
|
|
|
|
|
@pytest.fixture
|
|
def 授权环境(monkeypatch):
|
|
状态 = {"authorized_uses": ["analysis", "sample"], "authorization_revision": 1}
|
|
更新 = []
|
|
monkeypatch.setattr(来源授权, "读取当前授权", lambda *a: dict(状态))
|
|
|
|
class 存储:
|
|
def __init__(self, 连):
|
|
pass
|
|
|
|
def 查询(self, sql, params):
|
|
uses, source_id, revision = params
|
|
assert source_id == 源ID and revision == 状态["authorization_revision"]
|
|
更新.append(tuple(uses.obj))
|
|
状态.update(authorized_uses=uses.obj, authorization_revision=revision + 1)
|
|
return SimpleNamespace(fetchone=lambda: dict(状态))
|
|
|
|
monkeypatch.setattr(来源授权, "资料存储", 存储)
|
|
return 状态, 更新
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-REVOKE")
|
|
def test_用途可减少或清空且不变请求不升版(授权环境):
|
|
状态, 更新 = 授权环境
|
|
请求 = 来源用途变更(源ID, 1, ("analysis",), "撤回样本")
|
|
提交 = 来源授权.来源授权参与者().提交
|
|
assert 提交(None, 授权写入("author", 请求))["authorization_revision"] == 2
|
|
assert 状态["authorized_uses"] == ["analysis"]
|
|
同值 = replace(请求, expected_authorization_revision=2)
|
|
assert 提交(None, 授权写入("author", 同值))["no_change"]
|
|
with pytest.raises(资料错误, match="版本已改变"):
|
|
提交(None, 授权写入("author", 请求))
|
|
全撤 = replace(同值, uses=(), reason="撤回全部")
|
|
assert 提交(None, 授权写入("author", 全撤))["authorization_revision"] == 3
|
|
assert 更新 == [("analysis",), ()]
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-REIMPORT")
|
|
def test_旧导入请求不复活授权(monkeypatch):
|
|
calls = []
|
|
|
|
class 存储:
|
|
def __init__(self, 连):
|
|
pass
|
|
|
|
def 锁来源导入(self, *a):
|
|
calls.append("lock-origin")
|
|
|
|
def 查源(self, *a):
|
|
return {"source_id": 源ID, "authorized_uses": ["analysis"]}
|
|
|
|
def 锁当前来源版本(self, *a):
|
|
calls.append("lock-source")
|
|
|
|
def 建源(self, *a):
|
|
pytest.fail("已有来源重导入不得写授权")
|
|
|
|
def 写版本(self, *a):
|
|
pytest.fail("冲突请求不得写版本")
|
|
|
|
monkeypatch.setattr(来源导入, "资料存储", 存储)
|
|
with pytest.raises(资料错误, match="重导入不能修改"):
|
|
来源导入.导入来源(
|
|
None,
|
|
"author",
|
|
导入请求("reference", "样例", "fixture://source", "合成文字", ("analysis", "sample")),
|
|
)
|
|
assert calls == ["lock-origin", "lock-source"]
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-SAMPLE")
|
|
def test_撤回sample保留analysis只返回定位哈希(monkeypatch):
|
|
import muse.资料研究.接口 as 接口
|
|
|
|
服务 = 资料服务()
|
|
|
|
def 核对(连, source, purpose):
|
|
if purpose == "sample":
|
|
raise 资料错误("撤回sample")
|
|
return {"authorized_uses": ["analysis"], "authorization_revision": 2}
|
|
|
|
monkeypatch.setattr(服务, "核对来源授权", 核对)
|
|
monkeypatch.setattr(
|
|
服务,
|
|
"读取版本",
|
|
lambda *a, **k: {
|
|
"import_result": {"导入者": "author"},
|
|
"content": "合成文字",
|
|
"content_hash": "hash",
|
|
},
|
|
)
|
|
monkeypatch.setattr(服务, "读取当前版本号", lambda *a: 1)
|
|
monkeypatch.setattr(接口, "读取证据", lambda *a: {"片段": "合成"})
|
|
结果 = 服务.读取案例证据(None, "author", 源ID, 1, 0, 2)
|
|
assert 结果["excerpt"] is None and 结果["context"] is None and not 结果["text_allowed"]
|
|
assert 结果["excerpt_hash"] and 结果["current_revision"] == 1
|
|
|
|
|
|
@pytest.mark.case_id("NC-O09-HTTP-AUTH")
|
|
def test_HTTP授权动作调用同一具名服务():
|
|
from unittest.mock import patch
|
|
|
|
import muse.接入.http.路由.资料研究 as 模块
|
|
from muse.接入.http.路由.资料研究 import 变更来源用途, 来源授权请求
|
|
|
|
calls = []
|
|
服务 = SimpleNamespace(
|
|
变更来源用途=lambda *args: calls.append(args) or {"receipt_id": "receipt"}
|
|
)
|
|
装配 = SimpleNamespace(配置=None, 要求资料=lambda: 服务)
|
|
request = SimpleNamespace(app=SimpleNamespace(state=SimpleNamespace(装配=装配)))
|
|
with patch.object(模块, "创作身份", lambda *a: "identity"):
|
|
result = 变更来源用途(
|
|
源ID,
|
|
来源授权请求(
|
|
command_id="revoke", expected_authorization_revision=2, uses=[], reason="撤回"
|
|
),
|
|
request,
|
|
"author",
|
|
)
|
|
assert result == {"receipt_id": "receipt"}
|
|
assert calls == [("identity", "revoke", 来源用途变更(源ID, 2, (), "撤回"))]
|