fix(telegram): make Windows-unmasked tests cross-platform

Guarding the fcntl import let Windows collection succeed, which surfaced 3
telegram tests that had never run on Windows — all test-portability bugs:
- log_streamer byte-count broke on CRLF -> fixture writes newline=''
- bot_registry write-failure used Unix-only /proc -> file-as-parent (all OS)
- validate_bot_config rejected POSIX work_dir on Windows (Path.is_absolute is
  host-dependent) -> test absoluteness under PurePosixPath OR PureWindowsPath
493 telegram tests green on Linux; ruff clean.
This commit is contained in:
AIOSAI
2026-06-25 03:44:26 -07:00
parent ec6e966137
commit 7e9c0cfca7
4 changed files with 28 additions and 13 deletions
@@ -1,5 +1,5 @@
# Standard library
from pathlib import Path
from pathlib import PurePosixPath, PureWindowsPath
from typing import Optional, List
# Logging
@@ -208,8 +208,11 @@ def validate_bot_config(config: object) -> tuple[bool, str]:
return False, "bot_token must be a string in format 'id:hash'"
if "work_dir" in config and config["work_dir"] is not None:
work_dir = Path(config["work_dir"])
if not work_dir.is_absolute():
# work_dir is a deployment-target (Linux) path. Test absoluteness under
# POSIX *and* Windows semantics so validation is platform-independent —
# a bare host Path().is_absolute() would reject "/home/..." on Windows.
work_dir = str(config["work_dir"])
if not (PurePosixPath(work_dir).is_absolute() or PureWindowsPath(work_dir).is_absolute()):
return False, "work_dir must be an absolute path"
if "allowed_user_ids" in config:
@@ -6,7 +6,6 @@ No external dependencies beyond pytest.
"""
import json
from pathlib import Path
import pytest
from apps.handlers import bot_registry # type: ignore[import-not-found]
@@ -191,11 +190,15 @@ class TestSaveRegistry:
assert result is True
assert bot_registry.REGISTRY_DIR.is_dir()
def test_returns_false_on_write_failure(self, monkeypatch):
def test_returns_false_on_write_failure(self, monkeypatch, tmp_path):
"""Should return False when writing fails (e.g. permission error)."""
# Point to an impossible path
monkeypatch.setattr(bot_registry, "REGISTRY_DIR", Path("/proc/nonexistent/impossible"))
monkeypatch.setattr(bot_registry, "REGISTRY_FILE", Path("/proc/nonexistent/impossible/_registry.json"))
# Put a regular file where a directory is expected. mkdir(parents=True)
# then fails on every OS (NotADirectoryError/FileExistsError), so this is
# cross-platform — unlike a hardcoded Unix-only path such as /proc/...
blocker = tmp_path / "blocker"
blocker.write_text("x", encoding="utf-8")
monkeypatch.setattr(bot_registry, "REGISTRY_DIR", blocker / "sub")
monkeypatch.setattr(bot_registry, "REGISTRY_FILE", blocker / "sub" / "_registry.json")
result = bot_registry.save_registry({"bots": {}, "metadata": {}})
@@ -62,11 +62,13 @@ def streamer(logs_dir, tmp_path):
@pytest.fixture
def streamer_with_files(logs_dir, tmp_path):
"""Create a LogStreamer after pre-populating matching and non-matching log files."""
# Create matching log files with content
(logs_dir / "api_main.log").write_text("line1\nline2\n", encoding="utf-8")
(logs_dir / "api_error.log").write_text("err1\n", encoding="utf-8")
# Create matching log files with content. newline="" disables newline
# translation so byte counts match len() on Windows too (\n stays 1 byte,
# not \r\n) — real log files are LF-terminated.
(logs_dir / "api_main.log").write_text("line1\nline2\n", encoding="utf-8", newline="")
(logs_dir / "api_error.log").write_text("err1\n", encoding="utf-8", newline="")
# Create a non-matching file (should be ignored)
(logs_dir / "trigger_main.log").write_text("other\n", encoding="utf-8")
(logs_dir / "trigger_main.log").write_text("other\n", encoding="utf-8", newline="")
return _make_streamer(logs_dir, tmp_path)