公开数据看板、四位 Key 录入面板、管理后台与三级权限、动态字段配置、 PostgreSQL/SQLite 双支持、数据库备份,以及本版新增的成品图上传与预览。 图片相关: - 录入表单支持相册选图与手机端直接拍照,每条记录最多 6 张 - 浏览器内压缩到最长边 1600 并剥离 EXIF,入库统一为 JPG/PNG - 二进制直接入库,现有备份自动覆盖图片,部署无需新增卷 - 详情页缩略图宫格与全屏 lightbox,公开看板同样可见 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
46 lines
1.8 KiB
Python
46 lines
1.8 KiB
Python
from datetime import date
|
||
|
||
import pytest
|
||
from pydantic import ValidationError
|
||
|
||
from app.schemas import EntryRecordSubmission, MaterialRecordInput
|
||
|
||
|
||
def valid_payload():
|
||
return {
|
||
"experiment_id": "LAS-2026-001", "test_date": date(2026, 7, 17), "material_category": "木材", "material_name": "椴木板",
|
||
"material_thickness": 3, "actual_output_power": 8.5, "display_current": 2, "scanning_speed": 100,
|
||
"pulse_frequency": 20, "pulse_width": 5, "defocus_amount": 0, "scan_line_spacing": .1,
|
||
"filling_method": "双向", "processing_size": "20×20", "is_cut_through": True,
|
||
"carbonized_edge_width": .2, "etching_depth": 30, "is_fire_smolder": False,
|
||
"pattern_clarity_score": 9, "presentation_balance_score": 8, "finished_image_filename": "LAS-2026-001.jpg", "remarks": "正常",
|
||
}
|
||
|
||
|
||
def test_all_optional_physical_properties_may_be_empty():
|
||
record = MaterialRecordInput(**valid_payload())
|
||
assert record.apparent_density is None
|
||
assert record.hardness is None
|
||
assert len(record.model_fields) - 3 == 32 # 32 fixed fields plus the dynamic-field map and the two image lists
|
||
|
||
|
||
def test_scores_are_limited_to_ten():
|
||
payload = valid_payload()
|
||
payload["pattern_clarity_score"] = 10.1
|
||
with pytest.raises(ValidationError):
|
||
MaterialRecordInput(**payload)
|
||
|
||
|
||
def test_percentage_is_limited_to_hundred():
|
||
payload = valid_payload()
|
||
payload["moisture_content"] = 101
|
||
with pytest.raises(ValidationError):
|
||
MaterialRecordInput(**payload)
|
||
|
||
|
||
def test_entry_submission_requires_confirmation_username():
|
||
payload = valid_payload()
|
||
with pytest.raises(ValidationError):
|
||
EntryRecordSubmission(**payload)
|
||
assert EntryRecordSubmission(**payload, confirm_username="operator").confirm_username == "operator"
|