"""安装入口在仓外启动;HTTP推进真实S02导出并下载实际字节。""" import hashlib import json import os import subprocess import sys from dataclasses import asdict import pytest import test_偏好实际消费 as 浏览器测试 import test_定稿与导出 as 定稿测试 import test_生产评测权限隔离 as 接入测试 from fastapi.testclient import TestClient from muse.接入.http.应用 import 创建应用 from muse.配置 import 读取配置 pytestmark = pytest.mark.数据库 候选环境 = 定稿测试.候选环境 交付环境 = 定稿测试.交付环境 @pytest.mark.case_id( "NC-w27-27e001", environment="隔离PG", given="本作者完整目录、确切正文版本与独立隔离数据", when="通过定稿、S02导出、跨章候选或连载反馈实际入口执行并检查失败恢复", then=["CLI仓外定稿与HTTP导出推进下载真实文件"], contract="docs/系统架构/新版设计/模块设计/B08-交付连载.md", ) def test_CLI仓外定稿与HTTP导出推进下载真实文件__27e001(交付环境, tmp_path): app, author, pools, req = 交付环境 config = 接入测试._配置文件(pools[author.用途], tmp_path) config.write_text(config.read_text().replace("eval-author", author.作者)) request = tmp_path / "freeze.json" request.write_text(json.dumps({"command_id": "cli-freeze", "delivery": asdict(req)})) process = subprocess.run( [sys.executable, "-m", "muse", "交付", str(config), "冻结", str(request)], cwd=tmp_path, text=True, capture_output=True, timeout=30, ) assert process.returncode == 0, process.stderr assert json.loads(process.stdout)["results"][0]["delivery_id"] == req.delivery_id with TestClient(创建应用(读取配置(config)), headers={"origin": "http://testserver"}) as client: assert ( client.post( "/api/v1/session", json={"password": "synthetic-evaluation-only"}, ).status_code == 200 ) path = "/api/v1/deliveries/" + req.delivery_id result = client.post( path + "/exports", json={ "command_id": "http-export", "formats": ["txt", "md", "docx", "epub"], }, ) assert result.status_code == 200, result.text tid = result.json()["task_id"] advanced = client.post(path + "/exports/" + tid + "/advance") assert advanced.status_code == 200, advanced.text assert advanced.json()["state"] == "completed" for fmt in ("txt", "md", "docx", "epub"): downloaded = client.get(path + "/files/" + fmt) assert downloaded.status_code == 200, downloaded.text digest = hashlib.sha256(downloaded.content).hexdigest() assert downloaded.headers["etag"] == '"' + digest + '"' assert app.要求交付().读取导出(author, req.delivery_id, fmt)["content_hash"] == digest file = tmp_path / "download.json" file.write_text(json.dumps({"delivery_id": req.delivery_id, "format": "txt"})) output = tmp_path / "原样交付.txt" cmd = [ sys.executable, "-m", "muse", "交付", str(config), "下载", str(file), "--输出", str(output), ] first = subprocess.run(cmd, cwd=tmp_path, capture_output=True, text=True, timeout=30) assert first.returncode == 0, first.stderr original = output.read_bytes() assert original.startswith("雨中旧事\n\n合成作者".encode()) refused = subprocess.run(cmd, cwd=tmp_path, capture_output=True, text=True, timeout=30) assert refused.returncode != 0 and output.read_bytes() == original if os.environ.get("MUSE_RUN_BROWSER") == "1": 浏览器测试._浏览器偏好(读取配置(config), req.work_id, tmp_path, "定稿连载.spec.ts") workspace = app.要求交付().连载工作面(author, req.work_id) assert len(workspace["releases"]) == 1 assert len(workspace["feedback"]) == 2 assert {x["payload"]["association"] for x in workspace["feedback"]} == { "explicit", "unlinked", }