"""Проверки генерации Caddyfile и запуска.""" from app.launcher import MARK, ensure_caddyfile, render_caddyfile class TestRender: def test_domains_go_into_site_block(self): text = render_caddyfile("a.example.com, b.example.com", 8756, 500) assert "a.example.com, b.example.com {" in text def test_extra_spaces_and_empty_entries_are_dropped(self): text = render_caddyfile(" a.example.com ,, b.example.com ,", 8756, 500) assert "a.example.com, b.example.com {" in text def test_port_and_limit_come_from_settings(self): text = render_caddyfile("a.example.com", 9000, 250) assert "reverse_proxy 127.0.0.1:9000" in text assert "max_size 250MB" in text def test_xff_is_left_to_caddy_default(self): """Caddy сам игнорирует X-Forwarded-For от клиента и ставит реальный адрес. Свой header_up был лишним - Caddy предупреждал об этом при каждом запуске. Важнее обратное: trusted_proxies появляться не должен, иначе Caddy начнёт верить заголовку клиента и адрес станет подделываемым. """ # Комментарии не в счёт: в них эти слова упомянуты как предостережение. directives = "\n".join( line for line in render_caddyfile("a.example.com", 8756, 500).splitlines() if not line.strip().startswith("#")) assert "header_up" not in directives assert "trusted_proxies" not in directives def test_caddy_log_goes_to_file(self): """Иначе Caddy забивает консоль сообщениями про сертификаты.""" text = render_caddyfile("a.example.com", 8756, 500) assert "output file logs/caddy.log" in text def test_generated_file_is_marked(self): assert render_caddyfile("a.example.com", 8756, 500).startswith(MARK) def test_no_blank_line_before_global_block(self): """caddy fmt считает такой файл неформатированным и ругается при запуске.""" lines = render_caddyfile("a.example.com", 8756, 500).splitlines() assert lines[lines.index("{") - 1].strip() != "" class TestEnsure: def test_creates_file_when_missing(self, tmp_path): content = render_caddyfile("a.example.com", 8756, 500) written = ensure_caddyfile(tmp_path, content) assert written == tmp_path / "Caddyfile" assert written.read_text(encoding="utf-8") == content def test_overwrites_own_previous_version(self, tmp_path): ensure_caddyfile(tmp_path, render_caddyfile("old.example.com", 8756, 500)) fresh = render_caddyfile("new.example.com", 8756, 500) ensure_caddyfile(tmp_path, fresh) assert (tmp_path / "Caddyfile").read_text(encoding="utf-8") == fresh assert not (tmp_path / "Caddyfile.new").exists() def test_keeps_hand_written_file(self, tmp_path): """Чужой файл не трогаем: молча стереть настройку хуже, чем оставить старую.""" handmade = "site.example.com {\n\treverse_proxy 127.0.0.1:1234\n}\n" (tmp_path / "Caddyfile").write_text(handmade, encoding="utf-8") written = ensure_caddyfile(tmp_path, render_caddyfile("a.example.com", 8756, 500)) assert (tmp_path / "Caddyfile").read_text(encoding="utf-8") == handmade assert written == tmp_path / "Caddyfile.new" assert MARK in written.read_text(encoding="utf-8") def test_no_rewrite_when_nothing_changed(self, tmp_path): content = render_caddyfile("a.example.com", 8756, 500) ensure_caddyfile(tmp_path, content) before = (tmp_path / "Caddyfile").stat().st_mtime_ns assert ensure_caddyfile(tmp_path, content) is None assert (tmp_path / "Caddyfile").stat().st_mtime_ns == before class TestStartupOrder: def test_updater_runs_before_service(self, tmp_path, monkeypatch): """Обновиться нужно до запуска, иначе обновление бессмысленно.""" import app.launcher as launcher calls: list[str] = [] class FakeSettings: base_dir = tmp_path models_dir = tmp_path / "models" diarize = False port = 8756 max_upload_mb = 500 https_domains = "" monkeypatch.setattr("app.config.load_settings", lambda: FakeSettings()) monkeypatch.setattr("app.updater.main", lambda: calls.append("updater")) monkeypatch.setattr("app.models.ensure_models", lambda *a: []) monkeypatch.setitem( __import__("sys").modules, "app.main", type("M", (), {"run": staticmethod(lambda: calls.append("run"))})) assert launcher.main([]) == 0 assert calls == ["updater", "run"] def test_https_without_domains_stops_with_explanation(self, tmp_path, monkeypatch): """Пустые домены - это ошибка настройки, а не повод падать внутри Caddy.""" import app.launcher as launcher class FakeSettings: base_dir = tmp_path models_dir = tmp_path / "models" diarize = False port = 8756 max_upload_mb = 500 https_domains = " " monkeypatch.setattr("app.config.load_settings", lambda: FakeSettings()) monkeypatch.setattr("app.updater.main", lambda: None) monkeypatch.setattr("app.models.ensure_models", lambda *a: []) assert launcher.main(["https"]) == 1