"""SP9 — SFTP stub tests.""" from __future__ import annotations import json from pathlib import Path import pytest from cyclone.clearhouse import SftpClient from cyclone.providers import SftpBlock @pytest.fixture def sftp_block(tmp_path): staging = tmp_path / "staging" return SftpBlock( host="mft.gainwelltechnologies.com", port=22, username="colorado-fts\\coxix_prod_11525703", paths={ "outbound": "/CO XIX/PROD/coxix_prod_11525703/FromHPE", "inbound": "/CO XIX/PROD/coxix_prod_11525703/ToHPE", }, stub=True, staging_dir=str(staging), poll_seconds=300, auth={"method": "keychain", "secret_ref": "sftp.gainwell.password"}, ) def test_stub_writes_preserving_remote_path(sftp_block, tmp_path): client = SftpClient(sftp_block) remote = "/CO XIX/PROD/coxix_prod_11525703/FromHPE/11525703-837P-20260620132243505-1of1.x12" target = client.write_file(remote, b"ISA*00*...~IEA*1*1~") assert target.exists() assert target.read_bytes() == b"ISA*00*...~IEA*1*1~" # Confirm the full nested MFT path is preserved under staging rel = target.relative_to(sftp_block.staging_dir) assert str(rel) == "CO XIX/PROD/coxix_prod_11525703/FromHPE/11525703-837P-20260620132243505-1of1.x12" def test_stub_creates_parent_dirs(sftp_block): client = SftpClient(sftp_block) remote = "/deep/nested/path/file.x12" target = client.write_file(remote, b"data") assert target.exists() assert target.parent.is_dir() def test_stub_list_inbound_empty_when_no_local_files(sftp_block): client = SftpClient(sftp_block) assert client.list_inbound() == [] def test_stub_list_inbound_returns_local_files(sftp_block): # Simulate operator dropping a file in the inbound staging dir inbound_dir = Path(sftp_block.staging_dir) / "CO XIX/PROD/coxix_prod_11525703/ToHPE" inbound_dir.mkdir(parents=True, exist_ok=True) (inbound_dir / "TP11525703-837P_M019048402-20260520231513488-1of1_999.x12").write_bytes(b"X") client = SftpClient(sftp_block) files = client.list_inbound() assert len(files) == 1 assert files[0].name.startswith("TP11525703-837P_M019048402") assert files[0].size == 1 def test_stub_get_secret_returns_stub_when_keychain_empty(sftp_block): client = SftpClient(sftp_block) # Keychain is empty on the test box, so we get the stub sentinel secret = client.get_secret("sftp.gainwell.password") assert secret == "" def test_stub_read_file_raises(sftp_block): client = SftpClient(sftp_block) with pytest.raises(RuntimeError, match="Stub SFTP cannot read"): client.read_file("/x.x12")