CI / test (push) Canceled after 0s
## Summary epic r04 - begin refactor ## Change Type - [x] Cowork feature - [ ] Bug fix - [ ] Core AI contribution - [ ] Test / hardening - [ ] Performance - [ ] Documentation ## Related Work Cowork Task: Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets Core AI Issue: Core Task: Related PR: ## Scope What is intentionally included? What is intentionally NOT included? ## Validation - [ ] Unit tests - [ ] Integration tests - [ ] Manual verification - [ ] Regression check Commands / evidence: ## Security Impact Permission / credential / network / customer data impact: ## Compatibility - [ ] No breaking change - [ ] Breaking change documented ## Reviewer Notes Anything Cowork reviewers should pay attention to. --------- Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com> Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com> Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com> Co-authored-by: Vu Dam Tuan <vudt15@fpt.com> Co-authored-by: Hiep Ha Van <hiephv3@fpt.com> Co-authored-by: Lam Hoang Van <lamhv7@fpt.com> Reviewed-on: #7 Co-authored-by: Duy Le Huu <duylh19@fpt.com>
103 lines
4.4 KiB
Python
103 lines
4.4 KiB
Python
"""Smoke test cho ``presentation.co4e.co4e_tab.build_co4e_tab`` — gọi thật
|
|
factory, dựng thật ``Co4ETab``, xác nhận nó không vỡ.
|
|
|
|
Vì sao chạy trong tiến trình con thay vì import thẳng trong tiến trình pytest
|
|
chính: ``CONFIG_DIR`` (config.py) và ``CO4E_DIR`` (core/co4e.py) đều là hằng số
|
|
module tính MỘT LẦN lúc import từ ``Path.home()``. Nhiều file test khác trong
|
|
bộ này (chạy trước theo thứ tự collect) đã import ``cowork_local.config``/
|
|
``cowork_local.core.co4e`` với HOME thật rồi — monkeypatch thuộc tính module
|
|
(cách ``tests/characterization/test_co4e_run_manager_behavior.py`` dùng cho
|
|
``CO4E_DIR``) chỉ vá được đúng chỗ đó, còn ``AppConfig.load()`` có thêm một bẫy
|
|
riêng: tham số mặc định ``path: Path = CONFIG_PATH`` được gán MỘT LẦN lúc định
|
|
nghĩa hàm, nên monkeypatch ``CONFIG_PATH`` sau đó không đổi được giá trị mặc
|
|
định đã đóng băng — gọi ``AppConfig.load()`` không tham số vẫn đọc file thật
|
|
dù đã vá module. Dựng ``Co4ETab`` thật kéo theo cả hai đường trên (và có thể
|
|
còn đường khác chưa biết, vì lớp này 2000+ dòng). Cô lập bằng biến môi trường
|
|
``HOME``/``USERPROFILE`` TRƯỚC bất kỳ import nào, trong một tiến trình con
|
|
sạch hoàn toàn, né được toàn bộ lớp bẫy này một lần — không cần biết hết mọi
|
|
hằng số tính lúc import ở đâu trong file 2000+ dòng đó.
|
|
|
|
Bắt được gì: đổi sai độ sâu dấu chấm ở import tương đối trong
|
|
``presentation/co4e/co4e_tab.py`` (``from ...ui.co4e_tab import Co4ETab``),
|
|
đổi chữ ký ``Co4ETab.__init__`` mà quên sửa lệnh gọi trong factory, hoặc
|
|
factory trả sai kiểu/sai ``ctx`` — không có test nào khác trong bộ này gọi
|
|
``build_co4e_tab()``, nên đây là lưới an toàn DUY NHẤT cho hàm này.
|
|
|
|
KHÔNG chạm dữ liệu thật: sandbox trống hoàn toàn, không copy
|
|
``~/.cowork_local`` thật (khác ``tools/capture_screens.py::_isolate_home()`` —
|
|
ở đó cố tình copy để chụp ảnh có dữ liệu mẫu; ở đây không cần, càng sạch càng
|
|
tốt cho một smoke test).
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import os
|
|
import subprocess
|
|
import sys
|
|
from pathlib import Path
|
|
|
|
REPO_ROOT = Path(__file__).resolve().parent.parent
|
|
REPO_PARENT = REPO_ROOT.parent
|
|
|
|
_SMOKE_SCRIPT = """
|
|
import sys
|
|
sys.path.insert(0, {repo_parent!r})
|
|
|
|
from PySide6.QtWidgets import QApplication, QWidget
|
|
|
|
from cowork_local.config import AppConfig, CONFIG_DIR
|
|
from cowork_local.state import AppContext
|
|
from cowork_local.presentation.co4e.co4e_tab import build_co4e_tab
|
|
|
|
sandbox = sys.argv[1]
|
|
assert str(CONFIG_DIR).startswith(sandbox), "khong co lap: CONFIG_DIR=" + str(CONFIG_DIR)
|
|
|
|
app = QApplication([])
|
|
ctx = AppContext(AppConfig.load())
|
|
|
|
|
|
class _FakeWorkflowService:
|
|
\"\"\"Chua dung toi trong than ham build_co4e_tab hien tai (xem docstring
|
|
cua factory) - chi can mot doi tuong bat ky de kiem factory nhan dung
|
|
tham so bat buoc thu hai.\"\"\"
|
|
|
|
|
|
widget = build_co4e_tab(ctx, _FakeWorkflowService())
|
|
assert isinstance(widget, QWidget), "khong phai QWidget: " + repr(type(widget))
|
|
assert widget.ctx is ctx, "factory khong gan dung ctx cho widget tra ve"
|
|
print("SMOKE_OK")
|
|
"""
|
|
|
|
|
|
def test_build_co4e_tab_dung_that_va_gan_dung_ctx(tmp_path):
|
|
sandbox = tmp_path / "home"
|
|
sandbox.mkdir()
|
|
|
|
env = dict(os.environ)
|
|
env["HOME"] = str(sandbox)
|
|
env["USERPROFILE"] = str(sandbox)
|
|
env["QT_QPA_PLATFORM"] = "offscreen"
|
|
env.pop("HOMEDRIVE", None)
|
|
env.pop("HOMEPATH", None)
|
|
|
|
script = _SMOKE_SCRIPT.format(repo_parent=str(REPO_PARENT))
|
|
result = subprocess.run(
|
|
[sys.executable, "-c", script, str(sandbox)],
|
|
cwd=str(REPO_ROOT),
|
|
env=env,
|
|
capture_output=True,
|
|
text=True,
|
|
timeout=60,
|
|
)
|
|
|
|
assert result.returncode == 0, (
|
|
f"smoke build_co4e_tab that bai (exit {result.returncode}):\n"
|
|
f"--- stdout ---\n{result.stdout}\n--- stderr ---\n{result.stderr}"
|
|
)
|
|
assert "SMOKE_OK" in result.stdout, result.stdout
|
|
|
|
# Sandbox khong duoc dung: chua co gi ghi vao no truoc khi tien trinh con
|
|
# chay (con AppConfig.load() khong ghi gi ca - chi save() moi ghi).
|
|
assert not (sandbox / ".cowork_local").exists(), (
|
|
"AppConfig.load() khong duoc tu tao thu muc config that trong sandbox"
|
|
)
|