from __future__ import annotations import os import pytest from yuxi.channels.adapters.nextcloudtalk.credentials import ( read_secret_file, resolve_credential, ) class TestReadSecretFile: def test_reads_content(self, tmp_path): file_path = tmp_path / "secret.txt" file_path.write_text(" my-secret-value ", encoding="utf-8") result = read_secret_file(str(file_path)) assert result == "my-secret-value" def test_empty_content(self, tmp_path): file_path = tmp_path / "empty.txt" file_path.write_text(" \n ", encoding="utf-8") result = read_secret_file(str(file_path)) assert result == "" def test_empty_path_raises(self): with pytest.raises(ValueError, match="filepath cannot be empty"): read_secret_file("") def test_file_not_found(self, tmp_path): with pytest.raises(ValueError, match="Secret file not found"): read_secret_file(str(tmp_path / "nonexistent.txt")) def test_symlink_blocked(self, tmp_path): real_file = tmp_path / "real_secret.txt" real_file.write_text("secret", encoding="utf-8") symlink = tmp_path / "symlink_secret.txt" try: if hasattr(os, "symlink"): os.symlink(str(real_file), str(symlink)) with pytest.raises(ValueError, match="symlinks"): read_secret_file(str(symlink)) except OSError: pass class TestResolveCredential: def test_direct_value_wins(self): result = resolve_credential("direct", "file.txt", "MY_ENV") assert result == "direct" def test_file_value_when_no_direct(self): result = resolve_credential(None, None, "PATH") assert result != "" def test_env_value(self): result = resolve_credential(None, None, "PATH") assert len(result) > 0 def test_all_empty_returns_empty(self): result = resolve_credential(None, None, "NONEXISTENT_VAR_XYZZY") assert result == "" def test_file_takes_priority_over_env(self, tmp_path): file_path = tmp_path / "cred.txt" file_path.write_text("file-value", encoding="utf-8") result = resolve_credential(None, str(file_path), "PATH") assert result == "file-value" def test_direct_empty_string_not_used(self): result = resolve_credential("", None, "PATH") assert result != ""